OpenWrt Forum Archive

Topic: [SOLVED] OpenVPN via SOCKS (socks_proxy='localhost 1080')

The content of this topic has been archived on 21 Mar 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

[EDIT] For the solution, see post #6, below.

Has anyone got this to work - I have been beating my head around it for a week!  Any advice would be appreciated!

I am using

  • OpenWRT client and server, both on BB (builds less than a week old), and the OpenSSL version of OpenVPN

  • OpenSSH (rather than Dropbear) with autossh (which has been exhibiting its own problems) to create a dynamic SSH tunnel

The SOCKS tunnel is confirmed working as it can punch a Chrome client through a SPI firewall (using network A).  The SOCKS tunnel also functions correctly on networks without any significant firewall (network B).

Scenario 1: The OpenVPN tunnel is working fine (using network B) if I do not have socks_proxy configured:

uci del openvpn.MYVPN.socks_proxy
uci commit openvpn
/etc/init.d/openvpn restart
ping 8.8.8.8

Scenario 2: However, the OpenVPN tunnel doesn't work if I use the SOCKS proxy (again, on network B):

uci set openvpn.MYVPN.socks_proxy='localhost 1080'
uci commit openvpn
/etc/init.d/openvpn restart
ping 8.8.8.8

The only difference is the socks_proxy option. In both cases, the OpenVPN tunnel is established OK (I will add the logs tomorrow), but only Scenario 1 'works' (i.e. I get  an ICMP echo reply).  Yes, I am using TCP rather than UDP.

In Scenario 2, the tunnel fails according to the keepalive option, and does a ping restart after 2 minutes.

uci set openvpn.MYVPN.keepalive='10 120'

If someone can help me on this, I will add it to a HOWTO wiki!

References:
http://wiki.openwrt.org/doc/howto/vpn.openvpn
https://community.openvpn.net/openvpn/w … n23ManPage

PS: When the OpenVPN tunnel triggers a SIGUSR1 after the expiration of the ping_restart timer, I think it is the reason why autossh is stopping gracefully when it shouldn't?

(Last edited by zxdavb on 2 Jun 2014, 15:35)

Some further testing:

I still get the same issue, even when I temporarily disable the firewall of the OpenVPN server.

/etc/init.d/firewall stop

Anyway, here is a log of Scenario 2 (the SOCKS session):

