0

I have a server with 2 WAN interfaces, eth1 and eth2. Each one have one router connected which gives them these IPs: 192.168.3.101 and 192.168.1.101.

The thing is that I want to completely avoid traffic through eth1 and instead create a tun0 which will tunnel all the traffic eth1 should receive.

I have complete control on which interface my programs should use (MPTCP will use all the interfaces it can that can reach the server), so I prepared a simple OpenVPN client/server configuration (binding to local 192.168.3.101), with server IP 192.168.99.1 and client IP 192.168.99.2. With this I have a working interface where I can send/receive data to 192.168.99.1 without problems.

Now the problem comes when I want to send/receive data to ifconfig.co (for example) using interface tun0. What I though it would do is to send data through eth1 to my server, then my server redirect the traffic to ifconfig.co, but that's not what is happening. It simply drops the connection:
Connection refused

If I try with interfaces eth1 and eth2 everything works as expected.

I've read/tried a lot of things for about 7 hours without stop and now I'm really lost. I'm not sure what is happening or what I'm doing wrong.

I think is a routing problem because when I try the command above tcpdump shows nothing on server. Zero packets received. This is what I have for now:
enter image description here
enter image description here
enter image description here

I see everything equal to each other, but eth0/eth1 are working and tun0 is not.

Just in case, this is my OpenVPN config (a simple point to point config):

;SERVER
dev tun
ifconfig 192.168.99.1 192.168.99.2
secret /etc/openvpn/static.key
keepalive 10 60
ping-timer-rem
persist-tun
persist-key

;CLIENT
dev tun
remote XXXXXXXXXXXX
resolv-retry infinite
local 192.168.3.101
lport 0
ifconfig 192.168.99.2 192.168.99.1
secret /etc/openvpn/static.key
keepalive 10 60
ping-timer-rem
persist-tun
persist-key

NOTE: I know that the convention for VPN IPs are 10.*, but I changed to 192.168.* as a desperate move to have a similar configuration as the other 2 interfaces.

The reason of all this is an idea to workaroud this issue: https://github.com/Ysurac/openmptcprouter/issues/670#issuecomment-533816813

1 Answers1

1

You are trying to implement a solution based on routing tunnel mode, but your problem description rather looks to me perfectly fit for bridging tap mode.

OpenVPN can not only tunnel IP packets. It also can tunnel the whole Ethernet packets. In short, you can replace "mode tun" with "mode tap" and remove any IP address assignments in OpenVPN config. Also remove all non-default routing rules. Then, with the help of your OS you make a bridge between eth1 and tap interface.

In Debian (/etc/network/interfaces):

iface eth1 inet manual

auto br0
iface br0 inet manual
    bridge_ports    eth1
    bridge_stp      off
    bridge_fd       0

Next, we need to instruct OpenVPN to add tapX to br0 once it starts (this goes to OpenVPN config):

script-security 2
up up.sh

Why script-security is needed see https://community.openvpn.net/openvpn/wiki/OpenVPNBridging

The up.sh script:

#!/bin/sh
bridge=br0
brctl addif "$bridge" "$1"
ip link set "$1" up

It uses bridge-utils brctl, because this config was done on debian 7. Modern systems should use ip utility from modern iproute2 suite instead of obsolete bridge-utils, iputils and so on; I'll leave this as homework, how to add interface to a bridge using ip, it is't hard.

You see, I don't even configure any IP addresses. This is because my OpenVPN box will just bridge ethernet packets from physical interface to virtual and back. In OSI network model this counts as Layer 2 bridge, i.e. as if you have a ethernet switch.

The remote system ("CLIENT") running OpenVPN will have its tap interface as if it is plugged into the same ethernet switch where eth1 of "SERVER" is plugged in:

(LAN) - [switch] ---ethernet-cable--- [eth1 tapX] ---virtual-ethernet-cable--- [tapY]
                                        "switch"         OpenVPN tunnel          remote system

You can run DHCP client on a tap on a remote system ("CLIENT"), and it should receive IP address from DHCP server in the LAN. You can also bridge there, and this will just work like you joined your distant sites with the ethernet cable. Think of it like you run a long optical line from one site to another and connected these networks with it.

