1

I'm having a bit of difficulty tunneling a Public IP to a remote VPS using OpenVPN. I have a Linux server with a block of 32 Public IP Addresses 192.0.2.160/27, named Server 1, along with one other Public IP Address that is bound to eth0 on that same server: 203.0.113.43.

I have another Linux machine, Server 2, behind NAT somewhere else. I want to be able to setup an OpenVPN server on Server 1 such that the client, Server 2, can use an IP Address in the 192.0.2.160/27 subnet.

I have followed the following guide on ServerFault, and i'm attempting to use Ethernet bridging with OpenVPN using TAP.

On Server 1, the network configuration looks something like this (I've replaced the IPs for documentation purposes - see RFC5737):

Server 1 /etc/network/interfaces

auto eth0

auto br0
iface br0 inet static
     address 203.0.113.43
     netmask 255.255.255.0
     gateway 203.0.113.1
     pre-up openvpn --mktun --dev tap0
     bridge_ports eth0 tap0
     bridge_fd 3

I then run openvpn on Server 1 with openvpn --dev tap0, and when I enter the following on Server 2:

openvpn --remote 203.0.113.43 --dev tap0 --route-gateway 203.0.113.1 \
--redirect-gateway def1 --ifconfig 192.0.2.160 255.255.255.224

A connection is established, but I cannot ping 192.0.2.160 on any other machine other than on Server 2 (can't even do it on Server 1).

I definitely believe I am missing something, but I can't seem to figure it out.

I'll also add that I have enabled IPv4 Packet forwarding in /etc/sysctl.conf on Server 1.

If anyone can complete this configuration or suggest an alternative method of achieving this, that would be much appreciated.

[EDIT 1 - Thanks A.B.]

The hosting provider is Heficed, and they explain how to add additional public IPs (on CentOS anyway) here: https://kb.heficed.com/en/articles/2854555-adding-ip-to-your-network-interface

medemi68
  • 13
  • 1
  • 4
  • It could help if you told the name of your host provider, so we can read about their explanation on how to configure additional/failover IPs. This can change the resulting setup. Also in advance: if you assign 192.0.2.161/27 (or 192.0.2.162/27 etc.) to an interface you lose the 1st and last address, resulting in 30 usable instead of 32. Assigning just once a /27 address on an interface will disrupt proper use of 192.0.2.160 and 192.0.2.191. Of course assigning 192.0.2.160/27 is twice a problem and should never be done. Using 192.0.2.160/27 in routes if needed is still fine. – A.B Oct 08 '20 at 23:26
  • Hey, Thank you for replying! The provider I am using is Heficed, They explain how to do it here: https://kb.heficed.com/en/articles/2854555-adding-ip-to-your-network-interface , Of course, they explain how to do it with CentOS. Do the IP Addresses have to be mounted on Server 1 first? – medemi68 Oct 09 '20 at 21:16
  • And I guess I should assign it as /32 on the client? – medemi68 Oct 09 '20 at 21:21
  • I would like more informations, that I couldn't get from the IPS's doc. To determine how the ISP's router in front of server1 has its own route set. This can be determined by listening to ARP requests done. So I would like you to run on server1 `tcpdump -e -n -s0 -p -i eth0 arp or icmp` and from remote do a ping 192.0.2.162. Do you get 1/ an ARP for 192.0.2.162 2/ directly an ICMP for 192.0.2.162 (with server1's MAC as dest)? 2/ means that the route for 192.0.2.160/27 is using your own server1.All this is to consider alternate solutions using TUN instead of TAP which is often more efficient. – A.B Oct 10 '20 at 10:40
  • Never mind I found the information in the 1st paragraph of: https://kb.heficed.com/en/articles/3660203-making-additional-ips-as-source-ips (thus case 2/ ) – A.B Oct 10 '20 at 10:42

1 Answers1

0

According to this Heficed's KB article:

When you have bought a server with a main IP and assigned additional IPs, additional IPs are routed statically on your main IPs, thus no gateway or broadcast addresses are needed when configuring the IPs on your NIC.

server1's main IP address is used to reach other IP addresses, so one can imagine server1's router (if it were Linux too) has probably a setting similar to this:

ip route add 192.0.2.160/27 via 203.0.113.43

There's no need to have eth0 bridged and having it bridged will create additional difficulties for the goal. The complexity needed to have to use anyway uncommon routing in the end (still using a gateway not part of the IP LAN) is not worth it.

So server1's network configuration can be simplified into:

auto eth0
iface eth0 inet static
    address 203.0.113.43
    netmask 255.255.255.0
    gateway 203.0.113.1

Beware of connectivity loss when changing configuration, you should have a remote/virtual console access available as backup.

Below are solutions without bridging the host's main interface, using routing, either with TAP (possibly allowing for example server1 to run a DHCP server for server2's side) or with TUN.

To keep the 32 IP addresses available, some unusual route settings are used, for which OpenVPN has a few issues. So a script is used to override the --ifconfig option. If one chooses to sacrifice 3 IP addresses from the /32 pool: one assigned to server1 as well as 192.0.2.160 and 192.0.2.191 used as network and broadcast network addresses then everything becomes simple and there's no need of additional script.