Fri May 30 09:20:56 2014 OpenVPN 2.3.2 mips-openwrt-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [MH] [IPv6] built on May 28 2014
Fri May 30 09:20:56 2014 NOTE: --fast-io is disabled since we are not using UDP
Fri May 30 09:20:56 2014 Socket Buffers: R=[87380->131072] S=[16384->131072]
Fri May 30 09:20:56 2014 Attempting to establish TCP connection with [AF_INET]127.0.0.1:1080 [nonblock]
Fri May 30 09:20:56 2014 TCP connection established with [AF_INET]127.0.0.1:1080
Fri May 30 09:20:56 2014 TCPv4_CLIENT link local: [undef]
Fri May 30 09:20:56 2014 TCPv4_CLIENT link remote: [AF_INET]127.0.0.1:1080
Fri May 30 09:20:56 2014 TLS: Initial packet from [AF_INET]127.0.0.1:1080, sid=4de0297b ae446342
Fri May 30 09:20:57 2014 VERIFY OK: depth=1, C=GB, ST=England, L=London, O=XXXXXXX., OU=XXXXXXX, CN=XXXXXXX, name=EasyRSA, emailAddress=XXXXXXX
Fri May 30 09:20:57 2014 Validating certificate key usage
Fri May 30 09:20:57 2014 ++ Certificate has key usage  00a0, expects 00a0
Fri May 30 09:20:57 2014 VERIFY KU OK
Fri May 30 09:20:57 2014 Validating certificate extended key usage
Fri May 30 09:20:57 2014 ++ Certificate has EKU (str) TLS Web Server Authentication, expects TLS Web Server Authentication
Fri May 30 09:20:57 2014 VERIFY EKU OK
Fri May 30 09:20:57 2014 VERIFY OK: depth=0, C=GB, ST=England, L=London, O=XXXXXXX, OU=XXXXXXX, CN=db-router, name=EasyRSA, emailAddress=XXXXXXX
Fri May 30 09:21:00 2014 Data Channel Encrypt: Cipher 'BF-CBC' initialized with 128 bit key
Fri May 30 09:21:00 2014 Data Channel Encrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Fri May 30 09:21:00 2014 Data Channel Decrypt: Cipher 'BF-CBC' initialized with 128 bit key
Fri May 30 09:21:00 2014 Data Channel Decrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Fri May 30 09:21:00 2014 Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA, 2048 bit RSA
Fri May 30 09:21:00 2014 [db-router] Peer Connection Initiated with [AF_INET]127.0.0.1:1080
Fri May 30 09:21:03 2014 SENT CONTROL [db-router]: 'PUSH_REQUEST' (status=1)
Fri May 30 09:21:03 2014 PUSH: Received control message: 'PUSH_REPLY,redirect-gateway def1,route 172.31.1.1,topology net30,ping 10,ping-restart 1200,ifconfig 172.31.1.6 172.31.1.5'
Fri May 30 09:21:03 2014 OPTIONS IMPORT: timers and/or timeouts modified
Fri May 30 09:21:03 2014 OPTIONS IMPORT: --ifconfig/up options modified
Fri May 30 09:21:03 2014 OPTIONS IMPORT: route options modified
Fri May 30 09:21:03 2014 TUN/TAP device tun0 opened
Fri May 30 09:21:03 2014 TUN/TAP TX queue length set to 100
Fri May 30 09:21:03 2014 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Fri May 30 09:21:03 2014 /sbin/ifconfig tun0 172.31.1.6 pointopoint 172.31.1.5 mtu 1500
Fri May 30 09:21:03 2014 /sbin/route add -net 127.0.0.1 netmask 255.255.255.255 gw 192.168.95.231
Fri May 30 09:21:03 2014 /sbin/route add -net 0.0.0.0 netmask 128.0.0.0 gw 172.31.1.5
Fri May 30 09:21:03 2014 /sbin/route add -net 128.0.0.0 netmask 128.0.0.0 gw 172.31.1.5
Fri May 30 09:21:03 2014 /sbin/route add -net 172.31.1.1 netmask 255.255.255.255 gw 172.31.1.5
Fri May 30 09:21:03 2014 Initialization Sequence Completed

FWIW, although /sbin/route add -net 127.0.0.1 netmask 255.255.255.255 gw 192.168.95.231 is a bit odd, I don't think it causes any problems. [EDIT] See post #3, below.

Scenario 1 (the 'direct' session) has exactly the same log, but with two differences:

Fri May 30 08:55:52 2014 Attempting to establish TCP connection with [AF_INET]77.77.77.77:1194 [nonblock]
Fri May 30 08:55:53 2014 TCP connection established with [AF_INET]77.77.77.77:1194
Fri May 30 08:55:53 2014 TCPv4_CLIENT link local: [undef]
Fri May 30 08:55:53 2014 TCPv4_CLIENT link remote: [AF_INET]77.77.77.77:1194
Fri May 30 08:55:53 2014 TLS: Initial packet from [AF_INET]77.77.77.77:1194, sid=302da3e6 28062a63

and

Fri May 30 08:56:02 2014 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Fri May 30 08:56:02 2014 /sbin/ifconfig tun0 172.31.1.6 pointopoint 172.31.1.5 mtu 1500
Fri May 30 08:56:02 2014 /sbin/route add -net 77.77.77.77 netmask 255.255.255.255 gw 10.42.0.1
Fri May 30 08:56:02 2014 /sbin/route add -net 0.0.0.0 netmask 128.0.0.0 gw 172.31.1.5
Fri May 30 08:56:02 2014 /sbin/route add -net 128.0.0.0 netmask 128.0.0.0 gw 172.31.1.5
Fri May 30 08:56:02 2014 /sbin/route add -net 172.31.1.1 netmask 255.255.255.255 gw 172.31.1.5
Fri May 30 08:56:02 2014 Initialization Sequence Completed

