0x01 前言

上周我在知乎专栏编写了我博客的服务架构,其中介绍到数据库master-master同步以实现高可用的内容。该服务需要用到2个端口,若SSH隧道则很复杂,此时我选择ipsec服务建立安全隧道,供数据库集群使用。

该知乎专栏请留意以下链接:

数据库集群的相关文章请留意以下链接:

因为我家里用的是电信家庭宽带,虽然有公网IP,但有时候会被屏蔽所有端口的入展数据,所以我选择腾讯云作为服务端,而我家里的服务器作为客户端。

因为只需要给数据库使用,因此不需要配置iptables NAT,只需要制定ipsec两侧的IP即可;

不同于我常用的IKEv2协议,ipsec不需要准备数字证书,但需要准备预共享密钥;不需要配置左右两侧的id等信息。

0x02 安装服务端

首先在腾讯云上安装服务端,为了使用最新版的软件,我一般会到官网下载最新版并自行编译安装。

编译过程可以参考以下文章:

首先在strongswan官网下载最新版源代码:

然后解压、编译和安装即可:

#我喜欢在/root 目录下新建一个文件夹存放用于编译的源代码
mkdir -p /root/codex/ipsec
 
#进入文件夹
cd /root/codex/ipsec
 
#下载strongSwan 源代码
wget https://download.strongswan.org/strongswan-5.6.3.tar.gz
 
#解压
tar zxvf strongswan-5.6.3.tar.gz
 
#进入文件夹
cd strongswan-5.6.3
 
#config ,请注意我将strongSwan 安装在/usr/local/ipsec 这个目录下。
#请根据需要调整安装目录
./configure --prefix=/usr/local/ipsec \
--libexecdir=/usr/local/ipsec/libexec \
--libdir=/usr/local/ipsec/lib \
--sysconfdir=/usr/local/ipsec/etc \
--enable-certexpire  --enable-dhcp \
--enable-eap-dynamic --enable-eap-identity \
--enable-eap-md5 --enable-eap-mschapv2 \
--enable-eap-peap  --enable-eap-radius \
--enable-eap-tls --enable-openssl \
--enable-unity --enable-xauth-eap \
--enable-xauth-pam --enable-eap-tnc \
--enable-eap-ttls --enable-addrblock \
--enable-radattr --disable-gmp

#编译
make
 
#安装
make install
 
#创建软连接到/usr/sbin 
ln /usr/local/ipsec/sbin/ipsec /usr/sbin/
ln /usr/local/ipsec/sbin/swanctl /usr/sbin/

至此已完成软件的编译安装,过程极其简单,因为这款软件的难点在配置与调试。

0x03 配置服务端

首先进入软件的配置文件目录:

[[email protected] ~]# cd /usr/local/ipsec/etc

该目录下有以下文件与文件夹:

[[email protected] etc]# ll
总用量 24
-rw-r--r--  1 root root 1654 8月  13 01:07 ipsec.conf
drwxr-xr-x 10 root root 4096 8月   7 19:51 ipsec.d
-rw-------  1 root root   48 8月   7 21:20 ipsec.secrets
-rw-r--r--  1 root root  682 8月   7 21:21 strongswan.conf
drwxr-xr-x  3 root root 4096 8月   7 19:51 strongswan.d
drwxr-xr-x 16 root root 4096 8月   7 19:51 swanctl
  • ipsec.conf:定义连接规范的配置文件;
  • ipsec.d:放置各类数字证书的文件夹
  • ipsec.secrets:记录用户名、密码与预共享密钥等信息的文件,主要用于本地验证;
  • strongswan.conf:strongswan:配置文件,配置验证服务器与DNS等信息;
  • strongswan.d:strongswan各模块配置文件的目录;
  • swanctl:strongswan认证类型配置文件的目录。

在本文的使用环境中,需要编辑ipsec.conf、ipsec.secrets与strongswan.conf这三个文件。

