OpenVPN and passing Internet through to clients

Background:

I recently setup a little headless server at home to go with our new fibre connection. I’ve got basically all the services I want setup. Can’t get pi-hole working yet, but that is for another thread. My biggest concern right now is OpenVPN. The purpose of the VPN is to make local network resources available to everybody in the family no matter where they are in the world.

What I did:

I followed this guide: https://www.howtoforge.com/tutorial/how-to-install-and-configure-open-vpn-on-opensuse-leap-42.1/I paid particular attention to the firewall settings.
**
What works:**

Pretty much everything. I can connect to the VPN, from inside our home network or outside and access local resources. Perfect.

The problem:

The internet connection doesn’t work when I’ve VPN’ed in. Everything else works, but the client cannot use the internet. I understand this has to do with routing, but I can’t seem to figure it out. I do not want to do split-tunneling. We occasionally need to secure our internet connection.

Aiming for a Client <> Server <> Internet layout.

**What I’ve tried:
**
I’ve tried turning the firewall off entirely. Did nothing. Connecting works with firewall on or off from both the internet and within the network.

Additional information:

VPN Off:


daniel@nohostname:~> netstat -nr
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         192.168.1.1     0.0.0.0         UG        0 0          0 wlp3s0
192.168.1.0     0.0.0.0         255.255.255.0   U         0 0          0 wlp3s0


daniel@nohostname:~> ip route get 8.8.8.8
8.8.8.8 via 192.168.1.1 dev wlp3s0 src 192.168.1.110 
    cache 

VPN On:


daniel@nohostname:~> netstat -nr
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         10.10.2.5       0.0.0.0         UG        0 0          0 tun0
0.0.0.0         192.168.1.1     0.0.0.0         UG        0 0          0 wlp3s0
10.10.2.1       10.10.2.5       255.255.255.255 UGH       0 0          0 tun0
10.10.2.5       0.0.0.0         255.255.255.255 UH        0 0          0 tun0
192.168.1.0     0.0.0.0         255.255.255.0   U         0 0          0 wlp3s0
192.168.1.1     0.0.0.0         255.255.255.255 UH        0 0          0 wlp3s0
192.168.1.100   0.0.0.0         255.255.255.255 UH        0 0          0 wlp3s0


daniel@nohostname:~> ip route get 8.8.8.8
8.8.8.8 via 10.10.2.9 dev tun0 src 10.10.2.10 
    cache 

**Server.conf
**

 
#change with your port
port 2034
 
#You can use udp or tcp
proto udp
 
# "dev tun" will create a routed IP tunnel.
dev tun
 
#Certificate Configuration
 
#ca certificate
ca /etc/openvpn/keys/ca.crt
 
#Server Certificate
cert /etc/openvpn/keys/server.crt
 
#Server Key and keep this is secret
key /etc/openvpn/keys/server.key
 
#See the size a dh key in /etc/openvpn/keys/
dh /etc/openvpn/keys/dh2048.pem
 
#Internal IP will get when already connect
server 10.10.2.0 255.255.255.0
 
#this line will redirect all traffic through our OpenVPN
push "redirect-gateway def1"
 
#Provide DNS servers to the client, you can use goolge DNS
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 208.67.220.220"
 
#Enable multiple client to connect with same key
duplicate-cn
 
keepalive 20 60
comp-lzo
persist-key
persist-tun
daemon
 
#openvpn status log
status /var/log/openvpn/openvpn-status.log
 
#enable log
log-append /var/log/openvpn/openvpn.log
 
#Log Level
verb 3


**

sysctl.conf
**


net.ipv4.ip_forward = 1

**
SuseFirewall2-custom**


fw_custom_after_chain_creation() {
    # these rules will be loaded after the various input_* and forward_* chains
    # are created.
    # You can use this hook to allow/deny certain IP protocols or TCP/UDP
    # ports before the SuSEfirewall2 generated rules are hit.


iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 10.10.2.0/24 -j ACCEPT
iptables -A FORWARD -j REJECT
iptables -t nat -A POSTROUTING -s 10.10.2.0/24 -o eth0 -j MASQUERADE

    true
}

w_custom_before_port_handling() {
    # these rules will be loaded after the anti-spoofing and icmp handling
    # and after the input has been redirected to the input_XXX and
    # forward_XXX chains and some basic chain-specific anti-circumvention
    # rules have been set,
    # but before any IP protocol or TCP/UDP port allow/protection rules
    # will be set.
    # You can use this hook to allow/deny certain IP protocols or TCP/UDP
    # ports before the SuSEfirewall2 generated rules are hit.

    true
}