(Last edited by zxdavb on 30 May 2014, 11:42)

Hmm...

If I configure the OpenVPN server with uci set openvpn.vpn1.push='redirect-gateway def1', it does not work (i.e. I do not get an ICMP echo reply from 172.31.1.1).  The client's log file and route table as follows:

Fri May 30 10:42:07 2014 PUSH: Received control message: 'PUSH_REPLY,redirect-gateway def1,route 172.31.1.1,topology net30,ping 10,ping-restart 120,ifconfig 172.31.1.6 172.31.1.5'
   ...
Fri May 30 10:42:07 2014 /sbin/ifconfig tun0 172.31.1.6 pointopoint 172.31.1.5 mtu 1500
Fri May 30 10:42:07 2014 /sbin/route add -net 127.0.0.1 netmask 255.255.255.255 gw 192.168.95.231
Fri May 30 10:42:07 2014 /sbin/route add -net 0.0.0.0 netmask 128.0.0.0 gw 172.31.1.5
Fri May 30 10:42:07 2014 /sbin/route add -net 128.0.0.0 netmask 128.0.0.0 gw 172.31.1.5
Fri May 30 10:42:07 2014 /sbin/route add -net 172.31.1.1 netmask 255.255.255.255 gw 172.31.1.5
Fri May 30 10:42:07 2014 Initialization Sequence Completed

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         172.31.1.5      128.0.0.0       UG    0      0        0 tun0
default         192.168.95.231  0.0.0.0         UG    0      0        0 eth0
127.0.0.1       192.168.95.231  255.255.255.255 UGH   0      0        0 eth0
128.0.0.0       172.31.1.5      128.0.0.0       UG    0      0        0 tun0
172.31.1.1      172.31.1.5      255.255.255.255 UGH   0      0        0 tun0
172.31.1.5      *               255.255.255.255 UH    0      0        0 tun0
192.168.64.0    *               255.255.224.0   U     0      0        0 eth0

If I configure the OpenVPN server with uci set openvpn.vpn1.push='redirect-gateway' (NB: the def1 has been removed), it doesn't work either.  The client's log file and route table as follows:

Fri May 30 10:47:52 2014 PUSH: Received control message: 'PUSH_REPLY,redirect-gateway,route 172.31.1.1,topology net30,ping 10,ping-restart 120,ifconfig 172.31.1.6 172.31.1.5'
   ...
Fri May 30 10:47:52 2014 /sbin/ifconfig tun0 172.31.1.6 pointopoint 172.31.1.5 mtu 1500
Fri May 30 10:47:52 2014 /sbin/route add -net 127.0.0.1 netmask 255.255.255.255 gw 192.168.95.231
Fri May 30 10:47:52 2014 /sbin/route del -net 0.0.0.0 netmask 0.0.0.0
Fri May 30 10:47:52 2014 /sbin/route add -net 0.0.0.0 netmask 0.0.0.0 gw 172.31.1.5
Fri May 30 10:47:52 2014 /sbin/route add -net 172.31.1.1 netmask 255.255.255.255 gw 172.31.1.5
Fri May 30 10:47:52 2014 Initialization Sequence Completed

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         172.31.1.5      0.0.0.0         UG    0      0        0 tun0
127.0.0.1       192.168.95.231  255.255.255.255 UGH   0      0        0 eth0
172.31.1.1      172.31.1.5      255.255.255.255 UGH   0      0        0 tun0
172.31.1.5      *               255.255.255.255 UH    0      0        0 tun0
192.168.64.0    *               255.255.224.0   U     0      0        0 eth0

However, if I configure the OpenVPN server with uci del openvpn.vpn1.push (i.e. delete the redirect-gateway option), it does work.  The client's log file and route table as follows:

Fri May 30 10:56:47 2014 PUSH: Received control message: 'PUSH_REPLY,route 172.31.1.1,topology net30,ping 10,ping-restart 120,ifconfig 172.31.1.6 172.31.1.5'
   ...
