What's new

A simple guide to use ocserver(openconnect VPN) under asuswrt-merlin

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

xfgavin

Occasional Visitor
As I requested, entware-ng team added ocserver (Openconnect VPN server) to the repository. This may help a lot of people where many other VPN techniques blocked (e.g. China). Here is a very simple guide:
1. Install entware-ng as stated here: https://github.com/RMerl/asuswrt-merlin/wiki/Entware
2. opkg update; opkg install ocserv
3. Follow https://www.vultr.com/docs/setup-openconnect-vpn-server-for-cisco-anyconnect-on-ubuntu-14-04-x64 to create certificates if you would like to use certificate as the authentication method. Put your certificates under /opt/etc/ocserv/cert/. Or some other places but you will have to modify the ocserv.conf by yourself. This guide is based this method.
4. Put the attached ocserv.conf.txt in /opt/etc/ocserv/, rename it to ocserv.conf and tailor it to your need.
5. Put the attached S79ocserv.txt in /opt/etc/init.d/, rename it to S79ocserv and chmod +x /opt/etc/init.d/S79ocserv
6. Append content of the attached ocserv_iptables.txt to /jffs/scripts/firewall_start and chmod +x /jffs/scripts/firewall_start if needed.
7. Reboot your router and enjoy!

I guess this guide fits all dd-wrt based roms as well.

Credits:
zyxmon@entware_ng for compiling & adding ocserv to the repository
https://wiki.openwrt.org/doc/howto/openconnect-setup for iptables script insight
@RMerlin for the wonderful asuswrt-merlin
@RMerlin, @sfx2000 and @jeff288 for valuable discussion and insights.
 

Attachments

  • ocserv.conf.txt
    24 KB · Views: 1,326
  • S79ocserv.txt
    223 bytes · Views: 882
  • ocserv_iptables.txt
    626 bytes · Views: 1,354
Last edited:
Surprise! OpenConnect VPN still being actively worked on. It supports multithreads. Speed wise shall be faster than OpenVPN at equivalent crypto settings. Also not require a special kernel. Can work on any asuswrt/merlin. Very tempting to make use of AnyConnect iOS client - lots of praise about the cisco client.

What kind of throughput are you getting?
 
Yep, that's another intention I want to make it work! I have it installed on almost all of my clusters so I hope to have one installed on my home network. The AnyConnect IOS client is so easy to use and free! No need to jail break anymore:)

I didn't test it's throughput and I don't care it that much either, sorry. But I heard from some Chinese forums that it is slower than openvpn.
 
Yep, that's another intention I want to make it work! I have it installed on almost all of my clusters so I hope to have one installed on my home network. The AnyConnect IOS client is so easy to use and free! No need to jail break anymore:)

I didn't test it's throughput and I don't care it that much either, sorry. But I heard from some Chinese forums that it is slower than openvpn.

I have managed to install everything as per instructions. I am having problems with using userid/password based authentication to start my VPN sessions.

From your "ocserv.conf", I made the following changes:

1. Commented out the line: auth = "certificate"
2. Added line: auth = "plain[passwd=./opt/etc/ocserv/ocpasswordfile]"
3. Also, I changed the ports to 1443 (both tcp & udp)

Next, I ran "ocpasswd -c ocpasswordfile client1" through SSH on my router. I verified the "ocpasswordfile" created in my "ocserv" directory. I looked at the contents of the file and it has one line: "client1:*:encryped-password". So far so good.

Next, I tried to connect to my router using my IPhone (using Cisco Anyconnect app). Now, I disabled the certficate based authentication in the app. Now, I can initiate the connection fine from the phone. I get the prompt to enter the username and once I enter "client1", it prompts for a password. I enter the password, but at this point it simply errors out and disconnects the session. The server is reading the the password file correctly (I verified it by purposefully entering a wrong password and the client will correctly identify the wrong password).

This is the log from the server (ASUS RT-AC66U running Merlin 380.59). The relevant entries are generated by clearing the log and trying to connect.

