bookmark_borderNo networking in Docker containers under Debian 10

I finally started to migrate the first few servers to Debian 10, codename „Buster“. With the last upgrades I never stumbled upon any issues. However, this time we see a problem when using Docker as the containers are unable to communicate to the internet.

Upgrade to Debian 10 reliable as always

As usually, the upgrade process went through very smoothly. Something I really love Debian for. Fast, simple and reliable upgrade processes are basically things you always want to see on a server. Sadly, Debian itself doesn’t provide a Docker package in their repositories. This means you have to install it from a third party repository. In this case this repository comes from the official Docker developers. But with a third party repository enabled, we have to expect possible hassles when it comes to upgrading.

No networking connection within containers

If you upgrade your Debian 9 machine to Debian 10 and you’re using Docker, you will not be able to use get the network running within any container. This is due to the heavy dependency of Docker to IPTables.

With Debian 10, nftables is the new standard for package filtering in Debian. This is also mentioned in the offical Debian Wiki. However, it seems like that Docker isn’t ready for nftables at the current date (of writing this).

Workaround: Fallback to the „old iptables way“

Luckily, there is already a workaround available. People who are upgrading to Debian 10 and aren’t using nftables already can simply force Debian to switch back to IPTables again as the user arkodog figured this out on the moby GitHub:

user@debian:~$ sudo update-alternatives --config iptables
There are 2 choices for the alternative iptables (providing /usr/sbin/iptables).

Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/sbin/iptables-nft 20 auto mode
1 /usr/sbin/iptables-legacy 10 manual mode
2 /usr/sbin/iptables-nft 20 manual mode

Press <enter> to keep the current choice[*], or type selection number:

In this case you have to choose number 1 because it’s the desired „iptables-legacy“ which we need to get the networking with Docker working again. Press enter and reboot your machine.

Will Docker support nftables in the future?

There is a lot of talking going on about this topic. Right now, Docker doesn’t support nftables but it seems like the support will come sooner or later. So long, we have to live with the workaround in using IPTables instead. An alternative however would be to use the –iptables=false switch. But this would mean you would have to write all the rules normally automatically created by Docker with nftables in your own.

Further links

bookmark_borderPost Script for OpenVPN clients

OpenVPN Logo
Image source: openvpn.net
Did you ever wanted to automatically do something after you OpenVPN client has successful connected to your OpenVPN server? To do so you can just add 2 simple lines to your client OpenVPN file:

script-security 2
up postscript.sh

This 2 lines above are doing the following:

  • script-security 2: Allows the calling of built-in executables (ip, route, ifconfig, …) and user-defined scripts (see next line). A script-security of 1 would mean that only built-in executables are allowed to be called.
  • up postscript.sh: This line defines the script which should be started after the client successfully connected to the server. In this case the script is called postscript.sh. If you don’t define the total path to the script here, the script has to be in the same directory as the OpenVPN client configuration.

And that’s it. After you are connected to your OpenVPN Server the given script will be fired up. Don’t forget to make the script executable for course.
For e.g. I use this to create a route on specific clients after they connected to the OpenVPN server. Of course you can do whatever you want inside the script.

bookmark_borderHow To get your Realtek RTL8111/RTL8168 working (updated guide)

Realtek Logo
Image Source: wikipedia.org
A lot of people will remember my guide how to get a RTL8111/RTL8168 running under your Linux box. This guide is almost 5 years old now and I wanted to make a complete overhaul, because a lot of things has changed since then.

Why do I need this driver anyway?

Some people asked me, „Why do I need this driver anyway? Doesn’t the Linux Kernel ship it?“. This is of course a valid question. As far as I can see this, the RTL8111/RTL8168 is not Open Source and this would be of course the reason why the driver isn’t included into the Linux Kernel. As long as the driver isn’t Open Sourced, we have to build it on our own.

The installation methods

A lot of things have changed since I written the initial article about how to compile the driver under Ubuntu / Debian. Today we can use 2 methods for installing the driver. The following lines describes both of them.

The automatic way

