Category: Linux

Namecheap DDNS Updates via DD-WRT

DD-WRT has limit support for different DDNS update mechanisms.
A simple workaround is the following script.

Login to your router and go to Administration > Commands

Add the following to the startup script, modifying it for your details

cat < /tmp/namecheap.sh
KEY="YOUR NAME CHEAP DIRTY LONG KEY"
DDNS_DOMAIN="feeditout.com"
DDNS_HOST="dave-pc"
IP=\$(curl ifconfig.co)

curl -s -o temp.html "http://dynamicdns.park-your-domain.com/update?domain=\$DDNS_DOMAIN&password=\$KEY&host=\$DDNS_HOST&ip=\$IP"
EOF

chmod +x /tmp/namecheap.sh
/tmp/namecheap.sh

Finally, go to the Administration > Management and add a crontab to update it hourly.

0 */1 * * * /tmp/namecheap.sh

Enjoy 😉


DD-WRT with CA Signed certificate, bundle and key

Surprisingly enough, finding new documentation on DD-WRT, with a custom certificate, is difficult.
Yes, there is information around, however it’s date years old which doesn’t inspire a lot of confidence.

Login to your DD-WRT front end.
Go to Management -> commands.

In the commands box, paste your keys like so.
Finally at the bottom choose ‘save startup’ and your are done.
If you are concerned about it going wrong, you can run it interactively on the console first to test 🙂

Enjoy

#!/bin/sh 

cat < /tmp/key.pem
-----BEGIN RSA PRIVATE KEY-----
## YOUR PRIVATE KEY HERE ##
-----END RSA PRIVATE KEY-----
EOF

cat < /tmp/cert.pem
-----BEGIN CERTIFICATE-----
## YOUR CERTIFICATE HERE ##
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
## YOUR INTERMEDIATE CERTIFICATE HERE ##
-----END CERTIFICATE-----
EOF

mount -o bind /tmp/cert.pem /etc/cert.pem 
mount -o bind /tmp/key.pem /etc/key.pem 

stopservice httpd 
startservice httpd 

Golang DD-WRT Bandwidth Usage with Conky

I setup a golang script to fetch the DD-WRT bandwidth usage for the previous 2 months, as well as the last 30 days(rolling).
Using conky then i can display it on my desktop.
My ISP (digiweb), don’t provide any means to check your bandwidth.
Picture at end of post 🙂

Golang DD-WRT script

package main

import (
    "fmt"
    "strconv"
    "net/http"
    "crypto/tls"
    "io/ioutil"
    "regexp"
    "time"
)

// You set these
var _ddwrt_ip = "10.1.1.1"
var _ddwrt_ssl = true
var _ddwrt_port = 443
var _ddwrt_user = "root"
var _ddwrt_pass = "password"

// don't set these
var _ddwrt_this_month = ""
var _ddwrt_last_month = ""

