我们用 VPN 传送的数据是没有经过加密的。为了不让别人知道我们传送了什么数据,可以使用加密工具来加密两台计算机或者两个子网之间传输的数据。使用 IPSec,可以对两台主机之间的通信进行加密,而不仅仅加密 VPN 通信。openvpn 可以建立使用 SSL 加密的 VPN 连接。本文仅介绍 IPSec 的配置方法。
下面是 IPSec 的配置过程。
操作系统:FreeBSD13.1-RELEASE。
要使用 IPSec,需要安装 ipsec-tools,它在 ports 树中的 /usr/ports/security 目录下面。分别在两台主机上安装 ipsec-tools:
# pkg install ipsec-tools
使用 FreeBSD 的 ports 树,我们可以看到很多软件,可以通过 pkg-descr 文件看它的功能是什么。大多数软件都有示例配置。FreeBSD 拥有全面细致的手册,能够解决安装配置和使用中遇到的许多问题。软件自带示例配置,在 /usr/local/share/examples 目录下面。
一、两个主机之间的数据加密。
主机一:10.10.10.74 主机二:10.10.10.92。两个主机都已经安装了ipsec-tools。
两个主机之间能够通常通信:
主机一(10.10.10.74)配置:
创建文件 /usr/local/etc/psk.txt,并设置属性:
# cd /usr/local/etc
# echo "10.10.10.92 abcdefg1234567">>psk.txt
# chmod 400 psk.txt
创建文件 sekey.conf,内容如下:
#!/sbin/setkey -f
flush;
spdflush;
spdadd 10.10.10.74 10.10.10.92 any -P out ipsec esp/transport//require ah/transport//require;
spdadd 10.10.10.92 10.10.10.74 any -P in ipsec esp/transport//require ah/transport//require;
创建文件 racoon.conf,内容如下:
path pre_shared_key "/usr/local/etc/racoon/psk.txt" ;
listen # address [port] that racoon will listen on
{
isakmp 10.10.10.74 [500];
isakmp_natt 10.10.10.74 [4500];
}
remote anonymous
{
exchange_mode mAIn,base;
lifetime time 24 hour ; # sec,min,hour
proposal {
encryption_algorithm 3des;
hash_algorithm sha1;
authentication_method pre_shared_key ;
dh_group 2 ;
}
proposal_check strict;
}
sainfo anonymous
{
pfs_group 2;
lifetime time 12 hour ;
encryption_algorithm aes 256;
authentication_algorithm hmac_sha1;
compression_algorithm deflate ;
}
执行命令:
# setkey -f /usr/local/etc/racoon/setkey.conf
用下面的命令可以看到 setkey.conf 文件的两项已经装入:
# setkey -DP
10.10.10.92[any] 10.10.10.74[any] any
in ipsec
esp/transport//require
ah/transport//require
spid=6 seq=1 pid=15268 scope=global
refcnt=1
10.10.10.74[any] 10.10.10.92[any] any
out ipsec
esp/transport//require
ah/transport//require
spid=5 seq=0 pid=15268 scope=global
refcnt=1
执行下面的命令:
# /usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf -l /var/log/racoon.log
Foreground mode.
2022-06-15 16:49:32: INFO: @(#)ipsec-tools 0.8.2 (http://ipsec-tools.sourceforge.NET)
2022-06-15 16:49:32: INFO: @(#)This product linked OpenSSL 1.1.1o-freebsd 3 May 2022 (http://www.openssl.org/)
2022-06-15 16:49:32: INFO: Reading configuration from "/usr/local/etc/racoon/racoon.conf"
2022-06-15 16:49:32: WARNING: setsockopt(UDP_ENCAP_ESPINUDP): UDP_ENCAP Protocol not available
2022-06-15 16:49:32: ERROR: privsep_setsockopt (Protocol not available)
2022-06-15 16:49:32: ERROR: privsep_setsockopt (Protocol not available)
2022-06-15 16:49:32: INFO: 10.10.10.92[4500] used as isakmp port (fd=5)
2022-06-15 16:49:32: ERROR: privsep_setsockopt (Protocol not available)
2022-06-15 16:49:32: ERROR: privsep_setsockopt (Protocol not available)
2022-06-15 16:49:32: INFO: 10.10.10.92[500] used as isakmp port (fd=6)
提示错误。原因是默认安装的操作系统内核没有 ipsec 支持。可以定制内核,重新编译安装就行了。我在内核配置文件中加上了下面两行:
options IPSEC
options IPSEC_DEBUG
也可以不定制内核,直接用下面的命令动态加载 ipsec:
# kldload ipsec.ko
这时再执行下面的命令就显示正常:
# /usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf -l /var/log/racoon.log
Foreground mode.
2022-06-15 16:50:51: INFO: @(#)ipsec-tools 0.8.2 (http://ipsec-tools.sourceforge.net)
2022-06-15 16:50:51: INFO: @(#)This product linked OpenSSL 1.1.1o-freebsd 3 May 2022 (http://www.openssl.org/)
2022-06-15 16:50:51: INFO: Reading configuration from "/usr/local/etc/racoon/racoon.conf"
2022-06-15 16:50:51: INFO: 10.10.10.92[4500] used for NAT-T
2022-06-15 16:50:51: INFO: 10.10.10.92[4500] used as isakmp port (fd=5)
2022-06-15 16:50:51: INFO: 10.10.10.92[500] used as isakmp port (fd=6)
主机二(10.10.10.92)配置:
复制上面的文件到同一目录下(可以用 scp 或者 sftp 复制)。将配置文件中的 IP 地址对调,即把 10.10.10.74 全部换成 10.10.10.92
加载 ipsec 支持:
# kldload ipsec.ko
依次执行前面主机一执行过的两个命令:
# setkey -f /usr/local/etc/racoon/setkey.conf
# /usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf -l /var/log/racoon.log
Foreground mode.
2022-06-15 09:51:49: INFO: @(#)ipsec-tools 0.8.2 (http://ipsec-tools.sourceforge.net)
2022-06-15 09:51:49: INFO: @(#)This product linked OpenSSL 1.1.1o-freebsd 3 May 2022 (http://www.openssl.org/)
2022-06-15 09:51:49: INFO: Reading configuration from "/usr/local/etc/racoon/racoon.conf"
2022-06-15 09:51:49: INFO: 10.10.10.74[4500] used for NAT-T
2022-06-15 09:51:49: INFO: 10.10.10.74[4500] used as isakmp port (fd=5)
2022-06-15 09:51:49: INFO: 10.10.10.74[500] used as isakmp port (fd=6)
在主机一ping主机二,会这样显示:
第一次ping,丢掉了两个包,建立加密连接之后,就正常了。
看主机一的输出:
2022-06-15 09:51:49: INFO: @(#)ipsec-tools 0.8.2 (http://ipsec-tools.sourceforge.net)
2022-06-15 09:51:49: INFO: @(#)This product linked OpenSSL 1.1.1o-freebsd 3 May 2022 (http://www.openssl.org/)
2022-06-15 09:51:49: INFO: Reading configuration from "/usr/local/etc/racoon/racoon.conf"
2022-06-15 09:51:49: INFO: 10.10.10.74[4500] used for NAT-T
2022-06-15 09:51:49: INFO: 10.10.10.74[4500] used as isakmp port (fd=5)
2022-06-15 09:51:49: INFO: 10.10.10.74[500] used as isakmp port (fd=6)
2022-06-15 09:52:28: INFO: IPsec-SA request for 10.10.10.92 queued due to no phase1 found.
2022-06-15 09:52:28: INFO: initiate new phase 1 negotiation: 10.10.10.74[500]<=>10.10.10.92[500]
2022-06-15 09:52:28: INFO: begin Identity Protection mode.
2022-06-15 09:52:28: INFO: received Vendor ID: DPD
2022-06-15 09:52:28: INFO: ISAKMP-SA established 10.10.10.74[500]-10.10.10.92[500] spi:9c05e88e55dd0ead:3be77ea323c63ae8
2022-06-15 09:52:28: [10.10.10.92] INFO: received INITIAL-CONTACT
2022-06-15 09:52:29: INFO: initiate new phase 2 negotiation: 10.10.10.74[500]<=>10.10.10.92[500]
2022-06-15 09:52:29: INFO: IPsec-SA established: AH/Transport 10.10.10.74[500]->10.10.10.92[500] spi=187131851(0xb2767cb)
2022-06-15 09:52:29: INFO: IPsec-SA established: ESP/Transport 10.10.10.74[500]->10.10.10.92[500] spi=196520647(0xbb6aac7)
2022-06-15 09:52:29: INFO: IPsec-SA established: AH/Transport 10.10.10.74[500]->10.10.10.92[500] spi=56908505(0x3645ad9)
2022-06-15 09:52:29: INFO: IPsec-SA established: ESP/Transport 10.10.10.74[500]->10.10.10.92[500] spi=170687013(0xa2c7a25)
主机二的输出:
Foreground mode.
2022-06-15 17:52:11: INFO: @(#)ipsec-tools 0.8.2 (http://ipsec-tools.sourceforge.net)
2022-06-15 17:52:11: INFO: @(#)This product linked OpenSSL 1.1.1o-freebsd 3 May 2022 (http://www.openssl.org/)
2022-06-15 17:52:11: INFO: Reading configuration from "/usr/local/etc/racoon/racoon.conf"
2022-06-15 17:52:11: INFO: 10.10.10.92[4500] used for NAT-T
2022-06-15 17:52:11: INFO: 10.10.10.92[4500] used as isakmp port (fd=5)
2022-06-15 17:52:11: INFO: 10.10.10.92[500] used as isakmp port (fd=6)
2022-06-15 17:52:27: INFO: respond new phase 1 negotiation: 10.10.10.92[500]<=>10.10.10.74[500]
2022-06-15 17:52:27: INFO: begin Identity Protection mode.
2022-06-15 17:52:27: INFO: received Vendor ID: DPD
2022-06-15 17:52:27: INFO: ISAKMP-SA established 10.10.10.92[500]-10.10.10.74[500] spi:9c05e88e55dd0ead:3be77ea323c63ae8
2022-06-15 17:52:27: [10.10.10.74] INFO: received INITIAL-CONTACT
2022-06-15 17:52:28: INFO: respond new phase 2 negotiation: 10.10.10.92[500]<=>10.10.10.74[500]
2022-06-15 17:52:28: INFO: IPsec-SA established: AH/Transport 10.10.10.92[500]->10.10.10.74[500] spi=56908505(0x3645ad9)
2022-06-15 17:52:28: INFO: IPsec-SA established: ESP/Transport 10.10.10.92[500]->10.10.10.74[500] spi=170687013(0xa2c7a25)
2022-06-15 17:52:28: INFO: IPsec-SA established: AH/Transport 10.10.10.92[500]->10.10.10.74[500] spi=187131851(0xb2767cb)
2022-06-15 17:52:28: INFO: IPsec-SA established: ESP/Transport 10.10.10.92[500]->10.10.10.74[500] spi=196520647(0xbb6aac7)
到路由器用 tcpdump 查看传送的数据:
# tcpdump -i em0 host 10.10.10.92 and dst 10.10.10.74
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on em0, link-type EN10MB (Ethernet), capture size 262144 bytes
09:56:29.252361 IP 10.10.10.92 > 10.10.10.74: AH(spi=0x0b2767cb,seq=0x5): ESP(spi=0x0bb6aac7,seq=0x5), length 84
09:56:29.254597 IP 10.10.10.92 > 10.10.10.74: AH(spi=0x0b2767cb,seq=0x6): ESP(spi=0x0bb6aac7,seq=0x6), length 372
09:56:29.254961 IP 10.10.10.92 > 10.10.10.74: AH(spi=0x0b2767cb,seq=0x7): ESP(spi=0x0bb6aac7,seq=0x7), length 84
09:56:29.255449 IP 10.10.10.92 > 10.10.10.74: AH(spi=0x0b2767cb,seq=0x8): ESP(spi=0x0bb6aac7,seq=0x8), length 84
表明数据已经被加密。退出 racoon,再用 tcpdump 查看数据,显示这样:
# tcpdump -i em0 host 10.10.10.92 and dst 10.10.10.74
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on em0, link-type EN10MB (Ethernet), capture size 262144 bytes
09:59:01.746824 IP 10.10.10.92.http > 10.10.10.74.54689: Flags [S.], seq 4062076932, ack 3510823228, win 65535, options [mss 1460,nop,wscale 6,sackOK,TS val 3952843041 ecr 1536066686], length 0
09:59:01.748276 IP 10.10.10.92.http > 10.10.10.74.54689: Flags [P.], seq 1:303, ack 266, win 1027, options [nop,nop,TS val 3952843041 ecr 1536066687], length 302: HTTP: HTTP/1.1 200 OK
09:59:01.748480 IP 10.10.10.92.http > 10.10.10.74.54689: Flags [F.], seq 303, ack 266, win 1027, options [nop,nop,TS val 3952843041 ecr 1536066687], length 0
09:59:01.748796 IP 10.10.10.92.http > 10.10.10.74.54689: Flags [.], ack 267, win 1026, options [nop,nop,TS val 3952843041 ecr 1536066688], length 0
能看到传送的内容是http内容,已经不再加密,说明已经配置成功。加密前后都是执行同一命令:
lynx http://10.10.10.92
退出 racoon 之后,两台机器可能就连不通了。可在两边创建文件 setkey.x,文件内容如下:
#!/sbin/setkey -f
flush;
spdflush;
#spdadd 10.10.10.74 10.10.10.92 any -P out ipsec esp/transport//require ah/transport//require;
#spdadd 10.10.10.92 10.10.10.74 any -P in ipsec esp/transport//require ah/transport//require;
也就是把 setkey.conf 后面两项注释或删除掉,然后两边执行命令:
# setkey -f /usr/local/etc/racoon/setkey.x
此后两边恢复正常通信,传送的数据不再加密。
二、两个子网之间的数据加密。
子网一:10.10.10.0 路由器:10.10.10.99
子网二:172.15.0.0 路由器:172.15.0.19
先在两子网之间先建立 VPN 连接,然后再加密两台路由器之间的数据。因为我用的是动态 IP 地址,自动建立并保持 VPN 连接,然后再加密。如果知道双方的公网 IP 地址,也是可以将 VPN 一起加密的。ipsec 通过 500 或者 4500 端口连接,加密之后,就没人知道你使用 VPN 连接了。这种方法听起来更科学。
分别安装 ipsec-tools,加载 ipsec 模块:
# pkg install ipsec-tools
# kldload ipsec
可用下面的命令来查看系统加载了哪些模块:
# kldstat
Id Refs Address Size Name
1 33 0xffffffff80200000 1f30590 kernel
2 1 0xffffffff82131000 1fee0 ipsec.ko
3 1 0xffffffff82319000 3218 intpm.ko
4 1 0xffffffff8231d000 2180 smbus.ko
5 1 0xffffffff82320000 39c0 ng_socket.ko
6 9 0xffffffff82324000 aac8 netgraph.ko
7 1 0xffffffff8232f000 43c4 ng_mppc.ko
8 1 0xffffffff82334000 20b0 rc4.ko
9 1 0xffffffff82337000 2398 ng_iface.ko
10 1 0xffffffff8233a000 61e8 ng_ppp.ko
11 1 0xffffffff82341000 2138 ng_tee.ko
12 1 0xffffffff82344000 3278 ng_pptpgre.ko
13 1 0xffffffff82348000 31e8 ng_ksocket.ko
14 1 0xffffffff8234c000 3138 ng_vjc.ko
15 1 0xffffffff82350000 2a08 mac_ntpd.ko
16 1 0xffffffff82353000 2138 ng_tcpmss.ko
子网一:10.10.10.0 路由器 10.10.10.99 的配置:
创建 psk.txt 文件
# cd /usr/local/etc/racoon
# echo "172.15.0.19 abcdefg123456">psk.txt
# chmod 400 psk.txt
setkey.conf 文件内容:
flush;
spdflush;
# To the home network
spdadd 10.10.10.0/24 172.15.0.0/24 any -P out ipsec esp/tunnel/10.10.10.99-172.15.0.19/use;
spdadd 172.15.0.0/24 10.10.10.0/24 any -P in ipsec esp/tunnel/172.15.0.19-10.10.10.99/use;
racoon.conf 文件内容:
path pre_shared_key "/usr/local/etc/racoon/psk.txt"; #location of pre-shared key file
#log debug; #log verbosity setting: set to 'notify' when testing and debugging is complete
padding # options are not to be changed
{
maximum_length 20;
randomize off;
strict_check off;
exclusive_tail off;
}
timer # timing options. change as needed
{
counter 5;
interval 20 sec;
persend 1;
# natt_keepalive 15 sec;
phase1 30 sec;
phase2 15 sec;
}
listen # address [port] that racoon will listen on
{
isakmp 10.10.10.99 [500];
isakmp_natt 10.10.10.99 [4500];
}
remote anonymous [500]
{
exchange_mode main,aggressive;
doi ipsec_doi;
situation identity_only;
my_identifier address 10.10.10.99;
peers_identifier address 172.15.0.19;
lifetime time 8 hour;
passive off;
proposal_check obey;
# nat_traversal off;
generate_policy off;
proposal {
encryption_algorithm blowfish;
hash_algorithm md5;
authentication_method pre_shared_key;
lifetime time 30 sec;
dh_group 1;
}
}
sainfo (address 10.10.10.0/24 any address 172.15.0.0/24 any) # address $network/$netmask $type address $network/$netmask $type ( $type being any or esp)
{ # $network must be the two internal networks you are joining.
pfs_group 1;
lifetime time 36000 sec;
encryption_algorithm aes 256;
authentication_algorithm hmac_sha1;
compression_algorithm deflate;
}
子网二:172.15.0.0 路由器:172.15.0.19 的配置。
配置和前述路由器的配置相似,将IP地址和子网地址对调,或者对应更换 IP 地址。
配置完成之后,两端分别执行以下命令:
# setkey -f /usr/local/etc/racoon/setkey.conf
# # /usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf -l /var/log/racoon.log
在内网访问对方内网机器,在路由器运行 tcpdump,会看到类似以下内容:
# tcpdump -i ng0 host 172.15.0.19 and dst 10.10.10.99
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ng0, link-type NULL (BSD loopback), capture size 262144 bytes
10:24:29.593381 IP 172.15.0.19 > 10.10.10.99: ESP(spi=0x0936e5a7,seq=0x7a7), length 100
10:24:29.609804 IP 172.15.0.19 > 10.10.10.99: ESP(spi=0x0936e5a7,seq=0x7a8), length 100
10:24:29.625372 IP 172.15.0.19 > 10.10.10.99: ESP(spi=0x0936e5a7,seq=0x7a9), length 100
10:24:29.625393 IP 172.15.0.19 > 10.10.10.99: ESP(spi=0x0936e5a7,seq=0x7aa), length 164
10:24:29.646215 IP 172.15.0.19 > 10.10.10.99: ESP(spi=0x0936e5a7,seq=0x7ab), length 84
10:24:29.688834 IP 172.15.0.19 > 10.10.10.99: ESP(spi=0x0936e5a7,seq=0x7ac), length 100
10:24:29.688852 IP 172.15.0.19 > 10.10.10.99: ESP(spi=0x0936e5a7,seq=0x7ad), length 100
10:24:29.689152 IP 172.15.0.19 > 10.10.10.99: ESP(spi=0x0936e5a7,seq=0x7ae), length 1316
10:24:29.689239 IP 172.15.0.19 > 10.10.10.99: ESP(spi=0x0936e5a7,seq=0x7af), length 1316
10:24:29.689306 IP 172.15.0.19 > 10.10.10.99: ESP(spi=0x0936e5a7,seq=0x7b0), length 500
说明两内网之间的通信已经成功加密。查看另一个网卡的通信数据:
# tcpdump -i em0 host 172.15.0.19 and dst 10.10.10.1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on em0, link-type EN10MB (Ethernet), capture size 262144 bytes
10:28:01.303099 IP 172.15.0.19.http > 10.10.10.1.60732: Flags [S.], seq 2241464426, ack 4023246556, win 65535, options [mss 1352,nop,wscale 6,sackOK,eol], length 0
10:28:01.391391 IP 172.15.0.19.http > 10.10.10.1.60732: Flags [.], ack 460, win 1036, length 0
10:28:01.504631 IP 172.15.0.19.http > 10.10.10.1.60732: Flags [.], seq 1:1236, ack 460, win 1036, length 1235: HTTP: HTTP/1.1 200 OK
10:28:01.504753 IP 172.15.0.19.http > 10.10.10.1.60732: Flags [.], seq 1236:2471, ack 460, win 1036, length 1235: HTTP
10:28:01.504772 IP 172.15.0.19.http > 10.10.10.1.60732: Flags [P.], seq 2471:2889, ack 460, win 1036, length 418: HTTP
ng0 是 mpd5 建立 VPN 连接时创建的,em0 是内部网的网卡。可见数据进入子网内部之后是以明文方式传送的,我访问的是 http 服务。
要在机器启动时自动加载 ipsec 来加密通信,可在 /etc/rc.conf 文件中加入以下几行。
ipsec_enable="YES"
ipsec_program="/usr/local/sbin/setkey"
ipsec_file="/usr/local/etc/racoon/setkey.conf"
racoon_enable="yes"
如果机器启动时没有加载 ipsec,可以在 /boot/loader.conf 中加入
ipsec_load="YES"
以后重新启动机器,就会自动启动ipsec。