Notes:

  • To configure server1 as an IPv4 router, required for any of the methods described below, one can for example uncomment/add this entry in /etc/sysctl.conf or /etc/sysctl.d/<somefile>:

    net.ipv4.ip_forward=1
    

    and also run this as root just after the configuration was changed:

    sysctl -w net.ipv4.ip_forward=1
    
  • commands evolve:

    openvpn --mktun --dev {tap,tun}0
    

    can be replaced with one of these:

    ip tuntap add dev tap0 mode tap
    ip tuntap add dev tun0 mode tun
    

    ip tuntap appeared "only" in 2009.


TAP

Simple method

To stay really simple, no permanent TAP interface is used (feel free to change this configuration).

It will consume 192.0.2.160, 192.0.2.161 (assigned to server1) and 192.0.2.191 out of the pool.

  • server1:

    openvpn --dev tap --ifconfig 192.0.2.161 255.255.255.224
    
  • server2:

    openvpn --remote 203.0.113.43 --dev tap --ifconfig 192.0.2.162 255.255.255.224 --route-gateway 192.0.2.161 --redirect-gateway def1
    

    You could also add any of the 28 remaining IP addresses between 192.0.2.163 and 192.0.2.190 to server2 on any of its interfaces (eg: assign it on tap0 or assign it on lo so it won't disappear even before):

    ip address add 192.0.2.163/32 dev lo
    

Method keeping all 32 addresses usable

  • server1:

    Add a TAP interface in /etc/network/interfaces to simplify server1's OpenVPN's config:

    auto tap0
    iface tap0 inet static
        pre-up ip tuntap add dev tap0 mode tap || :
        address 10.10.10.10/32
        up ip route add 192.0.2.160/27 dev tap0
        down ip link delete dev tap0
    

    Run ifup tap0 if just done and run:

    openvpn --dev tap0
    
  • server2:

    have an executable called up-cmd-server2.sh (the variables used inside will be inherited from OpenVPN):

    #!/bin/sh
    
    ip address add "$ifconfig_local"/32 dev "$dev"
    ip link set dev "$dev" up
    ip route add "$route_vpn_gateway"/32 dev "$dev"
    

    and run:

    openvpn --remote 203.0.113.43 --dev tap --ifconfig-noexec --ifconfig 192.0.2.160 255.255.255.255 --route-gateway 10.10.10.10 --redirect-gateway def1 --script-security 2 --up up-cmd-server2.sh
    

    The IP address 10.10.10.10 will never be seen outside of the VPN, and even inside will only be seen in case of errors, like in the result of a traceroute command or of course if it's used to reach server1 from the VPN rather than from Internet. A traceroute run from outside would show errors from 203.0.113.43.

What about having containers or VMs on server1?

If some traffic should be routed over the VPN and some traffic be local, then tap0 above can again be enslaved to a bridge. This bridge will still be for a routed LAN: it will not bridge eth0 and 10.10.10.10/32 should be assigned to it instead of tap0. Beside this, above settings and explanations still apply. Containers can use veth links and VMs additional TAP links, all enslaved to the bridge.

TUN

TAP is useful if properties related to using Ethernet over the tunnel are needed like having server1 run a DHCP server for server2 or actually share LAN traffic over the VPN (TUN could be used for mixed use too with a few more route tweaks and proxy ARP, but it's then probably not worth the configuration complexity). Else TUN can be used with less overhead (eg: IP packet smaller than Ethernet frame and no ARP). As both cases are routing, the settings are almost the same as above.

Simple method

  • server1:

    openvpn --dev tun --topology subnet --ifconfig 192.0.2.161 255.255.255.224
    
  • server2:

    openvpn --remote 203.0.113.43 --dev tun --topology subnet --ifconfig 192.0.2.162 255.255.255.224 --route-gateway 192.0.2.161 --redirect-gateway def1
    

Method keeping all 32 addresses usable

  • server1:

    Add a TUN interface in /etc/network/interfaces to simplify server1's OpenVPN's config:

    auto tun0
    iface tun0 inet static
        pre-up ip tuntap add dev tun0 mode tun || :
        address 10.10.10.10/32
        up ip route add 192.0.2.160/27 dev tun0
        down ip link delete dev tun0
    

    Run ifup tun0 if just done and run:

    openvpn --dev tun0
    
  • server2:

    Use the same up-cmd-server2.sh as above in the TAP version and run:

    openvpn --remote 203.0.113.43 --dev tun --topology subnet --ifconfig-noexec --ifconfig 192.0.2.160 255.255.255.255 --route-gateway 10.10.10.10 --redirect-gateway def1 --script-security 2 --up up-cmd-server2.sh
    
A.B
  • 9,037
  • 2
  • 19
  • 37
  • I haven't had a chance to try things out, but I definitely will today. Thanks for the detailed reply! – medemi68 Oct 14 '20 at 18:25
  • Could you add to your response the **need to enable Ipv4 packet forwarding** [like this](https://www.eukhost.com/kb/how-to-enable-ip-forwarding-on-linux-ipv4-ipv6/) (just in case someone re-reads this and forgets). First method worked! Haven't tested the others just yet. – medemi68 Oct 14 '20 at 19:42
  • Done. I added it as an additional note. – A.B Oct 14 '20 at 20:38