OpenWrt Forum Archive

Topic: OpenVPN Control Scripts.

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

Hi All,
Spent this afternoon working on some scripts to provide better control of OpenVPN connections and wanted to share and get some feed back. First a DISCLAMER!  This is the first time I've really done any shell scripting so let me know of any style improvements I can make you wont offend me. Hope some other people find this useful! let me know if you've got any other feature ideas as well!

Thanks!

Quick Feature overview.
*init.d script that will start openvpn servers and clients on bootup (with appropriate /etc/rc.d/ link)
*Ability to control which individual connections start on boot up so not all connections have to always start
*ovpnctl script to control connections on a running router. (stop, start, list, status)

All the scripts assume that the openvpn configuration is stored in /etc/openvpn/ with each connection having a config file [connectionName].conf

So first the init.d script. It's primary purpose is to scan the connections (/etc/openvpn/*.conf) for files that have the execute bit set and start them. Only configs with the execute bit set will be started at boot time. All others can be manually started later with the ovpnctl script below.
/etc/init.d/openvpn

#!/bin/sh /etc/rc.common
# Copyright (C) 2007 OpenWrt.org
# Copyright (C) 2007 CICAT Networks (joe@cicat.com)

. /lib/network/openvpn.sh

start () {
        local connList=$(ovpn_conn_list)
        local connName

        for conn in $connList
        do
                if [ -x "$conn" ]
                then
                        connName=`echo "$conn" | cut -d '/' -f 4 | cut -d '.' -f 1`
                        ovpn_conn_start "$connName"
                fi
        done
}

stop () {
        killall /usr/bin/openvpn && rm /var/run/*.ovpn.pid
}

Second is the ovpnctl script which allows you to stop, start, list, and retrieve status on the connections. So some sample executions.

root@OpenWrt:/etc/init.d# ovpnctl  help
Syntax ./ovpnctl [command]
Available commands:
        start   Starts a openvpn connection.
                example: ./ovpnctl start tunnel_name

        stop    Bring down a openvpn connection.
                example: ./ovpnctl stop tunnel_name

        list    List available connections.
                example: ./ovpnctl list

        status  Display the status of each connection.
                example: ./ovpnctl status
root@OpenWrt:/etc/init.d# ovpnctl status
Connection      Status          PID
cicats2s        running         1207
testtest        down

And the code
/sbin/ovpnctl

#!/bin/sh
# Copyright (C) 2007 OpenWrt.org
# Copyright (C) 2007 CICAT Networks (joe@cicat.com)

. /lib/network/openvpn.sh

start() {
        local CONN="$1"
        if [ -e "/etc/openvpn/${CONN}.conf" ]
        then
                ovpn_conn_start "$CONN"
        else
                echo "Unable to find connection ${CONN}"
                echo "try running 'ovpnctl list' to see a list of available connections"
        fi
}

stop() {
        local CONN="$1"
        if [ -e "/var/run/${CONN}.ovpn.pid" ]
        then
                ovpn_conn_stop "$CONN"
        else
                echo "${CONN} does not appear to be running"
                echo "try running 'ovpnctl status' to see a list of running connections"
        fi
}

list() {
        for i in `ls /etc/openvpn/*.conf`
        do
                name=`echo "$i" | cut -d '/' -f 4 | cut -d '.' -f 1`
                echo "$name"
        done
}

status() {

cat <<EOF
Connection      Status          PID
EOF
        for i in `ls /etc/openvpn/*.conf`
        do
                name=`echo "$i" | cut -d '/' -f 4 | cut -d '.' -f 1`
                if [ -e "/var/run/${name}.ovpn.pid" ]
                then
                        echo "${name}   running         $(ovpn_get_pid ${name})"
                else
                        echo "${name}   down"
                fi

        done
}

help () {
        cat <<EOF
Syntax ./ovpnctl [command]
Available commands:
        start   Starts a openvpn connection.
                example: ./ovpnctl start tunnel_name

        stop    Bring down a openvpn connection.
                example: ./ovpnctl stop tunnel_name

        list    List available connections.
                example: ./ovpnctl list

        status  Display the status of each connection.
                example: ./ovpnctl status
EOF
}


ACTION="$1"

case "$ACTION" in
        start) start "$2";;
        stop) stop "$2";;
        list) list;;
        status) status;;
        *) help;;
esac

Finally the helper functions. they provide ways to stop and start connections, get a list of connections, and get a PID for a connection.
/lib/network/openvpn.sh

#!/bin/sh
# Copyright (C) 2007 OpenWrt.org
# Copyright (C) 2007 CICAT Networks (joe@cicat.com)

ovpn_conn_start() {
        local CONN="$1"
        if [ -e "/etc/openvpn/${CONN}.conf" ]
        then
                /usr/sbin/openvpn --daemon "${CONN}" --config "/etc/openvpn/${CONN}.conf" --writepid "/var/run/${CONN}.ovpn.pid"
        fi
}

ovpn_conn_stop() {
        local CONN="$1"
        if [ -e "/var/run/${CONN}.ovpn.pid" ]
        then
                kill -TERM "$(ovpn_get_pid $CONN)" && rm "/var/run/${CONN}.ovpn.pid"
        fi
}

ovpn_conn_list() {
        for i in `ls /etc/openvpn/*.conf`
        do
                list="$list $i"
        done

        echo "$list"
}

ovpn_get_pid() {
        local CONN="$1"
        if [ -e "/var/run/${CONN}.ovpn.pid" ]
        then
                echo "$(head -n1 -q /var/run/${CONN}.ovpn.pid 2>/dev/null)"
        fi
}

Thank you!

Any chance that these could be included in the package in the future?

The discussion might have continued from here.