Author
Christopher Marshall (christopherlmarshall@yahoo.com)
Raw Notes on IPv6
# some commands
# load the kernel module
insmod ipv6
# show ipv6 routes
route -A inet6
# ping a link local address residing somewhere on the LAN eth0 is connected to
# this works from one machine to another!
ping6 -I eth0 fe80::2e0:81ff:fe10:38cd
# restart sshd with ipv6 support (meaning you restart it after the kernel module is loaded),
# then connect to ssh using ipv6.
# this also works!
/etc/rc.d/rc.sshd restart
ssh -6 -l user ::1
# this is what doesn't work.
ssh -6 -l user fe80::2e0:81ff:fe10:38cd
# from searching the internet, I gather one problem may be that fe80 is a link local address and,
# as such, you have to specify an interface to use with it.
# ssh may not let you specify an interface.
# so, perhaps, if you could create a global address, and put a route for it in your routing
# table, you could ssh from one machine to another.
# Ah HA!
# This lets me connect from one machine to another.
# on A:
ifconfig eth0 inet6 add 3ffe::1/64
# on B:
ifconfig eth0 inet6 add 3ffe::2/64
# on A:
ssh -6 -l user 3ffe::2
# that's because to use tcp or udp from one machine to another requires global addresses.
# link local addresses are only for machines to discover routes, I guess.
# I can't believe I got this working!!!
# commands and documents
# the main userspace command tool for manipulating tunnels, links, and routes.
/sbin/ip
# this package contains the all important /sbin/ip command
/var/adm/packages/iproute2-2.6.7
# example of "ip link set" commands
ip link set dev eth0 up
ip link set dev eth0 down
ip link set dev eth0 arp on
ip link set dev eth0 arp off
# this would change the name of the device, supposedly
ip link set dev eth0 name eth1
# change the link layer (mac) address
ip link set dev eth0 address <lladdress>
ip link set dev eth0 mtu <mtu>
ip link set dev eth0 broadcast <lladdress>
# This is described as changing the link layer peer address in the case of point-to-point links,
# which makes no sense to me. There is no link layer address in that case.
ip link set dev eth0 peer <lladdress>
# example "ip link show" commands
# show stats on eth0
ip link show dev eth0
# only show up interfaces
ip link show up
# example "ip address add" commands
# adds an ip address to eth0. you can add a slash and prefix length if you want
ip address add dev eth0 local <ip or ip6 address>
# specifies the local and remote address on point to point links
# If you specify a peer address, the local address can't have a prefix associated with it.
# The prefix can only be associated with the peer.
ip address add dev eth0 local <ip or ip6 address> peer <ip or ip6 address>
# the label argument lets you tag an address with a name, like in ip-aliasing.
ip address add dev eth0 local <ip or ip6 address> label eth0:0
# the possible scope arguments are specified in /etc/iproute2/rt_scopes.
# they are global, site, link, and host.
ip address add dev eth0 local <ip or ip6 address> scope global
# "ip address delete" commands mirror "ip address add" commands
# example "ip address show" commands
# show all addresses assigned to eth0
ip address show dev eth0
# only show addresses with the given scope
ip address show scope <scope_val>
# only show addresses matching the given prefix
ip address show to <prefix>
# only show addresses whose labels match the shell pattern
ip address show label <pattern>
# only list addresses installed due to stateless address configuration
ip address show dynamic
# only list addresses permanent addresses
ip address show permanent
# god only knows what these mean
ip address show primary
ip address show secondary
# "ip neigh" commands
# these are about the arp cache in ipv4 and the neighbor table in ipv6
ip neigh add
ip neigh change
ip neigh replace
# and their arguments
to <neighbor ip or ip6 address>
dev <net dev>
lladdr <lladdress>
nud <nud state>
# complete examples
# we associate the mac de:ad:be:ef:ff:ff with the ipv6 address fe80::2e0:81ff:fe10:0000
ip neigh add dev eth0 to fe80::2e0:81ff:fe10:0000 lladdr de:ad:be:ef:ff:ff
# more "ip neighbor" commands
ip neigh delete
ip neigh show
# and their arguments
# prefix address selecting which neighbours to list
to <address>
# the network device
dev <name>
# only list neighbours which are not currently in use
unused
# god only knows what this means
nud <nud state>
# complete commands
# we remove the ipv6 to mac mapping for ipv6 address fe80::2e0:81ff:fe10:0000
ip neighbour delete to fe80::2e0:81ff:fe10:0000
# "ip route" commands
ip route add
ip route change
ip route replace
# route types
unicast
unreachable
blackhole
prohibit
local
broadcast
throw
nat
anycast
multicast
# arguments
to <address/prefix>
tos <tos>
dsfield <tos>
metric <number>
preference <number>
table <number or string from /etc/iproute2/rt_tables which includes main, local, and nat>
dev <network dev>
via <address or next hop router or, for NAT routes, the first address in the block of translated IP destinations>
src <source address to prefer when sending to this destination>
scope <scope value>
# RTPROTO is one of redirect, kernel, boot, static, ra.
protocol <RTPROTO>
# this is a cute one. IT takes its own subarguments: via, dev, and weight. It is for
# specifying mulipath routes that are switched between. A form of load balancing,
# in a sense
nexthop <NEXTHOP>
# more "ip route commands"
# takes the same arguments as "ip route add"
ip route delete
# more "ip route commands"
# this will only show you ipv4 info, for some reason
ip route show
# this will show you ipv6 info
ip -f inet6 route show
# arguments
to
tos
table
cloned
cached
from
protocol
scope
type
dev
via
src
realm
realms
# This command gets a single route to a destination and prints its contents as the kernel sees it.
ip route get to <address> from <address>
# a routing example using a ppp link
# on A
ip address add dev ppp0 3ffe::1
ip route add dev ppp0 3ffe::0/64
# on B
ip address add dev ppp0 3ffe::2
ip route add dev ppp0 3ffe::0/64
ping6 3ffe::1
ssh -l user 3ffe::1
# I would have though this would work but it doesn't
# perhaps local and peer are ipv4 only concepts for pointtopoint links?
# on A
ip address add dev ppp0 local 3ffe::1 peer 3ffe::2
# on B
ip address add dev ppp0 local 3ffe::2 peer 3ffe::1
ping6 3ffe::1
ssh -l user 3ffe::1
# ip tunnels
# ip tunnel commands
ip tunnel add
ip tunnel change
ip tunnel delete
# arguments
name <name of tunnel device>
mode <ipip, sit, or gre>
remote <address of remote endpoint>
local <address of local tunnel endpoint. must be an address of another interface of this host>
ttl <N>
tos T
dsfield T
dev <name of net dev to force tunneled packets to traverse to prevent escape when endpoint changes>
nopmtudisc
key <key to use for GRE tunnels in both directions>
ikey <key to use for GRE tunnels for input packets>
okey (key to use for GRE tunnels for output packets>
csum, icsum, ocsum
seq,iseq,oseq
# this command lists tunnels
ip tunnel show
# experiments
# GRE ip6 on ip4 tunnel
# I wasn't able to get an ip6 on ip6 tunnel going
# the ip route commands don't seem to be necessary.
# they are implied by the preifx length in the address assigned to the interface
# I mismatched the keys to see if it would prevent communication and it did.
# the key has to be either a number or an ip address-like dotted quad. Does that mean
# only 32 bit keys? Isn't that awful?
A:
ip address add dev eth0 3ffe::1/64
ping6 3ffe::2
modprobe ip_gre
ip tunnel add tun1 mode gre dev eth0 key 1234567890 local 12.26.73.160 remote 12.26.73.158
ip link set tun1 up
ip address add dev tun1 3ffd::1/64
ip route add dev tun1 3ffd::/64
ip route show table all
ip link set tun1 down
ip tunnel del tun1
B:
ip address add dev eth0 3ffe::2/64
ping6 3ffe::1
modprobe ip_gre
ip tunnel add tun1 mode gre dev eth0 key 1234567890 remote 12.26.73.160 local 12.26.73.158
ip link set tun1 up
ip address add dev tun1 3ffd::2/64
ip route add dev tun1 3ffd::/64
ip route show table all
ip link set tun1 down
ip tunnel del tun1
# ipv4 compatible ipv6 addresses
# these are used to carry ipv6 packets over an ipv4-only routing infrastructure
# with automatic tunneling.
# the address format it ::a.b.c.d/96, where a.b.c.d is the ipv4 address a dual stack node
# has as far as the ipv4 routing infrastructure is concerned.
# you enable this by adding the route ::/96 to whatever link connects you to the ipv4 network.
A:
ip address add ::10.0.0.1 dev eth0
ip route add ::/96 dev eth0
B:
ip address add ::10.0.0.2 dev eth0
ip route add ::/96 dev eth0
A:
ping6 ::10.0.0.2
# after you have set this up, you will notice a GRE tunnel device has been created
# to handle it.
# I've tested this between two IP6 hosts on an ethernet, but that is not much of a test.
# I think you would need a minimum of three machines with two lan segments to test this
# fully (A6-B4-C4-D6), and you would have to prevent B4 and C4 from talking ip6 to each other
# (I believe you could do that by deleting ip6 addresses from the appropriate B4->C4 and C4->B4 links).
# You would ping6 from A to D, and by running tcpdump on B-C you would see ipv4 packets carrying the icmp6
# packets.
# ipsec
# setkey
# the main ipsec userspace tool
# manipulates the SAD (secutiry association database) and the SPD
# (security policy database)
# dump the SAD entries
setkey -D
# dump the SPD entries
setkey -D -P
# flush SAD entrie
setkey -F
# flush SPD entries
setkey -F -P
# the following two scripts show how to encrypt all traffic between 12.26.73.160 and
# 12.26.73.45
# this script is run on 12.26.73.160:
#!/bin/bash
# ipsec-ex-1.sh
key="5eda6794e8a9bd89491bec9dc66b52da"
modprobe ah4
modprobe ah6
modprobe esp4
modprobe esp6
(
echo "flush;"
echo "spdflush;"
# security associations
echo "add 12.26.73.160 12.26.73.45 esp 20000 -E rijndael-cbc 0x${key} ;"
echo "add 12.26.73.45 12.26.73.160 esp 20001 -E rijndael-cbc 0x${key} ;"
# security policies
echo "spdadd 12.26.73.160 12.26.73.45 any -P out ipsec"
echo " esp/transport//require;"
echo "spdadd 12.26.73.45 12.26.73.160 any -P in ipsec"
echo " esp/transport//require;"
) | setkey -c
# and this one on 12.26.73.45:
#!/bin/bash
# ipsec-ex-2.sh
key="5eda6794e8a9bd89491bec9dc66b52da"
modprobe ah4
modprobe ah6
modprobe esp4
modprobe esp6
(
echo "flush;"
echo "spdflush;"
# security associations
echo "add 12.26.73.160 12.26.73.45 esp 20000 -E rijndael-cbc 0x${key} ;"
echo "add 12.26.73.45 12.26.73.160 esp 20001 -E rijndael-cbc 0x${key} ;"
# security policies
echo "spdadd 12.26.73.160 12.26.73.45 any -P out ipsec"
echo " esp/transport//require;"
echo "spdadd 12.26.73.45 12.26.73.160 any -P in ipsec"
echo " esp/transport//require;"
) | setkey -c
# policies, unlike associations, can use address ranges in
# "address/prefix" notation, so you could write
# a single script to run on both like this:
#!/bin/bash
# ipsec-ex-3.sh
key="5eda6794e8a9bd89491bec9dc66b52da"
modprobe ah4
modprobe ah6
modprobe esp4
modprobe esp6
(
echo "flush;"
echo "spdflush;"
# security associations
echo "add 12.26.73.45 12.26.73.160 esp 20000 -E rijndael-cbc 0x${key} ;"
echo "add 12.26.73.160 12.26.73.45 esp 20001 -E rijndael-cbc 0x${key} ;"
# security policies
echo "spdadd 12.26.73.0/24 12.26.73.0/24 any -P out ipsec"
echo " esp/transport//require;"
echo "spdadd 12.26.73.0/24 12.26.73.0/24 any -P in ipsec"
echo " esp/transport//require;"
) | setkey -c
# radvd
# radvd is the ipv6 router advertisement daemon
#
# The simplest thing you can do is advertise a prefix on a link and have nodes
# global addresses from it. The references I looked up said you should use an 80
# bit prefix for global address autoconfiguration because the address would be
# composed of the prefix and the 48 bit ethernet mac address. When I tried this,
# however, I noticed a syslog message on the client host like this:
ADDRCONF: prefix with wrong length 80
# I looked at the kernel code in ipv6/addrconf.c and noticed that it would only accept
# 64 bit prefixes for address autoconfiguration. I then noticed an RFC on ipv6 privacy
# concerns (I forget the number) and it talked about how embedding the 48 bit ethernet address
# in a globally unique address was bad for privacy and this had been changed to the 64 bit
# prefix scheme.
#
# after copying this to /etc/radvd.conf :
interface eth0 {
AdvSendAdvert on;
prefix 5f15:9100:c2dd:1400::0/64
{
AdvOnLink on;
AdvAutonmous on;
};
};
# before starting radvd, you enable forwarding with
echo "1" > /proc/sys/net/ipv6/conf/all/forwarding
# you can start radvd like this
radvd -d 4 -m stderr
# which will set the debug level to 4 (the highest) and write debug statements to stderr
# instead of to syslog.
# I've noticed that radvd doesn't automatically put itself in the background. In a
# startup script it would have to be started like this, which is unusual:
radvd &
