From ccd38316a752ba00388bc28ce40e883cad27fbc3 Mon Sep 17 00:00:00 2001 From: Robert Pufky Date: Sun, 4 Jul 2021 12:08:50 -0700 Subject: [PATCH] Remove dropbear dependency. * Remove PREREQ dropbear dependency in init-bottom; this is not needed for dropbear to work correctly. * Move initramfs scripts to `/etc/initramfs-tools` since there is no longer a dependency on the dropbear system package. * Update Makefile to handle new location and automatically remove the old location. * Added IPv6 DNS support if IPv6 use is detected. * Standardized, clarify code & documentation. --- Makefile | 19 ++++++++--- README.md | 93 ++++++++++++++++++++------------------------------- config | 16 ++++----- hooks | 10 +++--- init-bottom | 13 +++---- init-premount | 40 ++++++++++++---------- 6 files changed, 91 insertions(+), 100 deletions(-) diff --git a/Makefile b/Makefile index 348a673..863c77b 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ # You can set these variables from the command line, and also # from the environment for the first two. TARGETDIR = /etc/wireguard-initramfs -INITRAMFS = /usr/share/initramfs-tools +INITRAMFS = /etc/initramfs-tools help: @echo "USAGE:" @@ -18,30 +18,39 @@ help: .PHONY: help Makefile -install: +install: remove_legacy @if ! [ "$(shell id -u)" = 0 ]; then echo "You must be root to perform this action."; exit 1; fi @echo "Installing wireguard-initramfs ..." @apt update && apt install initramfs-tools @mkdir -p "$(TARGETDIR)" @touch "$(TARGETDIR)/private_key" - @chmod 0400 "$(TARGETDIR)/private_key" + @chmod 0600 "$(TARGETDIR)/private_key" @cp -v config "$(TARGETDIR)/config" @chmod 0644 "$(TARGETDIR)/config" @cp -v hooks "$(INITRAMFS)/hooks/wireguard" + @chmod 0755 hooks "$(INITRAMFS)/hooks/wireguard" @cp -v init-premount "$(INITRAMFS)/scripts/init-premount/wireguard" + @chmod 0755 init-premount "$(INITRAMFS)/scripts/init-premount/wireguard" @cp -v init-bottom "$(INITRAMFS)/scripts/init-bottom/wireguard" + @chmod 0755 init-bottom "$(INITRAMFS)/scripts/init-bottom/wireguard" @echo "Done." @echo @echo "Setup $(TARGETDIR)/config and run:" @echo @echo " update-initramfs -u && update-grub" + @echo @echo "Done." -uninstall: +uninstall: remove_legacy @if ! [ "$(shell id -u)" = 0 ]; then echo "You must be root to perform this action."; exit 1; fi @echo "Uninstalling wireguard-initramfs ..." @rm -f "$(INITRAMFS)/hooks/wireguard" @rm -f "$(INITRAMFS)/scripts/init-premount/wireguard" @rm -f "$(INITRAMFS)/scripts/init-bottom/wireguard" - @echo "Done." @echo + @echo "Done." + +remove_legacy: + @rm -f "/usr/share/initramfs-tools/hooks/wireguard" + @rm -f "/usr/share/initramfs-tools/scripts/init-premount/wireguard" + @rm -f "/usr/share/initramfs-tools/scripts/init-bottom/wireguard" diff --git a/README.md b/README.md index 7732e8c..98e62ec 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,23 @@ # wireguard-initramfs Use dropbear over wireguard. -Start wireguard network during kernel init; enabling dropbear use over wireguard! Enables wireguard networking during kernel boot, before encrypted partitions are mounted. Combined with [dropbear](https://github.com/mkj/dropbear) this can enable FULLY ENCRYPTED remote booting without storing key material or exposing ports on the remote network. An Internet connection simply needs to -exist that can reach the wireguard endpoint. +exist that can reach the wireguard server endpoint. -Normal dropbear connections can still be used, as well as DNS resolution to -find wireguard endpoints. This essentially enables the creation of a fully -encrypted remote managed node, with the ability to prevent all local access. +Normal dropbear connections and DNS resolution can be used to find wireguard +endpoints. This essentially enables the creation of a fully encrypted remote +managed node, with the ability to prevent all local access. ## Requirements -Working knowledge of Linux. Understanding of networking and how Dropbear, -Wireguard work. +Working knowledge of Linux. Understanding of networking and Wireguard. -1. [Debian Bullseye](debian.org) (any version with wireguard support should work, but untested). -1. [Dropbear](https://github.com/mkj/dropbear) installed, configured and in a "known working" state. -1. [Wireguard](https://www.wireguard.com/) installed, configured and in a "known working" state. +1. [Debian Bullseye](debian.org) (any version with wireguard support should + work, but untested). +1. [Wireguard](https://www.wireguard.com/) installed, configured and in a + "known working" state. ## Install Installation is automated via make. Download, extract contents, and install on @@ -31,28 +30,18 @@ tar xvf 2021-07-03.tar.gz cd wireguard-initramfs-2021-07-03; make install ``` -## Configure -Configuration is explained within `/etc/wireguard-initramfs/config`. Be sure to -set the private key as well. - -Restricting dropbear connections to **only** wireguard: -> Confirm wireguard/dropbear work without restriction first. -> -> Set dropbear listen address to only wireguard client interface address. -> Using example configuration: -> -> /etc/dropbear-initramfs/config -> ```bash -> DROPBEAR_OPTIONS='... -p 172.31.255.10:22 ...' -> ``` +### Configure +See comments in `/etc/wireguard-initramfs/config`. Be sure to set the private +key as well. Refer to [wg set man page](https://man7.org/linux/man-pages/man8/wg.8.html) for additional information. :warning: -Most installs do not currently encrypt `/boot`; and therefore the client's +Most installs do not currently encrypt `/boot`; and therefore the client private key should be considered **untrusted/compromised**. It is highly -recommended that a separate wireguard network is used to for remote unlocking. +recommended that a separate point-to-point wireguard network with proper port +blocking is used for remote unlocking. Rebuild initramfs to use: ```bash @@ -61,37 +50,27 @@ update-grub reboot ``` -Any static errors will abort the build. Mis-configurations will not be caught; -test this where you can easily get physical access to the machine if something -goes wrong. - -## FAQ -Q: **I want to use this, but without dropbear** - -> A: Supported; just remove the pre-requisite dependency for `init-bottom`: -> -> `/usr/share/initramfs-tools/init-bottom/wireguard` -> ```bash -> #PREREQ="dropbear" -> PREREQ="" -> ``` -> -> and rebuild the initramfs image. - -Q: **I want to restrict dropbear to only wireguard** - -> A: Supported. Confirm wireguard works before restricting normal networks. -> -> Restricting dropbear connections to **only** wireguard: -> > Confirm wireguard/dropbear work without restriction first. -> > -> > Set dropbear listen address to only wireguard client interface address. -> > Using example configuration: -> > -> > /etc/dropbear-initramfs/config -> > ```bash -> > DROPBEAR_OPTIONS='... -p 172.31.255.10:22 ...' -> > ``` +Any static errors will abort the build. Mis-configurations will not be caught. +Be sure to test while you still have physical access to the machine. + +## Dropbear +`wireguard-initramfs` can be combined with dropbear to enable remote system +unlocking without needing control over the remote network, or knowing what the +public IP of that system is. It also creates an encrypted no-trust tunnel +before SSH connections are attempted. + +### Requirements + +1. [Dropbear](https://github.com/mkj/dropbear) installed, configured and in a "known working" state. + +### Configure +Set dropbear to use *all* network interfaces to ensure remote unlocks work over +wireguard first. Then restrict to the wireguard network once it is working: + +`/etc/dropbear-initramfs/config` +```bash +DROPBEAR_OPTIONS='... -p 172.31.255.10:22 ...' +``` ## Bug / Patches / Contributions? All are welcome, please submit a pull request or open a bug! diff --git a/config b/config index 1175a2d..39703fe 100644 --- a/config +++ b/config @@ -2,19 +2,17 @@ # # NOTE: As most systems do not encrypt /boot, private key material is exposed # and compromised/untrusted. Boot wireguard network should be -# **different** & untrusted, versus the network used after booting. +# **different** & untrusted; versus the network used after booting. +# Always restrict ports and access on the wireguard server. # # Be sure to test wireguard config with a running system before setting # options. See: https://manpages.debian.org/unstable/wireguard-tools/wg.8.en.html # # Restricting dropbear connections to **only** wireguard: -# Confirm wireguard/dropbear work without restriction first. -# -# Set dropbear listen address to only wireguard client interface address. -# Using example configuration: +# * Confirm wireguard/dropbear work without restriction first. +# * Set dropbear listen address to only wireguard client interface address. # # /etc/dropbear-initramfs/config -# ... # DROPBEAR_OPTIONS='... -p 172.31.255.10:22 ...' # @@ -24,7 +22,7 @@ INTERFACE=example_vpn # CIDR wireguard interface address. INTERFACE_ADDR=172.31.255.10/32 -# Peer public key (server's public key) +# Peer public key (server's public key). PEER_PUBLIC_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # IP:PORT of the peer (server); any reachable IP/DNS. @@ -33,8 +31,8 @@ PEER_ENDPOINT=wg.example.com:51820 # Client Private key. Specify location of file containing only the private key. CLIENT_PRIVATE_KEYFILE=/etc/wireguard-initramfs/private_key -# Keepalives. Required to ensure connection for non-exposed ports. +# Persistent Keepalive. Required to ensure connection for non-exposed ports. PERSISTENT_KEEPALIVES=25 -# CIDR IP's allowed on wireguard connection, typically the peer (server) +# Allowed IP's (CIDR) on wireguard; for boot this should be the peer (server). ALLOWED_IPS=172.31.255.254/32 diff --git a/hooks b/hooks index f56a29d..a1f684b 100755 --- a/hooks +++ b/hooks @@ -3,14 +3,14 @@ PREREQ="" prereqs() { - echo "${PREREQ}" + echo "${PREREQ}" } case "${1}" in - prereqs) - prereqs - exit 0 - ;; + prereqs) + prereqs + exit 0 + ;; esac . /usr/share/initramfs-tools/hook-functions diff --git a/init-bottom b/init-bottom index bf9971a..ea83985 100755 --- a/init-bottom +++ b/init-bottom @@ -1,21 +1,22 @@ #!/bin/sh -PREREQ="dropbear" +PREREQ="" prereqs() { - echo "${PREREQ}" + echo "${PREREQ}" } case "${1}" in - prereqs) - prereqs - exit 0 - ;; + prereqs) + prereqs + exit 0 + ;; esac . /scripts/functions . /etc/wireguard/config + log_begin_msg 'Stopping wireguard boot network' ip link delete dev ${INTERFACE} log_end_msg diff --git a/init-premount b/init-premount index f5b3346..5c52c74 100755 --- a/init-premount +++ b/init-premount @@ -3,28 +3,28 @@ PREREQ="udev" prereqs() { - echo "${PREREQ}" + echo "${PREREQ}" } case "${1}" in - prereqs) - prereqs - exit 0 - ;; + prereqs) + prereqs + exit 0 + ;; esac . /scripts/functions if [ ! -e /sbin/wg ]; then - log_failure_msg 'Wireguard binary not found, skipping setup' + log_failure_msg 'Wireguard binary not found; skipping start' exit 0 fi if [ ! -e /etc/wireguard/config ]; then - log_failure_msg 'Wireguard config not found, skipping setup' + log_failure_msg 'Wireguard config not found; skipping start' exit 0 fi if [ ! -e /etc/wireguard/private_key ]; then - log_failure_msg 'Wireguard client private key not found, skipping setup' + log_failure_msg 'Wireguard client private keyfile not found, skipping start' exit 0 fi @@ -32,45 +32,49 @@ log_begin_msg 'Loading wireguard config' . /etc/wireguard/config if [ -z ${INTERFACE} ]; then - log_failure_msg 'Interface name is not defined!' + log_failure_msg 'Interface name is not defined' return 1 fi if [ -z ${INTERFACE_ADDR} ]; then - log_failure_msg 'Interface address is not defined!' + log_failure_msg 'Interface address is not defined' return 1 fi if [ -z ${PEER_PUBLIC_KEY} ]; then - log_failure_msg 'Peer Public Key is not defined!' + log_failure_msg 'Peer public key is not defined' return 1 fi if [ -z ${PEER_ENDPOINT} ]; then - log_failure_msg 'Peer endpoint is not defined!' + log_failure_msg 'Peer endpoint is not defined' return 1 fi if [ -z ${PERSISTENT_KEEPALIVES} ]; then - log_failure_msg 'Persistent Keep Alives is not defined!' + log_failure_msg 'Persistent keepalive is not defined' return 1 fi if [ -z ${ALLOWED_IPS} ]; then - log_failure_msg 'Allowed IPs is not defined!' + log_failure_msg 'Allowed IPs is not defined' return 1 fi log_end_msg log_begin_ms 'Starting wireguard' - # Ensure networking is started (idempotent) and setup DNS. configure_networking touch /etc/resolv.conf for adapter in /run/net-*.conf; do - source "${adapter}" - echo nameserver "${IPV4DNS0}" >> /etc/resolv.conf - echo nameserver "${IPV4DNS1}" >> /etc/resolv.conf + . "${adapter}" + if [ ! -z "${IPV4DNS0}" ]; then + echo nameserver "${IPV4DNS0}" >> /etc/resolv.conf + echo nameserver "${IPV4DNS1}" >> /etc/resolv.conf + fi + if [ ! -z "${IPV6DNS0}" ]; then + echo nameserver "${IPV6DNS0}" >> /etc/resolv.conf + fi done ip link add dev ${INTERFACE} type wireguard