Dropbear 77 + ECDSA su OpenWRT 18.06.1

Da un po’ di tempo, su uno dei miei computer, avevo creato una chiave SSH con ECDSA, per poi scoprire di non poterla usare per connettermi al mio router che ha OpenWRT. Infatti, per impostazione predefinita di OpenWRT, Dropbear viene compilato senza supporto a questo algoritmo, per risparmiare una cosa come 23KiB.

Normalmente la cosa può avere senso, perché lo spazio sulle flash è sempre estremamente limitato. Tuttavia, io ho già una chiave ECDSA basata su curve NIST e ho una extroot, quindi ho deciso di provare a ricompilare il Dropbear di OpenWRT e posto qui le istruzioni per chi fosse interessato all’argomento, incluso un futuro me.

Come ulteriore nota, vorrei evidenziare che il supporto a ed25519 non è attualmente esistente in Dropbear! C’è la possibilità di usare curve25519-donna per lo scambio di chiavi, ed è anche abilitata di default, ma non c’è nient’altro che riguardi ed25519.

Ho provato personalmente queste impostazioni su OpenWRT 18.06.1 (non ho ancora fatto l’aggiornamento alla minor successiva), sul mio TD-W8970.

Tuttavia, ho deciso di installare l’ultima versione di Dropbear, il che ha reso il tutto un po’ più difficile.

Per un sistema come il mio router, preferirei la stabilità all’ultimissima versione, però, andando a vedere nei changelog di Dropbear, ho notato che nella versione di OpenWRT (2018.75), c’è un bug che provoca il crash in caso di chiavi ECDSA malformate. Inoltre, solitamente OpenWRT è molto stabile e, almeno nel mio caso, i pacchetti creati con questa procedura non vanno a influire su nessun altro pacchetto già esistente.

La prima cosa da fare è scaricare ed estrarre l’SDK per la propria versione di OpenWRT: tra i download ufficiali di solito si possono trovare ImageBuilder e SDK compilati per Linux su x86_64. A noi interessa il secondo, perché dobbiamo proprio compilare pacchetti.

L’SDK include diversi binari, tra cui i cross compilatori e git, tuttavia io ho riscontrato un problema: env non mi trovava il time incluso. Io ho risolto semplicemente installandolo dai repo Debian1.

Una volta estratto il pacchetto, dobbiamo andare con un terminale nella root dell’SDK e dare un primo comando per risolvere un altro problema che ho verificato, legato ai locale (fonte della soluzione):

export LC_ALL=C

A questo punto possiamo fare l’aggiornamento dei feed, che sono un sistema per scaricare i dati (Makefile, configurazioni, patch, etc) dei pacchetti già esistenti su OpenWRT, ma non prima di aver modificato la configurazione affinché il sistema usi le ultime versioni, dal master del Git di OpenWRT, come accennavo nell’introduzione.

Per farlo, creiamo nella root dell’SDK un file feeds.conf con il seguente contenuto:

src-git base https://git.openwrt.org/openwrt/openwrt.git;master
src-git packages https://git.openwrt.org/feed/packages.git;master

dopodiché, possiamo finalmente aggiornare i file dei feed, dando sempre dal terminale di prima:

./scripts/feeds update -a

Questo ci permetterà di scaricare appunto i dati per compilare Dropbear:

./scripts/feeds install dropbear

Nel mio caso, ci sono stati diversi warning riguardo le dipendenze del kernel Linux, ma possono essere tranquillamente ignorate, tanto noi non lo andremo a compilare.

Prima di passare alla compilazione, ci sono altre tre modifiche da fare, sempre dovute all’aggiornamento di Dropbear. Per prima cosa, i Makefile dell’attuale master di OpenWRT possono usare una nuova variabile, ESED, che dobbiamo aggiungere manualmente al file rules.mk nella root dell’SDK della 18.06.1 (io l’ho aggiunto a riga 268):

ESED:=$(STAGING_DIR_HOST)/bin/sed -E -i -e

Poi dobbiamo passare al file package/feeds/base/dropbear/Makefile: anche dropbearconvert viene linkato alla zlib (almeno se abilitate la compressione), ma non la indica espressamente come sua dipendenza, il che fa fallire la build. Per risolvere il problema, bisogna aggiungere la seguente linea dopo la linea 73:

  DEPENDS:= +DROPBEAR_ZLIB:zlib

Infine, ripristiniamo interamente il file di inizializzazion a quello e della versione 18.06.1, scaricando questo file nella directory package/feeds/base/dropbear/files.

Fatte queste modifiche, non necessarie se non avessimo aggiornato Dropbear, possiamo finalmente iniziare la build. Andiamo ad abilitare i moduli che ci interessano di Dropbear: eseguiamo make menuconfig. Si aprirà un menu, scegliamo Base system, dopo entriamo dentro la Configuration di Dropbear e abilitiamo quello che ci serve con la barra spaziatrice: degli asterischi indicano ciò che è stato abilitato. Salviamo e usciamo da questo menu con i tasti appositi. Se usate SSH solo in LAN, non ne vale la pena di abilitare la compressione: avrà l’unico effetto di abbassare le prestazioni. Se invece usate spesso dei tunnel SSH da remoto, potreste volerla attivare e non usarla in LAN.

A questo punto, non ci resta che compilare il tutto: sempre dal terminale di prima, diamo il comando make -j8 package/dropbear/compile (al posto di 8 mettete i thread del vostro processore).

Questo va a creare dei file in bin/packages/mips_24kc/base (o in una posizione simile qualora dovreste avere un’altra architettura). Copiamo nel router tutti i file, tranne zlib_dev (va bene metterli anche in /tmp, e possiamo copiarli, per esempio, con scp) e installiamoli con la linea di comando di opkg:

opkg install *.ipk

Probabilmente riceverete degli avvisi che alcuni file di configurazione differiscono da quelli predefiniti, che verranno copiati in un altro file, tuttavia potete tranquillamente cancellare questi nuovi file.

Adesso, riavviando Dropbear (/etc/init.d/dropbear restart), potremo connetterci anche con le chiavi ECDSA.

Footnotes

  1. Su Debian non è installato perché BASH fornisce time come keyword, non come programma
    ^top