fw_custom_before_masq() { # could also be named "after_port_handling()"
    # these rules will be loaded after the IP protocol and TCP/UDP port
    # handling, but before any IP forwarding (routing), masquerading
    # will be done.
    # NOTE: reverse masquerading is before directly after
    #       fw_custom_before_port_handling !!!!
    # You can use this hook to ... hmmm ... I'm sure you'll find a use for
    # this ...

    true
}

fw_custom_before_denyall() { # could also be named "after_forwardmasq()"
    # these are the rules to be loaded after IP forwarding and masquerading
    # but before the logging and deny all section is set by SuSEfirewall2.
    # You can use this hook to prevent the logging of annoying packets.

    true
}

fw_custom_after_finished() {
    # these are the rules to be loaded after the firewall is fully configured

    true
}


**Where to next:

**So what exactly is the issue and how can I fix it? I’ve tried googling for this issue and everything either directs to split-tunneling or doesn’t help me much. I’ve been trying to figure this out for three days now, and have got no closer to solving it.

I wonder if IP forwarding is really enabled here. Check with

cat /proc/sys/net/ipv4/ip_forward

This might be relevant here:
https://wiki.archlinux.org/index.php/sysctl#Configuration

Note: From version 207 and 21x, systemd only applies settings from /etc/sysctl.d/.conf and /usr/lib/sysctl.d/.conf. If you had customized /etc/sysctl.conf, you need to rename it as /etc/sysctl.d/99-sysctl.conf. If you had e.g. /etc/sysctl.d/foo, you need to rename is to /etc/sysctl.d/foo.conf.

and I note that in /etc/sysctl.conf it is mentioned

# To disable or override a distribution provided file just place a
# file with the same name in /etc/sysctl.d/

so move your sysctl.conf to /etc/sysctl.d/, then

sysctl --system

and report back.

Pretty sure ip forwarding is enabled. This is my result straight after a reboot


huis@linux-g6sx:~> cat /proc/sys/net/ipv4/ip_forward
1

Following your second set of commands I get this. Indicates that I seemed to have that setup right too. The ip forwarding seems to be being set twice to on, but that is hardly a problem…


linux-g6sx:~ # sysctl --system
* Applying /boot/sysctl.conf-4.8.12-1-default ...
kernel.hung_task_timeout_secs = 0
kernel.msgmax = 65536
kernel.msgmnb = 65536
kernel.shmmax = 0xffffffffffffffff
kernel.shmall = 0x0fffffffffffff00
vm.dirty_ratio = 20
* Applying /usr/lib/sysctl.d/50-coredump.conf ...
kernel.core_pattern = |/usr/lib/systemd/systemd-coredump %P %u %g %s %t %e
* Applying /usr/lib/sysctl.d/50-default.conf ...
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.promote_secondaries = 1
net.ipv4.conf.all.promote_secondaries = 1
net.ipv6.conf.default.use_tempaddr = 1
fs.inotify.max_user_watches = 65536
kernel.sysrq = 184
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
kernel.kptr_restrict = 1
* Applying /etc/sysctl.d/99-sysctl.conf ...
net.ipv4.ip_forward = 1
* Applying /etc/sysctl.conf ...
net.ipv4.ip_forward = 1

Still nothing. VPN in from outside or within own network works fine. Services and functions work perfectly fine. Just can’t access the internet through the VPN which is a large part of wanting it. So the issue is:

*Client <> Server <!!> Internet *
instead of
*Client <> Server <> Internet *
though
*Client <> Server <> Rest of internal Network *
is good.

Any other ideas?

Run tracepath 8.8.8.8 and post the results here.

I happen to run an OpenVPN server on 42.2 happily, although I use my own iptables rules instead of SFW.

I’ve tried figuring out iptables, but it is just beyond me. SFW has always been a good compromise on power and usability for me, and as far as I know it actually uses iptables in the background (as do pretty much all firewalls).

VPN Off:


daniel@nohostname:~> tracepath 8.8.8.8
 1?: [LOCALHOST]                                         pmtu 1500
 1:  192.168.1.1                                          38.239ms 
 1:  192.168.1.1                                           0.702ms 
 2:  192.168.1.1                                           5.102ms pmtu 1480
 2:  no reply
 3:  ipc-3-up.north.dsl.telkomsa.net                      68.122ms asymm  8 
 4:  105.224.0.130                                        67.778ms asymm  7 
 5:  ipc-aggr-1.north.telkomsa.net                        67.963ms asymm  6 
 6:  jb1-ti-pr-02-te1-3-0.net.telkomsa.net                68.174ms 
 7:  no reply
 8:  no reply
 9:  no reply
10:  no reply
11:  no reply
12:  no reply
13:  no reply
14:  no reply
15:  no reply

**
VPN On:**