NOTE: Thanks to the user „Liyu“ who gave me this hint!
NOTE2: For this way you need a working internet connection. You could use WLAN or a USB ethernet card like this one to get a temporary internet connection. You could also download every needed single package onto USB from another PC and install them in the right order.
As I said ealier, 5 years is a long time. And today Ubuntu and Debian have the driver included in it’s repository. For Debian you have to enable the non-free package sources. For Ubuntu you have to enable the universe package sources. You can easily do this by open your /etc/apt/sources.list as root with your editor of choice and add for each line starting with „deb“ non-free or universe at the end. So for example, if you use Debian a line like:

deb http://ftp.de.debian.org/debian/ jessie main contrib

would become to

deb http://ftp.de.debian.org/debian/ jessie main contrib non-free

The same for Ubuntu:

deb http://de.archive.ubuntu.com/ubuntu/ xenial main restricted

would become to

deb http://de.archive.ubuntu.com/ubuntu/ xenial main restricted universe

After this you have to do a:

sudo apt-get update

You can of course use graphical ways to enable non-free or universe. After you enabled the missing package repository, you will be ready to install the driver. This can be easily done with the following command:

sudo apt-get install r8168-dkms

The procedure will take some time, depending on your CPU because the driver will be build for your working Kernel. The good side is, that if any Kernel update happens on your machine, the kernel will be rebuild against the new Kernel automatically after the update because of the use of dkms.
After the procedure is finished, you should be able to use your network card instantly. If not, you should consider a reboot of your PC then.

The manual way

Well, the manual way is almost the same as it was before in the initial article. Anyway, I want to rewrite the steps here again. This is also tested against newer Kernels ( >= 4.0) which caused a lot of trouble for some people in the past.

  • 1. Install dependencies: Once more you need a working internet connection for this. You could also use the Debian or Ubuntu DVD which includes the needed packages. To install the dependencies just enter the following command:
    sudo apt-get install build-essential linux-headers-$(uname -r)
  • 2. Download the driver: You can download the driver from the official Realtek homepage mirror provided by mtorromeo at GitHub. This is the direct download link: click me.
  • 3. Blacklisting the r8169 driver: The r8169 is loaded when the r8168 is not found on your system. This will give you a network and internet connection, but with the r8169 driver your RTL8168 card will be very unstable. This means slow download rates, homepages taking hours to load and so on. To avoid that the r8169 is loaded, we blacklist it. This is be done by entering the following command:
    user@linux:~$ sudo sh -c 'echo blacklist r8169 >> /etc/modprobe.d/blacklist.conf'
  • 4. Untar the archive: After you successfully downloaded the driver, cd into the directory where the driver is downloaded and untar the driver with the following command:
    user@linux:~$ tar xfvz r8168-8.046.00.tar.gz

    NOTE: Your tar filename can of course differs if you download a newer version in the future for e.g.

  • 5. Compiling and installing the driver: Now we have to start compiling the driver. For this you cd into the extracted directory:
    user@linux:~$ cd r8168-8.046.00

    NOTE: Don’t forget to change your version number in the future here.
    Now that you are in the right directory, we can start with the real compiling process. For this Realtek brings an easy to use script which is called autorun.sh. So, to start compiling and installing the driver enter:

    user@linux:~/r8168-8.046.000$ sudo ./autorun.sh

    You should see a output which looks like this:

    Check old driver and unload it.
    rmmod r8168
    Build the module and install
    At main.c:222:
    - SSL error:02001002:system library:fopen:No such file or directory: bss_file.c:175
    - SSL error:2006D080:BIO routines:BIO_new_file:no such file: bss_file.c:178
    sign-file: certs/signing_key.pem: No such file or directory
    Backup r8169.ko
    rename r8169.ko to r8169.bak
    DEPMOD 4.4.0-31-generic
    load module r8168
    Updating initramfs. Please wait.
    update-initramfs: Generating /boot/initrd.img-4.4.0-31-generic
    Completed.

    You can ignore the SSL error for now. The driver should be successfully compiled and installed into your system. The driver is already loaded and should work.

  • 6. Check the driver: As a final step, you could start checking if the driver is really loaded into your Kernel. For this you can use the command lsmod. lsmod lists all drivers, which are usable by your Kernel. So, if everything was successful, you should see an output like this:
    user@linux:~/r8168-8.046.000$ lsmod | grep r8168
    r8168                 491520  0

    You can also check as well your ethernet device directly to see if the correct driver is loaded (special thanks goes to Tim which posted this in the comment section):

    user@linux:~$ sudo ethtool -i enp1s0
    driver: r8168
    version: 8.042.00-NAPI
    firmware-version:
    expansion-rom-version:
    bus-info: 0000:07:00.0
    supports-statistics: yes
    supports-test: no
    supports-eeprom-access: yes
    supports-register-dump: yes
    supports-priv-flags: no

    NOTE: You have to the change enp1s0 to the device name of your network card of course. This can be eth0, eth1, enp2s0, and so on.
    If your driver isn’t loaded until now, you should go with a reboot before further investigation.

That’s it

And that’s it. Now you’re ready to use your RTL8168/RTL8111 with the official Realtek drivers. If you have any questions and / or suggestions, please let me know in the comments.

bookmark_borderHow to create an SSH tunnel under Linux

Creating an SSH Tunnel allows you to encrypt every network communication you want. You are also be able to access other network services which are only available at the destination which you trying to ssh to. Almost every Linux distribution is already able to create such a tunnel. However in term of „tunneling“, using SSH to create a tunnel is more like doing port forwarding.

SSH command to create a tunnel

Tunneling with SSH is really simple. You define the port on your local machine, where your forwarded port should be listening to. Then you define the destination it should point to. The following picture tries to show you how easy it really is:
ssh_blog
As you can see in the picture, the first number after the -L parameter (marked red) states the local port on your local machine where you execute the ssh command. This means that the remote service will be available locally on your machine with this port. You should only use ports above the „System Ports“ which are regulated in RFC 6335. This means ports greater than 1023 (in the picture we use port 5000 which is fine).
The second value (yellow marked) states the remote address. The remote address can be localhost but in this case localhost does not mean your local machine. It means the remote machine you are ssh-ing to. It is possible that you insert a machine name or IP behind the destination machine. The destination tries to establish the connection to the remote address then.
The third value after the -L parameter (marked blue) is the port of the destination address which is given in the step before (yellow marked). This means, if you want to connect to a running Webserver, then you have to enter 80 here (80 is the standard port for a HTTP connection).
The last value (marked green) is your username and the server you’re going to ssh to.

A more pratical example

Another good example would be something like this:

ssh -L5000:www.google.de:443 myserver.my.domain

This example will open a SSH connection to the server myserver.my.domain and will tunnel (or forward) the Port 443 on the destination address (in this example „www.google.de“) to the local port 5000 on your local machine. After this you will be able to enter https://localhost:5000 in your webbrowser on your local machine and you should see the google start page. This means all traffic which is going to www.google.de via HTTPS is routed over your myserver.my.domain.

Encrypting VNC traffic

VNC doesn’t encrypt network traffic by default. If you do remote administration with VNC you could either use a VPN or SSH as a much more simpler solution. There are other remote administration solution available which do support encryption out of the box (like X2Go or NXNomachine). However, using VNC in combination with SSH for encryption is as easy as possible. Encrypting a VNC connection over an SSH tunnel gives you some great benefits:

  1. The VNC traffic between your local machine and the destination (VNC Server) is encrypted.
  2. As a home server user, you can just open the SSH port in your routers firewall for external access. All other ports can remain closed because you can port forward them with the help of SSH.
  3. Due to the SSH user authentication you have something like a „low-level“ user authentication.

The following example opens a SSH connection to the server myserver.my.domain and forwards the VNC Server port on this server so that the VNC Server is reachable locally under the port 5000:

ssh -L5000:localhost:5900 myserver.my.domain

After the connection is established the VNC Server on the server myserver.my.domain can now be reached under the address localhost port 5000. If your server does listen on another port than the standard port of SSH (22) you can add the -p parameter to ssh to your server with the port you want:

ssh -p1234 -L5000:localhost:5900 myserver.my.domain

Further links