How to Allow Specific IP Addresses in OpenVPN Server

Posted on November 3, 2020 at 11:42 am

The best and safest way to allow only specific IP addresses to use your VPN is by using iptables. First you need to add your accept (allow) rules and then you add a rule to drop (deny) all other traffic, example:

iptables -A INPUT -s 1.2.3.4/32 -i eth1 -p udp -m udp --dport 1194 -j ACCEPT
iptables -A INPUT -i eth1 -p udp -m udp --dport 1194 -j DROP

Alternatively, you can use client-connect to allow only certain IPs:

In your OpenVPN server .conf file add these lines:

script-security 2
client-connect /etc/openvpn/ipwhitelist.sh

Create a file /etc/openvpn/ipwhitelist.sh with following content:

#!/bin/bash
 
allowed_ip="1.1.1.1" # Add your allowed IP address
 
if [ "$trusted_ip" == "$allowed_ip" ]; then
    # Allow connection
    exit 0
else
    # Block connection
    exit 1
fi

Set execution +x permissions:

chmod +x /etc/openvpn/ipwhitelist.sh

In case client-connect bash script is not executed, make sure that:

1) OpenVPN is started with –client-connect parameter

/usr/sbin/openvpn --status /run/openvpn/server1.status 10 --cd /etc/openvpn/ --config /etc/openvpn/server1.conf --script-security 2 --client-connect /etc/openvpn/ipwhitelst.sh

2) Your OpenVPN server config supports IPv4

If you use UDP, comment “udp6” line and use only udp:

#proto udp6
proto udp

Moreover, comment any reference to IPv6:

#server-ipv6 XXXX::0/64
#push "route-ipv6 XXXX::0/64"
#push "route-ipv6 2000::/3"
#push "redirect-gateway ipv6"

3) /etc/init.d/openvpn is updated

You need to add following lines in /etc/init.d/openvpn:

    # Support script-security <level> argument
    SCRIPTSECURITYARG=""
    if test -z "$( grep '^[[:space:]]*script-security[[:space:]]' $CONFIG_DIR/$NAME.conf )" ; then
        SCRIPTSECURITYARG="--script-security 2"
    fi
 
    # Support client-connect </path/to/script> argument
    CLIENTCONNECTARG=""
    CLIENTCONNECTSCRIPT=$(cat $CONFIG_DIR/$NAME.conf | grep "client-connect" | cut -d' ' -f 2)
    if [ ! -z "$CLIENTCONNECTSCRIPT" ]; then
        if [ -f "$CLIENTCONNECTSCRIPT" ]; then
            CLIENTCONNECTARG="--client-connect $CLIENTCONNECTSCRIPT"
        fi
    fi
 
    log_progress_msg "$NAME"
    STATUS=0
 
    start-stop-daemon --start --quiet --oknodo \
        --pidfile /run/openvpn/$NAME.pid \
        --exec $DAEMON -- $OPTARGS --writepid /run/openvpn/$NAME.pid \
        $DAEMONARG $STATUSARG --cd $CONFIG_DIR \
        $SCRIPTSECURITYARG $CLIENTCONNECTARG \
        --config $CONFIG_DIR/$NAME.conf || STATUS=1

Then make sure to reload daemons scripts:

systemctl daemon-reload

And finally start openvpn daemon:

/etc/init.d/openvpn start

References:

Here you can find more environment variables to use in your bash script:

https://openvpn.net/community-resources/reference-manual-for-openvpn-2-3/

Scroll down until you see “SCRIPTING AND ENVIRONMENTAL VARIABLES”

A nice forum post with useful information:

https://forums.openvpn.net/viewtopic.php?t=10024

Receive updates via email

Other Posts

Updated Posts