daniel@nohostname:~> tracepath 8.8.8.8
 1?: [LOCALHOST]                                         pmtu 1500
 1:  10.10.2.1                                             1.888ms 
 1:  10.10.2.1                                             1.605ms 
 2:  no reply
 3:  no reply
 4:  no reply
 5:  no reply
 6:  no reply
 7:  no reply
 8:  no reply
 9:  no reply
10:  no reply

I’m pretty sure that indicates that things aren’t being passed on to the 192.168.1.1 gateway, but how can I fix that?

By the way I noticed one pitfall that may have nothing to do with it but may cause issues, change your server.conf;

push “redirect-gateway def1”
to
push “redirect-gateway def1 bypass-dhcp”

And restart your OpenVPN server service ( usually systemctl restart openvpn@server )

Alteration made, but as you suspected, no change. Out of interest’s sake, what does that addition do? Bypass the dhcp of the router?

Conceptually,
If you’re using the same network interface to VPN into your private network,
You need a working Internet Gateway to access the Internet.

So, that’s a start.
Can you open a session on the Server and access the Internet? (You can ssh or remote desktop into the Server and then try pinging an Internet address by name, and then by IP address).

If you can’t,
Then you can create a new interface using the same hardware network device and configure that as your Default Gateway.
You’ll then likely need to configure your OpenVPN clients with a routing entry that points to Internet addreses using the OpenVPN route as the path to the Default Gateway. Note, that’s different than just specifying that the Default Gateway is the route to the private network.

If you are able to remote into your Server and access the Internet, then maybe the route entry I describe is all that’s needed.
If you can’t grasp what I’m saying about routing, post your routing table for one of your OpenVPN clients when the VPN is active.

TSU

You appear to have packet forwarding and NAT working, but perhaps the client is not configured to redirect all traffic through the tunnel? Could you please show us your client routing table when connected?

|| 1. Redirect all the traffic into the tunnel
|—|
The easiest solution - use OpenVPN’s --redirect-gateway autolocal option (or put it in the config file as redirect-gateway autolocal.

|

Yeah, the server does indeed have internet access. No problems there. I do suspect its a routing issue, but I am unfortunately relatively weak at networking. I provided my routing table in the very first post. I don’t want to muddy up the thread by reposting it. However, I know some people prefer the output of route:
**
For the Clients:**

**VPN Off

**


daniel@nohostname:~> sudo route -n 
[sudo] password for root: 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.1.1     0.0.0.0         UG    600    0        0 wlp3s0
192.168.1.0     0.0.0.0         255.255.255.0   U     600    0        0 wlp3s0

VPN On


daniel@nohostname:~> sudo route -n 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.10.2.5       0.0.0.0         UG    50     0        0 tun0
0.0.0.0         192.168.1.1     0.0.0.0         UG    600    0        0 wlp3s0
10.10.2.1       10.10.2.5       255.255.255.255 UGH   50     0        0 tun0
10.10.2.5       0.0.0.0         255.255.255.255 UH    50     0        0 tun0
192.168.1.0     0.0.0.0         255.255.255.0   U     600    0        0 wlp3s0
192.168.1.1     0.0.0.0         255.255.255.255 UH    600    0        0 wlp3s0
192.168.1.100   0.0.0.0         255.255.255.255 UH    600    0        0 wlp3s0

**Server

**

linux-g6sx:~ # route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.1.1     0.0.0.0         UG    0      0        0 enp1s0
10.10.2.0       10.10.2.2       255.255.255.0   UG    0      0        0 tun0
10.10.2.2       0.0.0.0         255.255.255.255 UH    0      0        0 tun0
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 enp1s0

Does adding the routing table of the server maybe provide insight?

I thought the preferred option was push “redirect-gateway def1 bypass-dhcp”. Anyways, tried it, rebooted, no dice… Exact same routing tables as my previous message.

Hmmm… perusing your server firewall configuration and routing tables, I happened to note that your internet gateway interface is ‘enp1s0’

0.0.0.0         192.168.1.1     0.0.0.0         UG    0      0        0 enp1s0

but your iptables rule for NAT is configured using ‘eth0’

iptables -t nat -A POSTROUTING -s 10.10.2.0/24 -o eth0 -j MASQUERADE

Correct that, and you should find that NAT is then working.

Yeah, that did it. That’s probably one of my biggest brain-farts in a while. I’m so used to the ethernet adapter always being eth0 that it was something I totally didn’t pick up. Thank you so much.

Yes, sometimes it’s the simplest things that cause problems like this…an easy mistake to make. Posting all the requested information certainly helped here, as it eliminate assumption/speculation. Anyway, glad to have been of assistance. :slight_smile: