Category Archives: debian

ssh connection sharing

Another relatively unknown feature of openssh is connection sharing. This enables you to reuse an existing ssh connection for another one. The second (and subsequent) connections(s) (called slaves) will use the same TCP connection as the first one (called master). The advantages are that the slave connections are initiated faster and that there is no password needed. And both these improvements make bash tab completion very fast. For example if you have an ssh session already running to a remote host you can use tab completion from another shell for scp, and it finds the files on the remote host.

Setting it up is simple: in your .ssh/config, add these lines:

Host *
ControlMaster auto
ControlPath /home/oku/.ssh/%r@%h:%p

Replace ‘oku’ with your user name.

The ‘ControlMaster auto’ option tells ssh to check if there is already a master, and if not set itself to the master. Otherwise, be a slave and use the master’s socket. The next line tells ssh how to name the unix socket it needs to create. In this example, it is composed of the remote user name, the host name and the port number, and will be created in the user directory in the subdirectory ‘.ssh’.

That’s all.

I use this for years now. It usually works fine, but there are a few disadvantages:

  • when the ssh connection unexpectedly dies (for example, a cold hardware reset), it leaves the socket behind. When you then try to login again, ssh complains that it cannot create the socket. You need to manually delete it.
  • when there are slaves, you cannot terminate the master session without terminating the slave connections.
  • if you do port forwarding, this works only for the master – if you try it with a slave, you don’t see an error message though. This is pretty annoying if you don’t know it. I think this also applies to ssh tunneling. This is reported as a bug in Debian.

Despite these flaws, I still find it very useful.

You will also find information here, and of course in the man pages.

7 Comments

Filed under debian, linux, openssh

VPN with openssh

A relatively unknown feature of openssh is its abilty to create a VPN tunnel. This has been implemented in version 4.3. I am not talking about port forwarding. This VPN creates a virtual network interface, which you can use like any other network interface. This is much more flexible than simple TCP port forwarding. It can be used for udp and icmp.
To set it up is actually very simple, but because I couldn’t find any good documentation, it wasn’t easy to figure out.

Here are the steps:

On the server, in /etc/ssh/sshd_config, configure it to allow tunneling and allow root login (if it isn’t there already):

PermitTunnel yes
PermitRootlogin yes

Restart the server with

/etc/init.d/sshd restart

From the client, you can then as root, and login as root to the server.

sudo ssh -w any:any root@fedoku

You need to be root on the client, and login as root. This is important, because only root can create the needed network devices (this is where I was stuck for some time).

When that was successful, you will see on both server and client a tun device:

tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          POINTOPOINT NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

Now you just need to configure them, both on server and client. Because they are point-to-point devices, you need to set the respective peer. The ifconfig commands mirror each other:

Client:

ifconfig tun0 10.0.0.1 pointopoint 10.0.0.2

Server:

ifconfig tun0 10.0.0.2 pointopoint 10.0.0.1

That’s it, actually. Now you can set up routing, firewall, nat and so on, if needed.

There is also a way to use layer 2 networking, with virtual ethernet devices. All you have to do is to set the device type in the client configuration file:

TunnelDevice ethernet

The network devices now show up as tap instead of tun. The advantage is that you can use those for IPv6. I was never able to do that with the tun devices.

Another good documentation can be found here – which I found when I already had it figured out.

6 Comments

Filed under debian, ipv6, linux, openssh

Using ptrtd

I just checked out ptrtd. Understanding what it does is actually harder than installing and using it…: ptrtd is useful if you have an IPv6 only network. Of course, you do not want to isolate yourself from the IPv4 internet, so you need a way to access it. ptrtd maps every IPv4 address into IPv6 by prependig a prefix, so the whole internet becomes a tiny speck in the IPv6 address space. An address like 192.168.1.1 becomes fec0:0:0:ffff::192.168.1.1. ptrtd does this by creating a virtual network interface (tap) using tuntap.

But first the installation, which is pretty common:

./configure
make

I tested with:

sudo ./ptrtd

When it starts, it creates the interface:

tap0      Link encap:Ethernet  HWaddr D2:B2:5E:9D:07:89
          inet6 addr: fe80::1/64 Scope:Link
          inet6 addr: fe80::d0b2:5eff:fe9d:789/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:129 errors:0 dropped:0 overruns:0 frame:0
          TX packets:115 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:18747 (18.3 KiB)  TX bytes:15839 (15.4 KiB)

