Monday, May 23, 2011

RPKI certificates

Resource certificates are defined in the SIDR resource certificate profile specification. In this second part of the series, we'll start analysing a set of certificates from the AfriNIC repository (rsync:// from the top. We'll visit the trust anchor locator, trust anchor certificate, RIR certificate and an LIR certificate. An important point to note is that each certificate is a CA certificate with the exception of embedded end entity certificates.

Trust Anchor Locator

A trust anchor as a trusted entry point of any PKI is expected to be stable over time. However, the current practice has RIRs running their own roots with their resources specified in the root cert.

If an RIR receives an allocation, they have to issue a new certificate that contains the new resources which will have to be propagated to validators. Taking the case of IPV4, 17 blocks were allocated in a span of a year (2009). This corresponds to 1 trust anchor change every 21 days on average. On top of this, certificates have time constraints which will induce certificate re-issues due to expiry.

The TAL format is specified in the SIDR TA draft to work around these issues. Essentially, the TAL contains the rsync URI of the root certificate with rfc3779 extensions and the public key component of that certificate. These two are separated using a [CR]LF According to the specification, the public key is ``a base 64-encoded, DER-encoded X.509 subjectPublicKeyInfo [RFC5280]''.

It can easily be generated by using shell utilities and OpenSSL.
Since the TAL doesn't have resources and time constraints, It can be long lived requiring change when the key is rolled.

Here is the AfriNIC TAL.

Root certificate

The root certificate sits at the root of the Resource PKI. It contains all the resources suballocated in the tree below it. In an ideal world, there would be the one root certificate and it's number resources would be:
  • 0/0 for IPV4
  • 0/0 for IPV6
  • 1-4294967296 for AS numbers
Unfortunately, in the current structure, each RIR is running it's own root and encoding it's resources only. So for example, the AfriNIC certificate will only contain IANA's allocation to AfriNIC.

In the figure on the first post, the first dashed rectangle represents the root repository. It contains all the certificates issued by the root, a CRL and a manifest for this repository. This structure is replicated across the entire PKI tree that is, each certificate has a repository that is accessible over rsync and contains: 
  • A CRL.
  • A manifest.
  • Zero or more products (ROAs, AAAs...) in it's repository.
  • Certificates for sub CAs.
An example certificate can be seen below. It's highlights are:
  • Self signed which implies that it's a root certificate.
  • The location of the repository and manifest are encoded in the certificate.
  • The certificate has x509 CA extensions (Green sections).
  • Has rfc3779 extensions (sbgp-* sections). 
AfriNIC root certificate

Resource certificate

The root certificate is a special case of the resource certificate. A non root resource certificate has:
  • A parent - Authority Information Access in a certificate.
  • Zero or more children - Subject Information Access is a pointer to a store with this certificate's children.
  • Zero or more - Subject Information Access also points to a store with this certificate's products. products. 

 An example tree is shown below. In this case, the root certificate shown above issues the RIR certificate in figure below which in turn issues the LIR certificate in the last figure. Please note that relationship between the certificates as indicated by the colour coding.

RIR Certificate

LIR Certificate

Suppose I wanted to block facebook.

Suppose you have access to your firewall and you want to block Facebook.
Then you need to get their prefixes which you can find out their ASN.

You can find out their asn from traceroute:
$  traceroute -n -A
14 [AS3356]  630.713 ms  633.180 ms [AS3356]  629.633 ms
15 [AS3356]  578.959 ms  580.703 ms  579.624 ms
16 [AS32934/AS10753]  577.604 ms  557.247 ms  636.807 ms
17 [AS32934]  633.454 ms [AS32934]  602.556 ms  603.583 ms
18 [AS32934]  634.461 ms [AS32934]  634.431 ms [AS32934]  702.079 ms
19 [AS32934/AS10753]  701.423 ms  700.644 ms  700.937 ms
Which you can verify with tools such as these
$ dig +short TXT
"32934 | US | arin | 2004-08-24 | FACEBOOK - Facebook, Inc."
Then you'd get their prefixes using a lookup service
$ lynx --dump 2>&1 | grep AS32934
   IPv4 Prefixes seen at AS32934:       [AS32934]
     2620:0:1c00::/40     [AS32934]      [AS32934]      [AS32934]      [AS32934]      [AS32934]      [AS32934]      [AS32934]      [AS32934]       [AS32934]       [AS32934]       [AS32934]
You can then feed the prefixes into your firewall.
Of course, If I was a determined user, I could use any of the free proxies out there rendering this whole post moot (DPI anyone?).

Screen capture in X

This is the cheapest screen capture in town. It's also probably installed right now and you can get it to work in seconds.

