OpenWrt su D-Link DSL-504T

Anche se gli ultimi firmware ufficiali funzionano abbastanza bene, ho voluto provare ad installare OpenWrt sul mio router D-Link DSL-504T.

L'operazione non è delle più banali ed è anche abbastanza rischiosa. Prima di riuscire a farlo funzionare ho dovuto ricompilare OpenWrt diverse volte provando diverse configurazioni.

L'hardware

Diversi router ed anche alcuni modem D-Link sono basati sul chipset AR7 della Texas Instruments che include quasi tutti i componenti necessari ad implementare un router ADSL: tutti i dettagli sono disponibili su http://www.linux-mips.org/wiki/AR7. In particolare il 504T monta una memoria flash da 4MB (32Mbit), 16MB di RAM e 4 porte fast ethernet.

Motivi per passare a OpenWrt

  • Sistema aperto totalmente modificabile anche “dal vivo”
  • Amministrazione tramite SSH
  • Supporto per QoS
  • Firewall a livello 7
  • Caching DNS funzionante (il firmware originale ha seri problemi)
  • Package manager ipkg (molto simile ad apt)
  • Supporto per VLAN 802.3q
  • Kernel 2.6

Motivi per NON passare a OpenWrt

  • Installazione NON banale
  • Elevato rischio di “brickare” il router durante l'installazione (quasi sempre risolvibile con flashing tramite JTAG)
  • Mancanza (ancora per poco?) di una interfaccia web

Cosa serve

  • Il router :-o. Probabilmente la stessa procedura è applicabile anche su altri modem/router D-Link (con modello che termina con la lettera T) e altre marche purchè basate su AR7. Le interfacce WiFi sono supportate per ora sono TI ACX1xx, Prism2/2.5/3, Atheros, Cisco Aironet, Hermes, Prism54, Zydas ZD1211, Zydas ZD1211 USB; il 504T non è wireless, quindi non ne ho provata nessuna.
  • Un PC, meglio se con CPU veloce, dato che c'è molto da compilare, con GNU/Linux (io l'ho compilato sia su Ubuntu 6.10 Edgy Eft / amd64 che, più recentemente, su Debian 4.0r0 (Etch) ) e i soliti pacchetti per lo sviluppo (gcc, make, libc-dev, ncurses-dev, subversion, automake, autoconf, autoconf-archive, zlib1g-dev)
  • Molta pazienza
  • Sprezzo del pericolo e un po' di fortuna ;-)

Potrebbero tornare utili in caso di problemi:

  • Un router/modem ADSL “di backup” per potersi connettere alla ricerca delle soluzioni agli eventuali problemi
  • Dimestichezza con il saldatore a stagno
  • Collegamento di una porta seriale: il 504T è dotato di un connettore stripline a 4 pin con GND, 3.3V, TX e RX a livelli logici LVTLL che è possibile collegare alla seriale di un PC tramite un opportuno circuito per l'adattamento dei livelli: questa porta è usata sia dal bootloader che dal kernel come terminale e torna utile per leggere eventuali messaggi d'errore ed interagire col bootloader.

Scaricare i sorgenti

:!: In nessuna delle fasi da qui in avanti bisogna lavorare con i diritti di root :!:

Il supporto per AR7 esiste solo nella versione Kamikaze che è il ramo di sviluppo del progetto OpenWrt. Quindi occorre prelevare i sorgenti dal repository SVN:

