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 配置服务端
首先进入软件的配置文件目录:
[root@cn2 ~]# cd /usr/local/ipsec/etc
该目录下有以下文件与文件夹:
[root@cn2 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服务:
#重启 [root@cn2 ~]# ipsec restart #启动 [root@cn2 ~]# ipsec start #停止 [root@cn2 ~]# ipsec stop
如果需要查看连接情况,则需要使用以下命令:
[root@cn2 ~]# ipsec status Security Associations (0 up, 0 connecting):
当然,还可以通过以下命令实时查看日志:
[root@cn2 ~]# swanctl --log
0x04 配置客户端
客户端就没服务端那么多配置项了,同时客户端也可以通过yum安装:
[root@pub-db ~]# yum install strongswan -y
然后进入配置文件目录:
#进入相关目录 [root@pub-db ~]# cd /etc/strongswan/ #查看文件与文件夹 [root@pub-db 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启动:
#设为开机启动 [root@pub-db ~]# systemctl enable strongswan #立即启动 [root@pub-db ~]# systemctl start strongswan #检查状态 [root@pub-db ~]# 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:
[root@pub-db ~]# 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
如果需要关闭连接,则使用以下命令:
[root@pub-db ~]# 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
如果需要拉起连接,则使用以下命令:
[root@pub-db ~]# 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,因此只支持访问对方的网关。
再次查看以下信息:
[root@pub-db ~]# 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客户端 [root@cn2 ~]# 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服务端 [root@pub-db ~]# 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地址的填写。