OpenVPN bypass on some ports

8,409

Solution 1

After a little more searching, I've found this thread : https://web.archive.org/web/20170315080843/https://forum.linode.com/viewtopic.php?p=50114&sid=b440414422596bb7dbc96cf7c9ee511f

I've now modified my "route-up" OpenVPN script as follow, and it's finally working ! I've removed all the others messy rules (iptable PREROUTING, MASQUERADE, etc).

Here is my final "route-up" script :

ip route flush table 100
ip route flush cache

ip rule add from x.x.x.x table 100
ip route add table 100 to y.y.y.y/y dev ethX
ip route add table 100 default via z.z.z.z

Where x.x.x.x is my server's public IP, y.y.y.y/y is the subnet of my server's public IP address, ethX is my server's public Ethernet interface, and z.z.z.z is the default gateway.

Hope this may help someone else.

Solution 2

After going through the same ordeal myself I found at least one problem with the route-up script.

iptables -t mangle -A PREROUTING ...

should be:

iptables -t mangle -A OUTPUT ...

Read about why here: http://www.iptables.info/en/structure-of-iptables.html

I didn't have to turn on IP forwarding.

Share:
8,409

Related videos on Youtube

Leeroy Brun
Author by

Leeroy Brun

Updated on September 18, 2022

Comments

  • Leeroy Brun
    Leeroy Brun over 1 year

    I have a server running Debian 7 and I would like to connect to a VPN and let all the traffic pass via the VPN except for some ports (SSH, hosted websites, etc).

    I've searched for some time now in the Internet, but nothing seems to work as expected.

    I'm not an iptables/network expert, so maybe I'm missing something...

    Here are my scripts :

    Before VPN script

    Here is the script started before the VPN, it is used to block all traffic going out/in without passing via the VPN, except for some ports (SSH here).

    If I start only this script, it does his job. I can connect to my server via SSH, but all other ports are blocked and the server can't go in the Internet (because the VPN is not launched).

    #!/bin/bash
    
    # Flush iptables
    iptables -P INPUT ACCEPT
    iptables -P FORWARD ACCEPT
    iptables -P OUTPUT ACCEPT
    iptables -F
    iptables -X
    iptables -t nat -F
    iptables -t nat -X
    iptables -t mangle -F
    iptables -t mangle -X
    
    # Default policy
    iptables -P INPUT DROP
    iptables -P FORWARD DROP
    iptables -P OUTPUT DROP
    
    # Accept packets through VPN
    iptables -A INPUT -i tun+ -j ACCEPT
    iptables -A OUTPUT -o tun+ -j ACCEPT
    
    # Accept local connections
    iptables -A INPUT -i lo -j ACCEPT
    iptables -A OUTPUT -o lo -j ACCEPT
    
    # Accept connection to/from VPN servers
    iptables -A INPUT -s xxx.xxx.xxx.xxx -j ACCEPT
    iptables -A OUTPUT -d xxx.xxx.xxx.xxx -j ACCEPT
    
    # Disable Reverse Path Filtering on all network interfaces
    for i in /proc/sys/net/ipv4/conf/*/rp_filter ; do
        echo 0 > $i
    done
    
    # Open ports on iptable
    iptables -A INPUT -p tcp --dport 22 -j ACCEPT
    iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
    

    Route-up OpenVPN script

    Here is the script called via the "route-up" OpenVPN's option. This is the script that should make the ports bypass the VPN.

    #!/bin/bash
    
    WAN_GATEWAY="xxx.xxx.xxx.xxx"
    
    echo 1 > /proc/sys/net/ipv4/ip_forward
    
    # Delete table 100 and flush all existing rules
    ip route flush table 100
    ip route flush cache
    iptables -t mangle -F PREROUTING
    
    # Table 100 will route all traffic with mark 1 to WAN (no VPN)
    ip route add default table 100 via $WAN_GATEWAY dev eth0
    ip rule add fwmark 1 table 100
    ip route flush cache
    
    # Mark packets on port 22
    iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 1
    
    iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
    iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
    

    OpenVPN config file

    Here is the OpenVPN client config file.

    client
    dev tun
    proto udp
    resolv-retry infinite
    nobind
    tun-mtu 1500
    tun-mtu-extra 32
    mssfix 1450
    persist-key
    persist-tun
    comp-lzo
    verb 3
    redirect-gateway def1
    user nobody
    group nogroup
    script-security 2
    auth-user-pass /path/to/config/login.conf
    route-up /path/to/scripts/vpn_up.sh
    remote xxx.xxx.xxx.xxx 443
    ca /path/to/config/certs/ch.crt
    

    My problem is that when the VPN goes up, I can't access my server anymore.

    What am I doing wrong?

    Thanks a lot for your help !

  • diachedelic
    diachedelic about 9 years
    I just had the same journey as you, it was horrible
  • Leeroy Brun
    Leeroy Brun about 8 years
    @diachedelic I feel you man
  • Grahamvs
    Grahamvs almost 8 years
    Can this be set to allow x.x.x.x to be any ip? (the server I want to connect with keeps changing their ip)