Networking over VPN

During my work at home, it was desirable to be directly connected to my company network. This is mainly based on a linux server. As I have a 24/7 homeserver running linux as well, the best approach was to establish a connection via OpenVPN that merges my home network with the net in my company.
A firewall on the homeserver separates the machines I do not need so my colleagues cannot browse or use my homenet.

So the following is about how to connect two complete Networks via two linux-endpoints (one in each network).
The aim is that every PC of one network is reachable from every other in the second (as long as not restricted by a firewall in any of the two endpoints).
One of these (surprisingly the company-network) is completely under my control, including name servers and the default gateway. The other one (my own) uses a Fritz!Box as router to connect to the world. The box is default gateway and name server for all PCs in my net, and that proves to be tricky!

The pure network connection is only one part of the work. A major problem was (and still is) the transparency of DNS-names over both networks.

Internet connections

The client can have an anonymous IP-address. Most providers cut the connection regularly and on reconnect, the client's IP is different. This is no problem as long as you can tolerate dropouts of the VPN in the range of tens of seconds up to few minutes. On some routers (like Fritz!Box) you can choose a fixed time to reestablish the Internet connection so you can put the break at 2 o'clock in the morning where it is normally no problem.
OpenVPN will reestablish the tunnel as soon as Internet connectivity is available.

The server must be reachable via name or IP. It does not make much difference if it has a fixed IP or if you use dynamic DNS. If the server is not reachable when the client starts, OpenVPN will automatically try again in short intervals until it succeeds. Also if the server fails with the tunnel established, OpenVPN will reestablish it as soon as possible.

If possible, try to keep breaks in night time and you will mostly not even take notice of them. Of course, if both endpoints have persistent Internet connections, the tunnel should stay open forever.

Setting up the server

The first task is to create a certificate authority. This is pain. It is just like annual tax declaration but it is absolutely necessary! Since the IP-addresses of the server and the client are variable, there must be a way for each part to be absolutely sure the other one is what it claims to be. Without that, you would not need a VPN and could just open your private net to the Internet.

Read here how to setup the tunnel.

Name resolution

The direct way, if the name servers of both domains were under your control, would be to create a zone entry at each domain with the DNS of the remote net as a master for the remote domain. If the tunnel is active, my home-DNS would ask the company DNS for names in the company domain and vice versa. For me, this is not practicable since my home net has no DNS (except the Fritz!Box which only resolves public Internet names) and there is no way to make the Fritz!Box to ask the company DNS for the local company domain.

I just could set up the homeserver as default gateway and name server for my net but there is one reason I refused to:
If I was unavailable for any reason (in foreign country, at the hospital, dead, whatever you want), anyone remaining would be in serious trouble if my homeserver crashed. If the Fritz!Box died, he could buy a new one and would (after a few hours of talking to the official support line) again be able to place telephone calls, to send and receive emails and to surf the Internet. But if the homeserver had the main functionality, every non-guru supporter would have a hard job to find out what's going wrong. I personally witnessed my homeserver dying from one minute to the other so my way is clear. The homeserver is a nice-to-have but it must never become mission critical!

The problem with the Fritz!Box is that it does not support zone entries for DNS. If I could tell it to use our company-DNS for the company zone everything would work perfect.
My current solution is to enter the machines I normally need (fortunately only few) in the hosts-file of my home PCs. This is a major administrative task and you always forget one in some PCs. If the name is not known, I have to enter the IP address instead.

So, a short summary of the situation:
My Fritz!Box is the default gateway. My homeserver is one endpoint of the VPN-tunnel. The other endpoint at the company has IP-forwarding activated and therefore is the gateway for any machine reachable from there (including eventually other VPNs connected).

Any PC in my homenet trying to reach a PC in the company net will send its request to my Fritz. So I added a route in the Fritz-configuration redirecting IPs in my company's range to my homeserver. It again will pass the request over the tunnel.

The company endpoint is the OpenVPN-Server and my private endpoint is a client.

The server has a "push route..." for every network it can reach. So the client (my homeserver) knows what IPs to send over the tunnel. But the Fritz does not. You will have to add a route for every network reachable over the tunnel as client machines will send everything to Fritz. If there was no route, Fritz would silently ignore it or send it out to the Internet where the first router would ignore it.

Debugging

If it does not work (what is the default on the initial setup 😉), try to follow the packets. Ping a machine known to be pingable from the remote endpoint. Use wireshark on your local PC to see whats going out. Make a tcpdump on your homeserver's ETH to see what it receives. If it does not receive the packet, you probably forgot the route on Fritz. If that's ok, make a tcpdump on the homeserver's tun0 to see if the packet goes into the tunnel, make a tcpdump on the servers tun0 to make sure it arrives and a tcpdump of its eth0 to see it going out to the destination and on the destination machine to verify the arrival. If all that works, do the same for the response of the client. So you can see where the traffic gets lost. There must be a missing ip_forward, a missing route or a firewall discarding the packet somewhere on its way. Find it, correct it and find the next barrier. At the end, packets will travel forth and back and your connection will work.
If you see the packet entering the machine but it does not leave where you expect, have a look at its other interfaces. If it goes out somewhere else, you have a missing route, if you do not see it anywhere, there must be a firewall discarding the packet or the machine is not configured to forward the packet at all.