Sep 162014

I have fully functioning IPv6 network at home for a while now. I used to do tunneling but for last year or so, I have native IPv6 to my home router. And everything works really nice. Problem arises when I am not at home and I want to do some IPv6 development and I want some proper (other than link-local) IPv6 addresses assigned. There are many ways to deal with this, but I found that virtual IPv6 router works the best for me.

For this I started with preparation of the VirtualBox machine (any virtualization environment will do) for the 64-bit Linux Red Hat. Only change to the defaults was enabling the second network interface (either Bridged or Internal). That was the network I intend to use for the IPv6 router advertisement.

After installing the CentOS 7.0 Minimal Install Image onto the newly created virtual machine, there are a few manual steps needed.

First was actually enabling DHCP so additional packets can be installed. After verifying which network interfaces are present using the ip addr (I had enp0s3 and enp0s8), I edited both network startup files (/etc/sysconfig/network-scripts/ifcfg-enp0s3 and /etc/sysconfig/network-scripts/ifcfg-enp0s8) by changing the ONBOOT setting to yes followed by a network restart:

# service network restart
Restarting network (via systemctl):    [  OK  ]

With Internet working, I was ready for installing IPv6 Router Advertisement Daemon:

# yum install radvd


In /etc/radvd.conf I added the following content:

interface enp0s8
    AdvSendAdvert on;
    MaxRtrAdvInterval 5;
    prefix 2001:db8:42::/64;

This is followed by service start (and enabling it on boot):

# systemctl start radvd.service
# systemctl enable radvd.service

Now any IPv6 capable network adapter sharing the same network with second VirtualBox network interface will get our defined IPv6 prefix.

PS: Advertisement time is intentionally kept very short. I find it useful to get quick unsolicited router advertisement messages for the demonstration purposes.

Sep 142014

IPv6 Talk 2014Today I gave a talk at the Seattle Code Camp.
Wonderful atmosphere, excellent organization, and a plenty of fun. Only bad thing was that it ended too soon (single day only).

My session was mostly geared toward the beginners and it covered just the basics of IPv6 and how we can use it from C#. I can only hope I lit some IPv6 fire in the great crowd that came.

I went to many other sessions myself and, while they did vary in quality, there was not a single bad one. My day was definitely fulfilled.

Feel free to download slides and examples.

Sep 092014

In my last post I described how to do the client-authenticated TLS and one of magic ingredients there was a certificate with the private key in the form of .pfx files.

Server and client certificates are essentially the same but I’ll show creating of both anyhow. For this I will assume that your Windows SDK files are in the C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\ and that we are storing files in the root of the drive D:

> cd "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\"

> makecert -n "CN=MyServer" -r -sv D:\server.pvk D:\server.cer

> makecert -n "CN=MyClient" -pe -r -sv D:\client.pvk D:\client.cer

> pvk2pfx -pvk D:\server.pvk -spc D:\server.cer -pfx D:\server.pfx

> pvk2pfx -pvk D:\client.pvk -spc D:\client.cer -pfx D:\client.pfx

> DEL D:\client.cer D:\client.pvk D:\server.cer D:\server.pvk

This results in the server.pfx and client.pfx files. We can opt to import them into the Windows Certificate Store (also possible with makecert command) or to use them directly as in this example.

Sep 022014

Thanks to NSA, most probably every developer is aware of the HTTPS and the underlying TLS (or older SSL). While most scenarios involve authentication of a server, authentication of a client is often overlooked.

If you wonder what you gain, just be reminded of key-based authentication in the SSH. No need to exchange username/password with every client. You just exchange a (safely stored) key and you know who is on the other side.

Distribution and a safe storage of the client certificate is a non-trivial problem but easily handable on a smaller scale. Windows certificate store is not too bad and the client authentication makes it easy to block keys that aren’t trusted any more.

Here is the example code of a simple TLS encrypted TCP client/server with a self-signed certificates. Of course, one would expect proper certificates to be used in any production environment, but these will do in a pinch.

First we need to setup a server using just a standard TCP listener with a twist:

var serverCertificate = new X509Certificate2(ServerCertificateFile);

var listener = new TcpListener(IPAddress.Any, ServerPort);

while (true) {
    using (var client = listener.AcceptTcpClient())
    using (var sslStream = new SslStream(client.GetStream(), false, App_CertificateValidation)) {
        sslStream.AuthenticateAsServer(serverCertificate, true, SslProtocols.Tls12, false);

        //send/receive from the sslStream

Client is equally simple:

var clientCertificate = new X509Certificate2(ClientCertificateFile);
var clientCertificateCollection = new X509CertificateCollection(new X509Certificate[] { clientCertificate });

using (var client = new TcpClient(ServerHostName, ServerPort))
using (var sslStream = new SslStream(client.GetStream(), false, App_CertificateValidation)) {
    sslStream.AuthenticateAsClient(ServerCertificateName, clientCertificateCollection, SslProtocols.Tls12, false);

    //send/receive from the sslStream

Only trick in validation is to allow certificate chain errors. That is needed for self-signed certificates to work:

bool App_CertificateValidation(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) {
    if (sslPolicyErrors == SslPolicyErrors.None) { return true; }
    if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors) { return true; } //we don't have a proper certificate tree
    return false;

It is really this simple to convert any TCP socket code into the encrypted TLS.

Full example is available for download.