第21章 其他文件系统
附录 D. OpenPGP 密钥
14.7.IPsec 上的 VPN
互联网协议安全(IPsec)是一组位于互联网协议(IP)层之上的协议。它允许两个或多个主机通过对通信会话的每个 IP 数据包进行身份验证和加密,以安全的方式进行通信。FreeBSD IPsec 网络堆栈基于 http://www.kame.net/ 实现。同时支持 IPv4 和 IPv6 会话。
IPsec 由以下子协议组成:
  • *封装安全有效负载 (ESP):*此协议通过使用对称加密算法(如 Blowfish 和 3DES)加密内容来保护 IP 数据包数据免受第三方干扰。
  • *身份验证标头 (AH):*此协议通过计算加密校验和并使用安全哈希函数对 IP 数据包标头字段进行哈希处理来保护 IP 数据包标头免受第三方干扰和欺骗。然后,后面是包含哈希的附加标头,以允许对数据包中的信息进行身份验证。
  • IP 有效负载压缩协议 (IPComp):此协议尝试通过压缩 IP 有效负载来提高通信性能,以减少发送的数据量。
这些协议可以一起使用,也可以单独使用,具体取决于环境。
IPsec 支持两种操作模式。第一种模式(传输模式)保护两台主机之间的通信。第二种模式,隧道模式,用于构建虚拟隧道,通常称为虚拟专用网络(VPN)。请查阅 ipsec(4) 以获取有关 FreeBSD 中 IPsec 子系统的详细信息。
默认情况下,IPsec 支持在 FreeBSD 11 及更高版本上是启用的。对于更早的 FreeBSD版本。将这些选项添加到自定义内核配置文件中。然后按照 配置 FreeBSD 内核 中的说明重建内核:
1
options IPSEC IP security
2
device crypto
Copied!
如果需要 IPsec 调试支持,还应添加以下内核选项:
1
options IPSEC_DEBUG debug for IP security
Copied!
本章的其余部分演示了在家庭网络和企业网络之间设置 IPsecVPN 的过程。在示例场景中:
  • 这两个站点都通过运行 FreeBSD 的网关连接到互联网。
  • 每个网络上的网关至少有一个外部 IP 地址。在这个例子中,公司局域网的外部 IP 地址是 172.16.5.4,家庭局域网的外部 IP 地址是 192.168.1.12
  • 两个网络的内部地址可以是公用或私有 IP 地址。但是,地址空间不得重叠。在此示例中,公司 LAN 的内部 IP 地址为 10.246.38.1 ,而家庭 LAN 的内部 IP 地址为 10.0.0.5
1
corporate home
2
10.246.38.1/24 -- 172.16.5.4 <--> 192.168.1.12 -- 10.0.0.5/24
Copied!

14.7.1. 在 FreeBSD 上配置 VPN