Jun 20 19:44:54 ocserv[578]: sec-mod: using 'plain' authentication to authenticate user (session: 89HugI)
Jun 20 19:45:00 ocserv[574]: main: 192.168.5.26:63360 user disconnected (reason: unspecified, rx: 0, tx: 0)
Jun 20 19:45:00 ocserv[574]: main: 192.168.5.26:63361 user disconnected (reason: unspecified, rx: 0, tx: 0)
Jun 20 19:45:01 ocserv[578]: sec-mod: initiating session for user 'client1' (session: 89HugI)
Jun 20 19:45:01 ocserv[574]: main[client1]: 192.168.5.26:63362 new user session
Jun 20 19:45:01 ocserv[574]: main: tun.c:541: vpns0: TUNSETGROUP: Invalid argument
Jun 20 19:45:01 ocserv[574]: main[client1]: 192.168.5.26:63362 failed authentication attempt for user 'client1'
Jun 20 19:45:01 ocserv[1014]: worker: 192.168.5.26 failed cookie authentication attempt

Jun 20 19:45:01 ocserv[578]: sec-mod: temporarily closing session for client1 (session: 89HugI)
Jun 20 19:45:01 ocserv[574]: main[client1]: 192.168.5.26:63362 user disconnected (reason: unspecified, rx: 0, tx: 0)
Jun 20 19:45:01 ocserv[574]: main: 192.168.5.26:63357 user disconnected (reason: unspecified, rx: 0, tx: 0)

The problem is somewhere in the bold lines.... I tried googling "TUNSETGROUP: Invalid argument", but no joy. There was one mention of someone patching "tun.c" file for older linux kernels, but nothing relevant to OCSERV. I am guessing the problem is in the 2nd parameter in this line (in the ocpasswordfile that I have created): "client1:*:encryped-password". I looked at this parameter, and it is supposed to be the groupname of this user.

I also installed the Cisco Anyconnect app on my Windows 10 machine and it also errors out, so I don't think it is an IOS/Windows client side issue. Any help is much appreciated. Thanks.
 
1. Commented out the line: auth = "certificate"
2. Added line: auth = "plain[passwd=./opt/etc/ocserv/ocpasswordfile]"
3. Also, I changed the ports to 1443 (both tcp & udp)

Is it a typo? Worth trying with auth = "plain[passwd=/opt/etc/ocserv/ocpasswordfile]" without the leading dot.
 
Is it a typo? Worth trying with auth = "plain[passwd=/opt/etc/ocserv/ocpasswordfile]" without the leading dot.

No, the path simply goes to root and then navigates the directory structure down the tree. I didn't bother to find where the OCSERV process was running and use relative path out of laziness. Not a typo, but I wish it was and fixed my error! LOL.
 
No, the path simply goes to root and then navigates the directory structure down the tree. I didn't bother to find where the OCSERV process was running and use relative path out of laziness. Not a typo, but I wish it was and fixed my error! LOL.

Maybe Entware init.d scripts run with cwd = /. That's why...

I gave this a spin last week. I referenced xfgavin's configs. It worked for me. You did have generated certificates...right?

Regardless methods of auth, you will need two certificates (and three files): one CA cert, one server cert and its private key. All in PEM format.

To save the hassle, people can re-use the files from OpenVPN or pixelserv-tls if you happen to run one of these.

Attached is my ocserv.conf - as usual I stripped down to bare minimum. Hope a quick comparison may offer help in some way..

auth = "plain[passwd=/opt/etc/ocserv/ocpasswd]"

listen-host = <substitue with your ddns>.asuscomm.com
tcp-port = 443
udp-port = 443
run-as-user = nobody
run-as-group = nobody
socket-file = /opt/var/run/ocserv-socket

server-cert = /opt/etc/ocserv/cert/server-cert.pem
server-key = /opt/etc/ocserv/cert/server-key.pem
ca-cert = /opt/etc/ocserv/cert/ca-cert.pem

max-clients = 10
max-same-clients = 0

keepalive = 32400
dpd = 90
mobile-dpd = 1800
try-mtu-discovery = true

cert-user-oid = 0.9.2342.19200300.100.1.1
tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-VERS-SSL3.0"
auth-timeout = 40
min-reauth-time = 3
max-ban-score = 50
ban-reset-time = 300
cookie-timeout = 300
cookie-rekey-time = 14400

deny-roaming = false

rekey-time = 172800
rekey-method = ssl

