6in4 Tunnel

May 16, 2010

Thanks to company like Hurricane Electric or SixXS it is very easy to connect to IPv6 Internet backbone even if your ISP does not provide native access to IPv6. Those companies provide free access to their tunnel brokers. A tunnel broker is a dual homed router connected to IPv4 Internet backbone on one side and to IPv6 backbone on the other side. The concept is quite simple, you have access to the IPv4 world and you want to access the IPv6 world. You just need to build a 6in4 tunnel from your DSL router or from your PC or actually from whatever IPv4/IPv6 capable you want to the tunnel broker on the IPv4 side and you’ll encapsulate your IPv6 traffic into that tunnel. The broker will decapsulate your IPv6 packets and send them to the IPv6 Internet backbone. The tunnel broker will also advertise your IPv6 range to the backbone in order to allow the traffic to flow back to your 6in4 tunnel.

6in4 is a tunneling protocol acting in the same way as GRE but it is only used to transport IPv6 packets over IPv4 network. 6in4 is the IPv4 protocol 41. 6in4 tunneling is also referred to as proto-41 static because it requires static configuration… But as we will see, with good API, it does not necessarily need manual reconfiguration even with dynamic IP on a DSL line.

First you need to register to one tunnel broker provider. For the exemple I’ve chosen Hurricane Electric’s tunnel broker but other providers work similarly.

The you have to configure your 6in4 tunnel. On BSD system (here Mac OS X) you can use the following script :

#!/bin/bash
LOCAL_IF=en1
LOCAL_IP=`ifconfig $LOCAL_IF | grep "inet " | awk -F" " '{ print $2 }'`
LOCAL_IPV6=2001:db8::2
REMOTE_IP=216.66.80.26
REMOTE_IPV6=2001:db8::1
TUNNEL_IF=gif0

ifconfig $TUNNEL_IF tunnel $LOCAL_IP $REMOTE_IP
ifconfig $TUNNEL_IF inet6 $LOCAL_IPV6 $REMOTE_IPV6 prefixlen 128
route -n add -inet6 default $REMOTE_IPV6

Then if you have a dynamic public IP you may want to use the following script as a cron job to check whether your IP has changed and eventually update the tunnel broker.

#!/bin/bash
OLD_IPv4=/tmp/ipv4
CURRENT_IPv4=`curl -s http://demo.exp-networks.be/tools/ip.php`
UPDATE="TRUE"
USERID="xxx"
PASSWORD="xxx"
TUN="123"

if [ -f $OLD_IPv4 ];
then
  if [ "$CURRENT_IPv4" = "`cat $OLD_IPv4`" ];
  then
    UPDATE="FALSE"
  fi
fi

if [ "$UPDATE" = "TRUE" ];
then
  echo $CURRENT_IPv4 > $OLD_IPv4
  curl --insecure -s \
  "https://ipv4.tunnelbroker.net/ipv4_end.php?ipv4b=AUTO&pass=$PASSWORD&user_id=$USER&tunnel_id=$TUN"
fi

Where USERID has to be replaced by the user id found on the main page of HE’s tunnel broker; PASSWORD is an md5 hash of your password; and TUN is the global tunnel id found on your tunnel details’ page.

When done, you are ready to enter in the IPv6 world. And maybe starts the HE IPv6 certification and get your badge…
IPv6 Certification Badge for krik

SNMP on Debian

April 20, 2010

If you want to monitor your servers from a central management station, you’ll probably need to configure an SNMP daemon on your servers. Here is a quick note to show you how easy it is to get started with SNMP on Linux machine (examples are for Debian but should be easy to adapt for other distribution).

1) install snmpd package

# aptitude install snmpd

2) edit /etc/default/snmpd to remove restriction or replace the default listening address (127.0.0.1 by default). the line to modify is

SNMPDOPTS='-Lsd -Lf /dev/null -u snmp -I -smux -p /var/run/snmpd.pid 127.0.0.1'

or you can simply remove it with sed

# sed -i "s/.pid 127.0.0.1'/.pid'/" /etc/default/snmpd

3) add snmpd: 192.168.1.1 in /etc/hosts.allow to allow 192.168.1.1 to poll the server

# echo snmpd: 192.168.1.1 >> /etc/hosts.allow

4) edit /etc/snmp/snmpd.conf to define your community string(s), view(s) and allowed hosts (yes, again)

####
# First, map the community name (COMMUNITY) into a security name:
#        sec.name   source          community
com2sec  readonly   192.168.1.1/32  somecommunity

####
# Second, map the security names into group names:
#               sec.model  sec.name
group MyROGroup v2c        readonly

####
# Third, create a view for us to let the groups have rights to:
#          incl/excl   subtree   mask
view all   included    .1        80