首先,必须从 Ports Collection 安装 security/ipsec-tools。该软件提供了许多支持该配置的应用程序。
下一个要求是创建两个 gif(4) 伪设备,它们将用于隧道数据包并允许两个网络正确通信。使用 root 账户,在每个网关上运行以下命令:
1
corp-gw# ifconfig gif0 create
2
corp-gw# ifconfig gif0 10.246.38.1 10.0.0.5
3
corp-gw# ifconfig gif0 tunnel 172.16.5.4 192.168.1.12
4
home-gw# ifconfig gif0 create
5
home-gw# ifconfig gif0 10.0.0.5 10.246.38.1
6
home-gw# ifconfig gif0 tunnel 192.168.1.12 172.16.5.4
Copied!
使用 ifconfig gif0 验证每个网关上的设置。以下是家庭网关的输出:
1
gif0: flags=8051 mtu 1280
2
tunnel inet 172.16.5.4 --> 192.168.1.12
3
inet6 fe80::2e0:81ff:fe02:5881%gif0 prefixlen 64 scopeid 0x6
4
inet 10.246.38.1 --> 10.0.0.5 netmask 0xffffff00
Copied!
下面是企业网关的输出:
1
gif0: flags=8051 mtu 1280
2
tunnel inet 192.168.1.12 --> 172.16.5.4
3
inet 10.0.0.5 --> 10.246.38.1 netmask 0xffffff00
4
inet6 fe80::250:bfff:fe3a:c1f%gif0 prefixlen 64 scopeid 0x4
Copied!
完成后,两个内部 IP 地址都应该可以使用 ping(8) 访问:
1
home-gw# ping 10.0.0.5
2
PING 10.0.0.5 (10.0.0.5): 56 data bytes
3
64 bytes from 10.0.0.5: icmp_seq=0 ttl=64 time=42.786 ms
4
64 bytes from 10.0.0.5: icmp_seq=1 ttl=64 time=19.255 ms
5
64 bytes from 10.0.0.5: icmp_seq=2 ttl=64 time=20.440 ms
6
64 bytes from 10.0.0.5: icmp_seq=3 ttl=64 time=21.036 ms
7
--- 10.0.0.5 ping statistics ---
8
4 packets transmitted, 4 packets received, 0% packet loss
9
round-trip min/avg/max/stddev = 19.255/25.879/42.786/9.782 ms
10
11
corp-gw# ping 10.246.38.1
12
PING 10.246.38.1 (10.246.38.1): 56 data bytes
13
64 bytes from 10.246.38.1: icmp_seq=0 ttl=64 time=28.106 ms
14
64 bytes from 10.246.38.1: icmp_seq=1 ttl=64 time=42.917 ms
15
64 bytes from 10.246.38.1: icmp_seq=2 ttl=64 time=127.525 ms
16
64 bytes from 10.246.38.1: icmp_seq=3 ttl=64 time=119.896 ms
17
64 bytes from 10.246.38.1: icmp_seq=4 ttl=64 time=154.524 ms
18
--- 10.246.38.1 ping statistics ---
19
5 packets transmitted, 5 packets received, 0% packet loss
20
round-trip min/avg/max/stddev = 28.106/94.594/154.524/49.814 ms
Copied!
正如预期的那样,双方都能够从配置的私有地址发送和接收 ICMP 数据包。接下来,必须告知两个网关如何路由数据包,以便网关能够准确的转发来自网关之后的网络流量。使用下面的命令实现这一配置:
1
corp-gw# route add 10.0.0.0 10.0.0.5 255.255.255.0
2
corp-gw# route add net 10.0.0.0: gateway 10.0.0.5
3
home-gw# route add 10.246.38.0 10.246.38.1 255.255.255.0
4
home-gw# route add host 10.246.38.0: gateway 10.246.38.1
Copied!
内部计算机应可从每个网关以及网关后面的计算机访问。同样,使用 ping(8) 确认:
1
corp-gw# ping -c 3 10.0.0.8
2
PING 10.0.0.8 (10.0.0.8): 56 data bytes
3
64 bytes from 10.0.0.8: icmp_seq=0 ttl=63 time=92.391 ms
4
64 bytes from 10.0.0.8: icmp_seq=1 ttl=63 time=21.870 ms
5
64 bytes from 10.0.0.8: icmp_seq=2 ttl=63 time=198.022 ms
6
--- 10.0.0.8 ping statistics ---
7
3 packets transmitted, 3 packets received, 0% packet loss
8
round-trip min/avg/max/stddev = 21.870/101.846/198.022/74.001 ms
9
10
home-gw# ping -c 3 10.246.38.107
11
PING 10.246.38.1 (10.246.38.107): 56 data bytes
12
64 bytes from 10.246.38.107: icmp_seq=0 ttl=64 time=53.491 ms
13
64 bytes from 10.246.38.107: icmp_seq=1 ttl=64 time=23.395 ms
14
64 bytes from 10.246.38.107: icmp_seq=2 ttl=64 time=23.865 ms
15
--- 10.246.38.107 ping statistics ---
16
3 packets transmitted, 3 packets received, 0% packet loss
17
round-trip min/avg/max/stddev = 21.145/31.721/53.491/12.179 ms
Copied!
此时,流量在封装在 gif 隧道中的网络之间传输,但没有任何加密。接下来,使用 IPSec 使用预共享密钥 (PSK) 加密流量。除了 IP 地址之外,两个网关上的 /usr/local/etc/racoon/racoon.conf 将完全相同,并且看起来类似于:
1
path pre_shared_key "/usr/local/etc/racoon/psk.txt"; #location of pre-shared key file
2
log debug; #log verbosity setting: set to 'notify' when testing and debugging is complete
3
4
padding # options are not to be changed
5
{
6
maximum_length 20;
7
randomize off;
8
strict_check off;
9
exclusive_tail off;
10
}
11
12
timer # timing options. change as needed
13
{
14
counter 5;
15
interval 20 sec;
16
persend 1;
17
# natt_keepalive 15 sec;
18
phase1 30 sec;
19
phase2 15 sec;
20
}
21
22
listen # address [port] that racoon will listen on
23
{
24
isakmp 172.16.5.4 [500];
25
isakmp_natt 172.16.5.4 [4500];
26
}
27
28
remote 192.168.1.12 [500]
29
{
30
exchange_mode main,aggressive;
31
doi ipsec_doi;
32
situation identity_only;
33
my_identifier address 172.16.5.4;
34
peers_identifier address 192.168.1.12;
35
lifetime time 8 hour;
36
passive off;
37
proposal_check obey;
38
# nat_traversal off;
39
generate_policy off;
40
41
proposal {
42
encryption_algorithm blowfish;
43
hash_algorithm md5;
44
authentication_method pre_shared_key;
45
lifetime time 30 sec;
46
dh_group 1;
47
}
48
}
49
50
sainfo (address 10.246.38.0/24 any address 10.0.0.0/24 any) # address $network/$netmask $type address $network/$netmask $type ( $type being any or esp)
51
{ # $network must be the two internal networks you are joining.
52
pfs_group 1;
53
lifetime time 36000 sec;
54
encryption_algorithm blowfish,3des;
55
authentication_algorithm hmac_md5,hmac_sha1;
56
compression_algorithm deflate;
57
}
Copied!
有关每个可用选项的说明,请参阅 racoon.conf 的手册页。
安全策略数据库 (SPD) 需要配置。以便 FreeBSD 和 racoon 能够加密和解密主机之间的网络流量。
这可以通过企业网关上的 shell 脚本(类似于以下内容)来实现。此文件将在系统初始化期间使用,并应另存为 /usr/local/etc/racoon/setkey.conf
1
flush;
2
spdflush;
3
# To the home network
4
spdadd 10.246.38.0/24 10.0.0.0/24 any -P out ipsec esp/tunnel/172.16.5.4-192.168.1.12/use;
5
spdadd 10.0.0.0/24 10.246.38.0/24 any -P in ipsec esp/tunnel/192.168.1.12-172.16.5.4/use;
Copied!
一旦应用,可以使用以下命令在两个网关上启动 racoon:
1
# /usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf -l /var/log/racoon.log
Copied!
输出应类似于以下内容:
1
corp-gw# /usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf
2
Foreground mode.
3
2006-01-30 01:35:47: INFO: begin Identity Protection mode.
4
2006-01-30 01:35:48: INFO: received Vendor ID: KAME/racoon
5
2006-01-30 01:35:55: INFO: received Vendor ID: KAME/racoon
6
2006-01-30 01:36:04: INFO: ISAKMP-SA established 172.16.5.4[500]-192.168.1.12[500] spi:623b9b3bd2492452:7deab82d54ff704a
7
2006-01-30 01:36:05: INFO: initiate new phase 2 negotiation: 172.16.5.4[0]192.168.1.12[0]
8
2006-01-30 01:36:09: INFO: IPsec-SA established: ESP/Tunnel 192.168.1.12[0]->172.16.5.4[0] spi=28496098(0x1b2d0e2)
9
2006-01-30 01:36:09: INFO: IPsec-SA established: ESP/Tunnel 172.16.5.4[0]->192.168.1.12[0] spi=47784998(0x2d92426)
10
2006-01-30 01:36:13: INFO: respond new phase 2 negotiation: 172.16.5.4[0]192.168.1.12[0]
11
2006-01-30 01:36:18: INFO: IPsec-SA established: ESP/Tunnel 192.168.1.12[0]->172.16.5.4[0] spi=124397467(0x76a279b)
12
2006-01-30 01:36:18: INFO: IPsec-SA established: ESP/Tunnel 172.16.5.4[0]->192.168.1.12[0] spi=175852902(0xa7b4d66)
Copied!
要确保隧道正常工作,请切换到另一个控制台,并使用 tcpdump(1) 通过以下命令查看网络流量。根据需要更换为网络接口卡 em0
1
corp-gw# tcpdump -i em0 host 172.16.5.4 and dst 192.168.1.12
Copied!
类似于以下内容的数据应显示在控制台上。如果不是,则存在问题,需要调试返回的数据。
1
01:47:32.021683 IP corporatenetwork.com > 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xa)
2
01:47:33.022442 IP corporatenetwork.com > 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xb)
3
01:47:34.024218 IP corporatenetwork.com > 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xc)
Copied!
此时,两个网络都应该可用,并且似乎是同一网络的一部分。很可能两个网络都受到防火墙的保护。若要允许流量在它们之间传输,需要添加规则来传递数据包。对于 ipfw(8) 防火墙。请将以下行添加到防火墙配置文件中:
1
ipfw add 00201 allow log esp from any to any
2
ipfw add 00202 allow log ah from any to any
3
ipfw add 00203 allow log ipencap from any to any
4
ipfw add 00204 allow log udp from any 500 to any
Copied!
注意
规则编号可能需要更改,具体取决于当前的主机配置。
对于 pf(4)ipf(8) 的用户。以下规则应该可以解决问题:
1
pass in quick proto esp from any to any
2
pass in quick proto ah from any to any
3
pass in quick proto ipencap from any to any
4
pass in quick proto udp from any port = 500 to any port = 500
5
pass in quick on gif0 from any to any
6
pass out quick proto esp from any to any
7
pass out quick proto ah from any to any
8
pass out quick proto ipencap from any to any
9
pass out quick proto udp from any port = 500 to any port = 500
10
pass out quick on gif0 from any to any
Copied!
最后,要允许计算机在系统初始化期间启动对 VPN 的支持,请将以下行添加到 /etc/rc.conf
1
ipsec_enable="YES"
2
ipsec_program="/usr/local/sbin/setkey"
3
ipsec_file="/usr/local/etc/racoon/setkey.conf" # allows setting up spd policies on boot
4
racoon_enable="yes"
Copied!
Copy link
Edit on GitHub