Google

July 19, 2006

Sodium in water? Bah..try Caesium!

Back at high school, I took chemistry, and one class proved to be very memorable.

It involved the old sodium-in-water experiment, where you get a rice-sized piece of sodium and put it in a little bit of water and marvel at it fizzing around, reacting with the water. During this class, me and Affa decided to super-size it, chopping off a piece of sodium as large as an M&M. At the time, we were allowed to do it ourselves, but they banned students doing it after our attempt...

Into the water it went, and the little chunk quickly melted and started dancing on the water. Suddenly - it caught fire! This large blob of molten sodium was spitting sparks all over the bench, giving of white fumes - that's all we expected to happen. Then in an instant - BOOM! - the thing exploded, sending a mushroom cloud into the ceiling, and burning chunks of sodium across the room, giving one guy a couple of impressive holes in his shirt!

We stared in amazement for half a second before it registered, and the entire room fell silent. "Whoa!", came the Neo-esque cry. The teacher, who'd been out of the room at the time, quickly rushed back in to see what caused this earth shattering kaboom and his first glance was at us two - evidently he knew instinctively that it was us. Stifling his own laughter, he banned us from lab for a week, and gave us a puny punishment of 100 lines of "I will not put explosive quantities of sodium into water", but this punishment was more out of procedure - our "thinking outside the box" seemed to impress him more than anything else. The blast marks on our lab notebooks gave some graphics to our results section, and we ended up getting nearly top marks for that lab - minus a point for "unsafe method".

Which brings me to this video of two of the most reactive metals in existence, getting the water treatment. Our puny explosion is nothing compared to this stuff! Good ol' Brainiac...

Posted by Ben at 08:51 PM | Comments (0)

July 15, 2006

I'm off to Lugradio

I'm going to LugRadio Live 2006

Posted by Ben at 09:50 AM | Comments (0)

July 08, 2006

Food for thought...

From Slashdot:

George W. Bush has neither committed, nor ordered to have committed a single Act of Terror.

1. Terrorism: the systematic use of terror especially as a means of coercion. [OED]

2. Bush took the U.S. to a pre-emptive war without the approval of Congress.

3. Shock and Awe was used to corce Iraqis into civil war.

Hmmmmmmm...

Posted by Ben at 12:39 AM | Comments (0)

July 07, 2006

Replacing ugly Helvetica fonts in Xorg

Helvetica, as implemented on most operating systems, is very ugly.

This beautiful font has always been the ugly duckling of fonts under Linux because of the status of its implementations. Due to licencing, proper scaling implementations of the font are very expensive, so instead of nice truetype Helvetica, it's normally only possible to use bitmapped versions of the font, which have no antialiasing and are thus very jagged and ugly, especially on LCD monitors.

There's a workaround for this...

A lot of web sites specify Helvetica fonts - they're probably designed on a Mac which has licenced the font and thus displays nicely. Unfortunately for the rest of us, this means that the ugly bitmapped font is used, bringing the page aesthetics down. For Windows users, no Helvetica implementation is there at all - Arial is generally substituted.

This problem is easily solved under Xorg, of which most GNU/Linux distributions now use. Gnome and KDE both use the Fontconfig system for font management, and with this, it's easy to get a good looking Helvetica replacement. The trick is to tell Fontconfig to substitute Helvetica with a better looking font. I chose Nimbus Sans, as it closely resembles Helvetica and is standard on most systems.

To configure Fontconfig, you just have to edit the file .fonts.conf in your home directory. Open (or create) it and put the following section into it:

 <match target="pattern" >
  <test name="family" qual="any" >
   <string>Helvetica</string>
  </test>
  <edit mode="assign" name="family" >
   <string>Nimbus Sans</string>
  </edit>
 </match>

This needs to be placed outside any existing <match> .. </match> directive, and within the <fontconfig> block.

Then save the file and run fc-cache and restart Firefox. You should now have much prettier font where Helvetica once was. Compare the two screenshots below - on the left is the default bitmapped Helvetica, and on the right is the much smoother replacement Nimbus Sans.

This trick can also be done for other fonts - if you come across some font that renders horribly, insert another block into .fonts.conf with the old and new font names and enjoy your prettier X11!

Posted by Ben at 07:46 PM | Comments (0)

July 06, 2006

IPSec and NAT with Cisco and Linux boxen

Introduction

