Linux NAT IPIP Tunnel

An IPIP tunnel is similar to a GRE tunnel but with slightly less overhead.

$PUBLIC_IP - your local public IP address (https://ipv4.icanhazip.com)
$LAN_IP - your machines local LAN IP (ip a)
$REMOTE_IP - IP address of the remote Linux server you are tunneling to

Local

1
2
3
4
5
6
7
8
9
auto ipip1
iface ipip1 inet tunnel
address 192.168.0.2
netmask 255.255.255.252
mtu 1480
mode ipip
endpoint $REMOTE_IP
ttl 255
post-up ip rule add from 192.168.0.0/30 table IPIP && ip route add default via 192.168.0.1 table IPIP

Run this once:

1
echo '500 IPIP' >> /etc/iproute2/rt_tables
1
iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -o ipip+ -j TCPMSS --clamp-mss-to-pmtu

Remote

1
2
3
4
5
6
7
auto ipip1
iface ipip1 inet tunnel
address 192.168.0.1
netmask 255.255.255.252
mtu 1480
endpoint $PUBLIC_IP
ttl 255
1
2
3
iptables -A INPUT -p ipip -s $PUBLIC_IP -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.0.0/30 ! -o ipip+ -j SNAT --to-source $REMOTE_IP
iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -o ipip+ -j TCPMSS --clamp-mss-to-pmtu
1
2
3
4
# Port forwarding
iptables -A INPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 443 -j DNAT --to 192.168.0.2:443
iptables -A FORWARD -d 192.168.0.2 -p tcp --dport 443 -j ACCEPT

Make sure net.ipv4.ip_forward=1 and net.ipv4.conf.all.proxy_arp=1 are enabled and net.ipv4.conf.all.rp_filter=0 is off.

EdgeMAX

Inbound Interface: Internet facing interface
Translations Address: Local LAN IP
Protocol: ipip
Src Address: Remote server

Ubiquiti EdgeMAX

Keep Alive

The tunnel appears to become unreachable after a certain amount of time when no data is being passed between the ends. Any iptables forward rules will not reach the destination in this case. I could not find any information about setting a keepalive variable in the interfaces file for Debian. So, the easiest thing is to setup a systemd service with a ping interval of 5 seconds.

/etc/systemd/system/tunnel-keepalive.service

1
2
3
4
5
6
7
8
9
10
11
12
[Unit]
Description=Tunnel Keepalive
After=network.target
[Service]
Type=simple
Restart=always
RestartSec=5
ExecStart=/bin/ping -q -i 5 192.168.0.1
[Install]
WantedBy=multi-user.target