CloudVPN 1.0.x configuration howto¶
If you quickly need to get the thing working, read this. Alternate way to setup CloudVPN is by reading&understanding README, after which it usually gets trivial.
To be straightforward, I divided all the things into steps:
1. Get it working on your platform¶
We currently support and are tested on Linux (2.6), FreeBSD and OpenBSD. Linux should work out of the box, BSDs need some tuning before the launch.
On FreeBSD there's no tunctl device, so you need to create tap0 by hand:
ifconfig tap0 create
Also, iface configuration syntax is a little different from Linux, you probably want this:
iface yes iface_device tap0
OpenBSD uses tun that is slightly different than what the universe is used to see. You don't have a TAP device, only the tun device which is configured to use ethernet frames. You can set it up this way:
ifconfig tun0 create --probably not needed, there's 4 tun devices by default ifconfig tun0 link0 --set the device to ethernet mode
Configuration then seems just like on FreeBSD, you just don't give it iface_device "tap*", but use "tun*" instead.
2. decide the network topology¶
You will have to know at least the nodes that act as a server. (for most usages, this will be only one node, so it really doesn't need much care)
If you plan to use some kind of more complicated topology, probably draw a small map with arrows between computers showing which node will connect where. Double connections (on a pair of two adjacent nodes) are allowed, you just let both of the nodes listen, and tell them to connect to each other. Mark all the nodes you want listening (every one which has an arrow pointing to).
3. generate some keys¶
For running CloudVPN you need this:
- CA certificate for verifying server/client connections
- Your private key, and corresponding certificate, verifiable by the CA certificate above.
- Diffie-Hellman parameters for safe connection negotiation
Network is designated by usage of certificates signed by the same Certificate Authority. Therefore we need a certificate authority. You can generate it by any OpenSSL tool, or by direct OpenSSL usage, or use keygen supplied with the cloudvpn:
mkdir vpn-keys cd vpn-keys export PATH="/path/to/keygen/dsa/directory:$PATH" gen-ca ...fill in some values... ca-selfsign ...because we don't really need any verisign-like popularity...
Now, you will probably need some server keys. If you are generating more keys, use some simple bashing. Also please remember that you MUST supply different common name to each of the generated keys, otherwise OpenSSL key database gets mad. After that you just sign the key by your generated CA.
Also consider available documentation to decide between using RSA and DSA, and check for minimum suggested key sizes (which is around 4k for RSA and 2k for DSA).
KEY=server.key REQ=server.req gen-key REQ=server.req OUT=server.crt ca-sign
Note that client key generation is basically the same, clients and servers dont differ in any kind of key usage. Only problem is about that the clients usually generate the keys themselves, then mail the .req requests to you and expect that you sign them and send them back.
Diffie-Hellman parameters are generated for each node using gen-dh script. Size of 1024 bytes is usually strong enough.
OUT=dh.pem SIZE=1024 gen-dh
Now, send corresponding keys and certificates to each host, KEEP the CA key for yourself (because who owns it, owns your network), and remember the file names to the next step
4. Writing a configuration file¶
Config files are simple tab-separated name-value text files. As we are writing a simple config file here, let's follow the example here:
#CloudVPN example config #If the line starts with #, it's commented out. # #You can include other configuration files by using: # @include some/file.cfg #(note the `@' ) #basic SSL setup ca /etc/cloudvpn/ca.crt key /etc/cloudvpn/some.key cert /etc/cloudvpn/some.crt dh /etc/cloudvpn/dh.pem #if you have your key passworded, provide the password here: key_pass myp4s5w0rd #now decide whether you want local tun/tap interface or not. #If a node has an interface, it gets a mac-address, and can #use the virtual network. If not, it acts only as "headless" router. #Note that setting up such virtual network device needs root privileges. #That also means that pure CloudVPN server doesn't need root account. #Usually you want to use the network, so just choose "yes" iface yes #now define some tun/tap parameters. This is the TUN device #created by MAKEDEV 10 200. Default location is /dev/net/tun #so change it if you happen to have some weird kernel or udev config. tunctl /dev/net/tun #if you want to use exact MAC address, use this. Otherwise you will have #randomly generated one. Remember NOT to choose a broadcast address #(any address that has the 01:00:00:00:00:00 bit set, is broadcast.) mac c0:00:10:12:34:56 #if cloudvpn dies (which should happen only if you kill it), this #saves the interface for next cloudvpn instance (so for example IP #doesn't reset, and it usually doesn't even close TCP connections. #iface_persist no #select the network interface you want to use (tap0, tap1, ...) #iface_dev tap9 #Now, select IPs on which to listen, and IPs to which to connect. #syntax is: #listen/connect -whitespace- IP -space- PORT #This way we listen on IPv4 port 15135, and IPv6 port 15136 listen 0.0.0.0 15135 listen :: 15136 #You can also bind the connection to certain IP, for example to listen #on local LAN only, use this: listen 192.168.0.0 15137 #Now connect to someone: connect cvpn.myserver.com 15135 connect 192.168.1.1 15137 #...repeat as needed, you will be connected to all of specified hosts. #Note that repeating one connection entry is not an error, it just #connect to that host using more parallel connections. (so one could #say that it's more reliable or whatever...) #For greater security, let's switch to some unprivileged user. user nobody group nobody
Although those are the most needed configuration options, if you're planning some very large or specialized network, you should replace some of the other values, which are all described in supplied README file.
5. running the thing¶
First thing you need to know is that CloudVPN is NOT written as a daemon, and will probably never daemonize itself. That greatly simplifies some things, and moves the responsibility for daemonizing and service-management stuff to tools that are supposed to do this. CloudVPN log is printed to stdout, so you can just catch it and pipe it to some file, or configure a logger to handle it.
To simply run CloudVPN, use this:
cloudvpn -@include /etc/cloudvpn/config
Note that options passed to the executable are treated as normal config options, only specified in format with a `-': -optionname optionvalue. Note that when connecting, you must specify that port number is the part of the same option value, for example by doublequoting it:
cloudvpn -@include /etc/cloudvpn/ssl_keys_config -iface yes -connect "vpn.org 15135"
Fact that the CloudVPN itself is not a daemon doesn't necessarily mean it's not able to run as a daemon. Simple usage of shell and setsid (or nohup, or whatever) will do the magic for us, and the output can be simply redirected to form a log file:
setsid cloudvpn -@include some/config >>/var/log/cloudvpn.log &
If you want the CloudVPN to be scriptable by a kind of initscipt, just follow
its guidelines. Wrapping anything like start-stop-daemon around is pretty
simple, and (more probably) some ready-to-use iniscript for your favorite
distribution will be available in extras/ folder
6. Getting some real results¶
As CloudVPN doesn't assign any IP addresses to the virtual interfaces, you have to do it by yourself.
--- on node A: $ ifconfig tap0 10.1.0.1 --- on node B: $ ifconfig tap0 10.1.0.2 $ ping 10.1.0.1 PING 10.1.0.1 (10.1.0.1) 56(84) bytes of data. 64 bytes from 10.1.0.1: icmp_seq=1 ttl=255 time=9.73 ms 64 bytes from 10.1.0.1: icmp_seq=2 ttl=255 time=1.61 ms 64 bytes from 10.1.0.1: icmp_seq=3 ttl=255 time=1.66 ms 64 bytes from 10.1.0.1: icmp_seq=4 ttl=255 time=1.60 ms 64 bytes from 10.1.0.1: icmp_seq=5 ttl=255 time=1.60 ms 64 bytes from 10.1.0.1: icmp_seq=6 ttl=255 time=1.70 ms ^C --- 10.1.0.1 ping statistics --- 6 packets transmitted, 6 received, 0% packet loss, time 5009ms rtt min/avg/max/mdev = 1.601/2.987/9.736/3.018 ms
If you are creating a larger network, you might consider attaching a dhcp-daemon to one node, so every new node can do a classical DHCP query for an address. I recommend dnsmasq or dhcpd.
7. troubleshooting¶
General rules if something doesn't work are:- See the output (or the log, where the output is redirected). Critical errors don't pass silently.
- See and check the configuration for spelling mistakes (they are not checked).
- Read this howto again, see the README (because it contains updated information)
- One of the following:
- See the source and fix it yourself, then mail me about it (I will appreciate it)
- Mail me about it (I will appreciate it too, best if you write it like a helpful bugreport), and I will fix it for you.
- Try again
common questions¶
Why does it complain that I have "No CA certificates specified"? -- You are either providing a bad file with certificates (check for "-----BEGIN CERTIFICATE-----" line) or using the wrong option name (it was named "ca_cert", since 1.0.6 it's just "ca").
Should I use DSA or RSA keys? -- No idea, it's your choice. DSA are generally considered harder to bruteforce, and are used in similar security situations, like in ssh. RSA is commonly used in situations where the security doesn't rely solely on machines, and where performance is needed (because there's often some custom hardware designed to handle RSA efficiently, I mean embedded devices, mainframes and similar stuff.)
CloudVPN is transferring data around 10% slower than my internet can do! -- This is because of several reasons. First, the VPN carries the ethernet frames in another tcp/ip/ethernet frames, which adds some bandwidth. Then there's some protocol that nodes use to communicate, which also takes some. And finally, there is SSL encryption with negotiations, which usually increases data size around 5% (note if you are sending lots of similar data (zeroes only), OpenSSL will compress them, so you can get even 20 times the bandwidth you really have!)
Is the ethernet bridging possible? (like in 802.1D) -- Yes, it is. It's basically the same as with any other VPN:
- Create bridge interface (say, br0. we are linuxing don't we?)
- Assign interfaces to the bridge, add them 0.0.0.0 IPs, set correct br0 IP
- Use iptables to set policy ACCEPT on all interfaces' INPUTs and on the FORWARD, enable IP forwarding
- enable the CloudVPN 'bridge_mode' option! add 'bridge_mode yes' to the configuration file, otherwise it will fail. There are also some other options you might want to consider, these are described in README.
- on BSDs and other platforms please use the corresponding manual.
Does CloudVPN accept certificate revocation lists? -- Yes. Take it as a protection against a user who became rogue (or just did bad stuff). It's not simple to be perfectly secure and effective - as CloudVPN is decentralized, we have no method to provide a central CRL registry, so I decided to leave the CRL distribution on users. The list should be copied to all nodes that the rogue user can connect to, and specified by the 'crl' option. See README for details.
Can I somehow see what CloudVPN is doing? -- Yeah. Apart from the logs, we have a cool status export, which can be (for example) reformatted and displayed on server's website or so. It's activated by 'status-file' option (see README).
What do the numbers mean? -- Here are sample status exports:
cloudvpn status uptime: 103.176s --how long the server is running local interface: 00:ff:9f:57:75:75 --local mac address listening sockets: 1 connections: 2 connection 0 ping 1923 route count 3 (fd 6) --all pings are in usec (so this is 1.92ms ping) = connected to addr `127.0.0.1 57091' >> in 7.46KiB/s, 85pkt/s; total 379.68KiB, 3.22Kipkt --current speed and total data transferred << out 179.76KiB/s, 124pkt/s; total 6.74MiB, 4.73Kipkt `--route to 00:bd:58:4a:05:00 dist 2 ping 1795 -- "route" is an information telling `--route to 00:bd:d4:67:02:01 dist 0 ping 1 -- how the mac address is reachable `--route to 00:ff:9f:57:75:75 dist 1 ping 2959 connection 1 ping 1724 route count 3 (fd 7) = connected to addr `127.0.0.1 57092' >> in 1.88KiB/s, 2pkt/s; total 238.78KiB, 261pkt << out 1.88KiB/s, 2pkt/s; total 239.61KiB, 272pkt `--route to 00:bd:58:4a:05:00 dist 0 ping 1 `--route to 00:bd:d4:67:02:01 dist 2 ping 6608 `--route to 00:ff:9f:57:75:75 dist 1 ping 5 --- --this is sum of all transfers, from the beginning >> total in 9.34KiB/s, 87pkt/s; total 618.46KiB, 3.47Kipkt << total out 181.64KiB/s, 126pkt/s; total 6.97MiB, 5.00Kipkt --- --this is information about routes this node can reach via which connection. local route count: 3 route to 00:bd:58:4a:05:00 via conn 1 ping 1727 distance 1 route to 00:bd:d4:67:02:01 via conn 0 ping 1926 distance 1 route to 00:ff:9f:57:75:75 via conn -1 ping 1 distance 0 ---