####
# Finally, grant the groups access to the view with different
# read/write permissions:
#                context sec.model sec.level match  read   write  notif
access MyROGroup ""      any       noauth    exact  all    none   none

Once configured, start (or restart) the snmpd daemon.

# /etc/init.d/snmpd restart

And then test from the management station (here 192.168.1.1). We will try to get the hostname of the monitored device :

# snmpget -v 2c -c somecommunity 192.168.1.254 SNMPv2-MIB::sysName.0
SNMPv2-MIB::sysName.0 = STRING: gandalf

Dual stack IPv4/IPv6 on FreeBSD

April 14, 2010

Here is a quick note to show how easy it is to enable a dual IP stack on FreeBSD (and actually on most modern system)…

Here is what you need :

1. Native connectivity to IPv4 & IPv6 backbones

Connectivity to IPv4 should be OK. If you don’t have connectivity to IPv6 you may want to use 6in4 tunnel to connect to IPv6 backbone through a tunnel over IPv4 backbone. Several tunnel brokers are available for free, I personally know Hurricane Electric and SixXS.

2. An IPv4 gateway such as 192.168.1.1
3. An IPv4 address in that range such as 192.168.1.10
4. An IPv6 gateway such as 2001:db8:abcd::1
5. An IPv6 address in that range such as 2001:db8:abcd::e
6. Put all together in /etc/rc.conf

Extract from /etc/rc.conf

#IPv4 config
ifconfig_re0="inet 192.168.1.10 netmask 255.255.255.0"
static_routes="default"
route_default="default 192.168.1.1"

#IPv6 config
ipv6_enable="YES"
ipv6_ifconfig_re0="2001:db8:abcd::e/56"
ipv6_static_routes="default"
ipv6_route_default="default 2001:db8:abcd::1"

Then restart the server or the network related script from /etc/rc.d

ipv6#/etc/rc.d/netif start
re0: flags=8843 metric 0 mtu 1500
	options=9b
	ether 9e:65:96:1e:ca:5e
	inet 192.168.1.10 netmask 0xffffff00 broadcast 192.168.1.255
	media: Ethernet autoselect (100baseTX )
	status: active

ipv6#/etc/rc.d/routing start
add net default: gateway 192.168.1.1
Additional routing options:.

ipv6# /etc/rc.d/network_ipv6 start
add net ::ffff:0.0.0.0: gateway ::1
add net ::0.0.0.0: gateway ::1
net.inet6.ip6.forwarding: 0 -> 0
re0: flags=8843 metric 0 mtu 1500
	options=9b
	inet6 2001:db8:abcd::e prefixlen 56 tentative
plip0: flags=108810 metric 0 mtu 1500
lo0: flags=8049 metric 0 mtu 16384
	inet6 ::1 prefixlen 128
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x3
add net fe80::: gateway ::1
add net ff02::: gateway ::1
add net default: gateway 2001:db8:abcd::1
IPv4 mapped IPv6 address support=NO

You may notice the IPv6 address is marked as tentative, that’s because DAD (Duplicate Address Detection) is still validating the IPv6 address. If you run ifconfig a bit later and if you IPv6 is not a duplicate address, the tentative flag should disappear.

Test connectivity with some awesome tools…

ipv6# ping -c3 www.google.com
PING www.l.google.com (209.85.229.147): 56 data bytes
64 bytes from 209.85.229.147: icmp_seq=0 ttl=55 time=10.624 ms
64 bytes from 209.85.229.147: icmp_seq=1 ttl=55 time=10.675 ms
64 bytes from 209.85.229.147: icmp_seq=2 ttl=55 time=10.815 ms

--- www.l.google.com ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 10.624/10.705/10.815/0.081 ms

ipv6# ping6 -c3 ipv6.google.com
PING6(56=40+8+8 bytes) 2001:db8:abcd::e --> 2a00:1450:8006::93
16 bytes from 2a00:1450:8006::93, icmp_seq=0 hlim=56 time=15.562 ms
16 bytes from 2a00:1450:8006::93, icmp_seq=1 hlim=56 time=15.529 ms
16 bytes from 2a00:1450:8006::93, icmp_seq=2 hlim=56 time=15.541 ms

--- ipv6.l.google.com ping6 statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 15.529/15.544/15.562/0.014 ms

Congratulations, you now have IPv4 and IPv6 connectivity from your FreeBSD box!

VPS for rent

December 21, 2009

VPS

You need a server connected to Internet? You don’t want a shared server but you don’t want to pay for a dedicated server? exp-NETWORKS can rent you a Virtual Private Server (VPS). A VPS runs its own Linux OS with its own packages, users administration, configuration on a shared hardware. The VPS running on the same hardware are isolated from each other. [Read more]

ClamXav differential update

November 29, 2009

