OpenVPN Variables Passed via Script

6,064

when a user connects to OpenVPN the following learn-address script is called

The $1, $2, and $3 are the arguments passed to the script, that are documented in the man page.

--learn-address cmd

...

Three arguments will be appended to any arguments in cmd as follows:

[1] operation -- "add", "update", or "delete" based on whether or not 
    the address is being added to, modified, or deleted from OpenVPN's
    internal routing table. 
[2] address -- The address being learned or unlearned. This can be an IPv4 
    address such as "198.162.10.14", an IPv4 subnet such as "198.162.10.0/24", 
    or an ethernet MAC address (when --dev tap is being used) such 
    as "00:FF:01:02:03:04". 
[3] common name -- The common name on the certificate associated with the 
    client linked to this address. Only present for "add" or "update" 
    operations, not "delete".
Share:
6,064

Related videos on Youtube

Server Programmer
Author by

Server Programmer

Updated on September 18, 2022

Comments

  • Server Programmer
    Server Programmer over 1 year

    Can someone explain and/or direct me to a summary of the variables that are available to be passed to OpenVPN upon a client connection?

    For example, what do the following $1, $2, $3, $4 values produce for variables:

    ip=$1
    user=$2
    ?=$3
    ?=$4
    ?=$5
    

    etc

    To clarify: when a user connects to OpenVPN the following learn-address script is called (please see below)

    I would like to know what variables are available to pass to this bash script once a user connects

    Here is the learn-address script and the first (2) variables (at the top of the script) $1 and $2 - are there other variables we can capture (eth0 vs dev1, etc)?

    #!/bin/bash
    
    statedir=/tmp/
    
    function bwlimit-enable() {
        ip=$1
        user=$2
    
        # Disable if already enabled.
        bwlimit-disable $ip
    
        # Find unique classid.
        if [ -f $statedir/$ip.classid ]; then
            # Reuse this IP's classid
            classid=`cat $statedir/$ip.classid`
        else
            if [ -f $statedir/last_classid ]; then
                classid=`cat $statedir/last_classid`
                classid=$((classid+1))
            else
                classid=1
            fi
            echo $classid > $statedir/last_classid
        fi
    
        # Find this user's bandwidth limit
        # downrate: from VPN server to the client
        # uprate: from client to the VPN server
        if [ "$user" == "myuser" ]; then
            downrate=10mbit
            uprate=10mbit
        elif [ "$user" == "anotheruser"]; then
            downrate=2mbit
            uprate=2mbit
        else
            downrate=5mbit
            uprate=5mbit
        fi
    
        # Limit traffic from VPN server to client
        tc class add dev $dev parent 1: classid 1:$classid htb rate $downrate
        tc filter add dev $dev protocol all parent 1:0 prio 1 u32 match ip dst $ip/32 flowid 1:$classid
    
        # Limit traffic from client to VPN server
        tc filter add dev $dev parent ffff: protocol all prio 1 u32 match ip src $ip/32 police rate $uprate burst 80k drop flowid :$classid
    
        # Store classid and dev for further use.
        echo $classid > $statedir/$ip.classid
        echo $dev > $statedir/$ip.dev
    }
    
    function bwlimit-disable() {
        ip=$1
    
        if [ ! -f $statedir/$ip.classid ]; then
            return
        fi
        if [ ! -f $statedir/$ip.dev ]; then
            return
        fi
    
        classid=`cat $statedir/$ip.classid`
        dev=`cat $statedir/$ip.dev`
    
        tc filter del dev $dev protocol all parent 1:0 prio 1 u32 match ip dst $ip/32
        tc class del dev $dev classid 1:$classid
    
        tc filter del dev $dev parent ffff: protocol all prio 1 u32 match ip src $ip/32
    
        # Remove .dev but keep .classid so it can be reused.
        rm $statedir/$ip.dev
    }
    
    # Make sure queueing discipline is enabled.
    tc qdisc add dev $dev root handle 1: htb 2>/dev/null || /bin/true
    tc qdisc add dev $dev handle ffff: ingress 2>/dev/null || /bin/true
    
    case "$1" in
        add|update)
            bwlimit-enable $2 $3
            ;;
        delete)
            bwlimit-disable $2
            ;;
        *)
            echo "$0: unknown operation [$1]" >&2
            exit 1
            ;;
    esac
    
    exit 0
    
    • EEAA
      EEAA almost 8 years
      Please provide more context. Where are you seeing these in use?
    • Zoredache
      Zoredache almost 8 years
      In what context? Is this for passing from OpenVPN values to one of the various hook scripts? Did you check the environmental variables section of the man page?
  • Server Programmer
    Server Programmer almost 8 years
    Are you sure EEAA? The second line user=$2 passes the name of the OpenVPN client to the bash script
  • EEAA
    EEAA almost 8 years
    Yes I am sure. The script you refer to is a bash script, not anything unique to OpenVPN.
  • EEAA
    EEAA almost 8 years
    And your interpretation of user=$2 is incorrect. That line assigns to the variable "user" whatever value is passed as the second argument to the script.
  • Server Programmer
    Server Programmer almost 8 years
    Sorry, maybe I am missing something here - where does the second argument that is passed to the script come from?
  • EEAA
    EEAA almost 8 years
    It comes from whatever calls the script.
  • Server Programmer
    Server Programmer almost 8 years
    Thanks, are there any other arguments available beyond $1, $2 and $3? Or is it just these (3)?
  • Zoredache
    Zoredache almost 8 years
    have nothing to do with OpenVPN they aren't environment variables, but they do come from OpenVPN. That the values will be are pretty clearly documented in the man page.
  • Zoredache
    Zoredache almost 8 years
    Yes, and the are IN THE MAN PAGE. Under the 'Environmental Variables'. Seriously, spend some time. Look at the man page. You could also dig into the source code if really want to see what is going on.
  • Zoredache
    Zoredache almost 8 years
    If you want to see everything that is actually being passed add a line like this at the start of your script. (echo "$*" ; export )> /tmp/blah
  • Server Programmer
    Server Programmer almost 8 years
    Awesome, I will try this. I think this is a very relevant question - I was thrown off by $2 capturing the name of the OpenVPN certificate name which was not explained on the Man Page via learn-address, so I was wondering if there are other variables not mentioned in the Man Page that we can capture