If you want "SERVER" to also participate in this network, you configure IP addresses on the br0 itself, for this you replace "manual" with "static" or even "dhcp", this wouldn't affect its switching function at all.

There is special consideration with Linux Netfilter setup (the firewall). Some time ago there was sysctl variable that controls if bridged packets are passed through "filter FORWARD" chain, net.bridge.bridge-nf-call-iptables=1. On modern systems, AFAIK, it is 0 by default. If you have it, either set it to 0 (in /etc/sysctl.conf), or have rules that pass packets between switch ports. See "physdev match" in iptables manual.

Please note, designations "SERVER" and "CLIENT" you gave to your systems are purely cosmetical and don't reflect their protocol roles. From OpenVPN viewpoint both systems are equal, because you configured OpenVPN in "legacy" point-to-point mode. There is also dedicated "client-server" mode in OpenVPN, where there really are two distinct roles, and multiple clients could connect to a single OpenVPN server. The idea I presented here applies to that mode as well.

Also, note, there is no such convention to always use 10.* for OpenVPN. There couldn't be such a convention for any mature production-grade VPN solution. You always use network numbering that your network design requires.

UPD: when testing the bridge inside virtual machines, make sure, that hypervisor allows for using multiple MAC addresses at the VM port. In Hyper-V that feature called MAC Spoofing and should be enabled.

Nikita Kipriyanov
  • 8,033
  • 1
  • 21
  • 39
  • Still lost :-( I've created a `tap0` device, bridged it with `eth0` as shown here: https://i.imgur.com/htpiqOW.png was able to create a connection between client and server but was impossible to make DHCP work. Tried all `server-bridge` directives I found on Internet and nothing, then I forced the client IP to `192.168.0.200` and was able to connect and send/receive data to the IP of the server machine (`192.168.0.22` in this case). I'm exactly at the same point because I can't access anything that is not `192.168.0.22` though `tap0` interface... as a note, I've stopped client/server firewalls – Jorge Fuentes González Oct 15 '19 at 11:47
  • Oh, with SERVER/CLIENT I mean the one that has ports open to the Internet (which receive connections. Usually my server) and the one behind a NAT. For this I've changed it and removed point to point. Now is a real server xD – Jorge Fuentes González Oct 15 '19 at 11:50
  • @JorgeFuentesGonzález use tcpdump to find out where packets lost. But I think this is firewall issue, I covered that in my answer. It is also helpful to draw a simple network diagram what is connected where. – Nikita Kipriyanov Oct 15 '19 at 12:23
  • But I've stopped both firewalls, client and server. With tcpdump I see that ping requests reach the server, but when the request is outside of `192.168.0.22` then any reply is received: https://i.imgur.com/xgWf8io.png I guess that the diagram is something like this: https://i.imgur.com/vzTykfB.png the weird thing is that the one getting the `192.168.0.22` IP on the server is `br-lan` instead of `eth1`. `eth1` don't has any IP assigned, but I guess that all the packets arrive through `eth1` as is the physical interface with the cable plugged in. I have to eat something, will continue later. – Jorge Fuentes González Oct 15 '19 at 12:46
  • .22 is server, .200 is client and they can talk with each other. Where are hosts on your picture you ping from "client" but that doesn't work? Are they available from the "server"? It is good idea to capture tcpdumps for both cases (ping from "server" and from "client") both on target host and on the VPN gateway and compare. Also, does "stopped firewall" mean that all chains are empty and their default policies are ACCEPT? Verify that with iptables-save. – Nikita Kipriyanov Oct 15 '19 at 17:25
  • OMFG Finally got it!!!! Analyzing packets with tcpdump noticed that remote machine was not receiving ARP request replies, so it will never know where a machine is located. For testing, I had these images running inside a Hyper-V instance, so the problem was that I had to enable MAC spoofing for the virtual NIC. Without MAC spoofing the bridge won't work. I'm going to accept you answer as you helped me, but if you could add a small addition to it so people knows what happened (pointing to the commens or something) then it would be awesome. – Jorge Fuentes González Oct 16 '19 at 12:38