Скажем:
Мой OpenVPN сервер:
$ ip addr
1: lo:
inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500
inet 68.100.100.100/20 brd 68.183.223.255 scope global eth0
inet 10.19.0.6/16 brd 10.19.255.255 scope global eth0
3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500
inet 10.8.0.1 peer 10.8.0.2/32 scope global tun0
$ ip route
default via 68.100.111.1 dev eth0 proto static
10.8.0.0/24 via 10.8.0.2 dev tun0
10.8.0.2 dev tun0 proto kernel scope link src 10.8.0.1
10.19.0.0/16 dev eth0 proto kernel scope link src 10.19.0.6
68.100.111.0/20 dev eth0 proto kernel scope link src 68.100.100.100
Как видите, я не знаю, что делаю, я просто следил за множеством сообщений в Интернете, и теперь это моя текущая конфигурация:
$ sudo vim /etc/default/ufw
IPV6=no
DEFAULT_INPUT_POLICY="DROP"
DEFAULT_OUTPUT_POLICY="ACCEPT"
DEFAULT_FORWARD_POLICY="ACCEPT"
DEFAULT_APPLICATION_POLICY="SKIP"
MANAGE_BUILTINS=no
IPT_SYSCTL=/etc/ufw/sysctl.conf
IPT_MODULES="nf_conntrack_ftp nf_nat_ftp nf_conntrack_netbios_ns"
$ cat /proc/sys/net/ipv4/conf/all/forwarding
1
$ cat /proc/sys/net/ipv4/conf/default/forwarding
1
$ cat /proc/sys/net/ipv4/conf/eth0/forwarding
1
$ cat /proc/sys/net/ipv4/conf/tun0/forwarding
1
$ cat /proc/sys/net/ipv4/ip_forward
1
$ vim /etc/ufw/before.rules
# NAT Rules:
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-F
# Port Forwardings
-A PREROUTING -p tcp -m tcp -i eth0 --dport 2222 -j DNAT --to-destination 10.8.0.6:16000
# Allow traffic from OpenVPN client to eth0 (change to the interface you discovered (default)!)
-A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
-A POSTROUTING -p tcp -s 10.8.0.6 -j SNAT --to-source 68.100.100.100
COMMIT
# now the rest *filter etc (not modified)
$ sudo iptables -t nat --line-numbers -L
Chain PREROUTING (policy ACCEPT)
num target prot opt source destination
1 DNAT tcp -- anywhere anywhere tcp dpt:2222 to:10.8.0.6:16000
Chain INPUT (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
num target prot opt source destination
1 MASQUERADE all -- 10.8.0.0/24 !10.8.0.0/24
2 SNAT tcp -- 10.8.0.6 anywhere to:68.100.100.100
$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), allow (routed)
New profiles: skip
To Action From
-- ------ ----
1194/udp ALLOW IN Anywhere # openvpn
2222/tcp ALLOW IN Anywhere # public port
Anywhere on tun0 ALLOW IN Anywhere # tun0 allow any in port
10.8.0.6 16000/tcp ALLOW IN Anywhere
Anywhere ALLOW OUT Anywhere on tun0 # tun0 allow out any
Бэкэнд имеет ufw disabled
, хотя он использует докер и настроены правила iptables.
Теперь настоящий тест: с клиентского компьютера (через Интернет) я делаю curl 68.100.100.100:2222
, и я слушаю на обоих серверах:
$ sudo tcpdump -l -i eth0 | grep -E '(2222|16000)'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:33:18.816674 IP 170.170.170.170.53364 > serverhost.2222: Flags [S], seq 4201700907, win 29200, options [mss 1460,sackOK,TS val 1473590473 ecr 0,nop,wscale 7], length 0
$ ping serverhost
164 bytes from serverhost (10.19.0.6): icmp_seq=1 ttl=64 time=0.038 ms
И в Backend:
$ python3 -m http.server --bind 0.0.0.0 16000
Serving HTTP on 0.0.0.0 port 16000 (http://0.0.0.0:16000/) ...
Он также протестирован с --bind 10.8.0.6
. Там ничего не получено, но tcpdump показывает вызов:
$ sudo tcpdump -l -n -i tun0 | grep -E '(16000)'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
15:33:18.865521 IP 170.170.170.170.53364 > 10.8.0.6.16000: Flags [S], seq 4201700907, win 29200, options [mss 1358,sackOK,TS val 1473590473 ecr 0,nop,wscale 7], length 0
Почему-то Backend http-сервер не принимает вызов, хотя tcpdump может это видеть.
С другой стороны, клиент "зависает" примерно на 30 секунд, пока не истечет время ожидания:
$ curl 68.100.100.100:2222
curl: (28) Failed to connect to 68.100.100.100 port 2222: Connection timed out
Если я провожу тот же тест, но изменяю все с 10.8.0.6 (Backend) и просто использую 10.8.0.1 (ip сервера для tun0), он получает вызов (http-сервер прослушивает сервер, а не Backend). Но мне нужно заставить его работать с бэкэндом. Итак, как-то связано использование туннеля при подключении извне (клиент).
Еще один тест, если я попытаюсь подключиться напрямую с сервера к Backend, я могу это сделать:
$ curl 10.8.0.6:16000
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
...
И в Backend получено:
$ python3 -m http.server --bind 0.0.0.0 16000
Serving HTTP on 0.0.0.0 port 16000 (http://0.0.0.0:16000/) ...
10.8.0.1 - - [06/Dec/2019 15:50:17] "GET / HTTP/1.1" 200 -
$ sudo tcpdump -l -n -i tun0 | grep -E '(16000|13022)'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
15:51:16.083398 IP 10.8.0.1.43286 > 10.8.0.6.16000: Flags [S], seq 4180945297, win 64240, options [mss 1358,sackOK,TS val 2595670446 ecr 0,nop,wscale 7], length 0
15:51:16.083454 IP 10.8.0.6.16000 > 10.8.0.1.43286: Flags [S.], seq 2036127264, ack 4180945298, win 28960, options [mss 1460,sackOK,TS val 3255305882 ecr 2595670446,nop,wscale 7], length 0
15:51:16.142388 IP 10.8.0.1.43286 > 10.8.0.6.16000: Flags [.], ack 1, win 502, options [nop,nop,TS val 2595670505 ecr 3255305882], length 0
15:51:16.142446 IP 10.8.0.1.43286 > 10.8.0.6.16000: Flags [P.], seq 1:79, ack 1, win 502, options [nop,nop,TS val 2595670505 ecr 3255305882], length 78
15:51:16.142465 IP 10.8.0.6.16000 > 10.8.0.1.43286: Flags [.], ack 79, win 227, options [nop,nop,TS val 3255305941 ecr 2595670505], length 0
15:51:16.145741 IP 10.8.0.6.16000 > 10.8.0.1.43286: Flags [P.], seq 1:156, ack 79, win 227, options [nop,nop,TS val 3255305944 ecr 2595670505], length 155
15:51:16.145799 IP 10.8.0.6.16000 > 10.8.0.1.43286: Flags [.], seq 156:1502, ack 79, win 227, options [nop,nop,TS val 3255305944 ecr 2595670505], length 1346
15:51:16.145806 IP 10.8.0.6.16000 > 10.8.0.1.43286: Flags [.], seq 1502:2848, ack 79, win 227, options [nop,nop,TS val 3255305944 ecr 2595670505], length 1346
15:51:16.145869 IP 10.8.0.6.16000 > 10.8.0.1.43286: Flags [FP.], seq 2848:2942, ack 79, win 227, options [nop,nop,TS val 3255305944 ecr 2595670505], length 94
15:51:16.204476 IP 10.8.0.1.43286 > 10.8.0.6.16000: Flags [.], ack 156, win 501, options [nop,nop,TS val 2595670567 ecr 3255305944], length 0
15:51:16.204513 IP 10.8.0.1.43286 > 10.8.0.6.16000: Flags [.], ack 1502, win 498, options [nop,nop,TS val 2595670567 ecr 3255305944], length 0
15:51:16.204534 IP 10.8.0.1.43286 > 10.8.0.6.16000: Flags [.], ack 2848, win 489, options [nop,nop,TS val 2595670567 ecr 3255305944], length 0
15:51:16.210243 IP 10.8.0.1.43286 > 10.8.0.6.16000: Flags [F.], seq 79, ack 2943, win 501, options [nop,nop,TS val 2595670573 ecr 3255305944], length 0
15:51:16.210277 IP 10.8.0.6.16000 > 10.8.0.1.43286: Flags [.], ack 80, win 227, options [nop,nop,TS val 3255306009 ecr 2595670573], length 0
Итак, я хочу подключиться с клиентского компьютера в Интернете, используя общедоступный IP-адрес (сервер) и порт (2222), с узлом Backend в порту 16000. Что я делаю не так?