ClamXavClamXav is a free virus checker for Mac OS X. It uses the tried, tested and very popular ClamAV open source antivirus engine as a back end.

The default install of ClamXav does not enable the automatic virus definition update. When a user enables those automatic updates, a ‘good old cron job’ is created for that user. Three minor concerns with that method are:

  1. Each users on the system can enable the automatic updates leading to multiple redundant checks for new virus definitions
  2. The users do not have write access to ClamXav directories and are not able to create a temporary directory required for differential updates. Fortunately ClamXav fall back to a standard update where the entire virus definition file is downloaded.
  3. All the users who enable the automatic updates will get e-mails containing an error message like this one :
    clamxav ERROR: chdir_tmp: Can't create directory ./clamav-97e66bd7fbb

Only the _clamav user has write access to his directories. I’ve found several workarounds for this by googling but most of them were either not secure like setting the _clamav user’s directories world wide writable, either not elegant like putting the cron job in the root’s crontab…

The only elegant workaround I’ve found so far is still requiring some manual configuration but at least it uses Apple’s vision of daemon and recurrent tasks; it uses launchd. I won’t explain launchd here but Apple website or AFP548 website are very good start to understand its philosophy.

We will configure a launchd daemon to start the virus definition update every day at 21:30 as _clamav user. Launchd is configured via property list files (.plist) placed in appropriate directories. In this case we want the daemon to be started as long as the system is started (i.e. regardless if a user is logged or not). We will place our plist file in /Library/LaunchDaemons/.

 1. <?xml version="1.0" encoding="UTF-8"?>
 2. <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 3. <plist version="1.0">
 4.   <dict>
 5.     <key>Label</key>
 6.     <string>com.clamxav.freshclam</string>
 7.     <key>UserName</key>
 8.     <string>_clamav</string>
 9.     <key>LowPriorityIO</key>
10.     <true/>
11.     <key>Nice</key>
12.     <integer>1</integer>
13.     <key>Program</key>
14.     <string>/usr/local/clamXav/bin/freshclam</string>
15.     <key>ProgramArguments</key>
16.     <array>
17.       <string>/usr/local/clamXav/bin/freshclam</string>
18.       <string>--quiet</string>
19.       <string>--log=/usr/local/clamXav/share/clamav/freshclam.log</string>
20.     </array>
21.     <key>StartCalendarInterval</key>
22.     <dict>
23.       <key>Hour</key>
24.       <integer>21</integer>
25.       <key>Minute</key>
26.       <integer>30</integer>
27.     </dict>
28.   </dict>
29. </plist>

Lines 5-6 : define the daemon’s name
Lines 7-8 : define the user the daemon will run as
Lines 9-12 : reduce the update process priority as it is not required to run fast
Lines 13-20 : define the daemon’s executable and its parameters
Lines 21- 27 : schedule when the daemon must run

That plist file must be placed in /Library/LaunchDaemons/. It will be automatically loaded after each reboot but you can manually load it with launchctl if you don’t want to restart your computer.

$ sudo launchctl load /Library/LaunchDaemons/com.clamxav.freshclam.plist
$ sudo launchctl list | grep com.clamxav.freshclam
-	0	com.clamxav.freshclam

Now you can check in the log file (/usr/local/clamXav/share/clamav/freshclam.log) the error message has disappeared and differential update is now working fine…

ClamAV update process started at Sat Nov 28 21:30:09 2009
main.cvd is up to date (version: 51, sigs: 545035, f-level: 42, builder: sven)
Downloading daily-10091.cdiff [100%]
daily.cld updated (version: 10091, sigs: 115838, f-level: 44, builder: ccordes)
Database updated (660873 signatures) from database.clamav.net (IP: 193.1.193.64)
Clamd successfully notified about the update.

Thanks for leaving a comment if you found this useful

IPv6 Firewall with Linux

September 17, 2009

More and more server hoster have configured IPv6 on their network. And most of their Linux based servers come with a basic IPv6 configuration. Even if IPv6 is not used, it is there and widely open as the netfilter/iptables default policy is ACCEPT.

If you don’t use IPv6 at all, disable it. On Debian, the interfaces configuration is located in /etc/network/interfaces. Remove all the inet6 configuration looking like this :

iface eth0 inet6 static
  address 2001:db8:4:fe34::3ea1
  netmask 64

If you plan to use IPv6, first you have to know ICMPv6 should be filtered carefully. In IPv6, ICMPv6 is widely used. It replaces IPv4′s ARP with neighbour-solicitation and neighbour-advertisement ICMPv6 messages. It is used for router discovery via router-solicitation and router-advertisement ICMPv6 messages. It replaces IPv4′s IGMP with group-membership-query, group-membership-report and group-membership-reduction ICMPv6 messages.

Here is a small script to activate IPv6 filtering with netfilter/ip6tables. The script has been test on Debian but it should work on other Linux flavor.

