Unfortunately, there is this WLAN-router-thingie at home that connects my parents' PC (and my notebook) to the internet, and as that router is an inaccesible black box I can't just ssh to it and setup 6to4 like I did with my dedicated server over at hetzner. Also, I can't get an account at sixxs, as I already got one :) to supply our dorm with an IPv6 subnet (our telco owns its own sixxs POP that is only 15ms away). I could have gotten an account at a different free IPv6 tunnel provider (e.g. Hurricane Electric), but their POPs are "far away", giving bad latency.
So I tried a different approach: set up my own tunnel to my own IPv6-enabled dedicated server at hetzner in Nuremberg.
First at all, I had to establish a tunnel between the server and my notebook. Never having used other tunneling solutions than simple ip-in-ip tunnels (which can't be used in my situation, for one reason having no public IP address for my notebook and the other being these tunnels not supporting IPv6 traffic) I decided to go with OpenVPN, assuming plenty of documentation floating around.
First at all I didn't want to use simple username/password authentication but use certificates instead. To accomplish this I had to set up my own certificate authority (CA) to generate certificates for my notebook and my server to trust each other. This can easily be done with OpenSSL, with a simple workflow:
- set up basic directory structure and initial files
mkdir CA
cd CA
mkdir certs crl newcerts private
echo "01" > serial
cp /dev/null index.txt
- copy a sample openssl.cnf file and adjust its stored parameters
cp /usr/lib/ssl/openssl.cnf .
vim openssl.cnf
Basically, you must change the dir parameter in section CA_default to /.
- create the CA certificate and the corresponding private key:
openssl req -new -x509 -keyout private/cakey.pem -out cacert.pem -days 3650 -config openssl.cnf
You can adjust the expiration date of your certificate using the --days switch; I chose 10 years (3650 days) lifetime for the CA cert, as it will be signing all other future certificates (which will have a much lower lifetime, ususally a year).
- create a "new certificate request"
openssl req -nodes -new -x509 -keyout newreq.pem -out newreq.pem -config openssl.cnf
- sign the new certificate
openssl x509 -x509toreq -in newreq.pem -signkey newreq.pem -out tmp.pem
openssl ca -config openssl.cnf -policy policy_anything -out newcert.pem -infiles tmp.pem
Now that I had my four files (two certificates signed by my CA and their private keys) I copied two of them to my notebook, as I would be using that certificate to authenticate against my OpenVPN server which was yet to be configured. I also had to copy the cacert.pem (but not the cakey.pem! This file is to be kept secure so that nobody else can obtain its contents!) to my notebook, as OpenVPN needs that on the client side, too.
Now that I had the authentication certificates, I began to set up the two OpenVPN endpoints.
I started configuring the server side; though OpenVPN can be set up using command line switches (which may be useful e.g. when testing and playing around for the first time) it is set up best using a configuration file.
After some experimentation I ended up with the following content for the server.config:
tls-server port 1194 proto tcp-server dev tun tun-ipv6 ca cacert.pem cert tg-openvpn-cert.pem key tg-openvpn-req.pem # This file should be kept secret dh dh1024.pem keepalive 10 120 persist-key persist-tunThe first five lines tell OpenVPN to act as a server with TLS authentication (i.e. "use certificates") using TCP as means of communication (OpenVPN defaults to UDP, but I got strange messages about unsendable UDP messages, so I switched to the auto-retransmitting TCP) using normal tunneling devices tunX (instead of the lower-layer-tapX-devices that can relay broadcast/multicast traffic) to avoid the need for a bridge device. The tun-ipv6 parameter allows the tun device OpenVPN will be creating to forward IPv6 traffic.
The next three lines define the certificate to be used when authenticating with the client, while the fourth line specifies a file with parameters for the Diffie-Hellman key exchange protocol; I created this file with
openssl dhparam -out dh1024.pem 1024
Now that the server has a configuration file, I moved on to the client; its client.conf looks like this:
tls-client remote server.example proto tcp-client dev tun tun-ipv6 ca cacert.pem cert doc-holodoc-vpn-cert.pem key doc-holodoc-vpn-req.pem ping 30
This is quite similar to the server's configuration; I needed to specify the server to connect to (substitute server.example above with your server's hostname or IPv4 address) and the certificate to use.
After starting up OpenVPN at the server side using
openvpn --config server.config
I started OpenVPN on my laptop using
openvpn --config client.config
The notebook connects to the server, they exchange keys etc. and from there on I was ready to go :) - I had a new network interface on each endpoint, tun0, which was not configured yet (no IP addresses, no routing information). So I wrote a small script to setup these devices on each end. First take a look at the server-side script:
ifconfig tun0 up 192.168.234.1 dstaddr 192.168.234.2 ip -6 addr add 2002:dead:beef:1::1/128 dev tun0 ip -6 route add 2002:dead:beef:1::/64 dev tun0
First, I tell tun0 to have an IP address of 192.168.234.1, while the other end of the tunnel (my notebook) has IP 192.168.234.2. Then I assign the IPv6 address 2002:dead:beef:1::1 to the local tunnel endpoint, too. While my server has a whole 2002:dead:beef::/48 subnet, I dedicate the second /64-subnet (2002:dead:beef:1::/64) to my "tunnel network" (total overkill, but hey...), while the server itself has an IPv6 address of the first subnet (2002:dead:beef:0::/64).
This way, when the server gets packets for some IP in 2002:dead:beef:1::/64 he knows to forward it to tun0 (which will send the packets to my notebook).
Now that the server-side routing is done, the client also has to setup its tun0 device and adjust its routing tables:
ifconfig tun0 192.168.234.2 dstaddr 192.168.234.1 ip -6 addr add 2002:dead:beef::1::2/128 dev tun0 ip -6 route add 2002:dead:beef:1::/64 dev tun0 ip -6 route add default via 2002:dead:beef:1::1
As you can see, this just sets the tables "the other way around"; the notebook's tun0 gets IPv4 address 192.168.234.2 while the server end has IP 192.168.234.1 (this first command makes IPv4 packet routing possible between the server and the client). After that, the IPv6 address 2002:dead:beef::1::2 is assigned to the notebook's tunnel endpoint, the routing for the first /64-subnet is set up, and the last command tells the notebook to route all outgoing IPv6 traffic through the server at the other end of the tunnel.
After running these two scripts, I had a working IPv6 connection trough OpenVPN :)
In order to minimize the commands needed to type by hand I set up OpenVPN to start automatically at the server and extended both the server's and the client's configuration file to start the respective interface/routing-configuration-scripts on successful connection of the two OpenVPN endpoints. This however was just a quick and dirty solution as it only supports one connection at a time; if I wanted multiple concurrent connections I had to change the scripts to something more dynamically adjustable - but for my simple needs, this is sufficient to provide mw with IPv6 when at home.
Keine Kommentare:
Kommentar veröffentlichen