sudo modprobe dummy sudo ip link add rvl0 type dummy sudo ifconfig rvl0 up
route add -net 10.0.0.0 netmask 255.255.255.0 dev rvl0
route delete -net 10.0.0.0 netmask 255.255.255.0 dev rvl0
sudo ifconfig rvl0 down sudo ip link delete rvl0 type dummy sudo rmmod dummy
IPPROTO_RAW is protocol number 255.
http://www.pocketnix.org/posts/Linux%20Networking:%20Dummy%20Interfaces%20and%20Virtual%20Bridges http://unix.stackexchange.com/questions/152331/how-can-i-create-a-virtual-ethernet-interface-on-a-machine-without-a-physical-ad
http://osdir.com/ml/lang.haskell.libraries/2006-05/msg00076.html
http://www.arrowmail.co.uk/articles/iprange.aspx
From the command line, the following is a good starting point openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 30
Clients also expect the hostname and common name to agree (when setting ClientParams). Certificates need to abide by this.
Clients also need to know whether they can trust a certificate or not. Add trusted certificates to Shared’s sharedCAStoreCertificates can be loaded using readSignedObject (Data.X509.File), and translated to CertificateStore by makeCertificateStore (Data.X509.CertificateStore).
Could use a SHA hash to pass condensed certificate check to others. ClientHooks can be used on receipt of a certificate, to check it against a hash, and add it to a database.
To get TLS working: use contextNew backend params –randomNumGen? NOTE: A context should be made on a connection with a client, not just a listening socket. params : Client params and Server params serverParams = ServerParams … https://hackage.haskell.org/package/tls-1.2.2/docs/Network-TLS.html#g:6 Socket is an instance of HasBackend, so contextNew can be passed a socket. ClientParams is an instance of TLSParams, as is ServerParams (missing from documentation, but ghci confirms). NOTE: contextNew doesn’t appear to need a random number generator. Where on earth did I find CPRG?
ServerParams = ServerParams { serverWantClientCert :: Bool, serverCACertificates :: [SignedCertificate], serverDHEParams :: Maybe DHParams, serverShared :: Shared, serverHooks :: ServerHooks, serverSupported :: Supported }
Can get defaults by using def from Data.Default.Class
The old Network.TLS.Extra provides: fileReadCertificate :: FilePath -> IO X509 fileReadPrivateKey :: FilePath -> IO PrivateKey This is replaced by: credentialLoadX509 :: FilePath -> FilePath -> IO (Either String Credential) Note passphrases make this fail, remove passphrases with openssl rsa -in keyIn.pem -out keyNoPassphrase.pem or see http://serverfault.com/questions/366372/is-it-possible-to-generate-rsa-key-without-pass-phrase The option -nodes (No DES) will stop the key being encrypted.
Then credentialLoadX509 “cert.pem” “key.pem” loads the certificate.
Since on the fly (non-interactive) generation is also desirable, one can do this. E.g. http://crohr.me/journal/2014/generate-self-signed-ssl-certificate-without-prompt-noninteractive-mode.html http://unix.stackexchange.com/questions/104171/create-ssl-certificate-non-interactively
SystemRNG is probably enough (looking for an instance of CPRG) Actually, not required for contextNew
Using {-# LANGUAGE OverloadedStrings #-} with import Data.String to use ByteStrings with fromString (i.e. abstract string datatype ala Num)
DTLS is for unreliable transport protocols. May be useful for tunneling UDP etc.
aNY_PORT can be passed as a port number if a dynamically allocated port is required. Since I need many connections this is useful. There are functions available to discover this number also. Since I want asynchronous communication, each correspondence will have two sockets. It makes sense for these to be bound to a port to simplify port mapping etc. Also iNADDR_ANY for receiving from any interface (handy, since typically IP isn’t static).
Need to manage these for tunnelling!
http://www.upnp-hacks.org/igd.html
Probably the way needed to get a peer-to-peer system up and running. Haskell has the package stunclient, which provides the module Network.Stun This required libicu-dev to be installed in order that dependency text-icu can be installed.
Have separate(s) thread sending and receiving messages to each peer to keep connections alive.
Point-to-point protocol, can be used to deliver packets. Good idea here?
If STUN fails then TURN. Free (with sign up) TURN server http://numb.viagenie.ca/
https://downloads.haskell.org/~ghc/7.0.4/docs/html/Cabal/authors.html
http://blog.bjrn.se/2008/09/speeding-up-haskell-with-c-very-short.html
Small VPN for creating mesh networks. No server client structure.
Don’t want incoming packets (to be routed) to be too large to tunnel. If the TUN devices MTU (Maximum Transmission Unit) is set low enough, then enough room should be preserved to add a header and send it.
Wrapping Async might be the best way
Custom async spawning system, with a culling thread removing dead submanagers from a list.
Probably will follow from the above.
c-sources: src/Network/tuntap.c ghc-options: -O2 -threaded
http://nategood.com/client-side-certificate-authentication-in-ngi
app/ ├── Command │ ├── CliTypes.hs │ ├── CommandLine.hs │ ├── Interaction.hs │ └── Types.hs ├── Command.hs ├── Config │ └── Types.hs ├── Config.hs ├── Control │ └── Concurrent │ └── Stack.hs ├── Debug │ └── PacketParsing │ ├── Ether.hs │ ├── IP4.hs │ └── Parsing.hs ├── Main.hs ├── Manager │ ├── Manage.hs │ ├── Manager.hs │ └── Types.hs ├── Manager.hs ├── Network │ ├── tuntap.c │ ├── tuntap.h │ ├── TunTap.hi │ ├── TunTap.hs │ ├── tuntap.o │ └── TunTap.o ├── Relay │ ├── Connection.hs │ ├── Debug.hs │ ├── Interface.hs │ ├── Relay.hs │ └── Stun.hs ├── Routing │ ├── Routing.hs │ ├── RoutingTable │ │ └── Internal.hs │ └── RoutingTable.hs ├── Types.hs └── Utils.hs
All library functions should be imported with namespaces. This allows us to use more obvious variable names in the source.
Typically not very uniform, and quite hard to read. Short names are good, but often one finds oneself doing some processing of some input, and its not clear what to call this input. Maybe some factoring is required to avoid these steps, or maybe good names or datatype wrappers can be used to clear this up. Namespaced imports may help here.
Command contains Manager instances which setup sockets for communication with peers, and add entries to the routing table.
There are also functions which create a basic command line, and specify a communication protocol with the Manager instances to do this.
Contains parser function and parsing instances for various configuration data types.
Contains algebraic datatypes for various configuration objects.
Control structures for threads which depend uppon one another.
Generally useful debuggin functions for looking in to packets etc.
Launches the program, specified as a Stack (). Loads and parses the configuration file.
Manager.hs contains interface functions for spawning new Manager threads, and querying the environment.
Defines a function to run a manager, and implements the internal submanager thread tracking and exception handling mechanisms.
Tools for opening TUN devices. Could use some embellishment. Deferring for now, but will set as an ongoing task.
Contains the typeclass for abstracting away connections, and a utility function for resolving addresses.
Contains a connection typeclass instance which is just standard input and output. Not really used. Will probably be removed at some point in the future.
Create UDP sockets, and turn them into abstract connections.
Contains a function which spawns a send and receive thread which reads from a queue of packets and writes to a queue of packets, given a connection function.
Currently not in use, but contains experimental stubs for creating STUNned connections.
Contains functions to build routers and route packets.
Contains functions for building and manipulating routing tables.
Types.hs and Utils.hs could use a little rearranging. They contain types and functions for ubiquitous data.
The code should be polished to make it as readable as possible.
Factor out submanager tracking?
Embellish and improve network tools, i.e. creating TUN devices.
Here we present a basic overview of how the VPN works internally. We start with an overview of the core of the application, before looking more closely at how the individual components work.
At its core the VPN is just a router, consisting of a lookup table describing a mapping of virtual addresses to enpoints. The core of the application is heavily threaded, with packets (`ByteStrings`) passed around on Queues between threads for processing. Threads in Haskell are cheap (they are implemented as user space threads on top of a pool of OS threads), and so they are used liberally, and Software Transactional Memory provides exception safe threadsafe data passing.
There are several threads which form the backbone of the application. If one of these fails, the entire application should fail gracefully, and so they are specified as a linked data structure, called a `Stack`. Running the stack consists of instantiating these threads in such a way that an exception in one brings the rest down cleanly. This is defined in Control.Concurrent.Stack.
Our stack of critical threads consists of the following:
- the routing thread
- a thread pulling packets off of a tun device
- a thread putting packets on to a tun device
- a root Manager instance — connections are spawned from this and the Queues (for thread communication) placed in the routing table.
- a command thread; this is presently a primitive command line interface, but in the future will be more sophisticated, looking to an external bootstrap node to gather information on the network, and creating/authenticating connections etc.
The code for the routing, and reading and writing to the tun device is reasonably straightforward. The tun device has a small C driver which is interfaced to Haskell, and then operated with a bracketed operation `withTUN`, which ensures exception safety.
Want to load a configuration file and then automatically connect to our network. Need a central point of truth and an interface to this point.
Ultimately we need this to do STUN. We only want to connect with endpoints which are trusted. A central node is perhaps the most vulnerable point, so security of the entire network should not depend on the security of the central node. However, the central node should not contain excessive information.
So:
- TLS by default (of course).
- Endpoints can write to server if the endpoint has the appropriate key on the machine.
- Access rights tied to what key you are using. Each network has
several directories for communicating and keeping track of the
state of the network. There is
a) a list of connected nodes (possibly using hashes of some descriptor to describe them). Accessible to anyone with a valid network certificate. b) a store of public keys which is not readable by anyone apart from the node. However, it is writable indirectly by the nodes to introduce new trusted nodes, and distrust (possibly compromised) nodes.
each node has
c) an announce space where messages can be put d) a request space where other nodes can write requests (but not read).
New users can be added by generating one use only keys to set up an initial connection, and then generating a new key for use in the network. This new key can be shared around the already established network using the peer-to-peer connections, so that encrpytion can be guaranteed to be end-to-end.
Around September 2016, it was decided that the software should be divided in to two components, a piece to manage the dataplane, and another piece to manage to control plane.
- Dataplane
- Can provide a record of the current state of connections between nodes in the network
- Can initiate new connections to nodes in the network if asked
- Can time out connections / connection attempts if it needs to
- Can enforce certain policies about connections that are made (e.g. all authenticated, and encrypted). These settings would be global, and not fine grained.
- Is responsible for maintaining connections until it is asked to pull them down.
- Creates and manages certificates, identities, keys etc. for individual connections.
- Control plane
- Has the overall view of what the network should look like.
- Can ask the dataplane what the network currently looks like.
- Can ask the dataplane to create a certain kind of connection.
- Makes the decisions over which connections should be set up and torn down.
- Maintains certificates/keys etc. for connections to the bootstrapping node.
- Can ask the dataplane to create (ephemeral) credentials for a new endpoint.
POST/PUT to create a STUNned socket (returns address) : newSocket (take user, yield Socket), stunSocket (take socket, yield address) Update (PUT) to connect (connectSocket (yieldSuccess or failure)) DELETE to tear down. (delete : take user, yield ())