This is a quick mini-howto on how to get IPSec working between an OpenWRT (or any linux gateway) box and a Cisco IOS router, where both are also doing NAT for their networks. I'll also describe how to get the Linux gateway talking IPSec to a standalone Linux host elsewhere on the net. Last but not least, you'll also see how to get an IPV6 over IPv4 tunnel working across this.

I was recently rebuilding my home network topology, and part of that rebuild involved some IPSec tunnels across the Internet. I though I'd share my documentation on this to assist anyone else attempting a similar setup. The setup is built around Linux and Cisco IOS NAT gateways, as well as one standalone host, and the challenge faced here is to have IPSec running between the Linux NAT box and the other two devices.

The basic network topology is shown below. It consists of two NATed networks (Amsterdam and Sydney) and one standalone host (San Jose), all with static public IP addresses. These networks have significant communication between them, and with a desire for privacy and bypassing of ISP filters (eg port 25), tunnels have been built between the devices to give transparency across the network. The use of NAT adds to some of the challenges in building this.

Topology
The setup

The devices here consist of one standalone Linux host, one OpenWRT-Linux based router and one Cisco 827 ADSL router. The routers are NATting for the networks behind them, and some port redirection is enabling outside access to services on those networks. All networks have global IPv6 connectivity via tunnels (not shown here), and there are IPv6 tunnels directly connecting them. The internal networks behind the NAT gateways will be reachable from each other via IPSec tunnels.

My IPSec daemon of choice is OpenSwan, and a package is available for OpenWRT. There's a reasonable amount of documentation on it, but strangely I found only a few references to getting it working with a Cisco IOS box, and even fewer in combination with NAT.

The Cisco is an 827 ADSL router, running a 12.3 IOS with IPSec features. Conveniently, it also has support for IPv6, however IPSec on IPv6 is not supported, hence the use of tunneling IPv6 over the IPv4 IPSec.

IPSec and tunnel topology

For the Amsterdam to Sydney connection, I decided to build various tunnels linking the possible communication paths over IPv4. One of the niggles with IPSec is that you've got to define all source and destination combinations as separate tunnels. The IPv6 addresses are tunnelled over an IPv4 IPSec tunnel, using standard 6-in-4. I had to use this for IPv6 anyway, given that the devices don't support IPv6 IPSec.

Between Amsterdam and San Jose, IPv4 is tunnelled with IPSec, but IPv6 would is routed over an IPv6 in IPv4 tunnel, for the same reasons - limited device support.

Configuration

The configuration of OpenSwan is handled within two files. The file /etc/ipsec.conf is the main config file and describes the settings for each IPSec connection. Configuration of crypto keys are in /etc/ipsec.secrets, and if simple preshared keying is used, this is all that needs to be touched. In the following examples, the key will be "SecretKey" but of course you should use something much longer and more obscure.

Amsterdam to Sydney

The following is the OpenSwan configuration for the Amsterdam to Sydney connection. It contains four tunnel definitions, defining all possible traffic flows:

  • 31.31.31.31 to 61.61.61.61 (Amsterdam public to Sydney public)
  • 31.31.31.31 to 10.0.0.0/24 (Amsterdam public to Sydney internal)
  • 192.168.0.0/24 to 61.61.61.61 (Amsterdam internal to Sydney public)
  • 192.168.0.0/24 to 10.0.0.0/24 (Amsterdam internal to Sydney internal)
In the /etc/ipsec.conf file is:
conn sydney1
        left=31.31.31.31
        leftsubnet=31.31.31.31/32
        leftnexthop=%defaultroute
        right=61.61.61.61
        rightsubnet=61.61.61.61/32
        rightnexthop=%defaultroute
        authby=secret
        esp=3des-md5-96
        keyexchange=ike
        pfs=yes
        auth=esp
        auto=start
conn sydney2
        left=31.31.31.31
        leftsubnet=31.31.31.31/32
        leftnexthop=%defaultroute
        right=61.61.61.61
        rightsubnet=192.168.0.0/24
        rightnexthop=%defaultroute
        authby=secret
        esp=3des-md5-96
        keyexchange=ike
        pfs=yes
        auth=esp
        auto=start
