iamckn / wireguard_ansible

Ansible scripts for the set up a typical wireguard VPN connection
https://www.ckn.io/blog/2017/11/14/wireguard-vpn-typical-setup/
322 stars 69 forks source link

iptables NAT configuration doesn't forward packets #6

Closed kjgd closed 5 years ago

kjgd commented 5 years ago

The stock NAT iptables configuration does not seem to be enough for me:

 - name: Set up NAT
   iptables:
     table: nat
     chain: POSTROUTING
     source: 10.200.200.0/24
     out_interface: "{{ ansible_default_ipv4.interface }}"
     jump: MASQUERADE

If I leave it this way, then I can send ICMP echo traffic over the VPN but every other kind of traffic seems to stop at the VPN server.

Instead I am finding it necessary to add to the wg0-server.conf some lines I found in another Wireguard walkthrough:

[Interface]
Address = 10.200.200.1/24
SaveConfig = true
ListenPort = 51820
PrivateKey = {{ server_private_key }}
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

I am not very familiar with iptables but I assume the correct Ansible block would therefore be:

 - name: Forward packets from the tunnel to the outside world
   iptables:
     chain: FORWARD
     in_interface: wg0
     match: conntrack
     ctstate: NEW
     jump: ACCEPT

 - name: Set up NAT
   iptables:
     table: nat
     chain: POSTROUTING
     out_interface: "{{ ansible_default_ipv4.interface }}"
     jump: MASQUERADE

Does this make sense?

_Note: the "{{ ansible_default_ipv4.interface }}" is a System Fact and requires gather_facts: true in the main playbook_

iamckn commented 5 years ago

I've tested the setup with no forwarding issues. Please provide sample tcpdump logs on both the internet facing and vpn interfaces.

kjgd commented 5 years ago

tcpdump logs as requested:

from client:

$ ping 1.1.1.1
PING 1.1.1.1 (1.1.1.1): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
Request timeout for icmp_seq 3
...
--- 1.1.1.1 ping statistics ---
20 packets transmitted, 0 packets received, 100.0% packet loss

tcpdump on server (ethernet interface)

# 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
^C
0 packets captured
1 packet received by filter
0 packets dropped by kernel

(wireguard interface)

# tcpdump -i wg0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wg0, link-type RAW (Raw IP), capture size 262144 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel

tcpdump on client (wireguard interface):

# tcpdump -i utun1 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on utun1, link-type NULL (BSD loopback), capture size 262144 bytes
^C21:18:50.477236 IP 10.200.200.2 > 1.1.1.1: ICMP echo request, id 29695, seq 0, length 64

1 packet captured
129 packets received by filter
0 packets dropped by kernel

(Wireshark running on client utun1 sees a stream of ICMP ping requests going out, but not coming back)

Odd footnote: after re-imaging the server and running the playbook against it (as well as a standard playbook beforehand to set up basic firewall config/etc) the wireguard tunnel did not work, nor did DNS resolution on the server (could not even apt-get install as a result!).

However adding the above-mentioned POSTROUTING lines to the wg0.conf resulted in the tunnel working.

Then I solved the DNS resolution issue by taking more drastic steps to disable resolved while telling the system to use the local unbound instance instead (apt-get install started working again).

Unfortunately now nothing works, with or without the POSTROUTING lines in wg0.conf...

kjgd commented 5 years ago

Having fixed the firewall issues (see #9 ) I re-ran the test of the tunnel without the POSTROUTING lines in wg0.conf (serverside) and found the following:

Once I can figure out a test setup (something to create traffic, and a tcpdump filter to show only the test traffic) then I will post captures.

As it stands, tcpdump -i wg0 (server-side) shows plenty traffic originating from the client, but the only traffic destined for the client is the odd echo reply and DNS responses from the VPN server.

kjgd commented 5 years ago

Without the POSTROUTING lines in wg0.conf, running tcpdump simultaneously on the server's eth0 and wg0 interfaces produces the following (edited to remove private info):

(eth0)

# tcpdump -i eth0 "host 1.2.3.4 and port 80"
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel

(wg0)

# tcpdump -i wg0 "host 1.2.3.4 and port 80"
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wg0, link-type RAW (Raw IP), capture size 262144 bytes
16:17:40.450237 IP 10.200.200.2.54562 > 1.2.3.4.http: Flags [S], seq 843066468, win 65535, options [mss 1380,nop,wscale 5,nop,nop,TS val 1336481508 ecr 0,sackOK,eol], length 0
16:17:41.405838 IP 10.200.200.2.54562 > 1.2.3.4.http: Flags [S], seq 843066468, win 65535, options [mss 1380,nop,wscale 5,nop,nop,TS val 1336482508 ecr 0,sackOK,eol], length 0
16:17:42.403548 IP 10.200.200.2.54562 > 1.2.3.4.http: Flags [S], seq 843066468, win 65535, options [mss 1380,nop,wscale 5,nop,nop,TS val 1336483508 ecr 0,sackOK,eol], length 0
16:17:43.429194 IP 10.200.200.2.54562 > 1.2.3.4.http: Flags [S], seq 843066468, win 65535, options [mss 1380,nop,wscale 5,nop,nop,TS val 1336484508 ecr 0,sackOK,eol], length 0
16:17:44.419321 IP 10.200.200.2.54562 > 1.2.3.4.http: Flags [S], seq 843066468, win 65535, options [mss 1380,nop,wscale 5,nop,nop,TS val 1336485509 ecr 0,sackOK,eol], length 0
16:17:45.442736 IP 10.200.200.2.54562 > 1.2.3.4.http: Flags [S], seq 843066468, win 65535, options [mss 1380,nop,wscale 5,nop,nop,TS val 1336486510 ecr 0,sackOK,eol], length 0
16:17:47.533945 IP 10.200.200.2.54562 > 1.2.3.4.http: Flags [S], seq 843066468, win 65535, options [mss 1380,nop,wscale 5,nop,nop,TS val 1336488510 ecr 0,sackOK,eol], length 0
16:17:51.459260 IP 10.200.200.2.54562 > 1.2.3.4.http: Flags [S], seq 843066468, win 65535, options [mss 1380,nop,wscale 5,nop,nop,TS val 1336492511 ecr 0,sackOK,eol], length 0
^C
8 packets captured
8 packets received by filter
0 packets dropped by kernel
181 packets dropped by interface
iamckn commented 5 years ago

Closing this as it's related to #9