use-utmp = false
pid-file = /opt/var/run/ocserv.pid

#
# Network settings
#

device = vpns
predictable-ips = true
ipv4-network = 10.8.10.0/24
dns = 192.168.1.1
ping-leases = false
mtu = 1280
route-add-cmd = "/sbin/route add -net %{RI} dev %{D}"
route-del-cmd = "/sbin/route del -net %{RI} dev %{D}"

cisco-client-compat = true

#Advanced options

custom-header = "X-DTLS-MTU: 1280"
custom-header = "X-CSTP-MTU: 1280"
 
Maybe Entware init.d scripts run with cwd = /. That's why...

I gave this a spin last week. I referenced xfgavin's configs. It worked for me. You did have generated certificates...right?

Regardless methods of auth, you will need two certificates (and three files): one CA cert, one server cert and its private key. All in PEM format.

To save the hassle, people can re-use the files from OpenVPN or pixelserv-tls if you happen to run one of these.

Attached is my ocserv.conf - as usual I stripped down to bare minimum. Hope a quick comparison may offer help in some way..

I compared your conf with mine and see a few differences....

1. The path to the password file. (Changed it to match yours and re-created "ocpasswd" file in the "ocserv" folder)
2. I did not have "listen-host" (I have put "listen-host = 192.168.5.3") (My test router's WAN IP)
3. My TCP & UDP ports are 1443 (Cannot use 443 as I have 2 instances of OpenVPN running on 443 for both TCP and UDP)
-- So, I have to use "192.168.5.3:1443" as my "Server Address" in the Cisco app on my iPhone.
4. I had 0 for "max-clients". (Changed it to 10)
5. I did not have "max-same-clients" (I added "max-same-clients = 0")
6. I have "route = default", which your file did not have. (I commented this line out)

And yes, I have all 3 certificate/private key files (PEM encoded) in the correct location (made the "cert" folder in "ocserv" and copied the 3 files in the "cert" folder) on the server.

And still getting same error. So just to get my thoughts right, your setup is working with password authentication with the conf file you posted? How are you testing it? IOS/Windows?

EDIT: I downloaded the OpenConnect GUI app available for windows at http://openconnect.github.io/openconnect-gui/

And it gives me the same error on the server... Here is the log from this GUI app on windows..

2016-06-21 18:36 POST https://192.168.5.3:1443/
2016-06-21 18:36 Attempting to connect to server 192.168.5.3:1443
2016-06-21 18:36 Connected to 192.168.5.3:1443
2016-06-21 18:36 SSL negotiation with 192.168.5.3
2016-06-21 18:36 Connected to HTTPS on 192.168.5.3
2016-06-21 18:36 Got HTTP response: HTTP/1.1 200 OK
2016-06-21 18:36 Set-Cookie: webvpncontext=; expires=Thu, 01 Jan 1970 22:00:00 GMT; path=/; Secure
2016-06-21 18:36 Content-Type: text/xml
2016-06-21 18:36 Content-Length: 306
2016-06-21 18:36 X-Transcend-Version: 1
2016-06-21 18:36 HTTP body length: (306)
2016-06-21 18:36 XML POST enabled
2016-06-21 18:36 Please enter your username.
2016-06-21 18:36 Text form: username
2016-06-21 18:36 POST https://192.168.5.3:1443/auth
2016-06-21 18:36 Got HTTP response: HTTP/1.1 200 OK
2016-06-21 18:36 Set-Cookie: webvpncontext=6qnO/BFYCA8Fk5Wy4yi8qJNOK/9x+AHcwCbGUp/KM2c=; Max-Age=300; Secure
2016-06-21 18:36 Content-Type: text/xml
2016-06-21 18:36 Content-Length: 310
2016-06-21 18:36 X-Transcend-Version: 1
2016-06-21 18:36 HTTP body length: (310)
2016-06-21 18:36 Please enter your password.
2016-06-21 18:36 Password form: password
2016-06-21 18:36 POST https://192.168.5.3:1443/auth
2016-06-21 18:36 Got HTTP response: HTTP/1.1 200 OK
2016-06-21 18:36 Connection: Keep-Alive
2016-06-21 18:36 Content-Type: text/xml
2016-06-21 18:36 Content-Length: 189
2016-06-21 18:36 X-Transcend-Version: 1
2016-06-21 18:36 Set-Cookie: webvpncontext=6qnO/BFYCA8Fk5Wy4yi8qJNOK/9x+AHcwCbGUp/KM2c=; Secure
2016-06-21 18:36 Set-Cookie: webvpn=<elided>; Secure
2016-06-21 18:36 Set-Cookie: webvpnc=; expires=Thu, 01 Jan 1970 22:00:00 GMT; path=/; Secure
2016-06-21 18:36 Set-Cookie: webvpnc=bu:/&p:t&iu:1/&sh:BBFDB233694C933ADE37991CBF065AE8B711A7F0; path=/; Secure
2016-06-21 18:36 HTTP body length: (189)
2016-06-21 18:36 Got inappropriate HTTP CONNECT response: HTTP/1.1 401 Unauthorized
2016-06-21 18:36 Error establishing the CSTP channel
2016-06-21 18:36 Disconnected
 
Last edited:
Ok, I stopped the PPTP as well as both instances of OpenVPN servers on my test router. Changed the ports in the conf file to 443. Pushed the new conf file and rebooted the router. Now, I am getting a new error message in the log when I try to connect.

Jun 21 19:09:42 ocserv[573]: sec-mod: using 'plain' authentication to authenticate user (session: YJPyRg)
Jun 21 19:09:47 ocserv[572]: main: 192.168.5.26:56566 user disconnected (reason: unspecified, rx: 0, tx: 0)
Jun 21 19:09:48 ocserv[572]: main: 192.168.5.26:56567 user disconnected (reason: unspecified, rx: 0, tx: 0)
Jun 21 19:09:48 ocserv[573]: sec-mod: initiating session for user 'client1' (session: YJPyRg)
Jun 21 19:09:48 ocserv[572]: main[client1]: 192.168.5.26:56568 new user session
Jun 21 19:09:48 ocserv[572]: main: tun.c:495: Can't open /dev/net/tun: No such file or directory
Jun 21 19:09:48 ocserv[572]: main[client1]: 192.168.5.26:56568 failed authentication attempt for user 'client1'
Jun 21 19:09:48 ocserv[622]: worker: 192.168.5.26 failed cookie authentication attempt
Jun 21 19:09:48 ocserv[573]: sec-mod: temporarily closing session for client1 (session: YJPyRg)
Jun 21 19:09:48 ocserv[572]: main[client1]: 192.168.5.26:56568 user disconnected (reason: unspecified, rx: 0, tx: 0)
Jun 21 19:09:48 ocserv[572]: main: 192.168.5.26:56565 user disconnected (reason: unspecified, rx: 0, tx: 0)
 
Jun 21 19:09:48 ocserv[572]: main: tun.c:495: Can't open /dev/net/tun: No such file or directory

Enable back your OpenVPN server and reboot. Then turn off OpenVPN server but don't reboot. One way to get back the tun device. The FW overdoes by not creating the device when it thinks no one will be using it..

I only tried AnyConnect iOS client. A superb experience btw. Seamless hopping across available WiFi and LTE networks.
 
Sorry, I have no idea about plain authentication. I prefer certificate based because I'm too lazy to input username and password:)
I am not sure whether it has something to do with compiling parameters or not.
 
Enable back your OpenVPN server and reboot. Then turn off OpenVPN server but don't reboot. One way to get back the tun device. The FW overdoes by not creating the device when it thinks no one will be using it..

I only tried AnyConnect iOS client. A superb experience btw. Seamless hopping across available WiFi and LTE networks.

Ok, I tried that. When I stop the OpenVPN server, the tun interface disappears (that is without rebooting the router), so I tried to find another way to do it.

I found an old post from Merlin that suggested to run 2 commands to manually setup a TUN, and I added one of mine at the end.

modprobe tun (Merlin provided)
openvpn --mktun --dev tun1 (Merlin provided)
ip link set tun1 up (Mine)

So, running these 3 commands after a reboot sets up the TUN properly.

BUT, I am back to my original error (main: tun.c:541: vpns0: TUNSETGROUP: Invalid argument). I am not sure how to proceed from here. I guess, the next thing to do is to see if the certificate based authentication works...
 
Sorry, I have no idea about plain authentication. I prefer certificate based because I'm too lazy to input username and password:)
I am not sure whether it has something to do with compiling parameters or not.

I hear you. I was planning to use cert based authentication, but figured I should get the user/pwd going if I ever needed it as a backup. But looks like that plan is not gong anywhere.
 
Ok, I tried that. When I stop the OpenVPN server, the tun interface disappears (that is without rebooting the router), so I tried to find another way to do it.

Partially correct. You don't need that interface though. So your cause-effect analysis is wrong and directed yourself to the wrong course of action..

I found an old post from Merlin that suggested to run 2 commands to manually setup a TUN, and I added one of mine at the end.

modprobe tun (Merlin provided)
openvpn --mktun --dev tun1 (Merlin provided)
ip link set tun1 up (Mine)

Try to understand each line. That will help a better grasp of what they do..

BUT, I am back to my original error (main: tun.c:541: vpns0: TUNSETGROUP: Invalid argument). I am not sure how to proceed from here. I guess, the next thing to do is to see if the certificate based authentication works...

My gosh. Some weird config/setup in your router perhaps? Hmm...try changing these two lines in ocserv.conf to below and see if it helps:

run-as-user = admin
run-as-group = admin


I'm waving my white flag. IMO don't spend too much time if people can't quickly get it working. Unless of cos you know you need it and know why you need it. Good luck!
 
My gosh. Some weird config/setup in your router perhaps? Hmm...try changing these two lines in ocserv.conf to below and see if it helps:

run-as-user = admin
run-as-group = admin


I'm waving my white flag. IMO don't spend too much time if people can't quickly get it working. Unless of cos you know you need it and know why you need it. Good luck!

Just a follow-up. I tried using the above, also tried creating a separate user and group to run the OCSERV worker process, etc. Even the certificate based authentication does not work. I posted this question on the gitlab forum and the reason I get the error was because of older Linux kernel. The thread is located at https://gitlab.com/ocserv/ocserv/issues/60

Thanks kvic for your help.
 
So I upgraded my router with the latest Merlin. One of the issues that I could not solve was the DNS resolution for OCServ clients, I had put that issue on the back burner in the past, but I would like to fix it now, if I can.

I can't seem to get the client (iOS phone) to resolve the DNS if the DNS server passed to the client is internal. It only works if I give the client the DNS of 8.8.8.8 (or some external IP). Instructing the client to use the internal IP does not work and I have searched, but to no avail.

Here is the relevant (simplified as there are other route commands for instances of OpenVPN clients) piece of code from the ocserv.conf file. Note that the router's main subnet is "10.76.5.0/24".

# Client subnet
ipv4-network = 10.71.7.0/24

# Client DNS
dns = 8.8.8.8

# Client Routes
route = default
route = 10.76.5.0/255.255.255.0


The above configuration works. But, if I change the line for DNS to "dns = 10.76.5.1" or "dns = 10.71.7.1", the client cannot resolve DNS. Also, completely commenting out the DNS line with no defined DNS server does not help either.

There is one more config parameter that I commented/un-commented out but it does not seem to help. It is "tunnel-all-dns = true". It should be relevant to my situation, but I am not sure how to enable/disable this command in conjunction with the DNS and ROUTE commands to realize my goal. I would like the clients to use the router (router itself uses 8.8.8.8 for resolution, from its WAN settings) for their DNS queries and not any external one like Google directly. Any ideas would be appreciated.
 
Last edited:
Well, I got it figured out. My problem was that the DnsMasq was not responding to DNS queries from the OCServ's interface (named, vpns*). I had to modify the "dnsmasq.conf.add" file to add these 2 lines:

interface=vpns*
no-dhcp-interface=vpns*

I then put these lines in the "ocserv.conf" file:

dns = 10.76.5.1
tunnel-all-dns = true

route = default

I did not need to add any other extra route commands for other internal subnets. And, I am not sure if "tunnel-all-dns = true" is needed or not. I did not see any difference in behavior.

Any other suggestions on locking down the interface vpns* in the dnsmasq.conf.add file? Thanks.
 

Similar threads

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top