conn sydney3
        left=31.31.31.31
        leftsubnet=192.168.0.0/24
        leftnexthop=%defaultroute
        right=61.61.61.61
        rightsubnet=61.61.61.61/32
        rightnexthop=%defaultroute
        authby=secret
        esp=3des-md5-96
        keyexchange=ike
        pfs=yes
        auth=esp
        auto=start
conn sydney4
        left=31.31.31.31
        leftsubnet=192.168.0.0/24
        leftnexthop=%defaultroute
        right=61.61.61.61
        rightsubnet=10.0.0.0/24
        rightnexthop=%defaultroute
        authby=secret
        esp=3des-md5-96
        keyexchange=ike
        pfs=yes
        auth=esp
        auto=start
The sections above are all the same except for the leftsubnet/rightsubnet definitions.

In the /etc/ipsec.secrets file is:

31.31.31.31 61.61.61.61: PSK "SecretKey"

And here is the IOS configuration for Sydney:

crypto isakmp policy 10
 encr 3des
 hash md5
 authentication pre-share
 group 2
 lifetime 28800
crypto isakmp key SecretKey address 31.31.31.31
!
!
crypto ipsec transform-set SydAms esp-3des esp-md5-hmac 
!
crypto map Amsterdam 10 ipsec-isakmp 
 set peer 31.31.31.31
 set transform-set SydAms 
 set pfs group2
 match address 192
!
! This is the outgoing interface with the public IP address
!
interface Dialer1
 crypto map Amsterdam
!
access-list 192 permit ip host 218.214.47.18 host 80.61.87.81
access-list 192 permit ip 192.168.1.0 0.0.0.255 10.0.0.0 0.0.0.255
access-list 192 permit ip 192.168.1.0 0.0.0.255 host 80.61.87.81
access-list 192 permit ip host 218.214.47.18 10.0.0.0 0.0.0.255

We will now configure the IPv6 tunnel to complete the tunnel config for this connection.

First the Amsterdam configuration:


ip tunnel add Sydney6 mode sit ttl 64 remote 61.61.61.61  \
  && ip link set dev Sydney6 mtu 1420 up \
  && ip -6 addr add 2001:31::1/128 dev Sydney6 \
  && ip -6 route add 2001:61::/48 dev Sydney6

And the Cisco configuration:

!         
interface Tunnel0
 description IPV6 tunnel to Amsterdam
 no ip address
 ipv6 unnumbered Ethernet0
 ipv6 enable
 tunnel source Dialer1
 tunnel destination 31.31.31.31
 tunnel mode ipv6ip
!
ipv6 route 2001:31::/48 Tunnel0
!

Does the connection work yet?

No it doesn't. The problem is related to NAT and firewalling configuration on both ends.

On the Cisco side, the router will attempt to NAT the outgoing packets from the internal hosts before encrypting them with IPSec, and thus mangle the source address of the packet. Ingress traceroutes to an internal address will terminate on the public address, not the internal address. To solve this, we need to exclude IPSec-handled packets from the NAT processing. Somewhere in your IOS configuration will be a line similar to this:

ip nat inside source list 101 interface Dialer1 overload
The source-list referred to will need to be added to so that packets out via IPSec are excluded. So access-list 101 becomes:
access-list 101 deny   ip any 192.168.0.0 0.0.0.255
access-list 101 deny   ip any host 31.31.31.31
access-list 101 permit ip 10.0.0.0 0.0.0.255 any

On the OpenWrt box, NAT doesn't mangle with the IPSec packets, due to the rule processing order in iptables. NAT only affects packets leaving the WAN interface, but IPSec processing occurs before this, and by the time they're encrypted, the source address of the IPSec packets won't match the NAT rule any more.

However, the FORWARD table of the OpenWrt box will be default drop all packets that it can't establish as being related to an existing connection (ie anything not NAT or port forwarded) and so will drop any not destined for the local machine, ie IPSec traffic for any inside host.

Thus, to fix this, we put in a forwarding rule that allows all IPSec traffic through the box. In addition, we'll add a rule that ensures port 500 UDP traffic (IPSec key management aka ISAKMP) is handled locally:

In /etc/firewall.user:
# This is a catch all - it's essential to also put it more secure rules.
iptables -A forwarding_rule -i ipsec0 -j ACCEPT
iptables -A forwarding_rule -o ipsec0 -j ACCEPT
# These rules send ISAKMP traffic to the local OpenSwan daemon.
iptables -t nat -A prerouting_rule -i $WAN -p udp --dport 500 -j ACCEPT 
iptables -A input_rule      -i $WAN -p udp --dport 500 -j ACCEPT