mkdir ~/openwrt && cd ~/openwrt
svn co https://svn.openwrt.org/openwrt/trunk/
svn co https://svn.openwrt.org/openwrt/packages
cd trunk/package
ln -s ../../packages/*/* .

La revision che ho compilato io è la 5609 7232.

La configurazione

Una volta terminato il checkout dei sorgenti e dei packages bisogna procedere con la configurazione:

cd ~/openwrt/trunk
make menuconfig

Vista la scarsità di RAM a disposizione è bene selezionare, soprattutto a livello kernel, solo ed esclusivamente le funzionalità strettamente necessarie.

Le voci importanti sono “Target system” che ovviamente va impostato su “TI AR7 [2.6]”. Le altre voci possono essere configurate a seconda delle esigenze; nel mio caso ho:

  • disabilitato tutto ciò che riguarda il WiFi (sul 504T non avrebbe senso di esistere)
  • abilitato tutti i moduli non essenziali di iptables
  • abilitato il supporto per il QoS
  • abilitato il pacchetto ez-ipupdate per mantenere aggiornato il mio record dyndns
  • abilitato knockd per il supporto per il port knocking (non l'ho ancora provato)
  • abilitato netstat-nat
  • abilitato ntpclient
  • abilitato openvpn
  • disabilitato tutti i driver ide, pcmcia, lp, e tutto quello che ha a che fare con audio/video

Questo è il file .config risultante dalla mia selezione.

La compilazione

Terminata la configurazione basta dare:

make

e armarsi di pazienza ;-): in automatico verranno compilati gcc, binutils, kernel e tutto quello che è stato selezionato nel passaggio precedente.

Terminata la compilazione, l'immagine da flashare sul router si troverà in ~/openwrt/trunk/bin/openwrt-ar7-2.6-squashfs.bin e i pacchetti ipkg saranno nella directory ~/openwrt/trunk/bin/packages.

Questa è l'immagine del firmware che ho ottenuto io e questa la lista completa dei pacchetti che ho ottenuto.

L'installazione

Questo è il passo più rischioso: si tratta di operare direttamente sulla memoria flash del router per sovrascrivere il firmware originale con quello appena compilato.

ADAM2

ADAM2 prende il controllo del sistema all'avvio dell'apparecchiatura e si occupa di caricare il kernel e mandarlo in esecuzione. Informazioni più dettagliate su ADAM2 si possono trovare qui.

Trovare l'IP ADAM2

L'indirizzo a cui risponde ADAM2 non è lo stesso sul quale lavora l'interfaccia web del router ed è attivo solo nei due secondi immediatamente successivi all'avvio del router. In genere l'indirizzo è 10.8.8.8 ma potrebbe essere diverso. Per conoscerlo con certezza basta entrare in telnet sul router (l'utente è root e la password è quella che si usa per accedere all'interfaccia web) e cercare l'IP nel file /proc/ticfg/env:

cat /proc/ticfg/env | grep my_ipaddress

nel mio caso il risultato è:

my_ipaddress    10.8.8.8

Accedere ad ADAM2

ADAM2 funziona in modo simile ad un server FTP con qualche comando non standard. Alcuni di questi comandi non sono gestiti correttamente dal client FTP standard di Ubuntu, e per questi ho usato lftp che però ha problemi ad inviare il firmware al momento del flash del firmware.

sudo apt-get install lftp

Prepararsi a dare il comando

lftp ftp://adam2:adam2@10.8.8.8

(sostituendo eventualmente 10.8.8.8 con l'IP ottenuto al punto precedente) senza dare invio. Staccare l'alimentazione del router e riattaccarla. Dopo un secondo circa confermare il comando dando invio.

Settare le variabili d'ambiente

Prima di procedere al flash vero e proprio del firmware bisogna settare alcune variabili d'ambiente di ADAM2:

quote "SETENV modulation MMODE"
quote "SETENV autoload 1"

che servono a preimpostare il tipo di modulazione ADSL e abilitare l'avvio automatico del kernel al boot. Le impostazioni che seguono sono le più delicate, dato che consistono nella modifica della “tabella delle partizioni” della memoria flash. È importantissimo non modificare per nessuna ragione le variabili mtd2 e mtd3, dato che la partizione mtd2 contiene ADAM2 e mtd3 le variabili d'ambiente. La memoria flash è organizzata di fabbrica come segue (l'indirizzo finale NON è compreso nel range):

Inizio Fine Partizione Contenuto
0×90000000 0×90010000 mtd2 ADAM2
0×90010000 0x900a0000 mtd1 kernel
0x900a0000 0x903f0000 mtd0 filesystem
0x903f0000 0×90400000 mtd3 ambiente

Ora è bene verificare che le partizioni mtd0 e mtd1 si trovino nella posizione corretta:

quote "GETENV mtd0"

la risposta dovrebbe essere qualcosa del tipo:

mtd0    0x900a0000,0x903f0000
200 GETENV command successful

e poi:

quote "GETENV mtd1"

che dovrebbe riportare:

mtd1    0x90010000,0x900a0000
200 GETENV command successful

Procedere oltre SOLO se mtd1 inizia a 0×90010000 e mtd0 finisce a 0x903f0000.

Bisogna ora aggiungere una quinta partzione mtd4 che copra interamente kernel e filesystem:

quote "SETENV mtd4,0x90010000,0x903f0000"

Flash del firmware

A questo punto il router è pronto per ricevere il nuovo firmware. Uscire da lftp con il comando “bye” e riconnettersi con il client FTP da linea di comando:

cd ~/openwrt/trunk/bin
ftp 10.8.8.8

Con user adam2 e password adam2. Procedere con il flash:

quote "MEDIA FLSH"
bin
debug
hash
put "openwrt-ar7-2.6-squashfs.bin" "OpenWRT mtd4"

L'operazione richiede un po' di tempo e non viene avviata immediatamente: ADAM2, ricevuto il comando, prima cancella il contenuto della flash, e solo successivamente comincia a ricevere il file e a salvarlo nella flash. Terminato l'upload riavviare il router con

quote "REBOOT"

Primo avvio di OpenWrt

Attendere un paio di minuti finchè viene completata la preparazione del filesystem sulla flash che viene segnalata con lo spegnimento del led status.

Se tutto è andato liscio il router sta ora eseguendo OpenWrt ed è in ascolto all'indirizzo 192.168.1.1:

telnet 192.168.1.1
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.


BusyBox v1.4.2 (2007-05-14 21:50:52 CEST) Built-in shell (ash)
Enter 'help' for a list of built-in commands.

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 KAMIKAZE (bleeding edge, r7232) -------------------
  * 10 oz Vodka       Shake well with ice and strain
  * 10 oz Triple sec  mixture into 10 shot glasses.
  * 10 oz lime juice  Salute!
 ---------------------------------------------------
root@OpenWrt:~#

Ora occorre impostare subito una password:

passwd

Una volta impostata la password il demone telnet viene disabilitato ed attivato il demone ssh (dropbear).

Configurare l'interfaccia ADSL

Per verificare che la portante ADSL sia stata individuata e sincronizzata si può usare il file /proc/avalanche/avsar_modem_training:

cat /proc/avalanche/avsar_modem_training

Se il modem è riuscito a sincronizzarsi con il DSLAM in centrale si dovrebbe leggere “SHOWTIME”.

Per impostare i parametri di connessione usare i seguenti comandi, adattandoli ovviamente al proprio provider:

uci set network.wan=interface
uci set network.wan.ifname=nas0
uci set network.wan.proto=pppoa
uci set network.wan.encaps=vc
uci set network.wan.vpi=8
uci set network.wan.vci=35
uci set network.wan.username='username@provider'
uci set network.wan.password='latuapassword'
uci set network.wan.auto=1
uci set network.wan.keepalive=5,20
uci set qos.wan.download=4096
uci set qos.wan.upload=256
uci commit

Per fare in modo che l'ADSL venga attivata all'avvio del router, modificare /etc/init.d/network aggiungendo il comando ifup wan:

#!/bin/sh /etc/rc.common
# Copyright (C) 2006 OpenWrt.org

START=40
STOP=40

boot() {
        setup_switch() { return 0; }

        include /lib/network
        setup_switch
        [ -e /etc/config/wireless ] || \
                /sbin/wifi detect > /etc/config/wireless
        /sbin/wifi up
        ifup wan
}

Configurare il client dyndns

uci set updatedd.cfg1=updatedd
uci set updatedd.cfg1.ddns_service='dyndns'
uci set updatedd.cfg1.ddns_user='username'
uci set updatedd.cfg1.ddns_passwd='password'
uci set updatedd.cfg1.ddns_host='hostname.domain'
uci set updatedd.cfg1.ddns_update=1
uci commit

Impostare il fuso orario

Per impostare il fuso su Europe/Rome:

echo "CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00" > /etc/TZ

Riavvio

Per “portare a regime” il router è sufficiente riavviarlo:

reboot