Fri May 30 10:56:47 2014 /sbin/ifconfig tun0 172.31.1.6 pointopoint 172.31.1.5 mtu 1500
Fri May 30 10:56:47 2014 /sbin/route add -net 172.31.1.1 netmask 255.255.255.255 gw 172.31.1.5
Fri May 30 10:56:47 2014 Initialization Sequence Completed

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         192.168.95.231  0.0.0.0         UG    0      0        0 eth0
172.31.1.1      172.31.1.5      255.255.255.255 UGH   0      0        0 tun0
172.31.1.5      *               255.255.255.255 UH    0      0        0 tun0
192.168.64.0    *               255.255.224.0   U     0      0        0 eth0

As evidenced by executing ping -c 4 172.31.1.1:

PING 172.31.1.1 (172.31.1.1): 56 data bytes
64 bytes from 172.31.1.1: seq=0 ttl=64 time=35.816 ms
64 bytes from 172.31.1.1: seq=1 ttl=64 time=35.268 ms
64 bytes from 172.31.1.1: seq=2 ttl=64 time=36.817 ms
64 bytes from 172.31.1.1: seq=3 ttl=64 time=38.642 ms

--- 172.31.1.1 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 35.268/36.635/38.642 ms

I can even add (and utilize) static routes to the other side of the OpenVPN server!

(Last edited by zxdavb on 30 May 2014, 11:50)

The cause of this problem is discussed below, and best workaround (so far) in in post #6.

FYI, the SOCKS tunnel is established with the following command on the same system as the OpenVPN client:

ssh -f -N -D 1080 -g root@${SOCKS_SERVER_IP} -c blowfish -i /root/.ssh/id_dsa

If the dynamic SOCKS proxy (i.e. the listener) is on localhost (e.g. socks_proxy='127.0.0.1 1080'), then it can no longer reach the SSH gateway (i.e. ${SOCKS_SERVER_IP}) after redirect_gateway makes changes to the client's route table.

