个人博客:www.fuzoupyy.work 前两天有个刚做网络的小兄弟问我:“现在不都流行SSL VPN或者[WireGuard](https://zhida.zhihu.com/search?content_id=266937248&content_type=Article&match_order=1&q=WireGuard&zhida_source=entity)了吗?[IPsec](https://zhida.zhihu.com/search?content_id=266937248&content_type=Article&match_order=1&q=IPsec&zhida_source=entity)这种‘老古董’是不是没必要学了?” 我当时差点一口老血喷屏幕上。 兄弟,你这就好比在说,现在开自动挡的车多了,手动挡的原理就不重要了?IPsec这玩意儿,就像是网络世界的“重型装甲车”,它是笨重,配置是繁琐,但在Site-to-Site(站点对站点)的连接上,它依然是无可撼动的霸主。你看看现在的公有云,AWS也好,阿里云也罢,跟IDC做专线互联备份的时候,哪个推荐的不是IPsec? 别看WireGuard现在火得一塌糊涂,真到了复杂的企业级环境,还得是IPsec坐镇。 今天咱们就来扒一扒IPsec的底裤,顺便教大家用开源神器[StrongSwan](https://zhida.zhihu.com/search?content_id=266937248&content_type=Article&match_order=1&q=StrongSwan&zhida_source=entity)搭建一套企业级的VPN。 ### **为什么IPsec让人头大?** 咱们先不谈配置,先聊聊为什么这玩意儿难懂。 绝大多数人晕菜,是因为被IKE、[ISAKMP](https://zhida.zhihu.com/search?content_id=266937248&content_type=Article&match_order=1&q=ISAKMP&zhida_source=entity)、[ESP](https://zhida.zhihu.com/search?content_id=266937248&content_type=Article&match_order=1&q=ESP&zhida_source=entity)、[AH](https://zhida.zhihu.com/search?content_id=266937248&content_type=Article&match_order=1&q=AH&zhida_source=entity)、Phase 1、Phase 2这些缩写给绕晕了。 其实,你把IPsec想象成**“押镖”**。 你要把一车黄金(数据包)从北京运到上海。路上有土匪(黑客),你不能直接运。 **第一种方式:AH(Authentication Header)** 这就像是在车厢上贴了个封条,上面盖了皇帝的印(签名)。到了上海,一看封条没坏,就知道东西没被换过,也是朝廷发出来的。 **但是!** 封条只能保证东西没被换,**它不加密**。黄金还是黄金,土匪在路边能看个精光。而且,最坑爹的是,AH会对整个IP头做签名。大家都知道现在网络到处都是NAT(地址转换),路由器一改IP地址,签名就这就对不上了,封条就“碎”了。所以,**在现在的网络环境里,AH基本就是个废柴,很少用。** **第二种方式:ESP(Encapsulating Security Payload)** 这个厉害了。它不仅贴封条,还把黄金装进了保险箱(加密)。土匪截了车,只能看到一个铁箱子,里面是啥完全不知道。 ESP最骚的操作是“隧道模式”。它不光把数据加密,它还把原来的车牌(原IP头)也给拆下来扔进保险箱,然后在外面挂个新车牌(新IP头)。这就是为什么我们在隧道里抓包,只能看到两个网关之间的公网IP在通信,完全看不到内网IP。 ### **那个让人抓狂的协商过程:IKE** 真正让人掉头发的,是IKE(Internet Key Exchange)。 你想啊,两个网关(路由器或服务器)素不相识,怎么建立信任?怎么商量用什么密码?直接在公网上喊:“喂!密码是123456!”那不找死吗? 所以得谈判。这个谈判过程就是IKE。 **第一阶段(Phase 1):建立管理连接** 这就像两个外交官见面,先得在一个绝对安全的屋子里坐下来。 他们要确认对方身份(Pre-Shared Key预共享密钥,或者证书),然后商量:“咱俩待会怎么聊天?用什么加密算法?” 这一步要是通了,就建立了一个叫**ISAKMP SA**的东西。你可以理解为,外交官的保密电话接通了。 这里有个大坑。Phase 1有两种模式:**主模式(Main Mode)**和**野蛮模式(Aggressive Mode)**。 名字听着挺唬人。主模式慢,一来一回6个包,但是安全,它会隐藏身份信息。野蛮模式快,3个包搞定,但是它会把身份ID明文广播出去。 以前为了快,很多老设备喜欢用野蛮模式,现在为了安全,大家基本都切回主模式了。 **第二阶段(Phase 2):建立数据连接** 外交官电话通了(Phase 1成功),现在开始聊正事:怎么运黄金。 这时候商量的才是真正用来加密用户数据的密钥(IPsec SA)。 这就是所谓的“快速模式”(Quick Mode)。 这也是为什么你看日志的时候,经常看到Phase 1过了,Phase 2报错。通常是因为两边的“感兴趣流”(Subnet,也就是你要通的内网网段)没对上。左边说我要通192.168.1.0/24,右边配置写的是192.168.2.0/24,聊不到一块去,崩了。 ### **[NAT-T](https://zhida.zhihu.com/search?content_id=266937248&content_type=Article&match_order=1&q=NAT-T&zhida_source=entity):穿越NAT的救命稻草** 刚才说了,AH过不了NAT。其实ESP过NAT也费劲。 因为NAT路由器会修改端口号,而IPsec设计之初是基于IP层的,没端口号这概念(ESP协议号是50)。 为了解决这个问题,聪明的工程师搞了个**NAT-T(NAT Traversal)**。 简单说,就是把ESP数据包再包一层UDP头部,通常是用UDP 4500端口。这样NAT路由器一看:“哦,是UDP啊,改端口我会!” 于是,IPsec就能在NAT环境里活下来了。 **敲黑板:** 如果你的VPN服务器在防火墙后面,记得防火墙除了开**UDP 500**(IKE协商用),还得开**UDP 4500**(NAT穿透用)。好多人配半天不通,就是因为4500端口没开。 --- ### **实战:用StrongSwan搭建从阿里云到本地IDC的隧道** 理论扯多了容易困,咱们来点实操。 Linux下做IPsec,以前有Openswan、Libreswan,但现在**StrongSwan**是绝对的一哥。它对IKEv2的支持最好,配置也相对“阳间”一点(虽然也没好到哪去)。 假设场景: - **阿里云(左边 Left):** - 公网IP:1.1.1.1 - 内网段:172.16.0.0/16 - **本地IDC(右边 Right):** - 公网IP:2.2.2.2 - 内网段:192.168.10.0/24 系统咱们就用[CentOS 7](https://zhida.zhihu.com/search?content_id=266937248&content_type=Article&match_order=1&q=CentOS+7&zhida_source=entity)或者[Ubuntu 20.04](https://zhida.zhihu.com/search?content_id=266937248&content_type=Article&match_order=1&q=Ubuntu+20.04&zhida_source=entity),都差不多。 **1. 安装StrongSwan** 这就不用我教了吧? `yum install strongswan` 或者 `apt install strongswan`。 **2. 开启内核转发(这点最容易忘!)** 很多人配好了VPN,发现ping不通内网,查了一圈发现是Linux没开启路由转发。 编辑 `/etc/sysctl.conf`: ```bash net.ipv4.ip_forward = 1 # 如果有IPv6也顺手开了 net.ipv6.conf.all.forwarding = 1 ``` 执行 `sysctl -p` 生效。 **3. 配置 ipsec.conf** 这是核心配置文件。虽然StrongSwan出了新的 `swanctl.conf` 格式,但为了照顾老玩家的习惯,咱们还是用经典的 `ipsec.conf`。 阿里云那台机器(1.1.1.1)的配置 `/etc/strongswan/ipsec.conf`: ```bash config setup # 开启调试日志,排错的时候很有用,平时可以关了 charondebug="ike 2, knl 2, cfg 2" uniqueids=no ​ conn ali-to-idc authby=secret # 使用预共享密钥认证 auto=start # 服务启动时自动连接 type=tunnel # 隧道模式 keyexchange=ikev2 # 强烈建议用IKEv2,比v1快且稳 # 左边(本机/阿里云)配置 left=1.1.1.1 # 本机公网IP leftid=1.1.1.1 # 标识ID,通常和IP一样 leftsubnet=172.16.0.0/16 # 本机要暴露给对端的内网段 # 右边(远端/IDC)配置 right=2.2.2.2 rightid=2.2.2.2 rightsubnet=192.168.10.0/24 # 加密算法(这个得两边商量好,必须一模一样!) ike=aes256-sha256-modp1024! esp=aes256-sha256! # 存活检测 dpddelay=30s dpdtimeout=120s dpdaction=restart ``` **本地IDC那台机器的配置,基本就是反过来。** 把 `left` 换成 2.2.2.2,`right` 换成 1.1.1.1,subnet也对调一下。 这里有个细节:**`left` 不一定非得写公网IP。** 如果你的服务器是在NAT后面(比如AWS EC2,或者家里路由器后面的虚拟机),`left` 其实应该写内网IP,然后 `leftid` 写公网IP。这块逻辑如果没理顺,StrongSwan根本起不来。 **4. 配置密码 ipsec.secrets** 这个文件简单,就是存密码的。两边得一样。 ```bash # 格式:IP1 IP2 : PSK "你的超强密码" 1.1.1.1 2.2.2.2 : PSK "YoyouIsHandsome2025" ``` 记得这个文件权限要设成600,不然StrongSwan会报错说不安全。 **5. 启动与排错** 启动:`systemctl start strongswan` 查看状态:`strongswan statusall` 如果一切顺利,你会看到类似 `Security Associations (1 up, 0 connecting)` 的字样,那就是通了! ### **要是通不了怎么办?(运维的日常崩溃)** 这时候就显出真本事了。 要是状态里显示 `CONNECTING` 然后一直卡着,或者直接 `0 up`,千万别慌。 **第一招:看日志。** `tail -f /var/log/syslog` 或者 `/var/log/messages`。 如果你看到 `NO_PROPOSAL_CHOSEN`,这绝对是两边加密算法没对齐。比如一边配了AES128,另一边是AES256;或者一边是SHA1,另一边是SHA256。仔细检查 `ike=` 和 `esp=` 这两行。 **第二招:检查防火墙。** 再强调一遍,UDP 500 和 UDP 4500。 还有,云厂商的安全组!阿里云的安全组入方向开了吗? **第三招:MSS(最大报文段长度)问题。** 这是个隐形杀手。 VPN加上了ESP头,包变大了。如果原来是1500字节,加上头就超了,会被分片或者丢弃。 现象就是:**ping是通的,但SSH连不上,或者网页打不开。** 这时候需要在防火墙(iptables)里做个手脚,把MSS改小点: ```bash iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu ``` 或者暴力点,直接设成1300: ```bash iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1300 ``` 这招下去,90%的“怪病”都能好。 ### **总结** 说实话,配置IPsec VPN是一件挺枯燥的事,配置文件里哪怕多了一个空格,或者少了一个感叹号,都能让你查半天。 但这就是运维的价值所在啊。 当那条隧道打通,两边内网的数据像流水一样无缝传输的时候,那种成就感,真的是WireGuard这种“傻瓜式”工具给不了的(虽然我也很爱WireGuard,哈哈)。 而且,搞懂了IPsec,你再去看SD-WAN,看云专线,其实底层逻辑都是通的。 我知道这篇内容有点硬,可能大家得消化一会儿。建议收藏起来,下次被VPN折磨的时候,拿出来对一对配置,说不定就救了你的命。 技术这东西,没有什么捷径,就是一遍遍试错试出来的。 如果你在配置过程中遇到了奇葩的报错,或者对加密算法的选择有疑问,欢迎在评论区留言,咱一起探讨探讨。