and sets the route to the network fec0:0:0:ffff::/64 to that device:

# ip -6 route show
...
fec0:0:0:ffff::/64 via fe80::5 dev tap0  metric ...
...

So now every IPv4 address is reachable via IPv6. I can for example ssh to 192.168.2.1 using the address fec0:0:0:ffff::192.168.1.1. The destination host does not notice, it appears to be coming from a usual IPv4 address.

Of course, the host running ptrtd needs to have both IPv4 and IPv6 (dual stack). It becomes only really interesting for hosts in an IPv6 only network when they set the route to fec0:0:0:ffff::/64 to the host running ptrtd.

The problem left is that we do not want to use the literal IPv6 addresses, but DNS names. And that’s where totd steps in. It translates IPv4 addresses from DNS to IPv6 addresses. I will test that later, and hopefully write about it.

2 Comments

Filed under debian, ipv6, linux

llconf site created

A few days ago I finally released my ongoing open source project, llconf. It is a library to make parsing configuration files easy. To learn how it works, see the Quick Guide.

3 Comments

Filed under debian, linux, programming

Using radvd

A while ago I promised to show how to use radvd, so here it goes.

radvd is a daemon that distributes an ipv6 prefix to all nodes on the same network. This is called stateless IP autoconfiguration. It serves the same purpose dhcp does for IPv4 networks, but it is more limited, and just serves the clients with prefixes and a default router. There is no way to assign a specific address to clients, for example from a pool of addresses or based on the MAC address. So, for more specific configurations, dhcpv6 can be used. Still, to quickly configure addresses and default router automatically it is very useful. Supposedly there is alo a way to set the DNS server, but I haven’t tested that yet.

It has to run on the default ipv6 router, and there should be only one node running it it the whole network. Installing it is so simple that it is almost scary. To install it on Debian, do:

# apt-get install radvd

The configuration file is /etc/radvd.conf. It looks like this:

interface ath0
{
        AdvSendAdvert on;
        prefix 2001:db8:0:0::/64
        {
                AdvOnLink on;
        };
};

Just replace the prefix with the prefix assigned to your network. Start it with

# /etc/init.d/radvd start

Now, look at the IP addresses of clients attached to the same network. There is absolutely no configuration necessary on the clients. They will, almost magically, have an IPv6 address composed out of the configured prefix and a part based on the MAC address:

# ifconfig ath0

ath0      Link encap:Ethernet  HWaddr 00:11:22:33:44:55
            inet6 addr: 2001:db8:0:0::0011:2233:4455/64 Scope:Global
            ...

The part after the prefix of the address is not exactly the MAC address, but it is derived from it. You can use the addresses for example to add them to a DNS server.

Also, the default route of the clients will point to the node running radvd.

This works for Mac OS and Linux clients. I do not know about Windows clients.

2 Comments

Filed under debian, ipv6

Configuring an IPv6 gateway with Debian

Recently, I discovered that our ISP (sonic.net) offers IPv6 tunnels. So they do not give a direct IPv6 connection, but a tunnel is good enough.

It works by offering each customer an IPv6 transport network and a /60 network, enough room for 2^(128-60) = 295147905179352825856 addresses! When logged in to their web interface, they give detailed instructions:

  • the IPv4 address of the tunnel gateway
  • the IPv6 addresses of the enpoints (customer and tunnel)
  • the IPv6 network.

This is how it looks:

208.201.xxx.yyy = sonic-side v4 addy
209.204.xxx.yyy = customer-side v4 addy
2001:xxxx:0000:0001:0000:0000:0000:yyyy = Sonic-side transport IP
2001:xxxx:0000:0001:0000:0000:0000:yyyy = customer-side transport IP

To make use of that, a customer has to set up his own IPv4 to IPv6 gateway. I use Debian/unstable with a 2.6.17 kernel. It works with older 2.6 kernels, but at least 2.6.17 is recommended for proper ip6tables support with connection tracking. These are the relevant kernel options:

CONFIG_IPV6=m
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTER_PREF=y
# CONFIG_IPV6_ROUTE_INFO is not set
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m
CONFIG_INET6_XFRM_TUNNEL=m
CONFIG_INET6_TUNNEL=m
CONFIG_IPV6_TUNNEL=m
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_BRIDGE_NETFILTER=y

For iptables support with connection tracking, I have also enabled these:

