How can I setup NAT on my OpenVPN Server for the client?

Mohi asked:

I have created a VM instance in Oracle Cloud to use as my OpenVPN server. I am able to connect my client (Android phone) with the server but not able to access the internet.

It seems to me that the issue is with NAT configuration in the iptables.

Can anyone please help me fix this? I have been trying for almost a week now with no success.

My configuration is as follows:

/etc/openvpn/server/server.conf

;local a.b.c.d
port 443
proto tcp
;proto udp
;dev tap
dev tun
;dev-node MyTap
ca ca.crt
cert Lyra.crt
key Lyra.key  
;dh dh2048.pem
dh none
;topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100
;server-bridge
;push "route 192.168.10.0 255.255.255.0"
;push "route 192.168.20.0 255.255.255.0"
;client-config-dir ccd
;route 192.168.40.128 255.255.255.248
;learn-address ./script
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"
;client-to-client
;duplicate-cn
keepalive 10 120
;tls-auth ta.key 0 # This file is secret
tls-crypt ta.key
;cipher AES-256-CBC
cipher AES-256-GCM
auth SHA256
;compress lz4-v2
;push "compress lz4-v2"
;comp-lzo
;max-clients 100
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
log         openvpn.log
;log-append  openvpn.log
verb 3
;mute 20
explicit-exit-notify 0

/etc/openvpn/server/openvpn.log

OpenVPN 2.4.7 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Sep  5 2019
library versions: OpenSSL 1.1.1f  31 Mar 2020, LZO 2.10
Outgoing Control Channel Encryption: Cipher 'AES-256-CTR' initialized with 256 bit key
Outgoing Control Channel Encryption: Using 256 bit message hash 'SHA256' for HMAC authentication
Incoming Control Channel Encryption: Cipher 'AES-256-CTR' initialized with 256 bit key
Incoming Control Channel Encryption: Using 256 bit message hash 'SHA256' for HMAC authentication
ROUTE_GATEWAY 10.0.0.1/255.255.255.0 IFACE=ens3 HWADDR=00:00:17:02:e1:8d
TUN/TAP device tun0 opened
TUN/TAP TX queue length set to 100
/sbin/ip link set dev tun0 up mtu 1500
/sbin/ip addr add dev tun0 local 10.8.0.1 peer 10.8.0.2
/sbin/ip route add 10.8.0.0/24 via 10.8.0.2
Could not determine IPv4/IPv6 protocol. Using AF_INET
Socket Buffers: R=[131072->131072] S=[16384->16384]
Listening for incoming TCP connection on [AF_INET][undef]:443
TCPv4_SERVER link local (bound): [AF_INET][undef]:443
TCPv4_SERVER link remote: [AF_UNSPEC]
MULTI: multi_init called, r=256 v=256
IFCONFIG POOL: base=10.8.0.4 size=62, ipv6=0
ifconfig_pool_read(), in='mirza_s8,10.8.0.4', TODO: IPv6
succeeded -> ifconfig_pool_set()
IFCONFIG POOL LIST
mirza_s8,10.8.0.4
MULTI: TCP INIT maxclients=1024 maxevents=1028
Initialization Sequence Completed
TCP connection established with [AF_INET]103.208.70.45:56043
103.208.70.45:56043 TLS: Initial packet from [AF_INET]103.208.70.45:56043, sid=37acebde bb02752b
103.208.70.45:56043 VERIFY OK: depth=1, CN=Cygnus
103.208.70.45:56043 VERIFY OK: depth=0, CN=mirza_s8
103.208.70.45:56043 peer info: IV_VER=3.git:released:3e56f9a6:Release
103.208.70.45:56043 peer info: IV_PLAT=android
103.208.70.45:56043 peer info: IV_NCP=2
103.208.70.45:56043 peer info: IV_TCPNL=1
103.208.70.45:56043 peer info: IV_PROTO=2
103.208.70.45:56043 peer info: IV_AUTO_SESS=1
103.208.70.45:56043 peer info: IV_GUI_VER=net.openvpn.connect.android_3.2.2-5027
103.208.70.45:56043 peer info: IV_SSO=openurl
103.208.70.45:56043 WARNING: 'link-mtu' is used inconsistently, local='link-mtu 1551', remote='link-mtu 1523'
103.208.70.45:56043 Control Channel: TLSv1.3, cipher TLSv1.3 TLS_AES_256_GCM_SHA384, 384 bit EC, curve: secp384r1
103.208.70.45:56043 [mirza_s8] Peer Connection Initiated with [AF_INET]103.208.70.45:56043
mirza_s8/103.208.70.45:56043 MULTI_sva: pool returned IPv4=10.8.0.6, IPv6=(Not enabled)
mirza_s8/103.208.70.45:56043 MULTI: Learn: 10.8.0.6 -> mirza_s8/103.208.70.45:56043
mirza_s8/103.208.70.45:56043 MULTI: primary virtual IP for mirza_s8/103.208.70.45:56043: 10.8.0.6
mirza_s8/103.208.70.45:56043 PUSH: Received control message: 'PUSH_REQUEST'
mirza_s8/103.208.70.45:56043 SENT CONTROL [mirza_s8]: 'PUSH_REPLY,redirect-gateway def1 bypass-dhcp,dhcp-option DNS 208.67.222.222,dhcp-option DNS 208.67.220.220,route>
mirza_s8/103.208.70.45:56043 Outgoing Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key
mirza_s8/103.208.70.45:56043 Incoming Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key

ip a show ens3

2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:00:17:02:e1:8d brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.9/24 brd 10.0.0.255 scope global ens3
       valid_lft forever preferred_lft forever
    inet6 fe80::200:17ff:fe02:e18d/64 scope link
       valid_lft forever preferred_lft forever

iptables -t nat -L -n -v

Chain PREROUTING (policy ACCEPT 1389 packets, 95043 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain INPUT (policy ACCEPT 19 packets, 1080 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 985 packets, 87235 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 299 packets, 31308 bytes)
 pkts bytes target     prot opt in     out     source               destination
 3063  226K MASQUERADE  all  --  *      ens3    10.0.0.0/8           0.0.0.0/0
    0     0 MASQUERADE  all  --  *      ens3    10.8.0.0/24          0.0.0.0/0

/etc/ufw/before.rules

# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to ens3 (change to the interface you discovered!)
-A POSTROUTING -s 10.8.0.0/8 -o ens3 -j MASQUERADE
COMMIT
# END OPENVPN RULES

sysctl net.ipv4.ip_forward

net.ipv4.ip_forward = 1

My answer:


You appear to have already set up NAT correctly, but your MTU is not set properly. It should be below 1500 — and probably significantly below — to ensure that tunnelled traffic is not fragmented as it traverses the Internet.

On my prod OpenVPN servers I have set: mssfix 1350 which has been completely stable for well over a year. While the default is 1450, this seems to run into trouble with various network links which apparently inexplicably have an MTU below 1500. This value should not be set below 1328 as a smaller value will break tunnelled IPv6.


View the full question and any other answers on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.