Scenario
ClientA (Windows 10) and ClientB (Raspberry Pi OS) are both connected via OpenVPN to ServerA (Debian 10) over the internet. The OpenVPN network is 10.0.0.0/24.
Machine |
OpenVPN IP |
ServerA |
10.0.0.1 |
ClientA |
10.0.0.2 |
ClientB |
10.0.0.3 |
ClientB has access to network 192.168.0.0/24. 192.168.0.250 runs a webserver.
Goal
All internet traffic of ClientA goes through ServerA's internet connection. All traffic of ClientA to 192.168.0.0/24 goes through ClientB.
Current (faulty) setup
What works
ClientA is a client of ServerA's OpenVPN service and routes all traffic through the VPN.
ClientB is a client of ServerA's OpenVPN service.
ClientA and ClientB can ping each other.
ServerA routes all internet traffic of ClientA through its own internet connection.
ServerA routes all traffic from ClientA to 192.168.0.0/24 to ClientB.
What doesn't work:
ClientA cannot establish connection to any machine on 192.168.0.0/24. It seems ClientB is not routing the traffic or performing the NAT accordingly.
Setup
ClientA
IPv4 Route Table
===========================================================================
Active Routes:
Network Destination Netmask Gateway Interface Metric
0.0.0.0 0.0.0.0 192.168.1.1 192.168.1.6 25
0.0.0.0 128.0.0.0 10.0.0.1 10.0.0.2 281
192.168.0.0 255.255.255.0 10.0.0.1 10.0.0.2 281
10.0.0.0 255.255.255.0 On-link 10.0.0.2 281
10.0.0.2 255.255.255.255 On-link 10.0.0.2 281
10.0.0.255 255.255.255.255 On-link 10.0.0.2 281
127.0.0.0 255.0.0.0 On-link 127.0.0.1 331
127.0.0.1 255.255.255.255 On-link 127.0.0.1 331
127.255.255.255 255.255.255.255 On-link 127.0.0.1 331
128.0.0.0 128.0.0.0 10.0.0.1 10.0.0.2 281
x.x.x.x 255.255.255.255 192.168.1.1 192.168.1.6 281 # ServerA public IP
192.168.1.0 255.255.255.0 On-link 192.168.1.6 281
192.168.1.6 255.255.255.255 On-link 192.168.1.6 281
192.168.1.255 255.255.255.255 On-link 192.168.1.6 281
224.0.0.0 240.0.0.0 On-link 127.0.0.1 331
224.0.0.0 240.0.0.0 On-link 10.0.0.2 281
224.0.0.0 240.0.0.0 On-link 192.168.1.6 281
255.255.255.255 255.255.255.255 On-link 127.0.0.1 331
255.255.255.255 255.255.255.255 On-link 10.0.0.2 281
255.255.255.255 255.255.255.255 On-link 192.168.1.6 281
===========================================================================
Persistent Routes:
None
tracert 192.168.0.250
Tracing route to 192.168.0.250 over a maximum of 30 hops
1 72 ms 71 ms 73 ms 10.0.0.3
2 * * * Request timed out.
3 * * * Request timed out.
4 ^C
There is no firewall on ClientA.
ServerA
cat /proc/sys/net/ipv4/ip_forward
1
ifconfig -a (shortened)
ens3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet x.x.x.x netmask 255.255.252.0 broadcast x.x.x.255
tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500
inet 10.0.0.1 netmask 255.255.255.0 destination 10.0.0.1
ip route show
default via x.x.x.x dev ens3
192.168.0.0/24 via 10.0.0.3 dev tun0
10.0.0.0/24 dev tun0 proto kernel scope link src 10.0.0.1
x.x.x.0/22 dev ens3 proto kernel scope link src x.x.x.x
x.x.x.x dev ens3 scope link
nft list ruleset
table ip filter {
chain INPUT {
type filter hook input priority 0; policy accept;
iifname "tun0" counter packets 5003 bytes 808157 accept
}
chain FORWARD {
type filter hook forward priority 0; policy accept;
ct state established,related counter packets 1565233 bytes 1274112205 accept
iifname "tun0" counter packets 23326 bytes 1702134 accept
iifname "ens3" oifname "tun0" ct state established,related counter packets 0 bytes 0 accept
iifname "tun0" oifname "ens3" ct state established,related counter packets 0 bytes 0 accept
}
chain OUTPUT {
type filter hook output priority 0; policy accept;
}
}
table ip nat {
chain PREROUTING {
type nat hook prerouting priority -100; policy accept;
}
chain INPUT {
type nat hook input priority 100; policy accept;
}
chain POSTROUTING {
type nat hook postrouting priority 100; policy accept;
ip saddr 10.0.0.0/24 oifname "ens3" masquerade
oifname "ens3" ip saddr 10.0.0.0/24 counter packets 0 bytes 0 masquerade
}
chain OUTPUT {
type nat hook output priority -100; policy accept;
}
}
traceroute 192.168.0.250
traceroute to 192.168.0.250 (192.168.0.250), 30 hops max, 60 byte packets
1 10.0.0.3 (10.0.0.3) 46.951 ms 48.232 ms 48.180 ms
2 * * *
3 * * *
4 *^C
ClientB
cat /proc/sys/net/ipv4/ip_forward
1
ClientB has its internet connection and connection to 192.168.0.0/24 on the same interface. The traffic to both works flawlessly from ClientB.
ifconfig -a (shortened)
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.178.70 netmask 255.255.255.0 broadcast 192.168.178.255
eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.249 netmask 255.255.255.0 broadcast 192.168.0.255
tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500
inet 10.0.0.3 netmask 255.255.255.0 destination 10.0.0.3
ip route show
0.0.0.0/1 via 10.0.0.1 dev tun0
default via 192.168.178.1 dev eth0 proto dhcp src 192.168.178.70 metric 202
192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.249
10.0.0.0/24 via 10.0.0.1 dev tun0
128.0.0.0/1 via 10.0.0.1 dev tun0 # no clue where this comes from
x.x.x.x via 192.168.178.1 dev eth0
192.168.178.0/24 dev eth0 proto dhcp scope link src 192.168.178.70 metric 202
This is how I setup iptables:
iptables -A INPUT -i tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -o eth0:1 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0:1 -o tun0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0:1 -j MASQUERADE
iptables -A OUTPUT -o tun0 -j ACCEPT
iptables -L -n -v
Chain INPUT (policy ACCEPT 6619 packets, 2460K bytes)
pkts bytes target prot opt in out source destination
362 22004 ACCEPT all -- tun0 * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
4 240 ACCEPT all -- tun0 * 0.0.0.0/0 0.0.0.0/0 # 4 ICMP (ping) packets have been received, but not forwarded correctly
0 0 ACCEPT all -- tun0 eth0:1 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 ACCEPT all -- eth0:1 tun0 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
Chain OUTPUT (policy ACCEPT 6849 packets, 2466K bytes)
pkts bytes target prot opt in out source destination
280 52688 ACCEPT all -- * tun0 0.0.0.0/0 0.0.0.0/0
traceroute 192.168.0.250
traceroute to 192.168.0.250 (192.168.0.250), 30 hops max, 60 byte packets
1 192.168.0.250 (192.168.0.250) 1.630 ms 1.479 ms 0.927 ms
Assumption
I assume that ClientB is not routing the traffic or performing the NAT correctly.
I've played around with different iptables settings on ClientB, but couldn't get it working.
Any ideas?