pfSense, as of 2016-03-01, does not support OpenConnect out of the box. However, it’s in the FreeBSD repository, and relatively easy to add:
# pkg update -f
# pkg install openconnect
You can now play around with the openconnect command and test your connection.
Next step: Autostart, and adding the tun interface to the pfSense GUI. The GUI will, by default, ignore any interface named “tun*”, while openconnect will refuse to work with any interface not named “tun*”. Brilliant. The easiest workaround for this special case seems to be renaming the VPN interface after creation.
I made a script that automates checking if the connection is up, and (re-)starting it if it is not.
Replace the options in the “settings” section with appropriate values for your setup, and you should be good to go.
The “test” field should be a command that returns 0 when the connection is up, and anything else when it’s broken. I used netcat’s port testing feature on the remote desktop port of a server I needed to be able to connect to, but you can just as easily use things like ping with a limited count or similar.
test="nc -v -w 10 -z 172.16.0.4 3389"
$ifconfig "$1" down 2>/dev/null || :
$ifconfig "$1" destroy 2>/dev/null || :
# check if we're already running
if [ -n "$test" ] && $test; then
echo "Connection is already up"
# clean up previous instance, if any
if [ -e "$pidfile" ]; then
read pid <"$pidfile"
echo "Killing previous pid: $pid"
kill -TERM "$pid"
# open vpn connection
echo "$pass" |\
# rename the interface
if [ "$iface" != "$tmpif" ]; then
echo "Renaming $tmpif to $iface"
$ifconfig "$tmpif" name "$iface"
Next, use crontab -e and add an entry to run the script regularly.
*/5 * * * * /root/openconnect-vpn >/dev/null 2>&1
Again, replace the path and timing with your own preferred values.
With the connection established, you can now go ahead and add the interface in the "assignment" tab of the GUI and set up appropriate rules for it.
CAUTION: Adding an interface that's not available at boot time to the GUI will cause pfSense to think something is wrong on subsequent reboots and ask you to configure interfaces. I am not currently aware of a workaround for this, other than to not add the interface, controlling rules directly from the script instead.