OpenVPN – TLS Handshake Fails on Client Because Firewall Drops Packets

iptablesopenvpntls

I seem to have problem with my openvpn server – client connection.

now, the important information is in the log (verb3) of my client:

Mon Mar 30 17:09:59 2015 OpenVPN 2.2.2 x86_64-slackware-linux-gnu [SSL] [LZO2] [EPOLL] [eurephia] built on Jul  4 2012
Mon Mar 30 17:09:59 2015 NOTE: OpenVPN 2.1 requires '--script-security 2' or higher to call user-defined scripts or executables
Mon Mar 30 17:09:59 2015 LZO compression initialized
Mon Mar 30 17:09:59 2015 Control Channel MTU parms [ L:1546 D:138 EF:38 EB:0 ET:0 EL:0 ]
Mon Mar 30 17:09:59 2015 Socket Buffers: R=[229376->131072] S=[229376->131072]
Mon Mar 30 17:10:00 2015 Data Channel MTU parms [ L:1546 D:1300 EF:46 EB:135 ET:0 EL:0 AF:3/1 ]
Mon Mar 30 17:10:00 2015 Fragmentation MTU parms [ L:1546 D:1300 EF:45 EB:135 ET:1 EL:0 AF:3/1 ]
Mon Mar 30 17:10:00 2015 Local Options hash (VER=V4): 'c086e1aa'
Mon Mar 30 17:10:00 2015 Expected Remote Options hash (VER=V4): '8e7959c7'
Mon Mar 30 17:10:00 2015 NOTE: UID/GID downgrade will be delayed because of --client, --pull, or --up-delay
Mon Mar 30 17:10:00 2015 UDPv4 link local: [undef]
Mon Mar 30 17:10:00 2015 UDPv4 link remote: x.x.x.x:32386

This is where is gets stuck.
Note that x.x.x.x s my server's ip address and the openvpn listening port is 32386.
after a while this appears

Mon Mar 30 17:12:04 2015 TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)
Mon Mar 30 17:12:04 2015 TLS Error: TLS handshake failed
Mon Mar 30 17:12:04 2015 TCP/UDP: Closing socket
Mon Mar 30 17:12:04 2015 SIGUSR1[soft,tls-error] received, process restarting
Mon Mar 30 17:12:04 2015 Restart pause, 2 second(s)

If i disable the firewall of my client, and i restart the openvpn client, it connects fine.

So the problem is related to the firewall. I set up a tcpdump -i <external_if> host <public_ip_of_the_other_pc> to listen for packets between the 2 computers.

the 2 latest packets that arrived on client:

18:58:14.193351 IP adsl-x.x.x.x.tellas.gr.26382 > 192.168.201.210.42983: UDP, length 14
18:58:14.796510 IP 192.168.201.210.42983 > adsl-x.x.x.x.tellas.gr.32386: UDP, length 14
18:58:14.821572 IP adsl-x.x.x.x.tellas.gr.26382 > 192.168.201.210.42983: UDP, length 22

note that 192.168.201.210 is the ip of the ADSL modem on the client.

At the same time the firewall dropped the packets arriving on port 42983

Mar 30 18:57:44 halki INPUT packet died:  IN=eth1 OUT= MAC=00:11:6b:32:f7:7e:00:13:33:16:36:12:08:00  SRC=x.x.x.x DST=192.168.201.210 LEN=54 TOS=1C PREC=0x20 TTL=56 ID=0 DF PROTO=UDP SPT=26382 DPT=42983 LEN=34 
Mar 30 18:57:50 halki INPUT packet died:  IN=eth1 OUT= MAC=00:11:6b:32:f7:7e:00:13:33:16:36:12:08:00  SRC=x.x.x.x DST=192.168.201.210 LEN=50 TOS=1C PREC=0x20 TTL=56 ID=0 DF PROTO=UDP SPT=26382 DPT=42983 LEN=30 
Mar 30 18:58:14 halki INPUT packet died:  IN=eth1 OUT= MAC=00:11:6b:32:f7:7e:00:13:33:16:36:12:08:00  SRC=x.x.x.x DST=192.168.201.210 LEN=42 TOS=1C PREC=0x20 TTL=56 ID=0 DF PROTO=UDP SPT=26382 DPT=42983 LEN=22 

Obviously, 42983 is a high port that the client should not need to be open. However, since I have enabled stateful packet inspection in the client's firewall, port 42983 should be accessible to the outside world, considering that a moment ago the client had initiated a connection to the server on that source port.

For the record my client's firewall's INPUT chain looks like:

echo "Process INPUT chain ..."
$IPT -A INPUT -p ALL -i $LO_IFACE -j ACCEPT
$IPT -A INPUT -p ALL -i $INET_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -p ALL -i $LOCAL_IFACE -s $LOCAL_NET -j ACCEPT
$IPT -A INPUT -p TCP -i $INET_IFACE -j tcp_inbound
$IPT -A INPUT -p UDP -i $INET_IFACE -j udp_inbound
$IPT -A INPUT -p ICMP -i $INET_IFACE -j icmp_packets
$IPT -A INPUT -m pkttype --pkt-type broadcast -j DROP
$IPT -A INPUT -m limit --limit 3/minute --limit-burst 3 -j ULOG --ulog-prefix "INPUT packet died: " --ulog-nlgroup 1

so ESTABLISHED,RELATED connections should be able to pass through. Or what am I missing and the firewall does not allow responses from the openvpn server to the client?

EDIT:

$IPT -A udp_inbound -p UDP -s 0/0 --destination-port 113 -j REJECT
$IPT -A udp_inbound -p UDP -s 0/0 --destination-port 137 -j DROP
$IPT -A udp_inbound -p UDP -s 0/0 --destination-port 138 -j DROP
$IPT -A udp_inbound -p UDP -s $MODEM --destination-port 123 -j ACCEPT #NTP
$IPT -A udp_inbound -p UDP -j RETURN

$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 113 -j REJECT
$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 51235 -j ACCEPT #SSH
$IPT -A tcp_inbound -p TCP -j RETURN

$IPT -A icmp_packets --fragment -p ICMP -j ULOG --ulog-prefix "ICMP Fragment: " --ulog-nlgroup 1
$IPT -A icmp_packets --fragment -p ICMP -j DROP
$IPT -A icmp_packets -p ICMP -s $LOCAL_NET -d $VPN_NET --icmp-type 0 -j ACCEPT
$IPT -A icmp_packets -p ICMP -s $LOCAL_NET -d $VPNCL_NET --icmp-type 0 -j ACCEPT
$IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j ACCEPT
$IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT
$IPT -A icmp_packets -p ICMP -j RETURN

Best Answer

As it turned out the problem was not in my server or client openvpn configurations, but rather in the firmware of the ADSL modem on my server side.

The firmware has a bug and wrongly changed the source port of an outgoing packet. So while openvpn would respond on the server port, the ADSL modem would change the source port of openvpn packets. The result was that the client would drop these packets and the openvpn connection would not remain "alive".

Changing the firmware of the ADSL modem solved this issue.