1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Tomato + DNSSEC

Discussion in 'Tomato Firmware' started by lancethepants, Oct 22, 2013.

  1. lancethepants

    lancethepants Network Guru Member

    This tutorial will show you how to setup dnssec aware tomato using unbound.

    I've setup unbound to run from /jffs, and have compiled it to look in /jffs for configuration files by default.
    I think it's best to run from /jffs since this will be a system critical service. I've had external storage devices fail to mount in tomato, in some cases requiring me to unplug the router to get them to mount again (Simple reboot wouldn't do it).
    My instructions assume you are running from /jffs, and WILL need modification if you are not.

    Binaries available at http://lancethepants.com/files

    1. Download the unbound binaries.
    Place 'unbound' if '/jffs/sbin/'
    The rest of the binaries you can place on external media if you don't have much space in /jffs.
    Also download the 'hostip' utility found in the dnscrypt area, and also place it in /jffs/sbin.



    2. Create the configuration directory, and do some setup with the following commands.

    Code:
    mkdir -p /jffs/etc/unbound
    /path/to/unbound-anchor
    /path/to/unbound-control-setup
    wget ftp://FTP.INTERNIC.NET/domain/named.cache -O /jffs/etc/unbound/root.hints
    


    3. The following is the config I'm using with unbound. I'm using Comcast dns which is dnssec aware. I've also included google dns commented in the config.
    If you use something else, make sure that it is dnssec aware, or it won't work.
    I am also using IPv6, so you can comment out the IPv6 lines if you are not.

    /jffs/etc/unbound/unbound.conf
    Code:
    #Unbound conf file
    server:
            extended-statistics: yes
            verbosity: 1
            num-threads: 1
            port: 40
            username: "root"
            directory: "/jffs/etc/unbound"
            pidfile: "/var/run/unbound.pid"
            root-hints: "/jffs/etc/unbound/root.hints"
            prefetch: yes
            prefetch-key: yes
            auto-trust-anchor-file: "/jffs/etc/unbound/root.key"
    
    remote-control:
            control-enable: yes
    
    forward-zone:
    #        Comcast DNS
            name: "."
            forward-addr: 75.75.75.75
            forward-addr: 75.75.76.76
            forward-addr: 2001:558:feed::2
            forward-addr: 2001:558:feed::1
        
    #        Google DNS
    #        forward-addr: 8.8.8.8
    #        forward-addr: 8.8.4.4
    #        forward-addr: 2001:4860:4860::8888
    #        forward-addr: 2001:4860:4860::8844
    
    Unbound will also be keeping our DNS cache. Dnsmasq by default keeps a paltry 150 DNS entries (hardly anything I think). Unbound by default holds 4 Megabytes. Dnssec entries I think need more space anyway. Both can be adjusted though.
    The unbound documentation also has a "MEMORY CONTROL EXAMPLE" that use less cache. My config uses the default amount.
    Even with unbound running, I've never seen memory usage more than ~35 Mbytes, and that's including aseterisk and OpenSSH I'm also running on my router (RT-N16).
    I think DNS cache is a very justifiable use of memory anyway, and most our modern routers have plenty.



    4 The following script helps solve a chicken/egg scenario with helping the router to set the time. This make use of the hostip binary.
    I've called it 'ntp_resolve.sh' and have placed it in /jffs.

    /jffs/ntp_resolve.sh
    Code:
    #!/bin/sh
    
    for server in $(nvram get ntp_server)
    do
        addresses=$(/jffs/sbin/hostip $server)
    
        for address in $addresses
        do
            echo $address $server >> /tmp/etc/hosts
        done
    done
    
    Test ntp_resolve.sh, and make sure you see additional entries in /etc/hosts.



    5. Go ahead and start unbound with the following.

    Code:
    /jffs/sbin/unbound
    


    6. We'll then tell DNSmasq you use unbound as its upstream server, with the following additional config.

    Advanced -> DHCP/DNS -> Dnsmasq Custom configuration
    Code:
    cache-size=0
    proxy-dnssec
    server=127.0.0.1#40
    no-resolv
    no-poll
    


    7. To get it all working on boot, use the following Wan UP script.

    Administration -> Scripts -> Wan Up
    Code:
    /jffs/ntp_resolve.sh
    /jffs/sbin/unbound
    


    On a computer behind the router, you can test it with the following.

    Code:
    dig com. SOA +dnssec
    
    You should see the 'ad' flag
     
    Last edited: Oct 22, 2013
    darkknight93, lefty and szpunk like this.
  2. MassiveCollision

    MassiveCollision Reformed Router Member

    What options did you compile unbound with?

    I'm running Shibby without JFFS support so I'm trying to run it from a usbdrive.
    Instead of /jffs/ my base-path is /tmp/mnt/USBDRIVE/unbound/.

    I'm compiling from the official 1.4.21 sources with:
    Code:
    ./configure --prefix=/tmp/mnt/USBDRIVE/unbound && make
    I basically get binaries of way different sizes than yours. Also my unbound-anchor isn't right, as it's only 7.8KB instead of around 925KB and gives a "not found" error when trying to run.
     
  3. lancethepants

    lancethepants Network Guru Member

    I compile my binaries using the entware toolchain. https://code.google.com/p/wl500g-repo/
    Since entware has different libraries than tomato, I create static libraries so that they don't have any external dependencies. This may account for some larger binaries.

    I compiled with prefix=/jffs.

    Afterwards I compress the binaries with upx, which does a pretty good job. Almost always compresses to a fraction of their original size. http://upx.sourceforge.net/

    Below is the actual script I use. For OpenSSL I take from a pre-compiled version of my project tomatoware. https://github.com/lancethepants/tomatoware

    Code:
    #!/bin/bash
    
    mkdir ~/unbound && cd ~/unbound
    
    BASE=`pwd`
    SRC=$BASE/src
    WGET="wget --prefer-family=IPv4"
    PATCHES=$BASE/patches
    RPATH=/jffs/lib
    DEST=$BASE/jffs
    LDFLAGS="-L$DEST/lib -s -Wl,--dynamic-linker=/jffs/lib/ld-uClibc.so.0 -Wl,-rpath,$RPATH -Wl,-rpath-link,$DEST/lib"
    CPPFLAGS="-I$DEST/include -I$DEST/include/ncurses"
    CFLAGS="-mtune=mips32 -mips32 -O3"
    CONFIGURE="./configure --prefix=/jffs --host=mipsel-linux"
    MAKE="make -j`nproc`"
    mkdir -p $SRC
    
    ########### #################################################################
    # OPENSSL # #################################################################
    ########### #################################################################
    
    make install CC=mipsel-linux-gcc AR="mipsel-linux-ar r" RANLIB=mipsel-linux-ranlib INSTALLTOP=$DEST OPENSSLDIR=$DEST/ssl
    
    ######### ###################################################################
    # EXPAT # ###################################################################
    ######### ###################################################################
    
    mkdir $SRC/expat && cd $SRC/expat
    $WGET http://downloads.sourceforge.net/project/expat/expat/2.1.0/expat-2.1.0.tar.gz
    tar zxvf expat-2.1.0.tar.gz
    cd expat-2.1.0
    
    LDFLAGS=$LDFLAGS \
    CPPFLAGS=$CPPFLAGS \
    CFLAGS=$CFLAGS \
    $CONFIGURE \
    --enable-static \
    --disable-shared
    
    $MAKE
    make install DESTDIR=$BASE
    
    ######## ####################################################################
    # LDNS # ####################################################################
    ######## ####################################################################
    
    mkdir $SRC/ldns && cd $SRC/ldns
    $WGET http://www.nlnetlabs.nl/downloads/ldns/ldns-1.6.16.tar.gz
    tar zxvf ldns-1.6.16.tar.gz
    cd ldns-1.6.16
    
    LDFLAGS=$LDFLAGS \
    CPPFLAGS=$CPPFLAGS \
    CFLAGS=$CFLAGS \
    $CONFIGURE \
    --enable-static \
    --disable-shared
    
    $MAKE
    make install DESTDIR=$BASE
    
    ########### #################################################################
    # UNBOUND # #################################################################
    ########### #################################################################
    
    mkdir $SRC/unbound && cd $SRC/unbound
    $WGET http://unbound.net/downloads/unbound-1.4.21.tar.gz
    tar zxvf unbound-1.4.21.tar.gz
    cd unbound-1.4.21
    
    LDFLAGS="-Wl,-static -static -static-libgcc $LDFLAGS" \
    CPPFLAGS=$CPPFLAGS \
    CFLAGS=$CFLAGS \
    $CONFIGURE
    
    $MAKE
    make install DESTDIR=$BASE/unbound
    
    
    It is possible to use my binaries with your setup. You just need to pass unbound the location of your config file with the '-c' option.
     
  4. ryzhov_al

    ryzhov_al Networkin' Nut Member

    Try to add
    Code:
    CFLAGS += -ffunction-sections -fdata-sections
    LDFLAGS += -Wl,--gc-sections
     
  5. koitsu

    koitsu Network Guru Member

    Also be careful using things like MAKE="make -j`nproc`". You will be quite surprised how much open-source software using GNU autotools and GNU libtool break in bizarre/uncomfortable ways when using -jX where X > 1.

    I just had to rebuild a lot of our tools at my workplace to link against newer OpenSSL and spent almost an entire day on one single application, trying to track down why occasionally during linktime -l{libname} lines would be omitted/missing. Turns out the libtool version used by the software author was horribly broken with regards to use of parallel make, and the problem disappeared using -j1. As I progressed through all the packages that needed to be rebuilt, I ran into this a good 6 or 7 times. In our build scripts, I had to explicitly use -j1 and of course put a comment in explaining that use of such is justified for said package/program.

    Point is: don't get in the habit of using -jX everywhere, esp. when GNU autotools or GNU libtool are involved, as more often than not, the software comes with configure/libtool scripts and exclusively rely on those.
     
  6. MassiveCollision

    MassiveCollision Reformed Router Member

    Thanks for the script, (almost) worked like a treat! :)

    But I have an OpenSSL issue where unbound-control-setup throws an error when trying to generate unbound_server.key and unbound_control.key:
    Code:
    generating unbound_server.key
    openssl:Error: 'genrsa' is an invalid command.
    Same error with the version command on the router in OpenSSL:
    Code:
    OpenSSL> version
    openssl:Error: 'version' is an invalid command.
    
    Standard commands
    enc            req            rsa            x509      
    
    Cipher commands (see the `enc' command for more details)
    aes-128-cbc    aes-128-ecb    aes-192-cbc    aes-192-ecb    aes-256-cbc
    aes-256-ecb    bf-cbc        bf-ecb 
    What am I missing here? Weird OpenSSL version?

    EDIT:
    Okay, this now works beautifully with Google servers and the entware toolchain in /opt (I mounted it on my usbdrive to /opt) with OpenSSL 1.0.1e included, as unbound-control-setup definately needs it to generate keys.
     
    Last edited: Nov 17, 2013
  7. koitsu

    koitsu Network Guru Member

    @MassiveCollision - the OpenSSL build that comes with the base system is extremely compact/miniature (because OpenSSL is a gargantuan beast) due to flash space limitations of many routers, so many of the OpenSSL client commands -- such as "genrsa", in addition to many ciphers, are disabled. The Entware etc. versions are more complete.
     
  8. lancethepants

    lancethepants Network Guru Member

    Using ryzhov_al suggestion and couple other tricks I've made some binaries that are significantly smaller.
    I added the following as suggested
    Code:
    CFLAGS += -Os -ffunction-sections -fdata-sections
    LDFLAGS += -Wl,--gc-sections
    
    Adding the -Os flag also.

    I then ran 'mipsel-linux-strip' on the resulting binaries, shaving a bit off all of them.

    Than I compressed them with "upx --ultra-brute".

    Cumulitively, I reduced binary sized from ~4.4MB to ~3.0MB
     
  9. leandroong

    leandroong Addicted to LI Member

    .
     
    Last edited: Dec 31, 2014
  10. lancethepants

    lancethepants Network Guru Member

    Now that dnsmasq now supports dnssec, this isn't necessary unless you specifically want to run unbound. Shibby and Victek both have included my dnssec integration. Toastman has not yet, though I've made some builds that do on my site.
     
  11. leandroong

    leandroong Addicted to LI Member

    .
     
    Last edited: Dec 31, 2014

Share This Page