#!/bin/sh -e
#
# Simple example IPv6 Firewall configuration.
#
# Caveats:
# - This configuration applies to all network interfaces
# if you want to restrict this to only a given interface use
# '-i INTERFACE' in the ip6tables calls.
# - Remote access for TCP/UDP services is granted to any host,
# you probably will want to restrict this using '--source'.
#
# description: Activates/Deactivates the firewall at boot time
#
# You should test this script before applying with safe-restart option
#

IP6TABLES=/sbin/ip6tables
#IP6TABLES="/sbin/ip6tables -i eth0"

[ -x "$IP6TABLES" ] || exit 1

# Inbound TCP ports
TCP_INPUT_PORTS="21 22 53 443"

# Inbound UDP ports
UDP_INPUT_PORTS="53"

# Allowed ICMP messages
ALLOWED_ICMP="\
packet-too-big \
destination-unreachable \
time-exceeded parameter-problem \
echo-request \
echo-reply \
router-advertisement \
neighbour-solicitation \
neighbour-advertisement"

fw_start () {
# Allow related and established connection.
$IP6TABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# Allow ICMP as defined in ALLOWED_ICMP
if [ -n "$ALLOWED_ICMP" ] ; then
 for ICMP_TYPE in $ALLOWED_ICMP; do
  $IP6TABLES -A INPUT -p icmpv6 --icmpv6-type ${ICMP_TYPE} -j ACCEPT
 done
fi

# Open allowed TCP ports if any
if [ -n "$TCP_INPUT_PORTS" ] ; then
 for PORT in $TCP_INPUT_PORTS; do
  $IP6TABLES -A INPUT -m state --state NEW -p tcp --dport ${PORT} \
  -j ACCEPT
 done
fi

# Open allowed UDP ports if any
if [ -n "$UDP_INPUT_PORTS" ] ; then
 for PORT in $UDP_INPUT_PORTS; do
  $IP6TABLES -A INPUT -m state --state NEW -p udp --dport ${PORT} \
  -j ACCEPT
 done
fi

# Allow traffic to the loopback (needed by some applications)
$IP6TABLES -A INPUT -i lo -j ACCEPT

# Log and drop all other packets.
$IP6TABLES -A INPUT -j LOG
$IP6TABLES -P INPUT DROP

# Los and drop all packet to be forwarded, we're not a router...
$IP6TABLES -A FORWARD -j LOG
$IP6TABLES -P FORWARD DROP

# We're not going to filter outgoing packets
# but you can if you're paranoid like I am...
$IP6TABLES -P OUTPUT ACCEPT
}

# fw_stop disables completely the firewall and reset all chains to
# the default policy ACCEPT
fw_stop () {
  $IP6TABLES -P INPUT ACCEPT
  $IP6TABLES -P FORWARD ACCEPT
  $IP6TABLES -P OUTPUT ACCEPT
  $IP6TABLES -t mangle -P PREROUTING ACCEPT
  $IP6TABLES -t mangle -P POSTROUTING ACCEPT
  $IP6TABLES -t mangle -P INPUT ACCEPT
  $IP6TABLES -t mangle -P OUTPUT ACCEPT
  $IP6TABLES -t mangle -P FORWARD ACCEPT
  $IP6TABLES -t mangle -F
  $IP6TABLES -t mangle -X
  $IP6TABLES -F
  $IP6TABLES -X
}

# fw_clear remove the rule set from the firewall and keep the
# current default policy
fw_clear () {
  $IP6TABLES -t mangle -F
  $IP6TABLES -t mangle -X
  $IP6TABLES -F
  $IP6TABLES -X
}

case "$1" in
  start|restart)
    echo -n "Starting IPv6 firewall.."
    fw_clear
    fw_start
    echo "done."
    ;;
  stop)
    echo -n "Stopping IPv6 firewall.."
    fw_stop
    echo "done."
    ;;
  clear)
    echo -n "Clearing IPv6 firewall rules.."
    fw_clear
    echo "done."
    ;;
  test|safe-restart)
    echo -n "Safely restarting IPv6 firewall..."
    fw_clear
    fw_start
    test=""; read -t 10 -p "Is it still OK? " test ; \
    [ -z "$test" ] && fw_stop
    echo "done."
    ;;
  *)
    echo "Usage: $0 {start|stop|restart|safe-restart|clear}"
    exit 1
    ;;
esac

exit 0

Now let’s make the ip6firewall to start at boot time :
update-rc.d ip6firewall start 41 S . stop 34 0 6 .

Now the server is only accepting packets on ports we have decided.

IPv6 Certification Badge for krik
By the way, I’ve been certified ipv6 Guru by Hurricane Electric;-)

That’s all folks!

Thanks for leaving a comment if you found this useful