0x03.1 ipsec.conf

这个文件主要定义连接规范,常用的有ipsec与IKEv2,在本文的需求中,只需要使用psk的ipsec即可,因此配置文件如下:

config setup
     #唯一ID,默认为yes 。账户不能同时登录多台设备,B 上线会把已经在线上的A 强制断开!
     #这里设置为从不进行唯一性检查,如果你想要更高的安全性,请将下面这句移除
     uniqueids = never

conn %default

     #启用主动模式
     aggressive = yes

     #当ipsec服务启动时,加载并拉起connection
     auto = start

     #当意外关闭CHILD_SA时,清理connection
     closeaction = clear

     #连接存活检测间隔时间
     dpddelay = 30s

     #连接存活检测超时时间
     dpdtimeout = 30s

     #非活动时间,超时将关闭CHILD_SA
     inactivity = 30s

     #ike有效期
     ikelifetime = 12h

     #协商重试最大次数
     keyingtries = 3

     #连接最大生命周期,超时需要重新协商
     lifetime = 12h

     #连接超时前20分钟进行重新协商
     margintime = 20m

     #连接存活检测失败后清理connection
     dpdaction = clear

     #防火墙,允许子网内的主机相互联系
     leftfirewall = no

     #ipsec私有网络
     leftsubnet = 0.0.0.0/0

     #客户端IP
     right = %any

     #定义ike协商支持的加密算法
     ike=aes128-sha256-ecp256,aes256-sha384-ecp384,aes128-sha256-modp2048,aes128-sha1-modp2048,aes256-sha384-modp4096,aes256-sha256-modp4096,aes256-sha1-modp4096,aes128-sha256-modp1536,aes128-sha1-modp1536,aes256-sha384-modp2048,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha256-modp1024,aes128-sha1-modp1024,aes256-sha384-modp1536,aes256-sha256-modp1536,aes256-sha1-modp1536,aes256-sha384-modp1024,aes256-sha256-modp1024,aes256-sha1-modp1024!
     
     #定义esp协商支持的加密算法
     esp=aes128gcm16-ecp256,aes256gcm16-ecp384,aes128-sha256-ecp256,aes256-sha384-ecp384,aes128-sha256-modp2048,aes128-sha1-modp2048,aes256-sha384-modp4096,aes256-sha256-modp4096,aes256-sha1-modp4096,aes128-sha256-modp1536,aes128-sha1-modp1536,aes256-sha384-modp2048,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha256-modp1024,aes128-sha1-modp1024,aes256-sha384-modp1536,aes256-sha256-modp1536,aes256-sha1-modp1536,aes256-sha384-modp1024,aes256-sha256-modp1024,aes256-sha1-modp1024,aes128gcm16,aes256gcm16,aes128-sha256,aes128-sha1,aes256-sha384,aes256-sha256,aes256-sha1!

#建立连接规范
conn IKEv1_Psk

     #协商协议
     keyexchange = ikev1

     #启用拆包模块
     fragmentation = yes

     #自动填充路由
     left = %defaultroute

     #服务端认证方式
     leftauth = psk

     #客户端认证方式
     rightauth = psk

     #客户端认证方式2
     rightauth2 = xauth

     #指定ipsec私有IP地址
     rightsourceip = 10.10.1.1

以上配置文件中有几项较为重要的:

  • 连接存活检测相关的配置:因家庭宽带会自动断开,也有可能因为网络抖动引起连接失败,因此需要根据网络延迟进行调试与配置;
  • margintime:建议将重新协商的时间设置为超时前10至20分钟之间;
  • 加密算法:因为新版的strongswan中移除了老旧的加密算法,因此需要手动指定,提高协商的成功率;
  • rightsourceip:为客户端分配一个固定IP,若使用自带的DHCP则很难知道具体是哪一个。

0x03.2 ipsec.secrets

