Results tagged “networking”

I know that title is mouthful. But, I occasionally use this blog as place to dump interesting configuration settings and it helps me remember configuration which helps me to remember it and might be useful to lone surfers who stumbles upon this page.

graph.png

This weekend our nice network admin upgraded VLAN setup to enables 1Gb/s network across whole private segment. That is clearly visible in green arrows on picture, especially if you compare it with last one. We still have a few slower links (100 Mb/s) which pass through NAT to Internet (red arrows), but we now have private segment on every server in library and system room in main building and each server has IP address in new 1 Gb/s segment (you can notice that by blue arrows which are loopback interface on same machine).

All is not well, however. I had to reconfigure my OpenVZ containers from point-to-point ip configuration using venet devices to ethernet bridge setup because multiple hops on OpenVZ machine produced havoc with connections from our private network to containers. It was very wired, I saw TCP retransmission requests, but first packet somehow managed to pass through. ICMP traffic worked (thanks to small packet sizes), but I can't honestly say why our new VLAN setup and/or OpenVZ had problem with it. Up to that point, I just had private IP addresses assigned to OpenVZ container using vzctl set --ipadd 10.60.0.12 and ping -R did show multiple public and private addresses, but it all somehow worked.

First, I had to make network bridge which will be new VLAN 60

root@koha-hw:~# cat /etc/network/interfaces

auto br60
iface br60 inet static
        bridge_ports eth1 veth212226
        bridge_fd 0
        address 10.60.0.10
        netmask 255.255.254.0
        gateway 10.60.0.1
Then, I removed old private IP addresses:
root@koha-hw:~# vzctl set 212226 --ipdel 10.60.0.12 --save
and add new veth device (my version of vzctl requires MAC addresses, so beware!):
root@koha-hw:~# vzctl set 212226 --netif_add veth1,00:12:34:56:78:9A,veth212226,00:12:34:56:78:9B,br60 --save
This create veth1 device inside container to which I can assign IP address:
koha:~# ifconfig veth1 10.60.0.12 netmask 255.255.254.0 up
I decided to put that in /etc/rc.local because /etc/network/interfaces is managed by OpenVZ.

Next, I needed to reconfigure my ssh VPN which was using point-to-point tunneling with tap into real ethernet tunnel:

root@brr:~# tail -10 /etc/network/interfaces 

# vpn lib -> home
auto tap0
iface tap0 inet static
        pre-up ssh -M -S /var/run/tap0 -v -f -i /root/.ssh/koha-hw-tun0 -w 0:0 -o Tunnel=ethernet -o ServerAliveInterval=5 -o ServerAliveCountMax=2 koha-hw.ffzg.hr true
        address 10.60.0.81
        netmask 255.255.0.0
        up iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o tap0 -j MASQUERADE
        post-down ssh -S /var/run/tap0 -O exit koha-hw.ffzg.hr
On remote side, force tunnel number and add new device to bridge:
root@koha-hw:~# head -1 /root/.ssh/authorized_keys 
tunnel="0",command="ifconfig tap0 up ; brctl addif br60 tap0" ssh-rsa AAAAB3Nza...

Finally, little cron job to start (and restart) VPN:

root@brr:~# cat /etc/cron.d/tap0 
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
*/1     * * * * root    fping -q 10.60.0.10 || ( ifdown tap0 ; ifup tap0 )

Let's assume that you want to create virtual network which spans sites (or continents :-). While we are at it, let's assume that you want to have layer 2 connectivity (because you want to run just single DHCP server for example).

At first, it seemed logical to use Virtual Distributed Ethernet for which kvm has support. However, this involves running multiple processes to support nodes on network, and it's really virtual -- you can't use familiar Linux tools (like brctl or arp) to configure it. And it's connected over ssh anyway, so why to add unnecessary complexity to setup?

Since we will use ssh to transfer traffic anyway (it easiest hole to drill over firewalls and you probably already have it for administration anyway), why do we need another layer of software in between, with new commands to learn if we already know how to make it using plain old Linux brctl?

So, let's take another look at ssh, especially option Tunnel=ethernet which provides Ethernet bridging between two tap devices. As I wrote before, ssh have point-to-point links using tun device which is great solution if you want to connect two networks on IP level using routing. However, tap devices provide access to Ethernet layer from user-space (so ssh, kvm, VDE and various others user-land programs can send and receive Ethernet packets). However, finding information on internet how to setup ssh to use tap devices is nowhere to be found and motivated me for this blog post.

Let's assume that we have two machines in following configuration:

  • t61p - laptop at home behind DSL link and nat which wants to run kvm virtual machine in virtual network 172.16.10.0/24
  • t42 - desktop machine at work which have network bridge called wire which has 172.16.10.0/24 network which provides network booting services
So, we need ethernet tunneling to remote client.
# install tunctl
dpavlin@t61p:/virtual/kvm$ sudo apt-get install uml-utilities

dpavlin@t61p:/virtual/kvm$ sudo tunctl -u dpavlin -t kvm0
Set 'kvm0' persistent and owned by uid 1000