Use xwd which is the X Window Dumper to capture your desktop/window.
Use ImageMagick's convert to convert the xwd into a png/jpg etc
Collate the images into a video using mencoder

xwd is found in  x11-apps under debian.
convert is part of the ImageMagick suite.
mencoder is part of the mplayer suite.

So open a terminal, cd into a work dir and start capturing screenshots at 5fps.

while :; 
    xwd -root |convert - blah-$(date +%s.%N).png; 
    sleep 0.2; 
Then go do your stuff... Much later ctrl-c the while loop to terminate it and create your capture
mencoder "mf://*.png" -mf fps=5 -o output.avi -ovc lavc -lavcopts vcodec=mpeg4
You can also speed up your screencap by faking the fps. Make it 50 in the mencoder command above and see.

It should be pretty trivial to record a separate audio stream and add it to your video

Libvirt cheatsheet

Remote connection over ssh
virt-manager -c qemu+ssh://root@

In the installation/cloning examples below, I precreated LV using lvcreate. The path's given point to the LVs (For example /dev/xen02/member.root)
Installing without virtio might end up with a slow VM.

virt-install --name=member \
--ram 1024 \
--os-type linux --os-variant debianlenny \
--file /dev/xen02/member.root \
--network network=default \
--vnc \
--noautoconsole \
--hvm \
--cdrom /home/lmwangi/debian-505-amd64-netinst.iso
--force yes

Virtio speeds up things a lot.
virt-install --name=nms01 \
--ram 512 \
--os-type linux --os-variant debianlenny \
--disk path=/dev/dm-8,bus=virtio \
--network network=default,model=virtio \
--vnc \
--noautoconsole \
--cdrom /home/lmwangi/debian-505-amd64-netinst.iso
--virt-type kvm \
--force yes

Cloning is easy. Create/Install a template VM and clone it to create your workhorses.

virt-clone \
--prompt \
--connect qemu:///system \
--original template \
--name "champ" \
--file /dev/xen02/champ.root

By default, your default network should be started.
virsh net-start default && virsh net-autostart default
You can also view an existing VM's definition.
# virsh net-dumpxml default


You can also hotplug disks. The VM wasn't stable though :(

virsh # detach-disk
error: command 'detach-disk' requires option
error: command 'detach-disk' requires option
virsh # detach-disk nosql vdb
Disk detached successfully

virsh # attach-disk nosql /dev/xen02/ vdb
Disk attached successfully
On the VM, you may need to
modprobe acpiphp

Occasionally, I have legacy VMs that were not properly created (Someone bypassed libvirt.) Cloning is a pain. In essence, I create a similar LV (same size), define a VM using the new LV and then dd over the LV
[root@vm01 ~]# lvdisplay cnix/box1_root
--- Logical volume ---
LV Name /dev/cnix/box1_root
VG Name cnix
LV UUID xxxx-xxxx.....
LV Write Access read/write
LV Status available
# open 1
LV Size 19.53 GB
Current LE 5000
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:12
[root@vm01 ~]# lvcreate -L 19.53G -n signer sdbvg
Rounding up size to full physical extent 19.53 GB
Logical volume "signer" created

[root@vm01 ~]# virt-clone --prompt --original legacy1 --name signer --file /dev/sdbvg/signer.root --file /dev/sdbvg/signer.swap
This will overwrite the existing path '/dev/sdbvg/signer.root'!
Do you really want to use this disk (yes or no) yes
This will overwrite the existing path '/dev/sdbvg/signer.swap'!

Do you really want to use this disk (yes or no) yes
Cloning /dev/cnix/legacy1_root | 20 GB 02:11
Cloning /dev/cnix/legacy1_swap | 2.0 GB 00:08

Clone 'signer' created successfully.
Sometimes this is not always flawless
virt-clone --prompt --original master --name master1 --file /dev/sdbvg/master1.root --file /dev/sdbvg/master1.swap
ERROR Domain 'master' was not found.
What is the name of the original virtual machine? master
ERROR Domain 'master' was not found.
What is the name of the original virtual machine? legacy1
ERROR Domain 'legacy1' was not found.
What is the name of the original virtual machine? ERROR

So we have to dd the image to the new hdd
[root@vm01 ~]# dd if=/dev/cnix/legacy1_root of=/dev/sdbvg/master1.root
dd if=/dev/cnix/legacy2_root of=/dev/sdbvg/member.root
40960000+0 records in
40960000+0 records out
20971520000 bytes (21 GB) copied, 1237.21 seconds, 17.0 MB/s
And boot the new VM

Friday, May 20, 2011

Precedence for IPv4 vs IPv6

You can use /etc/gai.conf to set up your IPV4/IPV6 precedence as documented here and here.

