Configuring the IpTables - write UDPv4 Operation not permitted

edited December 2017 in Linux VPN Setup
Hello,

I've been struggling with configuring the ip tables correctly to avoid any leaks.
I'm running Linux Mint and OpenVpn 2.3.2

The problem seems to be with my UDP rules. I took a look at configuration file that OpenVPN uses and confirmed the Port number  

----
proto udp
remote nl.privateinternetaccess.com 1198
---

So I added my UDP rules as follow
iptables -A INPUT -p udp --dport 1198 -j ACCEPT
iptables -A OUTPUT -p udp --sport 1198 -j ACCEPT

However when I initiate the VPN connectivity, I get this..
-------------------------------------------------------------------------------
n Dec  3 12:12:26 2017 UDPv4 link local: [undef]
Sun Dec  3 12:12:26 2017 UDPv4 link remote: [AF_INET]46.166.186.235:1198
Sun Dec  3 12:12:26 2017 write UDPv4: Operation not permitted (code=1)
Sun Dec  3 12:12:29 2017 write UDPv4: Operation not permitted (code=1)
Sun Dec  3 12:12:33 2017 write UDPv4: Operation not permitted (code=1)
Sun Dec  3 12:12:41 2017 write UDPv4: Operation not permitted (code=1)
Sun Dec  3 12:12:57 2017 write UDPv4: Operation not permitted (code=1)
Sun Dec  3 12:13:26 2017 TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)
Sun Dec  3 12:13:26 2017 TLS Error: TLS handshake failed
----------------------------------------------------------------------------------------------------

I then reverted the IP table rules, connect to the VPN while running wireshark to see the port number it normally uses and I see 1198 and interesting enough I also see port 34350 for a couple of requests. So I added

iptables -A OUTPUT -p udp --sport 34350 -j ACCEPT

but that didn't help either.

if I allow ALL udp connection as the following, it works

iptables -A OUTPUT -p udp -j ACCEPT

So, it looks like I'm missing one or several ports to allow.

What am I missing? 

Thanks in advance.

Comments

  • it's quite likely the source port is different every time you attempt to initiate a VPN
  • edited December 2017
    Should I be handling this by IP then? The iptables were generated by a script I found online which extracts the IP Addresses used by PIA from https://www.privateinternetaccess.com/openvpn/openvpn.zip. I tweaked the script to use udp port 1198 instead of 1194 (although I've tried with both and no luck).

    I guess my question is how should I write the iptable rules to be able to start a connection with the vpn?
  • This is the script
    =================
    #!/bin/bash

    # vars

    IPTABLESFILE="/tmp/iptables.vpn"


    # Get openvpn configuration zip from PIA
    echo "piavpn: getting openvpn.zip"
    mkdir -p /tmp/pia
    echo "piavpn: openvpn.zip retrieved successfully"
    unzip -q /tmp/pia/openvpn.zip -d /tmp/pia/
    grep -h "remote " /tmp/pia/*ovpn | cut -d ' ' -f 2 | sort -u > /tmp/piaservers
    dig -f /tmp/piaservers A +short | sort > /tmp/piaserverips
    echo "piavpn: PIA server IP's retrieved, building iptables."


    # Start building iptables script - starts by overwriting old file
    echo -e "# Flush iptables" > $IPTABLESFILE
    echo "iptables -F" >> $IPTABLESFILE
    echo "iptables -X" >> $IPTABLESFILE
    echo -e "\n\n# Allow vpn tunnel and loopback connections" >> $IPTABLESFILE
    echo "iptables -A INPUT -i tun+ -j ACCEPT" >> $IPTABLESFILE
    echo "iptables -A OUTPUT -o tun+ -j ACCEPT" >> $IPTABLESFILE
    echo "iptables -A INPUT -s 127.0.0.1 -j ACCEPT" >> $IPTABLESFILE
    echo "iptables -A OUTPUT -d 127.0.0.1 -j ACCEPT" >> $IPTABLESFILE


    # accept openvpn port 1198 traffic
    echo -e "\n\n# Accept openvpn port 1198 traffic (needed for restarts)" >> $IPTABLESFILE
    echo "iptables -A INPUT -p udp --dport 1198 -j ACCEPT" >> $IPTABLESFILE
    echo "iptables -A OUTPUT -p udp --sport 1198 -j ACCEPT" >> $IPTABLESFILE

    # Add PIA server IPs to script
    echo -e "\n\n# Allow all PIA server IPS" >> $IPTABLESFILE
    IP_LIST=$(tr '\n' ' ' < /tmp/piaserverips)
    for IP in $IP_LIST; do
       echo "iptables -A INPUT -s" $IP "-j ACCEPT" >> $IPTABLESFILE
       echo "iptables -A OUTPUT -d" $IP "-j ACCEPT" >> $IPTABLESFILE
    done


    # Next two lines give me access to/from my internal servers
    echo -e "\n\n# Allow LAN connections" >> $IPTABLESFILE
    echo "iptables -A INPUT -s 192.168.0.0/24 -j ACCEPT" >> $IPTABLESFILE
    echo "iptables -A OUTPUT -d 192.168.0.0/24 -j ACCEPT" >> $IPTABLESFILE


    # Allow existing established connections
    echo -e "\n\n# Allow existing established connections" >> $IPTABLESFILE
    echo "iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT" >> $IPTABLESFILE
    echo "iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT" >> $IPTABLESFILE


    # Stop anything not from PIA or internal or localhost
    echo -e "\n\n# Drop everything else" >> $IPTABLESFILE
    echo "iptables -A INPUT -j DROP" >> $IPTABLESFILE
    echo "iptables -A OUTPUT -j DROP" >> $IPTABLESFILE


    # ipv6: drop everything
    echo -e "\n\n# IPV6: Drop/reject everything ####" >> $IPTABLESFILE
    echo "ip6tables -F" >> $IPTABLESFILE
    echo "ip6tables -X" >> $IPTABLESFILE
    echo "ip6tables -A INPUT -j DROP" >> $IPTABLESFILE
    echo "ip6tables -A OUTPUT -j REJECT" >> $IPTABLESFILE
    echo "ip6tables -A FORWARD -j REJECT" >> $IPTABLESFILE


    # make the vpn file executable, delete everything else
    chmod 744 $IPTABLESFILE
    rm -r /tmp/piaservers /tmp/piaserverips /tmp/pia

    # replace this line with the directory of your choice
    mv $IPTABLESFILE /root/vpn-profiles/pia-openvpn/
    echo "piavpn: complete. file in /root/vpn-profiles/pia-openvpn"

    ================================
  • you were using wireshark, after all. you can verify yourself how the interaction proceeds. pretty sure you'll find destination port 119x (value of 'x' depends on crypto selection) in the traffic but not so sure about source port number(s)
  • The source port numbers are indeed random unless set manually with the "lport" OpenVPN option, so you can avoid it being random with that. The reversed iptables rules should have worked however.

    There's always the possibility that another rule is interfering somewhere. The order is important with iptables.

    I would recommend flushing all the rules and testing those two specifically alone and only add them back to the rest of the script once you know they work, that way you'll know it's not because another rule is blocking it already accidentally.
Sign In or Register to comment.