用docker一步搭建VPN(L2TP)
昨天在阿里云服务器内网搭建了pptp协议的VPN,但是在使用的过程中出了问题,一般的例如curl、wget的请求能够正常使用VPN网络,但是使用docker pull 命令拉取镜像时,进度条走不到一秒钟就停下来了,ping www.baidu.com
连ip都无法显示出来,不仅VPN假死,DNS解析都受到了影响。于是查看系统日志,发现丢包严重,即VPN服务器发送给当前服务器的数据包基本被丢弃了,百度谷歌均无果,再折腾了路由表,也没有任何好转,于是怀疑是pptp协议的锅,准备使用L2TP协议试试。
除了上面提到的VPN客户端使用docker遇到的问题,其实服务端也受到了很大影响,按照昨天的配置方式,在配置nat转发时我们改动了iptables、而docker默认情况下端口映射的实现就是使用iptables、所以昨天的配置其实是影响到了VPN服务端的docker的正常运行,即便通过修改配置能够兼容到docker,后期修改时稍有不慎,直接就影响到业务了。作为一个docker爱好者,早应该想到无侵入形式的docker部署VPN。
好了,话不多说。
1、编写docker-compose编排文件
vi /data/docker/l2tp-ipsec-vpn-server/docker-compose.yml
main:
image: fcojean/l2tp-ipsec-vpn-server
environment:
- VPN_IPSEC_PSK=abcdefg#itmx
- VPN_USER_CREDENTIAL_LIST=[{"login":"itmx","password":"123456789"}]
- VPN_PUBLIC_IP=VPN服务器的IP,若无此项,默认为公网IP
ports:
- "500:500/udp"
- "4500:4500/udp"
volumes:
- /lib/modules:/lib/modules:ro
privileged: true
restart: always
写好编排文件之后,需要在 Docker 主机上加载 IPsec af_key 内核模块:
sudo modprobe af_key
2、启动容器
docker-compose up -d
别忘记在安全组中放行UDP协议500和4500端口哦
3、查看启动状态
#查看日志
docker-compose logs -f
#如需查看你的 IPsec VPN 服务器状态,可以在容器中运行 ipsec status 命令
docker exec -it l2tpipsecvpnserver_main_1 ipsec status
#若要查看当前已建立的 VPN 连接
docker exec -it l2tpipsecvpnserver_main_1 ipsec whack --trafficstatus
如果日志输出如下,则是创建成功了,如果没有日志输出,那可能是忘记加载模块,执行之后再试试
Attaching to l2tpipsecvpnserver_main_1
main_1 | Trying to auto discover IPs of this server...
main_1 | ================================================
main_1 | IPsec VPN server is now ready for use!
main_1 | Connect to your new VPN with these details:
main_1 | DNS: 8.8.8.8
main_1 | Server IP: 你的公网IP
main_1 | IPsec PSK: abcdefg#itmx
main_1 | Users credentials :
main_1 | Login : itmx Password : 123456789
main_1 | Write these down. You'll need them to connect!
main_1 | Setup VPN Clients: https://git.io/vpnclients
main_1 | ================================================
main_1 | Redirecting to: /etc/init.d/ipsec start
main_1 | Starting pluto IKE daemon for IPsec: Initializing NSS database ...
到此,VPN服务端就建立成功了!没错,你没看错,用Docker就是这么简单!
4、连接VPN
我这里主要介绍的是centos 7下连接L2TP,其他其他下连接请参考文末参考连接
如果服务器也使用docker,先检查一下IP转发是否开启
#检查是否开启ip转发,结果是1则已开启
cat /proc/sys/net/ipv4/ip_forward
#如果结果不是1,则
vi /etc/sysctl.conf
#修改或加入此行
net.ipv4.ip_forward = 1
#再通过以下命令使配置生效
sysctl -p
第一步、安装软件
yum -y install epel-release yum --enablerepo=epel -y install strongswan xl2tpd
第二步、编写配置文件
先准备几个必须的变量,从服务端的日志中可以获得
VPN_SERVER_IP='你的VPN服务器IP'
VPN_IPSEC_PSK='你的IPsec预共享密钥'
VPN_USER='你的VPN用户名'
VPN_PASSWORD='你的VPN密码'
接下来配置 strongSwan
:
cat > /etc/ipsec.conf <<EOF
# ipsec.conf - strongSwan IPsec configuration file
# basic configuration config setup
# strictcrlpolicy=yes
# uniqueids = no
# Add connections here.
# Sample VPN connections conn %default
ikelifetime=60m
keylife=20m
rekeymargin=3m
keyingtries=1
keyexchange=ikev1
authby=secret
ike=aes128-sha1-modp1024,3des-sha1-modp1024!
esp=aes128-sha1-modp1024,3des-sha1-modp1024!
conn myvpn
keyexchange=ikev1
left=%defaultroute
auto=add
authby=secret
type=transport
leftprotoport=17/1701
rightprotoport=17/1701
right=$VPN_SERVER_IP
EOF
cat > /etc/ipsec.secrets <<EOF : PSK "$VPN_IPSEC_PSK" EOF
chmod 600 /etc/ipsec.secrets
# For CentOS/RHEL & Fedora ONLY
mv /etc/strongswan/ipsec.conf /etc/strongswan/ipsec.conf.old 2>/dev/null
mv /etc/strongswan/ipsec.secrets /etc/strongswan/ipsec.secrets.old 2>/dev/null
ln -s /etc/ipsec.conf /etc/strongswan/ipsec.conf
ln -s /etc/ipsec.secrets /etc/strongswan/ipsec.secrets
然后配置xl2tpd
:
cat > /etc/xl2tpd/xl2tpd.conf <<EOF
[lac myvpn]
lns = $VPN_SERVER_IP
ppp debug = yes
pppoptfile = /etc/ppp/options.l2tpd.client
length bit = yes
EOF
cat > /etc/ppp/options.l2tpd.client <<EOF
ipcp-accept-local
ipcp-accept-remote
refuse-eap
require-chap
noccp
noauth
mtu 1280
mru 1280
noipdefault
defaultroute
usepeerdns
connect-delay 5000
name $VPN_USER
password $VPN_PASSWORD
EOF
chmod 600 /etc/ppp/options.l2tpd.client
至此 VPN 客户端配置已完成。按照下面的步骤进行连接。
第三步、建立连接
注意: 当你每次尝试连接到 VPN 时,必须重复下面的所有步骤。
#创建 xl2tpd 控制文件
mkdir -p /var/run/xl2tpd
touch /var/run/xl2tpd/l2tp-control
#重启服务
service strongswan restart
service xl2tpd restart
#开始 IPsec 连接
strongswan up myvpn
#开始 L2TP 连接
echo "c myvpn" > /var/run/xl2tpd/l2tp-control
#到此,若连接成功,执行ip addr并且检查输出。现在你应该看到一个新的网络接口 ppp0
由于我的当前服务器并没有公网IP,所以对于路由表route我无需做太多的配置,直接添加一个新的默认路由,并且开始通过 VPN 服务器发送数据:
route add default dev ppp0
到此,我的当前服务器就能够正常访问互联网了,试试 curl ip.cn
好了,时间不早了,更多操作请参考以下链接👇