Say we have two hosts and
$ host is an alias for has address has IPv6 address 2001:470:0:76::2

$ host has address has IPv6 address 2001:67c:2e8:22::c100:68b
Case 1: Prefer IPV4
Append the following to /etc/gai.conf
precedence ::ffff:0:0/96  100
then we have:
$ telnet 80
$ telnet 80
Case 1: Prefer IPV6 for specific hosts
If we append
precedence 2001:470::/32 100
then we have
$ telnet 80
$ telnet 80
Trying 2001:470:0:76::2...
So we seem to prefer that network for ipv6 and ipv4 everywhere else.

Case 3: Prefer ipv4 for specific hosts
Wondering if we invert the mask the reverse will be true.

Tuesday, May 17, 2011

It's all in the stars

Astrology is the prostitution of mathematics.
Galileo character - Galileo's Dream

Decrypting SSL using tshark/wireshark

I was banging my head on the keyboard last week trying to figure out why wireshar/tshark was not decrypting my SSL packets. Turns out that you cannot do this if the key exchange is Diffie-Hellman. You can get around this by telling the server to ignore DH, In apache's case, changing the SSLCipherSuite to something like:

The server hello changes from
Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039)


Cipher Suite: TLS_RSA_WITH_RC4_128_SHA (0x0005)

 tshark   -o "ssl.desegment_ssl_records: TRUE" -o "ssl.desegment_ssl_application_data: TRUE" -o "ssl.keys_list:,443,http,/path/to/server.key.pem" -o "ssl.debug_file: /tmp/wireshark-log" -r /path/to/example.pcap  -V| awk '/^Frame.*/;/Source: 2/;/Secure Socket Layer.*/,/^$/;' |tail -n 40

     Version: TLS 1.0 (0x0301)
        Length: 61
        Encrypted Application Data: 6C6423B17A7211C8F8E9E60B5F726D0C7C40B5645B234A36...
    SSL segment data (41 bytes)
[Reassembled SSL Segments (227 bytes): #60(186), #60(41)]
    [Frame: 60, payload: 0-185 (186 bytes)]
    [Frame: 60, payload: 186-226 (41 bytes)]
Hypertext Transfer Protocol
    HTTP/1.1 200 Script output follows\r\n
        [Expert Info (Chat/Sequence): HTTP/1.1 200 Script output follows\r\n]
            [Message: HTTP/1.1 200 Script output follows\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Request Version: HTTP/1.1
        Response Code: 200
    Date: Mon, 16 May 2011 13:41:11 GMT\r\n
    Server: Apache/2.2.8 (CentOS)\r\n
    Content-Length: 41\r\n
        [Content length: 41]
    Connection: close\r\n
    Content-Type: application/mercurial-0.1\r\n
Media Type
    Media Type: application/mercurial-0.1 (41 bytes)

Monday, May 2, 2011

Dammit, read the output...

I keep forgetting to read the output of  commands
$ gdb apache2 /tmp/gdb/core
GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
warning: The current binary is a PIE (Position Independent Executable), which
GDB does NOT currently support.  Most debugger features will fail if used
in this session.

Reading symbols from /usr/sbin/apache2...Reading symbols from /usr/lib/debug/usr/sbin/apache2-mpm-prefork...done.
(no debugging symbols found)...done.
Core was generated by `/usr/sbin/apache2 -k start'.
Program terminated with signal 11, Segmentation fault.
#0  0x00007f9779b25c4f in ?? ()
(gdb) bt
#0  0x00007f9779b25c4f in ?? ()
#1  0x00007fc05b93c8b0 in ?? ()
#2  0x0000000000000007 in ?? ()
#3  0x0000000000000000 in ?? ()
(gdb) where
#0  0x00007f9779b25c4f in ?? ()
#1  0x00007fc05b93c8b0 in ?? ()
#2  0x0000000000000007 in ?? ()
#3  0x0000000000000000 in ?? ()
(gdb) quit
root@acme:~# apt-get install apache2-mpm-worker
Turns out that squeeze's gdb doesn't support PIE, pulling in SID's copy works
$ gdb -p 21164
GNU gdb (GDB) 7.2-debian
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
.                                                                                                   Attaching to process 21164
Reading symbols from /usr/lib/apache2/mpm-worker/apache2...Reading symbols from /usr/lib/debug/usr/lib/apache2/mpm-worker/apache2-mpm-worke
Reading symbols from /lib/ debugging symbols found)...done.
Loaded symbols for /lib/
Reading symbols from /usr/lib/ debugging symbols found)...done.
Loaded symbols for /usr/lib/
Reading symbols from /usr/lib/libapr-1 .....