func printmonth(monthyear string) {
    tr := &http.Transport {
        TLSClientConfig: &tls.Config { InsecureSkipVerify: true },
    }

    client := &http.Client { Transport: tr }

    proto := "http"
    if _ddwrt_ssl == true {
      proto = "https"
    }

    req, err := http.NewRequest( "GET", proto + "://" + _ddwrt_ip + ":" + strconv.Itoa( _ddwrt_port ) + "/ttgraph.cgi?" + monthyear, nil )
    req.SetBasicAuth( _ddwrt_user, _ddwrt_pass )

    resp, err := client.Do( req )
    defer resp.Body.Close()

    if err != nil {
        fmt.Printf( "Error : %s", err)
    }

    if resp.StatusCode != 200 {
        fmt.Printf( "Error code: %s", strconv.Itoa( resp.StatusCode ) )
    }

    bodyBytes, err2 := ioutil.ReadAll( resp.Body )
    if err2 != nil {
        fmt.Printf( "Error : %s", err2 )
    }
    
    if len( _ddwrt_this_month ) == 0 {
        _ddwrt_this_month = string( bodyBytes )
    } else {
        _ddwrt_last_month = string( bodyBytes )
    }

    re := regexp.MustCompile( "(?s)
  • (.*?)
  • " ) matches := re.FindAllString( string( bodyBytes ), -1 ) rein := regexp.MustCompile( "(?s)Incoming: ([0-9]+)" ) reinmatches := rein.FindStringSubmatch( matches[0] ) reout := regexp.MustCompile( "(?s)Outgoing: ([0-9]+)" ) reoutmatches := reout.FindStringSubmatch( matches[0] ) fmt.Printf( "${goto 20}Down: %s ${goto 200}Up: %s\n", reinmatches[1], reoutmatches[1] ) } func parse30days() { var all = _ddwrt_last_month + _ddwrt_this_month re := regexp.MustCompile( "(?s)onmouseover=\"Show(.*?)onmouseout" ) matches := re.FindAllString( all, -1 ) var down int64 var up int64 var total int64 var days30 = 30 for i := len( matches )-1; i >= 0; i-- { reinout := regexp.MustCompile( "(?s)Incoming: ([0-9]+) MB / Outgoing: ([0-9]+) MB" ) inout := reinout.FindStringSubmatch( matches[i] ) r, _ := strconv.ParseInt( inout[1], 10, 64 ) if r == 0 { continue; } down = down + r t, _ := strconv.ParseInt( inout[2], 10, 64 ) up = up + t days30-- if days30 == 0 { break; } } total = down + up fmt.Printf( "\n${goto 20}Total 30 days:${goto 200}%d GB\n", total / 1024 ) } func main() { now := time.Now() monthyear := now.Format("01-2006") printmonth(monthyear) monthyear = now.AddDate(0,-1,0).Format("01-2006") printmonth(monthyear) parse30days() }

    Conky script Integration

    conky.config = {
        alignment = 'top_right',
        background = true,
        border_width = 1,
        cpu_avg_samples = 2,
    	default_color = 'white',
        default_outline_color = 'white',
        default_shade_color = 'white',
        draw_borders = false,
        draw_graph_borders = true,
        draw_outline = false,
        draw_shades = false,
        use_xft = true,
        font = 'DejaVu Sans Mono:size=12',
        gap_x = 50,
        gap_y = 50,
        double_buffer = true,
        minimum_height = 5,
    	minimum_width = 5,
        net_avg_samples = 2,
        no_buffers = true,
        out_to_console = false,
        out_to_stderr = false,
        extra_newline = false,
        own_window = true,
        own_window_class = 'Conky',
        own_window_type = 'desktop',
        own_window_transparent = true,
        stippled_borders = 0,
        update_interval = 3.0,
        uppercase = false,
        use_spacer = 'none',
        show_graph_scale = false,
        show_graph_range = false
    }
    
    conky.text = [[
    $sysname $kernel on $machine
    ${hr 2}
    
    ${color grey}Uptime:$color $uptime
    ${color grey}Frequency (in MHz):$color $freq
    ${color grey}Frequency (in GHz):$color $freq_g
    ${color grey}RAM Usage:$color $mem/$memmax - $memperc% ${membar 4}
    ${color grey}Swap Usage:$color $swap/$swapmax - $swapperc% ${swapbar 4}
    ${color grey}CPU Usage:$color $cpu% ${cpubar 4}
    ${color grey}Processes:$color $processes  ${color grey}Running:$color $running_processes
    
    
    ${color}File Systems
    ${hr 2}
    
    /${goto 80}$color${fs_used /}/${fs_size /} ${goto 250}${fs_bar 6 /}
    /home${goto 80}$color${fs_used /}/${fs_size /home} ${goto 250}${fs_bar 6 /home}
     
    ${color}Networking
    ${hr 2}
    
    ${goto 20}Up:$color ${upspeed wlp3s0} ${goto 200}${color grey}Down:$color ${downspeed wlp3s0}
    ${goto 20}${upspeedgraph wlp3s0 26,140 FFFFFF FFFFFF}${goto 200}${downspeedgraph wlp3s0 26,140 FFFFFF FFFFFF}
    ${execpi 3600 /usr/bin/go run /home/dave/.conky/ddwrt-bandwidth.go}
    
    ${color}Processes
    ${hr 2}
    
    Name                PID   CPU%   MEM%
    ${color lightgrey} ${top name 1} ${top pid 1} ${top cpu 1} ${top mem 1}
    ${color lightgrey} ${top name 2} ${top pid 2} ${top cpu 2} ${top mem 2}
    ${color lightgrey} ${top name 3} ${top pid 3} ${top cpu 3} ${top mem 3}
    ${color lightgrey} ${top name 4} ${top pid 4} ${top cpu 4} ${top mem 4}
    ${color lightgrey} ${top name 5} ${top pid 5} ${top cpu 5} ${top mem 5}
    ${color lightgrey} ${top name 6} ${top pid 6} ${top cpu 6} ${top mem 6}
    ${color lightgrey} ${top name 7} ${top pid 7} ${top cpu 7} ${top mem 7}
    ${color lightgrey} ${top name 8} ${top pid 8} ${top cpu 8} ${top mem 8}
    ${color lightgrey} ${top name 9} ${top pid 9} ${top cpu 9} ${top mem 9}
    
    ]]
    

    Enjoy
    rolling


    Debian SID Opendmarc Installation and Configuration

    In this post i will capture the installation of opendmarc and how its configure alongside Opendkim.

    Install opendmarc

    apt-get install opendmarc

    Configure systemd service file

    cat > /lib/systemd/system/opendkim.service <<EOT
    [Unit]
    Description=OpenDMARC Milter
    Documentation=man:opendmarc(8) man:opendmarc.conf(5)
    After=network.target nss-lookup.target 
    
    [Service]
    EnvironmentFile=/etc/default/opendmarc
    Type=forking
    PIDFile=/var/run/opendmarc/opendmarc.pid
    User=opendmarc
    ExecStart=/usr/sbin/opendkim -p $SOCKET -x /etc/opendmarc.conf -u opendmarc -P /var/run/opendmarc/opendmarc.pid
    Restart=on-failure
    ExecReload=/bin/kill -USR1 $MAINPID
    
    [Install]
    WantedBy=multi-user.target
    EOT

    The specific changes here are lines #9 EnvironmentFile #13 -p $SOCKET

    Defaults File

    cat > /etc/default/opendmarc <<EOT
    SOCKET="inet:12302@localhost"
    EOT

    Opendmarc Config file

    cat > /etc/opendmarc.conf <<EOT
    AuthservID example.com
    PidFile /var/run/opendmarc.pid
    #RejectFailures false
    Syslog true
    SyslogFacility mail
    UMask 0002
    UserID opendmarc:opendmarc
    TemporaryDirectory /tmp
    AutoRestart true
    EOT

    Modify Postfix milters
    If you are running both opendkim and opendmarc your milters will look like this:

    non_smtpd_milters = inet:127.0.0.1:12301, inet:127.0.0.1:12302
    smtpd_milters = inet:127.0.0.1:12301, inet:127.0.0.1:12302
    

    Restart the service

    systemctl daemon-reload
    systemctl restart opendmarc
    systemctl restart postfix
    

    DNS

    Now go modify your DNS, adding a TXT record ‘_dmarc‘with the value ‘v=DMARC1; p=none; rua=mailto:postmaster@example.com

    When you have validated dmarc is working properly you can change p=none to p=reject

    How can you validate it?

    There are a number of tools online to help you with this, also you open up a mail in google and click ‘show original’.

    screenshot_2016-11-20_12-32-23
     

    Enjoy

    Other resources
    https://www.google.com/search?q=opendkim+setup

    https://www.google.com/search?q=opendmarc+setup

     


    Debian SID Opendkim Installation and Configuration Woes

    TL;DR Opendkim. Hats off the to folk who do marvelous packing 99.99999% percent of the time.

    But sometimes they just get it wrong or at least all documentation regarding the package, does not match up with the behavior the packager intended.
    That said, hopefully i will help solve some of these issues here.

    I assume you have postfix already working and you are just looking to add dkim support.

    Install opendkim

    apt-get install opendkim opendkim-tools

    Configure systemd service file

    cat > /lib/systemd/system/opendkim.service <<EOT
    [Unit]
    Description=OpenDKIM DomainKeys Identified Mail (DKIM) Milter
    Documentation=man:opendkim(8) man:opendkim.conf(5) man:opendkim-genkey(8) man:opendkim-genzone(8) man:opendkim-testadsp(8) man:opendkim-testkey http://www.opendkim.org/docs.html
    After=network.target nss-lookup.target 
    
    [Service]
    EnvironmentFile=/etc/default/opendkim
    Type=forking
    PIDFile=/var/run/opendkim/opendkim.pid
    User=opendkim
    ExecStart=/usr/sbin/opendkim -P /var/run/opendkim/opendkim.pid -p $SOCKET
    Restart=on-failure
    ExecReload=/bin/kill -USR1 $MAINPID
    
    [Install]
    WantedBy=multi-user.target
    EOT

    The specific changes here are lines #9 EnvironmentFile #13 -p $SOCKET

    Defaults File

    cat > /etc/default/opendkim <<EOT
    SOCKET="inet:12301@localhost"
    EOT

    Opendkim Config file

    cat > /etc/opendkim <<EOT
    Mode                sv
    Syslog              yes
    SyslogSuccess       yes
    LogWhy              yes
    #Socket              inet:12301@localhost
    Umask               002
    SendReports         yes
    SoftwareHeader      yes
    Canonicalization    relaxed/relaxed
    Selector            default
    MinimumKeyBits      1024
    KeyTable            refile:/etc/dkimkeys/KeyTable
    SigningTable        refile:/etc/dkimkeys/SigningTable
    ExternalIgnoreList  refile:/etc/dkimkeys/TrustedHosts
    OversignHeaders     From
    TrustAnchorFile     /usr/share/dns/root.key
    EOT

    Specific changes here are lines #7 hashed out socket file,  it simply does not work.
    The only way to get opendkim to honour this setting is passing it to the command line #13 of the service file.

    Modify /etc/postfix/main.cf and add/edit the following lines

    smtpd_milters = inet:localhost:12301
    non_smtpd_milters = inet:localhost:12301

    Create referenced folders for your open dkim keys

    mkdir -vp /etc/dkimkeys/keys

    TrustedHosts

    cat > /etc/dkimkeys/TrustHosts <<EOT
    127.0.0.1
    ::1
    localhost
    example.com
    *.exmaple.com
    EOT

    SingingTable

    cat > /etc/dkimkeys/SigningTable <<EOT
    *@exmaple.com default._domainkey.example.com
    EOT

    KeyTable

    cat> /etc/dkimkeys/KeyTable <<EOT
    default._domainkey.example.com example.com:default:/etc/dkimkeys/keys/default.private
    EOT

    Create private/public key for signing

    cd /etc/dkimkeys/keys
    opendkim-genkey -s default
    

    Your directory should now look like this

    Opendkim Treeview of files

    Tell systemd to reload the the daemon files and restart

    systemctl daemon-reload
    systemctl restart opendkim
    systemctl restart postfix

    DNS

    Now go modify your DNS, adding a TXT record ‘default._domainkey‘.
    Copy and paste everything between the parenthesis. ( everything here ) into the value field of the TXT record

    cat keys/default.txt 
    default._dkim   IN      TXT     ( "v=DKIM1; k=rsa; "
              "p=MIGfMA0GCSqGSIGNA....BIG LONG DIRTY HASH ....ciaxOhS24T4MFwIDAQAB" )  ; ----- DKIM key default for com
    

    Enjoy

    Other resources
    https://www.google.com/search?q=opendkim+setup