Skip to content

Commit

Permalink
Remove dropbear dependency.
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
r-pufky committed Jul 4, 2021
1 parent 75e7567 commit ccd3831
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 100 deletions.
19 changes: 14 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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:"
Expand All @@ -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"
93 changes: 36 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand All @@ -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!
Expand Down
16 changes: 7 additions & 9 deletions config
Original file line number Diff line number Diff line change
Expand Up @@ -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 ...'
#

Expand All @@ -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.
Expand All @@ -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
10 changes: 5 additions & 5 deletions hooks
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 7 additions & 6 deletions init-bottom
Original file line number Diff line number Diff line change
@@ -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
40 changes: 22 additions & 18 deletions init-premount
Original file line number Diff line number Diff line change
Expand Up @@ -3,74 +3,78 @@
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

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
Expand Down

0 comments on commit ccd3831

Please sign in to comment.