dpavlin@t61p:/virtual/kvm$ kvm -net nic,macaddr=52:54:00:00:0a:3d -net tap,ifname=kvm0,script=no -boot n
This doesn't really boot our kvm from network because we didn't connect it together. Now we need to enable tunnels on t42 and setup remote tap device
dpavlin@t42:~$ grep -v PermitTunnel /etc/ssh/sshd_config > /tmp/conf
dpavlin@t42:~$ ( grep -v PermitTunnel /etc/ssh/sshd_config ; echo PermitTunnel yes ) > /tmp/conf
dpavlin@t42:~$ diff -urw /etc/ssh/sshd_config /tmp/conf
--- /etc/ssh/sshd_config        2009-04-20 12:50:27.000000000 +0200
+++ /tmp/conf   2009-08-14 20:42:40.000000000 +0200
@@ -75,3 +75,4 @@
 Subsystem sftp /usr/lib/openssh/sftp-server
 
 UsePAM yes
+PermitTunnel yes

# install and restart ssh
dpavlin@t42:~$ sudo mv /tmp/conf /etc/ssh/sshd_config
dpavlin@t42:~$ sudo /etc/init.d/ssh restart
Restarting OpenBSD Secure Shell server: sshd.
Now we can connect two machines using ssh ethernet tunnel
dpavlin@t61p:/virtual/kvm$ sudo ssh -w 1:1 -o Tunnel=ethernet root@10.60.0.94

t42:~# ifconfig tap1
tap1      Link encap:Ethernet  HWaddr fa:35:cb:9e:87:60  
          BROADCAST 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)

t42:~# ip link set tap1 up
t42:~# brctl addif wire tap1
t42:~# brctl show wire
bridge name     bridge id               STP enabled     interfaces
pan0            8000.000000000000       no
wire            8000.006097472681       no              eth2
                                                        eth3
                                                        tap0
                                                        tap1
                                                        tap94

t42:~# dmesg | grep tap1
[284844.064953] wire: port 5(tap1) entering learning state

t42:~# tshark -i wire
This created tap1 devices on both machines and added one on t42 to bridge and left us with dump from tshark on wire bridge.

Now we need to setup virtual bridge on t61p to connect ssh tunnel and kvm tap device.

dpavlin@t61p:/virtual/kvm$ sudo ifconfig tap1
tap1      Link encap:Ethernet  HWaddr 52:c5:f8:64:30:d4  
          BROADCAST 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)

dpavlin@t61p:/virtual/kvm$ sudo brctl addbr virtual
dpavlin@t61p:/virtual/kvm$ sudo brctl addif virtual kvm0
dpavlin@t61p:/virtual/kvm$ sudo brctl addif virtual tap1

dpavlin@t61p:/virtual/kvm$ sudo brctl show
bridge name     bridge id               STP enabled     interfaces
pan0            8000.000000000000       no
virtual         8000.4e1537af6cdc       no              kvm0
                                                        tap1

dpavlin@t61p:/virtual/kvm$ sudo ip link set kvm0 up
dpavlin@t61p:/virtual/kvm$ sudo ip link set tap1 up
dpavlin@t61p:/virtual/kvm$ sudo ip link set virtual up

dpavlin@t61p:/virtual/kvm$ dmesg | grep virtual
[31141.669760] virtual: port 1(kvm0) entering learning state
[31152.288025] virtual: no IPv6 routers present
[31156.668088] virtual: port 1(kvm0) entering forwarding state
[31211.699928] virtual: port 2(tap1) entering learning state
[31226.696070] virtual: port 2(tap1) entering forwarding state
dpavlin@t61p:/virtual/kvm$ kvm -net nic,macaddr=52:54:00:00:0a:3d -net tap,ifname=kvm0,script=no -boot n
This will boot our kvm using ethernet bridge from remote server using nothing more than brctl and ssh !

If you wanted even more lightweight solution to same problem, you might look into EtherPuppet.

