Skip to content

Commit

Permalink
Update and improve dropbear
Browse files Browse the repository at this point in the history
By updating to dropbear 2020.81 (mostly based on OpenWRT), we gain :
 - ed25519 host keys (and pubkeys)
 - curve25519 key exchange
 - rsa-sha2-256 pubkey authentication, instead of ssh-rsa (disabled on newer clients)

Both ed25519 host keys and curve25519 key exchange are much faster than RSA and DH, so
connecting is down from 3.5s to 0.6s.
But unlike host keys, pubkey authentication is faster with RSA (ed25519 is 0.3s slower).

The ed25519 host key is also much faster to generate than the RSA and DSS (deprecated) ones,
which allows to generate it on demand.
This saves a LOT of CPU on boot, dropbear starts about 1 min earlier !
It is now actually ready before the link, so actual gain is more about 30-40s.

Clients supporting ed25519 host keys will connect quickly, older ones
which only have RSA would have a slower first connection.

Now /etc/dropbear is persistent, so :
 - host keys no longer change on reboot
 - public keys can be copied to /etc/dropbear/authorized_keys
  • Loading branch information
hwti committed Jan 7, 2021
1 parent 0144cb0 commit e7c4928
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
/firmwares/*/
/firmwares/*_patched.bin
/OpenWrt-Toolchain-*
/patches/0000_dropbear/build
73 changes: 73 additions & 0 deletions patches/0000_dropbear/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
DROPBEAR_RELEASE = 2020.81
DROPBEAR_TAR = dropbear-$(DROPBEAR_RELEASE).tar.bz2
DROPBEAR_URL = https://matt.ucc.asn.au/dropbear/releases/$(DROPBEAR_TAR)
DROPBEAR_SRC = build/dropbear-$(DROPBEAR_RELEASE)
DROPBEAR_PATCHES = $(addprefix https://raw.githubusercontent.com/openwrt/openwrt/master/package/network/services/dropbear/patches/, \
100-pubkey_path.patch \
110-change_user.patch \
130-ssh_ignore_x_args.patch \
140-disable_assert.patch \
600-allow-blank-root-password.patch \
900-configure-hardening.patch \
910-signkey-fix-use-of-rsa-sha2-256-pubkeys.patch \
)

DROPBEAR_CONF = \
--host mips-openwrt-linux-uclibc \
--disable-lastlog \
--disable-utmpx \
--disable-utmp \
--disable-wtmp \
--disable-wtmpx \
--disable-loginfunc \
--disable-pututline \
--disable-pututxline \
--disable-zlib \
$()

# chacha20-poly1305 is more than 2x slower than aes-ctr for decryption on this HW.
# But it would be more than 2x faster for encryption.
DROPBEAR_DISABLED_FEATURES = \
INETD_MODE \
DROPBEAR_CLI_NETCAT \
DROPBEAR_DSS \
DO_MOTD \
DROPBEAR_ECDSA \
DROPBEAR_ECDH \
DROPBEAR_CHACHA20POLY1305

all: dropbear

clean:
rm -rf build

build:
mkdir -p $@

build/$(DROPBEAR_TAR): | build
wget -O $@ $(DROPBEAR_URL)

build/.dropbear_patches: | build
rm -f build/*.patch
cd build && wget $(DROPBEAR_PATCHES)
@touch $@

build/.dropbear_unpacked: build/$(DROPBEAR_TAR) build/.dropbear_patches
tar -C build -xf $<
set -e; for p in build/*.patch; do patch -d $(DROPBEAR_SRC) -p1 < $$p; done
@touch $@

build/.dropbear_autoreconf: build/.dropbear_unpacked
cd $(DROPBEAR_SRC) && autoreconf
@touch $@

build/.dropbear_configured: build/.dropbear_autoreconf | toolchain
cd $(DROPBEAR_SRC) && ./configure $(DROPBEAR_CONF)
printf "#define %s 0\n" $(DROPBEAR_DISABLED_FEATURES) > $(DROPBEAR_SRC)/localoptions.h
@touch $@

dropbear: build/.dropbear_configured
$(MAKE) -C $(DROPBEAR_SRC) PROGRAMS="dropbear dbclient dropbearkey scp" MULTI=1 SCPPROGRESS=1
$(OBJCOPY) --strip-all $(DROPBEAR_SRC)/dropbearmulti dropbear

include ../../toolchain.mk
Binary file added patches/0000_dropbear/dropbear
Binary file not shown.
46 changes: 46 additions & 0 deletions patches/0000_dropbear/generate-host-keys-as-needed.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
--- a/etc/init.d/dropbear 2017-07-11 07:03:05.000000000 +0200
+++ b/etc/init.d/dropbear 2020-12-29 02:09:43.719665917 +0100
@@ -65,7 +65,7 @@
local pid_file="/var/run/${NAME}.${PIDCOUNT}.pid"

procd_open_instance
- procd_set_param command "$PROG" -F -P "$pid_file"
+ procd_set_param command "$PROG" -F -P "$pid_file" -R
[ "${PasswordAuth}" -eq 0 ] && procd_append_param command -s
[ "${GatewayPorts}" -eq 1 ] && procd_append_param command -a
[ "${RootPasswordAuth}" -eq 0 ] && procd_append_param command -g
@@ -80,34 +80,8 @@
procd_close_instance
}

-keygen()
-{
- for keytype in rsa dss; do
- # check for keys
- key=dropbear/dropbear_${keytype}_host_key
- [ -f /tmp/$key -o -s /etc/$key ] || {
- # generate missing keys
- mkdir -p /tmp/dropbear
- [ -x /usr/bin/dropbearkey ] && {
- /usr/bin/dropbearkey -t $keytype -f /tmp/$key 2>&- >&- && exec /etc/rc.common "$initscript" start
- } &
- exit 0
- }
- done
-
- lock /tmp/.switch2jffs
- mkdir -p /etc/dropbear
- mv /tmp/dropbear/dropbear_* /etc/dropbear/
- lock -u /tmp/.switch2jffs
- #chown root /etc/dropbear
- #chmod 0700 /etc/dropbear
-}
-
start_service()
{
- [ -s /etc/dropbear/dropbear_rsa_host_key -a \
- -s /etc/dropbear/dropbear_dss_host_key ] || keygen
-
. /lib/functions.sh
. /lib/functions/network.sh

15 changes: 15 additions & 0 deletions patches/0000_dropbear/patch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh

set -e

ROOTFS=$1

echo "Updating dropbear to 2020.81"
cp -f dropbear "$ROOTFS/usr/sbin/dropbear"

# Generate host keys as needed (so we must not have placeholders)
patch -p1 -d "$ROOTFS" < generate-host-keys-as-needed.patch
rm -f "$ROOTFS"/etc/dropbear/dropbear_*_host_key

# Make dropbear config (host keys, authorized_keys) persistent
echo "/etc/dropbear:/configs/etc/dropbear" >> "$ROOTFS/usr/cfg/etc.cfg"
27 changes: 27 additions & 0 deletions toolchain.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
TOOLCHAIN_NAME = OpenWrt-Toolchain-lantiq-for-mips_34kc+dsp-gcc-4.8-linaro_uClibc-0.9.33.2
TOOLCHAIN_TAR = $(TOOLCHAIN_NAME).tar.bz2
TOOLCHAIN_URL = https://archive.openwrt.org/barrier_breaker/14.07/lantiq/xrx200/$(TOOLCHAIN_TAR)

ROOT_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
CROSS_COMPILE = $(ROOT_DIR)/$(TOOLCHAIN_NAME)/toolchain-mips_34kc+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-uclibc-

# We use the *.bin directly : the wrapper is not needed and add rpath...
export AR = $(CROSS_COMPILE)ar
export AS = $(CROSS_COMPILE)as.bin
export CC = $(CROSS_COMPILE)gcc.bin
export CXX = $(CROSS_COMPILE)g++.bin
export LD = $(CROSS_COMPILE)ld.bin
export OBJCOPY = $(CROSS_COMPILE)objcopy
export RANLIB = $(CROSS_COMPILE)ranlib
export STRIP = $(CROSS_COMPILE)strip

# Prevent "warning: environment variable 'STAGING_DIR' not defined"
export STAGING_DIR

toolchain: $(CC)

$(ROOT_DIR)/$(TOOLCHAIN_TAR):
wget -O $@ $(TOOLCHAIN_URL)

$(CC): | $(ROOT_DIR)/$(TOOLCHAIN_TAR)
tar -C $(ROOT_DIR) -xf $(TOOLCHAIN_TAR)

0 comments on commit e7c4928

Please sign in to comment.