这个文件的内容比较少,在IKEv1_Psk连接规范中有以下参数:

  • 服务端认证方式:leftauth = psk
  • 客户端认证方式:rightauth = psk
  • 客户端认证方式2:rightauth2 = xauth

xauth在这里是用户名与密码的验证,而psk就是预共享密钥,因此,该文件的全部内容为:

: PSK "your_psk"
your_username %any : EAP "your_passwd"

PSK冒号左侧留空,代表此为默认的psk;如果加上用户名,则该用户一定要填写该psk。

0x03.3 strongswan.conf

因为我的环境不需要radius,因此该文件的内容比较简单:

charon {
  i_dont_care_about_security_and_use_aggressive_mode_psk = yes
  dns1=114.114.114.114
  dns2=114.114.115.115
  ikesa_table_size = 2048
  ikesa_table_segments = 48
  reuse_ikesa = no
  load_modular = yes
  threads = 16
  make_before_break = yes

  filelog {
    /var/log/strongswan/charon.log {
      default = 1
      append = no
      flush_line = yes
      ike_name = yes
      time_format = %b %e %T
    }
  }

  syslog {
    identifier = strongswan_syslog
    daemon {
      default = 1
    }
    auth {
      default = 1
    }
  }

  plugins {
    include /usr/local/ipsec/etc/strongswan.d/charon/*.conf
  }

}
include /usr/local/ipsec/etc/strongswan.d/charon/*.conf

因为主动模式存在安全隐患,因此配置文件的第二行有一句非常明显的信息,需要设为yes才能启用主动模式。

其实DNS也是不需要的,毕竟不需要连接公网。

0x03.4 启用与检查

因为我的软件是自行编译的,因此需要将二进制文件链接到sbin目录中,具体请参考本文的“0x02 安装服务端”部分。

然后通过以下命令启动ipsec服务:

#重启
[[email protected] ~]# ipsec restart 

#启动
[[email protected] ~]# ipsec start 

#停止
[[email protected] ~]# ipsec stop

如果需要查看连接情况,则需要使用以下命令:

[[email protected] ~]# ipsec status
Security Associations (0 up, 0 connecting):

当然,还可以通过以下命令实时查看日志:

[[email protected] ~]# swanctl --log

0x04 配置客户端

客户端就没服务端那么多配置项了,同时客户端也可以通过yum安装:

[[email protected] ~]# yum install strongswan -y

然后进入配置文件目录:

#进入相关目录
[[email protected] ~]# cd /etc/strongswan/

#查看文件与文件夹
[[email protected] strongswan]# ll
总用量 20
-rw-r--r--  1 root root 1644 8月  18 19:03 ipsec.conf
-rw-r--r--  1 root root 1727 8月  13 00:31 ipsec.conf.bak
drwx------ 10 root root  119 8月   7 16:20 ipsec.d
-rw-------  1 root root   78 8月   7 16:21 ipsec.secrets
-rw-r--r--  1 root root   90 8月  27 19:55 resolv.conf
-rw-r--r--  1 root root  281 6月   7 03:12 strongswan.conf
drwxr-xr-x  3 root root  267 8月   7 16:20 strongswan.d
drwxr-xr-x 16 root root  218 8月   7 16:20 swanctl

客户端只需要配置ipsec.conf与ipsec.secrets即可。

0x04.1 ipsec.conf

配置文件比较简单:

config setup

conn %default
  ikelifetime=48h
  keyingtries=6
  dpddelay = 30s
  dpdtimeout = 30s
  dpdaction = clear
  ike=aes128-sha256-ecp256,aes256-sha384-ecp384,aes128-sha256-modp2048,aes128-sha1-modp2048,aes256-sha384-modp4096,aes256-sha256-modp4096,aes256-sha1-modp4096,aes128-sha256-modp1536,aes128-sha1-modp1536,aes256-sha384-modp2048,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha256-modp1024,aes128-sha1-modp1024,aes256-sha384-modp1536,aes256-sha256-modp1536,aes256-sha1-modp1536,aes256-sha384-modp1024,aes256-sha256-modp1024,aes256-sha1-modp1024!
  esp=aes128gcm16-ecp256,aes256gcm16-ecp384,aes128-sha256-ecp256,aes256-sha384-ecp384,aes128-sha256-modp2048,aes128-sha1-modp2048,aes256-sha384-modp4096,aes256-sha256-modp4096,aes256-sha1-modp4096,aes128-sha256-modp1536,aes128-sha1-modp1536,aes256-sha384-modp2048,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha256-modp1024,aes128-sha1-modp1024,aes256-sha384-modp1536,aes256-sha256-modp1536,aes256-sha1-modp1536,aes256-sha384-modp1024,aes256-sha256-modp1024,aes256-sha1-modp1024,aes128gcm16,aes256gcm16,aes128-sha256,aes128-sha1,aes256-sha384,aes256-sha256,aes256-sha1!

conn "cn1"
  keyexchange=ikev1
  aggressive=yes
  xauth=client
  leftsourceip=%config 
  leftauth=psk
  rightauth=psk
  leftauth2=xauth
  right=1.1.1.1
  rightid=10.1.1.5
  xauth_identity=your_username
  auto=add
  rightsubnet=10.1.1.5/32

首先还是重要的存活检测,客户端也要配置,发现连接异常时需要尝试重新连接;然后需要配置服务端的IP地址:

  • right:腾讯云的公网IP或域名,用于连接;
  • rightid:腾讯云主机的内网IP,用于识别id;
  • rightsubnet:定义ipsec私有网络的子网。

最后还有一个很重要的:

  • auto:当ipsec启动时的动作,设为add代表自动拉起“cn1”并尝试连接。

如果将strongswan设为开机启动,并且希望自动连接,则需要进行以上配置;如果需要手动连接,则配置为start即可。

0x04.2 ipsec.secrets

该配置文件与服务端的一致即可。

: PSK "your_psk"
your_username : XAUTH "your_passwd"

需要注意ipsec.conf中xauth_identity的值需要与该文件中“XAUTH”的用于名一致。

0x04.3 启动

strongswan自身会以一个守护程序存在系统中,如果在ipsec.conf中定义了多个连接规范,那么将会有多个连接。

因为客户端是通过yum安装的,在centos7中需要通过systemctl启动:

#设为开机启动
[[email protected] ~]# systemctl enable strongswan

#立即启动
[[email protected] ~]# systemctl start strongswan

#检查状态
[[email protected] ~]# systemctl status strongswan
● strongswan.service - strongSwan IPsec IKEv1/IKEv2 daemon using ipsec.conf
   Loaded: loaded (/usr/lib/systemd/system/strongswan.service; enabled; vendor preset: disabled)
   Active: active (running) since 一 2018-08-27 19:43:23 CST; 4h 35min ago
 Main PID: 1262 (starter)
   CGroup: /system.slice/strongswan.service
           ├─1262 /usr/libexec/strongswan/starter --daemon charon --nofork
           └─1447 /usr/libexec/strongswan/charon

如果在连接规范中设定了自动连接,那么通过以下命令将可以看到连接的session:

[[email protected] ~]# strongswan status
Routed Connections:
         cn2{1}:  ROUTED, TUNNEL, reqid 1
         cn2{1}:   10.1.1.29/32 === 10.1.1.5/32
Security Associations (1 up, 0 connecting):
         cn2[2]: ESTABLISHED 4 hours ago, 10.1.1.29[10.1.1.29]...cn2.t.com[10.1.1.5]
         cn2{8}:  INSTALLED, TUNNEL, reqid 1, ESP in UDP SPIs: cd45fa5b_i ce5f3fe8_o
         cn2{8}:   10.10.1.1/32 === 10.1.1.5/32

如果需要关闭连接,则使用以下命令:

[[email protected] ~]# strongswan down cn2
closing CHILD_SA cn2{8} with SPIs cd45fa5b_i (2894464 bytes) ce5f3fe8_o (2698418 bytes) and TS 10.10.1.1/32 === 10.1.1.5/32
sending DELETE for ESP CHILD_SA with SPI cd45fa5b
generating INFORMATIONAL_V1 request 373886275 [ HASH D ]
sending packet: from 10.1.1.29[4500] to cn2.t.com[4500] (92 bytes)
deleting IKE_SA cn2[2] between 10.1.1.29[10.1.1.29]...cn2.t.com[10.1.1.5]
sending DELETE for IKE_SA cn2[2]
generating INFORMATIONAL_V1 request 574225157 [ HASH D ]
sending packet: from 10.1.1.29[4500] to cn2.t.com[4500] (108 bytes)
removing DNS server 114.114.115.115 from /etc/strongswan/resolv.conf
removing DNS server 114.114.114.114 from /etc/strongswan/resolv.conf
IKE_SA [2] closed successfully

如果需要拉起连接,则使用以下命令:

[[email protected] ~]# strongswan up cn2
initiating Aggressive Mode IKE_SA cn2[3] to cn2.t.com
generating AGGRESSIVE request 0 [ SA KE No ID V V V V V ]
sending packet: from 10.1.1.29[500] to cn2.t.com[500] (1060 bytes)
received packet: from cn2.t.com[500] to 10.1.1.29[500] (388 bytes)
parsed AGGRESSIVE response 0 [ SA KE No ID V V V V NAT-D NAT-D HASH ]
received XAuth vendor ID
received DPD vendor ID
received FRAGMENTATION vendor ID
received NAT-T (RFC 3947) vendor ID
local host is behind NAT, sending keep alives
remote host is behind NAT
generating AGGRESSIVE request 0 [ HASH NAT-D NAT-D ]
sending packet: from 10.1.1.29[4500] to cn2.t.com[4500] (140 bytes)
received packet: from cn2.t.com[4500] to 10.1.1.29[4500] (92 bytes)
parsed TRANSACTION request 2868985192 [ HASH CPRQ(X_USER X_PWD) ]
generating TRANSACTION response 2868985192 [ HASH CPRP(X_USER X_PWD) ]
sending packet: from 10.1.1.29[4500] to cn2.t.com[4500] (108 bytes)
received packet: from cn2.t.com[4500] to 10.1.1.29[4500] (92 bytes)
parsed TRANSACTION request 2046926089 [ HASH CPS(X_STATUS) ]
XAuth authentication of 'your_username' (myself) successful
IKE_SA cn2[3] established between 10.1.1.29[10.1.1.29]...cn2.t.com[10.1.1.5]
scheduling reauthentication in 172109s
maximum IKE_SA lifetime 172649s
generating TRANSACTION response 2046926089 [ HASH CPA(X_STATUS) ]
sending packet: from 10.1.1.29[4500] to cn2.t.com[4500] (92 bytes)
generating TRANSACTION request 411176004 [ HASH CPRQ(ADDR DNS) ]
sending packet: from 10.1.1.29[4500] to cn2.t.com[4500] (92 bytes)
received packet: from cn2.t.com[4500] to 10.1.1.29[4500] (108 bytes)
parsed TRANSACTION response 411176004 [ HASH CPRP(ADDR DNS DNS) ]
installing DNS server 114.114.114.114 to /etc/strongswan/resolv.conf
installing DNS server 114.114.115.115 to /etc/strongswan/resolv.conf
installing new virtual IP 10.10.1.1
generating QUICK_MODE request 3319766461 [ HASH SA No KE ID ID ]
sending packet: from 10.1.1.29[4500] to cn2.t.com[4500] (284 bytes)
received packet: from cn2.t.com[4500] to 10.1.1.29[4500] (252 bytes)
parsed QUICK_MODE response 3319766461 [ HASH SA No KE ID ID ]
CHILD_SA cn2{9} established with SPIs c529fce2_i cba021eb_o and TS 10.10.1.1/32 === 10.1.1.5/32
generating QUICK_MODE request 3319766461 [ HASH ]
sending packet: from 10.1.1.29[4500] to cn2.t.com[4500] (76 bytes)
connection 'cn2' established successfully

0x05 测试与使用

在服务端与客户端中并没有配置路由或NAT,因此只支持访问对方的网关。

再次查看以下信息:

[[email protected] ~]# strongswan status
Routed Connections:
         cn2{1}:  ROUTED, TUNNEL, reqid 1
         cn2{1}:   10.1.1.29/32 === 10.1.1.5/32
Security Associations (1 up, 0 connecting):
         cn2[2]: ESTABLISHED 4 hours ago, 10.1.1.29[10.1.1.29]...cn2.t.com[10.1.1.5]
         cn2{8}:  INSTALLED, TUNNEL, reqid 1, ESP in UDP SPIs: cd45fa5b_i ce5f3fe8_o
         cn2{8}:   10.10.1.1/32 === 10.1.1.5/32

注意最后一行,等号左侧为本地的IP,如果在客户端上执行该命令,则为ipsec分配的私有IP地址,如果在服务端上运行该命令,则为服务器网卡IP。因为腾讯云用的是NAT,因此显示为一个内网IP。

等号右侧为对端IP。

此时在客户端与服务端上分别ping对端,如果网络可达则完成配置:

#在服务端上ping客户端
[[email protected] ~]# ping 10.10.1.1
PING 10.10.1.1 (10.10.1.1) 56(84) bytes of data.
64 bytes from 10.10.1.1: icmp_seq=1 ttl=64 time=6.88 ms
64 bytes from 10.10.1.1: icmp_seq=2 ttl=64 time=7.04 ms
64 bytes from 10.10.1.1: icmp_seq=3 ttl=64 time=6.76 ms

#在客户端上ping服务端
[[email protected] ~]# ping 10.1.1.5
PING 10.1.1.5 (10.1.1.5) 56(84) bytes of data.
64 bytes from 10.1.1.5: icmp_seq=1 ttl=64 time=6.95 ms
64 bytes from 10.1.1.5: icmp_seq=2 ttl=64 time=6.75 ms
64 bytes from 10.1.1.5: icmp_seq=3 ttl=64 time=6.97 ms

我在深圳,而腾讯云我选择了广州的数据中心,因此延迟在10ms以内,这有非常利于数据库集群的组建。

数据库集群中位于我家中的节点的配置文件如下:

[galera]
wsrep_on=ON
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
wsrep_cluster_name='wsrep_cluster'
wsrep_cluster_address='gcomm://10.1.1.5:4567'
wsrep_node_address='10.10.1.1:4567'
wsrep_sst_receive_address='10.10.1.1:3306'
binlog_format=row
wsrep_node_name='db-3'
wsrep_sst_auth='db_username:db_passwd'
wsrep_sst_method=mysqldump
bind-address=0.0.0.0

腾讯云中的数据库节点的配置文件如下:

[galera]
wsrep_on=ON
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
wsrep_cluster_name='wsrep_cluster'
wsrep_cluster_address='gcomm://10.10.1.1:4567'
wsrep_node_address='10.1.1.5:4567'
wsrep_sst_receive_address='10.1.1.5:3306'
binlog_format=row
wsrep_node_name='db-2'
wsrep_sst_auth='db_username:db_passwd'
wsrep_sst_method=mysqldump
bind-address=0.0.0.0

0x06 结语

腾讯云和别的大型云服务商一样,服务器上的IP为内网IP,而公网IP支持动态分配,这时候就需要NAT。因此在配置ipsec服务,在建立配置文件时需要注意IP地址的填写。