Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
OpenVPN scripts for per client iptables configuration

Every time a new client connects to OpenVPN server, script creates set of individual iptables rules based on client common name and content of ccd files. When client disconnects from OpenVPN server, removes these individual rules. can be used to launch OpenVPN in docker contaner.

This should be a part of openvpn.conf file for scripts to work

# Client configuration
script-security 2
client-config-dir  /etc/openvpn/ccd
client-connect     /etc/openvpn/scripts/
client-disconnect  /etc/openvpn/scripts/
#!/usr/bin/env bash
# Cleanup iptables
iptables -F
iptables -X
iptables -t raw -F
iptables -t raw -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -t security -F
iptables -t security -X
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
iptables -I INPUT -i lo -j ACCEPT
iptables -I INPUT -i eth0 -p udp --dport 1194 -j ACCEPT
iptables -I INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -I OUTPUT -o lo -j ACCEPT
iptables -I OUTPUT -o eth0 -d -j ACCEPT
iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
# Launch OpenVPN
exec openvpn --config /etc/openvpn/openvpn.conf
#!/usr/bin/env bash
# Add iptables rules based on CCD client config.
# iptables rule comment - the disconnect script will
# remove all strings matching this pattern
if [ -f $CCD_DIR/$common_name ]; then
sudo /sbin/iptables -N $RULE_COMMENT
grep "^push \"route" $CCD_DIR/$common_name | tr -d '"' | \
while read line; do
network=$(echo $line | cut -f3 -d" ")
netmask=$(echo $line | cut -f4 -d" ")
sudo /sbin/iptables -A $RULE_COMMENT -i $dev \
-s $ifconfig_pool_remote_ip/32 -o eth0 \
-d $network/$netmask -j ACCEPT \
-m comment --comment $RULE_COMMENT
sudo /sbin/iptables -A FORWARD -j $RULE_COMMENT
sudo /sbin/iptables -t nat -A POSTROUTING \
-s $ifconfig_pool_remote_ip/32 -o eth0 \
-m comment --comment $RULE_COMMENT
exit 0
#!/usr/bin/env bash
# Remove iptables rules based on CCD client config.
# 1st param - name of table
# 2nd param - rule comment
get_iptables_rule_by_comment () {
echo $(sudo /sbin/iptables -nL $1 --line-numbers | grep -m 1 $2 | cut -f1 -d" ")
get_iptables_nat_rule_by_comment () {
echo $(sudo /sbin/iptables -nL $1 -t nat --line-numbers | grep -m 1 $2 | cut -f1 -d" ")
# Delete link to FORWARD rule first
rule_number=$(get_iptables_rule_by_comment FORWARD $RULE_COMMENT)
if [ "$rule_number" ]; then
sudo /sbin/iptables -D FORWARD $rule_number
# Delete MASQUERADE rule
rule_number=$(get_iptables_nat_rule_by_comment POSTROUTING $RULE_COMMENT)
if [ "$rule_number" ]; then
sudo /sbin/iptables -D POSTROUTING $rule_number -t nat
# Delete user-specific chain
if [ "$RULE_COMMENT" ]; then
sudo /sbin/iptables -F $RULE_COMMENT
sudo /sbin/iptables -X $RULE_COMMENT
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment