Ubuntu full disc encryption on Hetzner Cloud adding add static route in initramfs

Solution 1:

had same problem / small discussion with tech support that it cannot be that the initramfs fails only in Hetzner cloud instances like this.

But Hetzner Support repeately states only that their DHCP server are compliant to RFC3442 which announces the default host route to the internal cloud GW. So this must be a problem of the initramfs dhcp client and they couldn't (wouldn't ?) try setup a perhaps possible BootP response e.g. with the right IP=... parameter.

I suggested to update their documentation for this but it seems the "feel free to use our wiki for documentation" ... The (marketing ;) ... ) answer here is then not right:

Hetzner_OL 6 months ago [-]

Thanks for the suggestion about Docker/dbaas. I have passed it on to our development team. We don't usually publish what new products and features we are developing until they are ready, but we will continue to post information about upgrades as they develop.

Regarding the DSGVO: Do you support encryption of the filesystem? ->

Hetzner Cloud servers are fully virtualized. So the customer can even fully encrypt the whole server. --Katie, Marketing, Hetzner Online

I tried finding questions/solutions for this problem but the only match I found today is your question ;)

Your referenced answer for setup the interface is partly correct. But from question it wasn't clear that he also needs a static host route to the gateway so it's missing in the answer.

My quick solution of the problem is to patch manually the needed function like this "dynamically" - you can check all your variables in /run/net-ens3.conf:

root@image-debian-jessie-94 ~ # diff -p /usr/share/initramfs-tools/scripts/functions{.orig,}
*** /usr/share/initramfs-tools/scripts/functions.orig   2018-07-31 12:46:40.911167456 +0200
--- /usr/share/initramfs-tools/scripts/functions        2018-07-31 12:50:30.736742035 +0200
*************** configure_networking()
*** 274,279 ****
--- 274,284 ----
                # ipconfig should have quit after first response
                . /run/net-*.conf
        fi
+
+       # Hack for Hetzner vServer static route enhanced like shown partly in this answer:
+       # https://serverfault.com/questions/909040/static-route-in-initramfs
+       ip route add ${IPV4GATEWAY}/${IPV4NETMASK} dev ${DEVICE}
+       ip route add default via ${IPV4GATEWAY} dev ${DEVICE}
  }

  # Wait for queued kernel/udev events

Tested and worked fine for me. I could setup / snapshot the smallest image.

The encrypted snapshot is ~18 GB compared to 0,5 GB unencrypted but snapshot price is still fine compared to improved security (normally Openstack based systems could/should have a key manager service which can this transparently. ;)

Solution 2:

jajo's answer starts on the right track, but it misses a few key things. Here is how I got this to work on Ubuntu Bionic without having to patch any files (meaning, this method isn't susceptible to being broken by an update):

  1. initramfs-tools scripts need to start with some boilerplate that hooks into its system; otherwise, the script will run at initramfs generation time, which is not what we want:

    #!/bin/sh
    PREREQ=""
    prereqs()
    {
        echo "$PREREQ"
    }
    
    case $1 in
    prereqs)
        prereqs
        exit 0
        ;;
    esac
    
    . /scripts/functions
    # Begin real processing below this line
    
  2. Invoke the configure_networking function right before adding the route. This causes the default network configuration to happen first, which would otherwise clobber any settings created by the script if it were to run later. The function creates some files in /run/, which make the second invocation (from the busybox-initramfs hook) do nothing.

    configure_networking
    
  3. Add the static routes, as in jajo's answer. If you are not configuring an IP address using e.g. a kernel command-line parameter, then add that here too.

    ip route add 1.2.3.4 dev ens3
    ip route add default via 1.2.3.4 dev ens3
    
    exit 0                   
    

As in jojo's answer, the file above should be placed in /etc/initramfs-tools/scripts/init-premount/static-routes, and made executable.

One more thing worth noting is that klibc has recently implemented support for RFC3442 (classless static routes in DHCP); so, if your service provider is announcing the necessity for these routes in their DHCP configuration, it's possible that you may not need this script in the latest Debian/Ubuntu versions.


Solution 3:

For those who come across this thread:

At least in Debian Stretch a little more generic configuration (which won't break on package update) works. We just configure network statically with a script in init-premount:

vi /etc/initramfs-tools/scripts/init-premount/static-routes

#!/bin/sh 
# /etc/initramfs-tools/scripts/init-premount/static-routes

# to avoid race condition
# we have to wait until the automatic network configuration via dhcp
# is finished
sleep 15

ip a add 192.168.0.18/32 dev eth0
ip route add 192.168.178.1 dev eth0
ip route add default via 192.168.178.1 dev eth0

exit 0

chmod 755 /etc/initramfs-tools/scripts/init-premount/static-routes


Solution 4:

Based on the other answers the following script placed as executable in /etc/initramfs-tools/scripts/init-premount/ did make it finally work with Hetzner Cloud Server Ubuntu 20.04:

#!/bin/sh
PREREQ=""
prereqs()
{
   echo "$PREREQ"
}

case $1 in
prereqs)
   prereqs
   exit 0
   ;;
esac

. /scripts/functions
# Begin real processing below this line
# /etc/initramfs-tools/scripts/init-premount/static-routes

configure_networking

ip route add 172.31.1.1/32 dev ens3 
ip route add default via 172.31.1.1 dev ens3 

exit 0

Name and save the script: /etc/initramfs-tools/scripts/init-premount/hetznernetwork

Make it executeable: chmod +x /etc/initramfs-tools/scripts/init-premount/hetznernetwork

Update initramfs to include the script: update-initramfs -u -k all

I recommend installing Ubuntu 20.04 with Ubuntu 20.04 legacy server ISO or manually with Debootstrap.

The really important line is configure_networking which did make the difference for my setup.