Simple single user VPN with OpenVPN as NAT Gateway

Posted on Thu 24 April 2014 in misc

Here's a quick brain-dump on setting up a single user VPN as a NAT gateway for use when i'm out and about.

I used the openvpn package from epel.

Note that in these examples the: tunnel endpoint = tun0

server tunnel address =

client tunnel address =

public interface = eth0

Create a user and group "openvpn" (the Epel rpm does this for you) e.g.

groupadd -r openvpn
useradd -r -g openvpn -s /sbin/nologin -c OpenVPN -d /etc/openvpn openvpn

Create a static key file which we use on server and on the client and set some secure perms (should be done already)

openvpn --genkey --secret /etc/openvpn/secret.key
sudo chown root:root /etc/openvpn/secret.key
sudo chmod 600 /etc/openvpn/secret.key

Create /etc/openvpn/server.conf (I've annotated the options)

# Run in single user tunnel mode
mode p2p

# Run only on the right address / interface
local (host or ip)

# Always setup and use tun0
dev tun0

# set addresses for local and remote tunnel endpoints
# ifconfig local remote

# Use UDP on port x
proto udp
port 1194

# Drop to openvpn:openvpn after starting
user openvpn
group openvpn

# use a static key
#(gen with openvpn --genkey --secret /etc/openvpn/secret.key)
secret secret.key

# Use separate keys for each traffic direction
# see
key-direction 0

# Don't re-read key on ping restart as we won't have enough perms

# Don't restart tun0 on ping restart as we won't have enough perms

# Keep alive (openvpn ping every 10s, ping restart if no traffic for 120s)
keepalive 10 120

#Use compression

# Logging and log level
log-append  /var/log/openvpn.log
verb 3

Client Config file e.g. client.ovpn

Notice here how we include the secret key all in one file - this works really well for easy deployment on android vpn client and tunnelblick

remote (ip or host of VPN server)
dev tun
proto udpport 1194
ping 10
key-direction 1

-----BEGIN OpenVPN Static key V1----- 
-----END OpenVPN Static key V1----- 

Should now be able to ping across the tunnel may need to add a rule to iptables if you are blocking all inbound traffic i.e. -A INPUT -i tun0 -p icmp -m icmp --icmp-type 8 -j ACCEPT

Finally enable routing at the kernel level, routing through iptables and NAT sysctl -w net.ipv4.ip_forward=1

iptables -A FORWARD -s -i tun0 -o eth0 -j ACCEPT
iptables -A FORWARD -d -i eth0 -o tun0 -j ACCEPT ]
iptables -t nat -A POSTROUTING -s -o eth0 -j MASQUERADE]

For reference here is my /etc/sysconfig/iptables


# NAT traffic coming from the remote VPN endpoint to the internet


# Allow all inbound traffic on lo
-A INPUT -i lo -j ACCEPT

# Allow vpn and ssh on public interface
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -i eth0 -p udp -m udp --dport 1194 -j ACCEPT

# Allow outbound related traffic back in

# Allow ping inbound on the vpn - useful for testing
-A INPUT -i tun0 -p icmp -m icmp --icmp-type 8 -j ACCEPT

# Allow NATed traffic which has to be routed across the interfaces
-A FORWARD -s -i tun0 -o eth0 -j ACCEPT
-A FORWARD -d -i eth0 -o tun0 -j ACCEPT