CONFIG_NF_CONNTRACK_IPV6=m
# CONFIG_IP6_NF_QUEUE is not set
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_RT=m
CONFIG_IP6_NF_MATCH_OPTS=m
CONFIG_IP6_NF_MATCH_FRAG=m
CONFIG_IP6_NF_MATCH_HL=m
CONFIG_IP6_NF_MATCH_OWNER=m
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_LOG=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_RAW=m

I had to build my own kernel, because the official Debian kernel package did not have all of the needed options enabled. I will not explain here how to compile a kernel – there are enough instructions elsewhere. After compiling the kernel and rebooting, the next step is loading the ipv6 module:

modprobe -v ipv6

To make this automatic on boot, append this to /etc/modules:

echo ipv6 >> /etc/modules

Now you need to configure the interfaces in /etc/network/interfaces. This will configure an IPv6 address for eth0. This entry needs to be right after the entry for the IPv4 address of eth0, otherwise it does not work. Also, so far it is not possible to configure more than one IPv6 address per interface, at least not without the manual method or using the ‘up’ and ‘down’ paramters.

iface eth0 inet6 static
address 2001:xxxx:xxxx:xxxx::1
netmask 64

You need to use an address of you assigned network. I chose ::1 because it is easy to remember. Next you need to set up the tunnel interface:

iface sixbone inet6 v4tunnel
        address 2001:xxxx:xxxx:xxxx::xxxx
        netmask 127
        endpoint 208.201.xxx.yyy
        local 192.168.2.3
        ttl 255

The address here is local address of the transport network. The endpoint is the IPv4 address of the remote gateway (labeled ‘sonic-side v4 addy’ above). I also set the parameter local to the local network address – this is needed if this gateway is not the router itself, and the router uses NAT to forward tunneled IPv6 packets to this gateway – I will explain that later in another post.

After restarting the eth0 interface and starting the sixbone interface (ifdown eth0; ifup eth0; ifup sixbone), you should now be able to ping6 an IPv6 address. For example, try

# ping6 www.ipv6.uni-muenster.de
PING www.ipv6.uni-muenster.de(2001:638:500:101:2e0:81ff:fe24:37c6) 56 data bytes
64 bytes from 2001:638:500:101:2e0:81ff:fe24:37c6: icmp_seq=1 ttl=47 time=215 ms
64 bytes from 2001:638:500:101:2e0:81ff:fe24:37c6: icmp_seq=2 ttl=47 time=209 ms

If it does not work, maybe your firewall blocks. Tunneled IPv6 packets have a special protocol type (41), this makes it easy to add a rule:

iptables -I INPUT -j ACCEPT --proto 41

To use this gateway in your home network as a router, you need to enable forwarding:

echo 1 > /proc/sys/net/ipv6/conf/all/forwarding

To make this automatic on boot, add a rule to /etc/sysctl.conf:

net.ipv6.conf.default.forwarding=1

But careful! As soon as other hosts have an IPv6 address and have your new gateway configured as a router, they are wide open to the internet. So you need to setup a few firewall rules, for example:

-A INPUT -s ::/0 -d ::/0 -i sixbone -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT
-A INPUT -s ::/0 -d ::/0 -i sixbone -p tcp -m tcp --dport 113 -m state --state NEW
  -j REJECT --reject-with icmp6-port-unreachable
-A INPUT -s ::/0 -d ::/0 -i sixbone -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -s ::/0 -d ::/0 -i sixbone -j DROP
-A FORWARD -s ::/0 -d ::/0 -i sixbone -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT
-A FORWARD -s ::/0 -d ::/0 -i sixbone -p tcp -m tcp --dport 113 -m state --state NEW
   -j REJECT --reject-with icmp6-port-unreachable
-A FORWARD -s ::/0 -d ::/0 -i sixbone -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s ::/0 -d ::/0 -i sixbone -j DROP

Now you can configure other hosts in your network to use this gateway as your IPv6 router, for example:

iface eth0 inet6 static
        address 2001:xxxx:xxxx:xxxx::2
        netmask 64
        gateway 2001:xxxx:xxxx:xxxx::1

The nice thing is that NAT is no longer needed, because there are enough addresses available. Of course, this also means that every host is identifiable.

Next I will explain how to setup radvd, so you do not need to configure an IPv6 address for ever host in the network. That’s even easier than DHCP…

2 Comments

Filed under debian, ipv6