At this point, there should be full connectivity between the internal networks of both ends on both IPv4 and IPv6. Traceroute from an internal host at one end to any IP address of the other end should reveal only one WAN hop.

That completes the configuration for the Amsterdam to Sydney link.

Amsterdam to San Jose

Between Amsterdam and San Jose, we'll also configure OpenSwan at both ends. There will be two IPSec tunnels configured here - one will carry traffic between the public addresses, and the other will carry traffic between the Amsterdam internal network and San Jose. So one tunnel will carry traffic between 1.1.1.1 and 31.31.31.31, whilst the other will carry it from 1.1.1.1 to 192.168.0.0/24. The rules for this configuration are quite simple:

Amsterdam config:

/etc/ipsec.conf
conn sj
        left=31.31.31.31
        leftsubnet=31.31.31.31/32
        leftnexthop=%defaultroute
        right=1.1.1.1
        rightsubnet=1.1.1.1/32
        rightnexthop=%defaultroute
        authby=secret
        keyexchange=ike
        pfs=yes
        esp=3des-md5-96
        auth=esp
        auto=start
        
conn sjpriv
        left=31.31.31.31
        leftsubnet=192.168.0.0/24
        leftnexthop=%defaultroute
        right=1.1.1.1
        rightsubnet=1.1.1.1/32
        rightnexthop=%defaultroute
        authby=secret
        keyexchange=ike
        pfs=yes
        esp=3des-md5-96
        auth=esp
        auto=start
/etc/ipsec.secrets
31.31.31.31 1.1.1.1: PSK "SecretKey"

San Jose config:

/etc/ipsec.conf
conn ams              
        left=1.1.1.1                           
        leftsubnet=1.1.1.1/32
        leftnexthop=%defaultroute                                          
        right=1.1.1.1
        rightsubnet=1.1.1.1/32
        rightnexthop=%defaultroute
        authby=secret                                                       
        keyexchange=ike              
        pfs=yes                      
        esp=3des-md5-96
        auth=esp
        auto=start                   

conn amspriv
        left=1.1.1.1                             
        leftsubnet=1.1.1.1/32
        leftnexthop=%defaultroute                                          
        right=31.31.31.31
        rightsubnet=192.168.0.0/24
        rightnexthop=%defaultroute
        authby=secret                                                       
        keyexchange=ike              
        pfs=yes                      
        esp=3des-md5-96
        auth=esp
        auto=start                   
/etc/ipsec.secrets
1.1.1.1 31.31.31.31: PSK "SecretKey"

When be bring these connections up, we see that all traffic is successful, and this tunnel works. The forwarding rule for the ipsec0 interface above is important and allows reachability to the inside hosts. Note that you don't need to put an equivalent forwarding rule on the Linux host, as nothing is forwarded through the box. But you may need to configure general input and output rules to allow IPSec packets.

Lastly, we configure an IPv6 tunnel across this IPSec link. It's quite straight forward and this is the configuration:

Amsterdam end:

ip tunnel add US mode sit ttl 64 remote 1.1.1.1  \
  && ip link set dev US mtu 1420 up \
  && ip -6 addr add 2001:31::1/128 dev US \
  && ip -6 route add 2001:1::1/128 dev US

San Jose end:

ip tunnel add NL mode sit ttl 64 remote 31.31.31.31  \
&& ip link set dev NL mtu 1420 up \
&& ip -6 addr add 2001:1::1/128 dev NL \
&& ip -6 route add 2001:31::1/64 dev NL

A quick ping will show the IPv6 tunnel up and there should be reachability to all hosts on the inside of the Amsterdam network. It's also a good idea to configure firewalling rules on the IPv6 side - anyone breaching the public host has full IPv4 and IPv6 access to the Amsterdam network, so be smart and build that firewall.

Last but not least...the IPSec connection between San Jose and Sydney....is left as an excercise to the reader.

Conclusion

IPSec is often seen as a mysterious protocol in the IP world, difficult to setup and hard to maintain. But a look into a basic configuration with it reveals it to be not that hard at all. The configurations above should be a good solution for many common network topologies, and with a clear understanding as to what it all does, adapting it to other networks should be relatively painless.

Posted by Ben at 10:02 PM | Comments (0)