我在 AWS EC2 实例 (Ubuntu AMI) 上配置 OpenVPN 时似乎遇到了一个奇怪的问题。连接已建立,双因素身份验证已通过,但连接后,客户端无法访问互联网。
为了进行调试,我开始在客户端上进行无休止的 ping:
$ ping 87.250.250.242
PING 87.250.250.242 (87.250.250.242): 56 data bytes
64 bytes from 87.250.250.242: icmp_seq=0 ttl=54 time=33.589 ms
64 bytes from 87.250.250.242: icmp_seq=1 ttl=54 time=31.275 ms
64 bytes from 87.250.250.242: icmp_seq=2 ttl=54 time=42.907 ms
64 bytes from 87.250.250.242: icmp_seq=3 ttl=54 time=49.470 ms
64 bytes from 87.250.250.242: icmp_seq=4 ttl=54 time=29.772 ms
我在服务器上测试数据包可以传输多远。它确实到达了tun0
接口:
$ sudo tcpdump -i tun0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
08:52:10.261730 IP ip-10-8-1-6.ec2.internal > ya.ru: ICMP echo request, id 52451, seq 2684, length 64
08:52:11.264706 IP ip-10-8-1-6.ec2.internal > ya.ru: ICMP echo request, id 52451, seq 2685, length 64
08:52:12.268201 IP ip-10-8-1-6.ec2.internal > ya.ru: ICMP echo request, id 52451, seq 2686, length 64
08:52:13.272732 IP ip-10-8-1-6.ec2.internal > ya.ru: ICMP echo request, id 52451, seq 2687, length 64
08:52:14.275066 IP ip-10-8-1-6.ec2.internal > ya.ru: ICMP echo request, id 52451, seq 2688, length 64
然而,它没有进一步行动——eth0
没有看到它:
$ sudo tcpdump -i eth0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
从 EC2 实例内部可以完全访问互联网:
$ curl google.com
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>
看起来像是典型的 NAT 后路由配置错误,但我再三检查是否一切都按需要设置。
IP 转发已打开:
$ cat /proc/sys/net/ipv4/ip_forward
1
iptables
存在后布线规则:
$ sudo iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER all -- anywhere !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- ip-172-17-0-0.ec2.internal/16 anywhere
MASQUERADE all -- ip-10-8-1-0.ec2.internal/24 anywhere
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- anywhere anywhere
明确检查也表明它在那里:
$ sudo iptables -t nat -C POSTROUTING -s 10.8.1.0/24 -o eth0 -j MASQUERADE && echo ok
ok
Ubuntu 已ufw
安装,但尚未激活:
$ sudo ufw status
Status: inactive
以下是有关该系统的更多信息:
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.5 LTS
Release: 16.04
Codename: xenial
$ openvpn --version
OpenVPN 2.4.4 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Sep 26 2017
library versions: OpenSSL 1.0.2g 1 Mar 2016, LZO 2.08
$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.2.50.1 0.0.0.0 UG 0 0 0 eth0
10.2.50.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
10.8.1.0 10.8.1.2 255.255.255.0 UG 0 0 0 tun0
10.8.1.2 0.0.0.0 255.255.255.255 UH 0 0 0 tun0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
服务器配置:
$ cat /etc/openvpn/server.conf | egrep -v '^#' | egrep -v '^$'
port 1194
proto udp
dev tun
ca ca.crt
cert VPN.crt
key VPN.key # This file should be kept secret
dh dh2048.pem
server 10.8.1.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
keepalive 10 120
tls-auth ta.key 0 # This file is secret
compress lzo
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status.log
verb 4
plugin openvpn-plugin-auth-pam.so openvpn
reneg-sec 43200
reneg-bytes 0
cipher AES-256-CBC
ncp-ciphers AES-256-GCM:AES-256-CBC:AES-128-GCM:AES-128-CBC:BF-CBC
crl-verify crl.pem
客户端配置:
client
dev tun
proto udp
remote <server IP> 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
key-direction 1
compress lzo
verb 3
auth-user-pass
auth-nocache
reneg-sec 43200
cipher AES-256-CBC
<ca>
-----BEGIN CERTIFICATE-----
# redacted
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
# redacted
-----END PRIVATE KEY-----
</key>
<tls-auth>
-----BEGIN OpenVPN Static key V1-----
# redacted
-----END OpenVPN Static key V1-----
</tls-auth>
系统信息:从ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-20180814
镜像构建的EC2实例。
安全组允许所有出站流量和以下入站流量:
- UDP/1194 来自任何地方
- 来自我的位置的 TCP/22(用于调试)
我读过有关禁用的信息Source/Destination Check
。不确定它是否适用于我的情况,因为我不需要提供对 AWS VPC 网络的访问权限,但我也尝试过,但没有帮助。
最让我困惑的是,我们已经在另一个区域以类似的方式设置了可用的 VPN 服务器,但出于某种原因,我无法让新实例运行。所以我甚至不确定这是否是 AWS 独有的。
有人能建议去哪里寻找问题吗?
答案1
不确定原因是什么,但我刚刚重新启动了实例,问题就神奇地消失了。
在此之前,我尝试调试iptables
(感谢这个问题) 并且似乎数据包根本没有完全到达iptables
(请注意 规则行中的零ip-10-8-1-0.ec2.internal/24
):
$ sudo iptables -t nat -L -v
Chain PREROUTING (policy ACCEPT 1249 packets, 93674 bytes)
pkts bytes target prot opt in out source destination
59 3938 DOCKER all -- any any anywhere anywhere ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT 2 packets, 140 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 923 packets, 58794 bytes)
pkts bytes target prot opt in out source destination
0 0 DOCKER all -- any any anywhere !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT 923 packets, 58794 bytes)
pkts bytes target prot opt in out source destination
29 1910 MASQUERADE all -- any !docker0 ip-172-17-0-0.ec2.internal/16 anywhere
0 0 LOG all -- any eth0 ip-10-8-1-0.ec2.internal/24 anywhere LOG level warning prefix "nat"
0 0 MASQUERADE all -- any eth0 ip-10-8-1-0.ec2.internal/24 anywhere
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- docker0 any anywhere anywhere
重启后数据包顺利通过:
$ sudo iptables -t nat -L -v
Chain PREROUTING (policy ACCEPT 35 packets, 2438 bytes)
pkts bytes target prot opt in out source destination
1 70 DOCKER all -- any any anywhere anywhere ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT 1 packets, 70 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 281 packets, 17695 bytes)
pkts bytes target prot opt in out source destination
0 0 DOCKER all -- any any anywhere !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT 283 packets, 17975 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- any !docker0 ip-172-17-0-0.ec2.internal/16 anywhere
32 2088 MASQUERADE all -- any eth0 ip-10-8-1-0.ec2.internal/24 anywhere
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- docker0 any anywhere anywhere
我标记我的问题已得到回答,但我很乐意将正确的答案标记转移给任何能提示为什么会发生这种情况的人。