Therefore, before starting the OpenVPN tunnel on the client, ensure it can continue to reach the SSH gateway (let's call this route option A):

route add -net ${SOCKS_SERVER_IP} netmask 255.255.255.255 gw ${LOCAL_DEFAULT_GW}

What OpenVPN is doing is ensuring you can reach the SOCKS proxy (I described it as a bit 'odd' in post #2), which is necessary if it's not on localhost, but not in my case (let's call this route option B):

route add -net 127.0.0.1 netmask 255.255.255.255 gw ${LOCAL_DEFAULT_GW}

As far as I am concerned, OpenVPN should know to do route option A because I used the socks_proxy option with localhost, or 127.0.0.1

Maybe I should submit a bug?

(Last edited by zxdavb on 2 Jun 2014, 15:35)

congratulations for the nice work !

would you mind to do a"howto" or even add it to the wiki ?

I think documentation will help followups alot.

Thank you

regards
3zl

The best option so far (on the OpenVPN Client):

uci set openvpn.MYVPN.route='SOCKS_SERVER_IP 255.255.255.255 net_gateway'
uci set openvpn.MYVPN.allow_pull_fqdn=1 # needed if SOCKS_SERVER_IP is a FQDN

(Last edited by zxdavb on 2 Jun 2014, 15:33)

zxdavb wrote:

The cause of this problem is discussed below, and best workaround (so far) in in post #6.

FYI, the SOCKS tunnel is established with the following command on the same system as the OpenVPN client:

ssh -f -N -D 1080 -g root@${SOCKS_SERVER_IP} -c blowfish -i /root/.ssh/id_dsa

If the dynamic SOCKS proxy (i.e. the listener) is on localhost (e.g. socks_proxy='127.0.0.1 1080'), then it can no longer reach the SSH gateway (i.e. ${SOCKS_SERVER_IP}) after redirect_gateway makes changes to the client's route table.

Therefore, before starting the OpenVPN tunnel on the client, ensure it can continue to reach the SSH gateway (let's call this route option A):

route add -net ${SOCKS_SERVER_IP} netmask 255.255.255.255 gw ${LOCAL_DEFAULT_GW}

What OpenVPN is doing is ensuring you can reach the SOCKS proxy (I described it as a bit 'odd' in post #2), which is necessary if it's not on localhost, but not in my case (let's call this route option B):

route add -net 127.0.0.1 netmask 255.255.255.255 gw ${LOCAL_DEFAULT_GW}

As far as I am concerned, OpenVPN should know to do route option A because I used the socks_proxy option with localhost, or 127.0.0.1

Maybe I should submit a bug?

The cause of this problem is your peculiar configuration, along with the use of the experimental --redirect-gateway directive.

I'm not sure how you expect to solve this. Normally the whole point of a SOCKS server works on the assumption that the local host cannot directly reach the destination in question, regardless I don't see how you can expect Openvpn to do "route option A". OpenVPN knows nothing about your SSH gateway and can't possibly know about it, so there is no way it can automatically add a static route for something it knows nothing about.

This is always going to be an unusual use case which OpenVPN cannot automatically "fix"

I respond for the benefit of the OpenWrt community...

qasdfdsaq wrote:

I'm not sure how you expect to solve this.

Actually, from my point of view, it's solved.

qasdfdsaq wrote:

The cause of this problem is your peculiar configuration, along with the use of the experimental --redirect-gateway directive.

That's a bit unfair!  However, I do agree it's a little peculiar.

The redirect-gateway option is not experimental! Or, if you're referring to the def1 flag (which is relatively new), then I should mention that the problem occurs with/or without it.

qasdfdsaq wrote:

OpenVPN knows nothing about your SSH gateway and can't possibly know about it, so there is no way it can automatically add a static route for something it knows nothing about.

[EDIT] Completely correct (thanks to: qasdfdsaq for the tip).  However, I have corrected the following for the benefit of those who may google their way here...

I know other people may choose to set up SSH in a way that is not apparent to OpenVPN, but that is not the case here...

In this case, OpenVPN knows all about the SOCKS proxy [EDIT was: SSH gateway] because I used the socks-proxy option, which is supported in OpenVPN 2.3.x (see: https://community.openvpn.net/openvpn/w … n23ManPage):

uci set openvpn.MYVPN.socks_proxy='localhost 1080'

As a consequence, OpenVPN even adds a route so that the SOCKS proxy [EDIT, was: SSH gateway] can still be reached via the pre-tunnel gateway rather than the post-tunnel gateway.  See a portion my log, from post #3, below:

Fri May 30 10:42:07 2014 /sbin/route add -net 127.0.0.1 netmask 255.255.255.255 gw 192.168.95.231

Usually, this would work fine, except (as in my case), the SOCKS proxy (and SSH client) [EDIT, was: SSH gateway] is the same system as the OpenVPN client (i.e. localhost). 

The 'except' is the issue here.  I would, if was was inclined to submit a bug report/feature request, ask the OpenVPN team to do:

route remote_host 255.255.255.255 net_gateway

...instead of:

route ${SOCKS_PROXY} 255.255.255.255 net_gateway

...when ${SOCKS_PROXY} resolves to 127.0.0.1. 

However, this assumes that the SSH gateway [EDIT, was: end-point of the SSH tunnel] is the same system as the OpenVPN server (which is why it's a work-around and not a solution).

(Last edited by zxdavb on 18 Jun 2014, 20:37)

zxdavb wrote:
qasdfdsaq wrote:

I'm not sure how you expect to solve this.

Actually, from my point of view, it's solved.

Well you said you were going to file a bug report, which implies you think it's a bug.

zxdavb wrote:

The redirect-gateway option is not experimental! Or, if you're referring to the def1 flag (which is relatively new), then I should mention that the problem occurs with/or without it.

Yes it is. Read the manual:
https://openvpn.net/man.html

--redirect-gateway [local] [def1]
    (Experimental)

qasdfdsaq wrote:

OpenVPN knows nothing about your SSH gateway and can't possibly know about it, so there is no way it can automatically add a static route for something it knows nothing about.

zxdavb wrote:

I know other people may choose to set up SSH in a way that is not apparent to OpenVPN, but that is not the case here...

In this case, OpenVPN knows all about the SSH gateway because I used the socks-proxy option, which is supported in OpenVPN 2.3.x (see: https://community.openvpn.net/openvpn/w … n23ManPage):

uci set openvpn.MYVPN.socks_proxy='localhost 1080'

As a consequence, OpenVPN even adds a route so that the SSH gateway can still be reached via the pre-tunnel gateway rather than the post-tunnel gateway.  See a portion my log, from post #3, below:

Fri May 30 10:42:07 2014 /sbin/route add -net 127.0.0.1 netmask 255.255.255.255 gw 192.168.95.231

Usually, this would work fine, except (as in my case), the SSH gateway is the same system as the OpenVPN client (i.e. localhost).

You seem to have completely misunderstood SOCKS, what an SSH gateway is and how it works. SSH has nothing to do with SOCKS or OpenVPN. Telling OpenVPN about a SOCKS proxy tells it nothing about any SSH gateway you have hidden behind it. OpenVPN does not add any route to any SSH gateway and cannot do so. The very definition of the 'S' in 'SSH' makes this so. It is impossible, end of story.

zxdavb wrote:

The 'except' is the issue here.  I would, if was was inclined to submit a bug report/feature request, ask the OpenVPN team to do:

route remote_host 255.255.255.255 net_gateway

...instead of:

route ${socks-proxy} 255.255.255.255 net_gateway

...when ${socks-proxy} resolves to 127.0.0.1.

And how do you expect OpenVPN to possibly know what remote_host? Your SSH gateway and remote host have nothing to do with the SOCKS proxy. You might as well be asking OpenVPN to magically find out what my ceiling lamp's IP address is.

(Last edited by qasdfdsaq on 18 Jun 2014, 13:13)

Hi qasdfdsaq,

1. Yes, you are right - I implied that it is a bug, but I agree that it is not a bug. 

What really should happen is a WARNING in the log file that using localhost as a socks-proxy may mean that the SSH gateway is no longer reachable when the route table is updated during tunnel negotiation. See also point 4, below.

2. No, you are wrong - the option is not experimental.

I don't know whay, but the link you gave me for the OpenVPN manual (https://openvpn.net/man.html) redirects to the v2.0.x manual!  If you look at the 2.3 manual (https://openvpn.net/man.html), the option is no longer experimental.

3. Yes, you are right - I got SOCKS proxy and SSH gateway 'confused'.

I was writing SSH gateway, but in my mind I mostly meant the SOCKS proxy/SSH client!  Later, I will therefore update my previous post(s) to avoid confusing people.

4. BTW, OpenVPN know exactly what remote_host is (it's used with --route.  In the case of --remote (but no SOCKS proxy), it's $REMOTE_SERVER_ADDR, but with --socks-proxy, (I understand) it's the $SOCKS_PROXY_ADDR (this doesn't appear to be documented, which led to my thinking it's a 'bug').

-----

In all, 2-1 your way! Well done. wink

(Last edited by zxdavb on 18 Jun 2014, 20:40)

1) I'm glad we agree. It's true that this behaviour may confuse people. But it's not really OpenVPN's fault.

2) Well their website linking to the wrong manual is OpenVPN's fault :-P

4) Well, yes it knows the address of the VPN endpoint, but still wouldn't know about the endpoint of your SSH gateway. Which might in this case be the remote server but could also be anything else - all OpenVPN knows is there is a SOCKS server at 127.0.0.1, it's up to the SOCKS server how it routes things, whether it be via SSH or anything else. It's just a bad interaction if that server is on the same machine. There's no "rule" to say the SOCKS proxy connects to the destination server at all - lots of services (e.g. Tor) present a SOCKS proxy on localhost and tunnel it to completely different addresses.

The discussion might have continued from here.