On related note, if your kvm Windows XP machines stopped working with upgrade to Debian kernel 2.6.30-1-686, just upgrade to 2.6.30-1-686-bigmem (even if you don't have more memory) and everything will be o.k.

So, you think that your network is slow. But, how would you test that? You can feel that speed between different hosts is different, but what you need some data to find problem. Here is my take on this...

First, select subset of machines to test network speed on and install netpipe-tcp. Then run NPtcp on target machines and NPtcp -h hostname -u 1048576 -o /tmp/hostname.np on machine from which you are testing bandwidth. Several iterations later, you will have a bunch of *.np files which are ready for analysis.

You can do it by hand, but this handy perl script will convert *.np files into graphviz's dot file. Which looks like this: netpipe-grahviz.png

GraphViz will make it's auto-layout magic and just looking at picture you will immediately notice that there are 100Mbit/s link somewhere in-between machines... Pictures can really replace thousands of words...

For a long time, I used combination of proxy.pac and DynamicForward in .ssh/config to enable seamless surfing over ssh tunnels. However, this time, I wanted to access university network from home DSL.

I remembered all warnings about tunneling tcp over tcp and why it is bad idea, but I really liked simplicity of reusing ssh. So, I start looking for guides to implement minimal solution like this:

client.lan                      ssh gateway             private network
eth0 192.168.1.20 <--DSL-nat--> eth0 gw.example.com
tun0 10.60.0.81 <-pointopoint-> tun0 10.60.0.80 
                                eth1 10.60.0.10 <-----> 10.60.0.0/24
It's a bit more complicated, because LAN clients have to use NAT to access private network, but that's a single line in configuration. So, let's get started...

client.lan

  1. Generate ssh key for VPN
    root@client:~# ssh-keygen -t rsa -f /root/.ssh/gw-tun0
    Generating public/private rsa key pair.
    Enter passphrase (empty for no passphrase): 
    Enter same passphrase again: 
    Your identification has been saved in /root/.ssh/gw-tun0.
    Your public key has been saved in /root/.ssh/gw-tun0.pub.
    
  2. Transfer it to server
    echo 'tunnel="0",command="/sbin/ifdown tun0;/sbin/ifup tun0"' `cat /root/.ssh/gw-tun0.pub` | \
        ssh dpavlin@gw.example.com 'sudo sh -c "cat >> /root/.ssh/authorized_keys"'
    
    If you didn't have authorized_keys on gw.example.com you will also have to fix group with:
    root@gw:~# chown root:root /root/.ssh/authorized_keys
    
  3. /etc/network/interfaces
    iface tun0 inet static
        pre-up ssh -i /root/.ssh/gw-tun0 -S /var/run/gw-tun0 -M -f -w 0:0 gw.example.com true
        pre-up sleep 5
        address 10.60.0.81
        netmask 255.255.0.0
        pointopoint 10.60.0.80
        up iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o tun0 -j MASQUERADE
        post-down ssh -S /var/run/gw-tun0 -O exit gw.example.com
    
    iptables are used to NAT all hosts on home network, so they can see whole private network and not just IPs on gw.example.com
    I also added following route to my home network gateway so that all traffic for private network will go through VPN:
    # netstat -rn
    Kernel IP routing table
    Destination     Gateway         Genmask
    10.60.0.0       192.168.1.20    255.255.0.0
    

gw.example.com

  1. /etc/ssh/sshd_config
    #PermitRootLogin yes
    PermitTunnel point-to-point
    PermitRootLogin forced-commands-only
    
  2. /etc/network/interfaces
    iface tun0 inet static
        address 10.60.0.80
        netmask 255.255.255.255
        pointopoint 10.60.0.81
        up arp -sD 10.60.0.81 eth1 pub
    
    arp entry is used to make home IP address 10.60.0.81 visible to all hosts in private network. That, together with rinetd on client.lan enabled me to tunnel connections to other hosts on my local network by creating port redirection (again, sigh!). I could have solved that with route on ssh gateway gw.example.com, but this solution leaves configuration of incomming connections on home side of link.
  3. /etc/cron.d/gw.example.com
    # monitor tun0
    */1     * * * * root    fping -q 10.60.0.81 || ( ifdown tun0 ; ifup tun0 ) | logger -t tun0
    

So, you have a laptop with wifi and enternet card and you want to make "real" AP from it. There are many ways to do this, but I like this one:

  1. Install packages required:
    apt-get install dnsmasq
    
  2. configure /etc/dnsmasq.conf to be DHCP server for your wifi network:
    listen-address=192.168.42.1
    dhcp-range=192.168.42.42,192.168.42.242,12h
    
  3. turn atheros card into master (AP) mode and configure new network 192.168.42.0/24 and setup masquarade:
    sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
    sudo wlanconfig ath0 destroy
    sudo wlanconfig ath0 create wlandev wifi0 wlanmode ap
    sudo iwconfig ath0 essid free4all
    sudo ifconfig ath0 192.168.42.1
    sudo iwconfig 
    sudo /etc/init.d/dnsmasq restart
    sudo iptables --flush  
    sudo iptables --table nat --flush
    sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
    sudo iptables -A FORWARD -i eth0 -o ath0 -m state --state RELATED,ESTABLISHED -j ACCEPT
    sudo iptables -A FORWARD -i ath0 -o eth0 -j ACCEPT
    

And that's it. You have new 192.168.42.0/24 network on your wifi interface ath0 which is passed to eth0 (which you should configure beforehand using dhclient eth0 or someting similar). Bring wifi to every home in next year ;-)

Instructions here are specific for configuration with atheros wifi card (that's why I'm using wlanconfig to switch card in EeePC into AP mode). For other wifi cards which support AP mode via standard iwconfig the syntax is: iwconfig eth1 mode master. If you get error using this command, you might try with ad-hoc mode instead of "real" AP...

I have heard several complaints about Cisco VPN client for Linux. It's a kernel module, so it's a mess.

However, few days ago I had to connect to one site using Cisco VPN. I got even Windows client. Which didn't work from emulated Windows on my Linux box... What should I do?

First idea to search Debian packages proved like a right thing to do: I soon found vpnc which had all the tools needed for transition. Even tool to convert Windows Support_template.pcf to format sutable for vpnc!

I also wrote a short tutorial how to install and configure it which might be helpful.