Skip to content

Instantly share code, notes, and snippets.

@mattbell87
Last active December 22, 2023 20:25
Show Gist options
  • Save mattbell87/ec1c1fa974fa989249a4bd0fbc8b8857 to your computer and use it in GitHub Desktop.
Save mattbell87/ec1c1fa974fa989249a4bd0fbc8b8857 to your computer and use it in GitHub Desktop.
IPtables for routing over OpenVPN on Linux

Enable forwarding:

sysctl -w net.ipv4.ip_forward=1

Create this script eg sudo nano iptables.sh

eth=$1
proto=$2
port=$3

# OpenVPN
iptables -A INPUT -i "$eth" -m state --state NEW -p "$proto" --dport "$port" -j ACCEPT

# Allow TUN interface connections to OpenVPN server
iptables -A INPUT -i tun+ -j ACCEPT

# Allow TUN interface connections to be forwarded through other interfaces
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -o "$eth" -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i "$eth" -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT

# NAT the VPN client traffic to the internet
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o "$eth" -j MASQUERADE

Run the script with sudo bash iptables.sh eth0 udp 1194:

  • where eth0 is the interface your server is running on. Could be br0 if using VMs.
  • where udp is the protocol you're using for OpenVPN
  • where 1194 is the port you're using for OpenVPN

Now test it!

If it didn't work reboot.

If it did work save the configuration with iptables-persistent.

Debian/Ubuntu: sudo apt install iptables-persistent. If already installed you can use sudo dpkg-reconfigure iptables-persistent.

Fedora: Consider using firewalld instead of iptables.

@rakbladsvalsen
Copy link

For everyone that might stumble upon this, please do NOT use this snippet for anything even remotely serious since this config might leak data outside the VPN. There should be a final DROP statement for any other traffic than that intended for tun0, or either way use a default DROP policy for OUTPUT traffic.

@mattbell87
Copy link
Author

If you're looking to do this for internal apps try looking at a zero trust solution instead of a VPN. It's faster, more secure and more user-friendly. It also doesn't require software installation on the clients.

@testcaoy7
Copy link

I use policy routing with WireGuard.
For OpenVPN the method is the same.

ip rule add fwmark 22 table 100
ip route add 0.0.0.0/0 dev wg0 table 100

My case is to only allow a specific device (172.30.1.4) in my network to be tunneled via WireGuard.

iptables -t mangle -A PREROUTING -s 172.30.1.4 -j MARK --set-mark 22
iptables -t nat -A POSTROUTING -j MASQUERADE

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment