The last item in my initial TODO list was implementing the --peer option available in pfinet. This week I've been working on it and it's now done, so I can say the LwIP translator is now able to replace pfinet.
The --peer
option is provided by pfinet for setting the peer's address in a point-to-point interface like PPP, tunnel, etc. Although as far as I know, the only point-to-point solution actually working on pfinet is setting a OpenVPN client over a tunnel device. Currently, when the user adds --peer
option to the command line, pfinet just assigns its value to an internal variable in the given interface, but it doesn't seem to be using it afterwards. The thing is that, actually, the stack doesn't need to know the peer address when working behind OpenVPN. I'll briefly explain how this all works.
Let's say our organization has an internal web application that must be only accessed by the authorized personnel. In this case, the HTTP server must only answer to requests coming from the network 10.8.0.0/24
. To simplify the schema, let's suppose the HTTP and the OpenVPN server are both in the same host. Then the schema would look as follows:
As we may see at the schema, the user LwIP is working to all intents and purposes as if it were plugged to the network 10.8.0.0/24
, therefore, we may set its IPv4 parameters as usual:
settrans -fga $HOME/servers/socket/2 /hurd/lwip -6 $HOME/servers/socket/26 -i $HOME/dev/tun0 -a 10.8.0.6 -m 255.255.255.0 -g 10.8.0.1
The system LwIP is also configured as usual to provide access to the Internet, so we haven't needed to give any --peer
parameter in either cases. Regarding the tunnel, the trick is that, on one side, the user LwIP is passing packets to the tunnel like any other interface; and, on the other side, the tunnel is a regular file that can be opened for reading or writing by the OpenVPN client.
A remarkable feature is the following: with this design, the user can choose which transit will go through the VPN and which not. For instance, if the user wants to download a file from the HTTP server, it may be done as follows:
remap /servers/socket/2 $HOME/servers/socket/2 /servers/socket/26 $HOME/servers/socket/26 -- wget https://10.8.0.22/test.txt
Whereas if the user doesn't remap the RPCs, the transit will go out through the system LwIP:
wget https://www.gnu.org/
And all of this may be done without root permissions.
I think it's a good moment to think about how could we add support for PPP on the Hurd. The current stack, pfinet, doesn't support PPP whereas LwIP does, but it provides a rather unsuitable API for us. According to the documentation, what LwIP provides is a pppd port modified to be lightweight. If we were working on an embedded system, the API provided by LwIP would be perfect, because in an embedded system everything would be in the same binary: RTOS, the stack and the user program which could directly call functions like ppp_set_auth()
or ppp_connect()
. But in a Unix-like system like the Hurd, what we want is to use the original pppd and give it the proper tools for communicating with the stack and creating new pppX interfaces. With my current knowledge about PPP, it's not quite clear to me whether we would need to create new operations or even a new MIG interface, but it seems an interesting topic to study in the future.