welw

Masquerade or Network Address Translation or Access the Internet from Local Area Network

We are dealing with the following setup: FreeBSD computer acting as server for OpenVPN and gateway for clients on local network and services behind the FreeBSD server. There are clients connecting to the server and they want to be able to access resources offered by these services. We want the FreeBSD server to provide DNS service so that clients connecting to it automatically get an IP address.

    +-----------+
    | Nextcloud | -------\
    +-----------+         \
                           \    
    +-----------+           \    +---------+                                       +--------+
    | WWW       | ---------------| FreeBSD |-------- ( The Internet ) ------------ | Client |
    +-----------+           /    +---------+                                       +--------+
                           /
    +-----------+         /
    | Samba     | -------/
    +-----------+

We'll start with our FreeBSD box:


+---------+
| FreeBSD |
+---------+

How to: Enable clients on LAN to connect to the Internet

Clients should be able to ping the gateway.

user@ubuntu$ ping gateway.local

But can they access the internet?

user@ubuntu$ ping dflund.se

If they can, it means that the client can access the Internet via some other gateway. In our setup, the clients cannot connect to the Internet yet. We want to enable the internet connection with the clients. This can be done with technique called masquerade. Although I heard that with IPv6 masquerade is not necessary.

How masquerade works?

Our gateway is equipped with 2 network cards: msk0 (connected to the local area network) and msk1 (connected to the Internet). The names msk0 and msk1 refer to network interfaces and not the cards itself (in reality a network card may have more than 1 interface, and multiple IP addresses, but let's not bother with that so far). The public interface msk1 has a public IP address and private interface has a private address.

Each IP packet has its source and destination address written in it. A computer on the local network with address 10.0.0.15 may ask gateway 10.0.0.1 for connection with 11.33.22.11 (a fictional address on the internet). The gateway cannot forward the packet to the host on the internet, because the host would not be able to answer. The reason a host is not able to answer is that we send a packet to the internet with private IP address in that packet. Therefore the remote host cannot answer it as it does not know about private IP addresses in our network. It only knows about the public IP address of our gateway on msk1.

In order to enable communication between hosts on our private network with the Internet, we need to rewrite source address of the IP packet to indicate public IP address of the gateway.

Ok, but how do we run this masquerade?

First, enable packet forwarding by adding the following line to /etc/rc.conf:

gateway_enable="YES"

By enabling packet forwarding we instruct the kernel of the operating system to take packets from one interface and put them to other interface or interfaces. Without this line, kernel would simply refuse to forward packages.

Next, we need to instruct PF (Packet Filter) which interfaces are taking part in masquerade. We do this by adding the following rule to /etc/pf.conf:

$lan_if=msk0
$ext_if=msk1
nat on $ext_if from $lan_if:network to any -> ($ext_if)

Let's explain what this rule means:

We should be able to reboot the gateway to make sure that the new changes apply. Or, if we want to save some time and do not wish to reboot the entire machine, we can only restart packet filter:

pfctl -d
pfctl -e

Which disables and enables the packet filter.

There are many ways of solving this problem, as with everything. You should now be able to access the internet from hosts on your local network, or ping servers on the Internet.

We have successfully set up network address translation on our gateway. Computers should now be able to access the Internet, if they need any updates, data, or anything else from there. This, of course, creates some problems as well as we are not able to see what the clients are sending to the Internet, and from security perspective a malicious user might want to do harm. This is however enough for our simple setup.

In the next part we will connect computers via OpenVPN to our network and access resources on local area network. This will enable us to access Nextcloud, WWW server and Samba shares on our LAN, as if we were at home.