INFO: OpenVPN between TP-LINK TL-WR1043ND (Client) and pfSense 2.0.1 (Server)



  • Hi all,

    I successfully linked the openVPN client on a TP-LINK TL-WR1043ND Access Point running DD-WRT v24-sp2 (Release 18024 - 12/20/11) to a pfSense 2.0.1 box. Since I encountered some difficulties with LZO compression, I decided to write this post about it.

    The setup of the DD-WRT is pretty easy, and if you use comp-lzo on your openVPN, then it will work right out of the box. One thing to note is, you need "Hash Algorithm" set to "SHA1". The other thing is, you need to configure the time server for DD-WRT, at least if you want to use TLS authentication.

    However, there's a bug in DD-WRT which causes some grief when you don't have comp-lzo enabled: The DD-WRT GUI incorrectly writes the directive "comp-lzo no" to the openVPN config file when LZO compression is disabled. Proper procedure would be NOT to write the directive when compression is disabled. This behaviour causes problems. While the openVPN link comes up, the openVPN server will complain about comp-lzo being used in the remote config and report "unknown ip protocol version=15" in its logs as soon as it gets traffic from the client. Communication will not be possible.

    It took me all night to debug the failure then try to fix it (which I couldn't, I'm not ddwrt-savvy enough - alas) and finally come up with a cheap n' dirty hack using sed, as to remove the unwanted comp-lzo directive from the GUI-generated config file. And here it is; with this DD-WRT startup-script, I employ sed to rewrite the config without the offending line and then restart openVPN:

    #!/bin/sh
    #openvpn comp-lzo workaround (startup)
    echo '#!/bin/sh' > /tmp/etc/fixovpn.sh
    echo 'cd /tmp/openvpncl/' >> /tmp/etc/fixovpn.sh
    echo 'sed "/$comp-lzo/d" openvpn.conf > openvpn.tmp' >> /tmp/etc/fixovpn.sh
    echo 'mv openvpn.tmp openvpn.conf' >> /tmp/etc/fixovpn.sh
    echo 'killall openvpn' >> /tmp/etc/fixovpn.sh
    echo 'sleep 1' >> /tmp/etc/fixovpn.sh
    echo '/usr/sbin/openvpn –config /tmp/openvpncl/openvpn.conf' >> /tmp/etc/fixovpn.sh
    chmod ugo+x /tmp/etc/fixovpn.sh

    Then, with this ddwrt-firewall script, I invoke the fixovpn.sh evoked by the above startup script and re-set NAT:

    #!/bin/sh

    openvpn comp-lzo workaround (firewall)

    /tmp/etc/fixovpn.sh
    iptables -t nat -A POSTROUTING -o tun1 -j MASQUERADE
    echo 'VPNfix applied.' > /tmp/etc/fixed

    Links fine. OpenVPN throughput is not well though, peaking at slightly below 7mbps over a 65mbps WLAN connection. Needs further investigation.

    Cheers
    Chris



  • I reported the problem to DD-WRT forums, and got this answer from Sash:

    regarding the man ddwrt uses the correct syntax. so not a problem on our side. also i never have seen this behavior. u should upgrade your servers…

    --comp-lzo [mode]
       Use fast LZO compression – may add up to 1 byte per packet for incompressible data. mode may be "yes", "no", or "adaptive" (default).

    In a server mode setup, it is possible to selectively turn compression on or off for individual clients.

    First, make sure the client-side config file enables selective compression by having at least one --comp-lzo directive, such as --comp-lzo
       no. This will turn off compression by default, but allow a future directive push from the server to dynamically change the on/off/adaptive
       setting.

    Next in a --client-config-dir file, specify the compression setting for the client, for example:

    comp-lzo yes
       push "comp-lzo yes"

    The first line sets the comp-lzo setting for the server side of the link, the second sets the client side.

    Looks like Sash is correct on the man. From what I understand now, the root cause is that the options mismatch:

    • openvpn cfg on dd-wrt always contains comp-lzo
    • openvpn cfg on pfSense does not contain comp-lzo when LZO is disabled.

    The error message in server logs "IP packet with unknown IP version=15 seen" makes sense when compression is enabled on one end, while not on the other.

    However, this behaviour appears … weird. One config tells no compression, the other tells nothing and the result is a link that establishes but can't exchange data  ??? why not simply disable compression? or throw an error? hmmmmm... what version is openVPN on pfsense anyways?



  • Here's some new information coming from DaveM on the dd-wrt forum:

    if "comp-lzo" is printed to the configuration, extra lzo bit is added (even if 'no' is specified as option), and this will cause errors if making a connection to another openvpn with no "comp-lzo" printed.

    i reported this and suggested that dd-wrt have a drop-down with a 'disabled' option to better reflect the real openvpn options (like tomatousb and other firmwares do) but the ticket was ignored and closed.

    So if you set up a new server, you can just include a "comp-lzo no" in the server config. For existing servers without comp-lzo, either try overriding by ccd config (didn't work for me) or use my dd-wrt scripts (here: http://www.dd-wrt.com/phpBB2/viewtopic.php?t=152253) for now. The second version is pretty cool as it turns on the SYS led as soon as the fw script completed, and uses the QSS led to signal openvpn connection status (lit when connected).

    Cheers
    Chris



  • Apparently, the issue was resolved in DD-WRT. A patch has been committed by Sash!
    So once Brainslayer rebuilds the WR1043ND image, you'll be able to link its VPN client to pfSense without any sed hacks!  :D

    To support the SYS and QSS-for-openVPN led functionality, you'll however still need something along the lines. My request for up/down script fields in the GUI got squashed :P



  • Thanks for your followups on this issue, it might save someone else lots of time !

    BTW would there be any benefit having pfsense offer a similar drop-down menu for configuring comp-lzo ? (i.e. disabled, yes, no, adaptive)



  • That's what I was thinking :)

    Hmm not sure about how useful such a drop-down box will be. You can always include any directive you want in the custom config section…



  • How did you manage to reach from behind the pfSense server, the net behind DD-WRT?
    It works fine the other way (from client to server), but I can't seem to be able to see the network behind the client from the server side.

    I correctly filled in the field named "Remote Network", I even added the route manually, it doesn't work. Doing a packet capture I get

    18:55:47.788623 IP 172.22.227.1 > 192.168.77.1: ICMP echo request, id 14779, seq 0, length 64
    18:55:48.799097 IP 172.22.227.1 > 192.168.77.1: ICMP echo request, id 14779, seq 1, length 64
    18:55:49.809135 IP 172.22.227.1 > 192.168.77.1: ICMP echo request, id 14779, seq 2, length 64
    18:55:50.819116 IP 172.22.227.1 > 192.168.77.1: ICMP echo request, id 14779, seq 3, length 64
    18:55:51.829126 IP 172.22.227.1 > 192.168.77.1: ICMP echo request, id 14779, seq 4, length 64
    18:55:52.839152 IP 172.22.227.1 > 192.168.77.1: ICMP echo request, id 14779, seq 5, length 64
    18:55:53.849249 IP 172.22.227.1 > 192.168.77.1: ICMP echo request, id 14779, seq 6, length 64
    18:55:54.859172 IP 172.22.227.1 > 192.168.77.1: ICMP echo request, id 14779, seq 7, length 64
    18:55:55.869187 IP 172.22.227.1 > 192.168.77.1: ICMP echo request, id 14779, seq 8, length 64
    
    

    So I guess on pfSense things are fine.

    Doing a tcpdump on the tap0 interface on DD-WRT side brings up nothing in the same time, so I can't understand what's happening.

    I have these added on DD-WRT client, do I need anything more, to see the client subnet from server side?

    iptables -A FORWARD -i tun0 -j ACCEPT
    iptables -A FORWARD -i br0 -o tun0 -j ACCEPT
    
    iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
    


  • @robi:

    How did you manage to reach from behind the pfSense server, the net behind DD-WRT?

    I didn't, as I have no need to.

    This comes to mind: Can you ping the dd-wrt VPN IP? Have you disabled NAT on the dd-wrt? You don't want to NAT the subnet behind the dd-wrt.

    Get rid of this line:

    iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
    

    And set the dd-wrt to operate in Router mode instead of Gateway: That's under Setup|Advanced Networking, IIRC



  • Indeed I don't want NAT in regards to the tunnel, but I still need NAT there as internet traffic would go locally.

    I can ping the DD-WRT leg of the tunnel, if I add this:

    iptables -I INPUT 3 -i tun0 -p icmp -j ACCEPT
    

    I'll change the mode, and see how things advance.



  • @gridrun:

    And set the dd-wrt to operate in Router mode instead of Gateway: That's under Setup|Advanced Networking, IIRC

    If I set dd-wrt to operate in Router mode instead of Gateway, I loose internet connection on LAN clients behind dd-wrt! As it seems router mode disables NAT.  :-[

    What I need:

    • have the dd-wrt box act as an OpenVPN client
    • the network behind dd-wrt have internet access through the local WAN, as usually NATted
    • the network behind dd-wrt have access to the network behind pfSense thorugh OpenVPN routed
    • network behind pfSense have access to the network behind dd-wrt also routed

    Can't seem to make it work.



  • So what you need is NAT for the clients behind the dd-wrt to reach the interwebz, but you dont want NAT on the openvpn tunnel.

    Do you still have this line?

    iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
    

    It masqs everything going out the openvpn tunnel, which is not what you want. You could try replacing the "tun0" with the wan interface.



  • I deleted that naturally. Still not going.

    I'm considering a TAP solution at the moment, it would require simpler routing as the vpn interface on the DD-WRT box would have directly an IP address from pfSense's pool.



  • @robi:

    @gridrun:

    What I need:

    • have the dd-wrt box act as an OpenVPN client
    • the network behind dd-wrt have internet access through the local WAN, as usually NATted
    • the network behind dd-wrt have access to the network behind pfSense thorugh OpenVPN routed
    • network behind pfSense have access to the network behind dd-wrt also routed

    Robi, I am looking for this same functionality. did you ever get yours working?  What was the issue?



  • @robi:

    If I set dd-wrt to operate in Router mode instead of Gateway, I loose internet connection on LAN clients behind dd-wrt! As it seems router mode disables NAT.  :-[

    What I need:

    • have the dd-wrt box act as an OpenVPN client
    • the network behind dd-wrt have internet access through the local WAN, as usually NATted
    • the network behind dd-wrt have access to the network behind pfSense thorugh OpenVPN routed
    • network behind pfSense have access to the network behind dd-wrt also routed

    Can't seem to make it work.
    [/quote]

    Hi, anyone got this working ? I did pretty much research tried MULTIPE solution and nothing worked ….

    I can easily ping network behind pfsense box, but I never managed to get pfsens network to ping  network behind dd-wrt..

    Anyone have some howto to share ?



  • It would be most interesting if gridrun would do a followup post about how this particular pfsense/ddwrt OpenVPN setup has worked for him over the past few months in terms of stability and throughput, but apparently he hasn't logged back again in this forum since April …



  • Issue is with the DD-wrt NAT, but DD-wrt forum is not the friendliest place on earth :-) So I was wondering if anyone here can give a helping hand with DD-WRT nat….


Locked