Let us say you want to connect two private networks at two different locations via the internet. Let us assume that private network #1 has the address 192.168.10.x (where x varies from 1 to 254) and private network #2 has the address 192.168.11.x. Note that the network portion of the addresses in the two networks must be different for proper routing to take place.
Here the network portion of network #1 IP addresses is 192.168.10.0 and of network #2 is 192.168.11.0.
Let us assume that a machine (let us call it gw #1) in network #1 is connected to Internet and its public IP address (the one given by the ISP either temporarily or permanently) is N1.N2.N3.N4. From any other machine connected to Internet we should be able to ping or access any network service available in this machine using its public IP.
Now let us assume that a machine in network #2 is also connected to the Internet (let us call it gw #2), either directly, or indirectly via a router/gateway which does IP masquerading. Note that gw #1 needs to have a public IP, but gw #2 doesnot need to have a public IP. From gw #2 we should be able to ping or access any network service (such as ssh or http) service running in gw #1 using N1.N2.N3.N4.
[network #2] [gw #2] <--Internet-->[gw #1] [network #1]
There could be a masquerading router sitting between gw #2 and Internet, but gw #1 should have direct connectivity. Note that AmritaVPN will be running in gw #2 and gw #1, so they need to be Linux machines. Other machines in the network can run any OS having IP stack (ofcourse, any modern OS does have an IP stack).
If you're an experienced sysadmin do skip this section
For VPN to work, gw #2 of network #2 should act as the gateway/router for network #2 routing all the packets destined for network #1 over the VPN connection to gw #1. Similarly gw #1 of network #1 should act as the gateway/router for network #1 routing all the packets.
For gw #2 or gw #1 to act as a router IP forwarding must be enabled in both these machines.
net.ipv4.ip_forward = 1
IP forwarding can also be temporarily enabled by:
echo 1 > /proc/sys/net/ipv4/ip_forward
Before you enable IP forwarding a fair understanding of some firewalling system must be gained so that the internal networks are properly shielded. The most popular open source firewall in Linux - iptables - could be used.
By running appropriately configured AmritaVPN in both gw #1 and gw #2 we will be getting direct IP-level connectivity between network #1 and network #2. In other words, sitting on a machine in network #2 we should be able to ping a machine in network #1 (and vice versa), and access any IP service.
AmritaVPN reads and writes IP packets through Universal TUN/TAP driver that is a part of Linux Kernel. On startup AmritaVPN opens and configures a special network interface (the tunnel interface). By default the tunnel interface name is "tun0", although a different name can be used (such as tun1) through 'tunnel-if' configuration parameter.
The tunnel interface must be configured with an IP-address. This IP is specified using the "tunnel-ip" configuration parameter. The network portion of the "tunnel-ip" addresses of both gw #1 and gw #2 must be same and the host portion must be different.
Use IP addresses that are not used in your internal networks for tunnel-ip
parameter.
An example tunnel-ip
configuration would be:
tunnel-ip 192.168.16.1
tunnel-ip 192.168.16.2
You can specify the remote network/machine addresses that must be forwarded through the VPN using the "route-ip" and "route-mask" configuration parameters. "route-ip" and "route-mask" must occur in pairs. A "route-mask" parameter is paired with the preceding "route-ip" parameter.
In gw #1 where we want VPN to forward packets to network #2, we would have:
Similarly in gw #2 we would have:
One routing table entry for the "tunnel-ip" network must be always present, so the routing configuration entries would be:
gw #1:
gw #2:
If you want to add default route through the VPN, add a routing entry with
route-ip and route-mask as 0.0.0.0
as:
route-ip 0.0.0.0
route-mask 0.0.0.0
Typically, the machine running amvpn must be configured as the default router for the machines in the local network for routing to work properly. Another option is to have specific routing table entries in the local-network machines that direct the traffic intended for the remote network via the VPN machine.
On successful startup AmritaVPN will automatically configure the system routing table with this information, and on shutdown the entries will be automatically removed.
For additional security it is mandatory to configure AmritaVPN to drop root privilege after startup (root privilege is required for startup). This can be done by specifying an alternate user-name to run as using the "run-as-user" config parameter.
run-as-user amvpn
During installation a user named amvpn would be added to the system (if not already present in the system). Instead of 'amvpn', an alternate user-name can be provided, depending on your requirement.
If an existing user-name is specified in the "run-as-user" config parameter then the process will run (after startup) under the user id and group id of that user. Alternately a user-id could be provided in the "run-as-user" config parameter and also a group-id in the "run-as-group" parameter. In any case, user id used by amvpn to drop privilege must not be root user id and the group id must not be root group id.
The user-name specified in 'run-as-user' must have access
rights to the directories and files in which private key and certificates
are stored. For security, key and certificate files (especially the
private key file) must be readable only by the 'run-as-user' user-id.
The group and world-readable/writable/executable permissions must be removed. This
can be easily done by running amvpn-keytool secure 'run-as-user-name'
.
One end of the VPN will run in server-mode, waiting for incoming connection requests from VPN clients. The other side will run as a client, connecting to the VPN server.
The end running VPN in server-mode must have a public IP. In our example gw #1 has a public IP. So gw #2 should run in client mode and connect to gw #1. This can be achieved by specifying the server-ip config parameter.
server-ip N1.N2.N3.N4
The amvpn-keytool must be used to generate and manage keys/certs for amvpn. It provides a very easy and error-free interface to somewhat complex openssl commands and the task of transfering CSRs and certs. Read this section only if you're interested in understanding what amvpn-keytool does internally.
The Certificate used in signing VPN certificates can either be a external CA certificate, in which case we have to get our certificate signed by the CA. Or we can create a Private key and a self-signed CA certificate and get our certificates signed by our CA. The latter approach is described here.
To generate CA Key and Certificate:
openssl genrsa -out ca_key.pem 1024
openssl req -new -key ca_key.pem -out ca_req.pem
openssl x509 -req -trustout -in ca_req.pem -signkey ca_key.pem -out ca_cert.pem
To generate VPN Key and Certificate:
openssl genrsa -out vpn_key.pem 1024
openssl req -new -key vpn_key.pem -out vpn_req.pem
openssl x509 -req -in vpn_req.pem -CA ca_cert.pem -CAkey ca_key.pem -CAcreateserial -out vpn_cert.pem
The Key and certificate files can be specified in the amvpn.conf as:
Some important notes
While a single instance of amvpn
can handle only one VPN connection at a time, it
is easy to run multiple instances and have multiple VPN connections fanning out of a single
machine. Each running instance must have a separate copy of the amvpn.conf
configuration
file.
amvpn
:amvpn -c amvpn_x.conf
amvpn
in background mode with alternate config file:amvpn -d -c amvpn_x.conf
The following configuration options must be different for each running instance:
tun0
.
For each additional instance provide values tun1
, tun2
, and so on. 192.168.16.1
for one instance and 192.168.17.1
for another.
See the table below for some examples.port 7172
. Note that the port 7172
entry must also be present in the client
configuration file if it wants to connect to the second instance.
Instance | tunnel-ip(c) | tunnel-ip(s) | route-ip | route-mask |
1 | 192.168.16.2 | 192.168.16.1 | 192.168.16.0 | 255.255.255.0 |
2 | 192.168.17.2 | 192.168.17.1 | 192.168.17.0 | 255.255.255.0 |
3 | 192.168.18.2 | 192.168.18.1 | 192.168.18.0 | 255.255.255.0 |
4 | 192.168.19.2 | 192.168.19.1 | 192.168.19.0 | 255.255.255.0 |
5 | 192.168.20.2 | 192.168.20.1 | 192.168.20.0 | 255.255.255.0 |
In the above configuration each connection uses a separate class-C (/24) network. An alternate configuration is shown below. Here subnetting is used so that each connection need not have an individual class-C network number. The example below uses /30 subnets for each connection since a connection requires allocation of only two IP addresses.
Instance | tunnel-ip(c) | tunnel-ip(s) | route-ip | route-mask |
1 | 192.168.16.5 | 192.168.16.6 | 192.168.16.4 | 255.255.255.252 |
2 | 192.168.16.9 | 192.168.16.10 | 192.168.16.8 | 255.255.255.252 |
3 | 192.168.16.13 | 192.168.16.14 | 192.168.16.12 | 255.255.255.252 |
4 | 192.168.16.17 | 192.168.16.18 | 192.168.16.16 | 255.255.255.252 |
5 | 192.168.16.21 | 192.168.16.22 | 192.168.16.20 | 255.255.255.252 |
The key/certificate files can be shared by all running instances, although you could choose to have seperate key/certificate files for each instance.
The amvpn
service script (/etc/rc.d/init.d/amvpn) can be used to
start multiple amvpn instances at boot time. When amvpn service is
started at boot time it will create one amvpn process for each of the
following configuration files:
For instance, to set up a VPN server catering to 5 clients, configuration file for each client connection can be placed in '/etc/amvpn.d' directory with names such as amvpn_1.conf, amvpn_2.conf, and so on.
When amvpn service script is started it will start one amvpn process for each configuration file present in the /etc/amvpn.d directory. Note that if /etc/amvpn.conf is present, then one amvpn process will be started with /etc/amvpn.conf as the configuration file as well.
As a security measure, the amvpn
checks the modification time of the key/cert files
each time a reconnect is attempted by the client or a new connection is received by
the server.
If configured for email-notification the amvpn
notifies the user through email
when it finds that the modification time of VPN key, VPN cert, or CA cert files
has changed.
See section
Event notification through email .
It also logs a message to this effect in the system log file. Note that when
an active connection is in progress amvpn
does not check continually to see
whether key/cert files have been modified. The file modification is checked only
when a reconnect is attempted by the client or a new connect is received by the
server.
Occurrence of certain events can be notified through email. In order to enable this feature, following configuration options need to be specified.
smtp-server-ip
: IP address/domain name of the SMTP mail server.notify-sender
: Email-id to be placed in the from
field of notification emails.notify
: Notification specification in event-name:email-id1,email-id2
format.max-pending-mails
: Maximum number of pending notification emails.connect
: Connection establishment.disconnect
: Connection termination.keycert
: Modification of VPN key, VPN cert, and CA cert files.Set the configuration directive smtp-server-ip
to the address of your SMTP server;
it can be either the IP address or fully qualified domain name. For instance,
smtp-server-ip 192.168.10.1
, or,
smtp-server-ip example.smtp.server
Email-id to be placed in the from
field of notification emails. Example:
notify-sender-id admin@example.com
If this option is not specified amvpn
will use an email-id of the form:
<run-as-user>@<host-name> where <run-as-user> is the
user-name specified in the run-as-user
option and <host-name> is
the host name of the local machine.
The events for which notification emails have to be sent and the email ids of
the recipients of these emails are specified using the notify
option. It
has the general form: notify event-name:email-id-list
.
The email-id-list
is one or more email-ids of the recipients. Multiple
email-ids must be separated by ',' (comma). The event-name
can be one of:
connect
: notifies successful establishment of a VPN connection.disconnect
: notifies termination of an active VPN connection.keycert
: notifies if VPN key, VPN cert, or CA cert files
were modified.Some examples of notification specifications using the notify
option are
given below.
notify connect:abc@example.xyz.com,def@example.xyz.com
notify disconnect:abc@example.xyz.com
notify keycert:abc@example.xyz.com
In the case of slow connections email notification may take considerable amount
of time and it is possible that the previous notification is still outstanding
when the next notification is being processed.
In order to avoid having a large number of pending notification requests,
which would consume system resources, this option may be used. If this option
is not specified the default value of '5' will be used.
A different value could be given as: max-pending-mails 8
.
If the amvpn
process gets killed (for instance by using 'kill -9'), then
it will not have the chance to send disconnect
notification email.
However, notification will be sent by the amvpn
at the other side of
the connection (if so configured), since it would detect a disconnect. Hence,
it is advisable to set notification option at both client and server side, so
that even if amvpn
at one end gets suddenly killed because of some reason
the disconnect
notification would still be sent (by the other side).
This feature sends a keepalive message when there is no outbound or inbound traffic
for more than a certain period of time as specified in the keepalive-time
configuration parameter.
Background:
When there is a break in the network connectivity between
the two amvpn
machines, if there is no pending outbound data at the time
of connection break the TCP/IP stack may take a very long time to detect
that the connection is broken. During this time, if the other end tries
to reconnect, the amvpn
rejects the request with the message
"Active Connection already exists. Dropped the newly accepted connection"
,
since it doesn't know yet that the previous connection was dropped.
If keepalive option is set then amvpn
will transmit keepalive messages
to the other end when there is no other data to be sent. So if a connection
break happens, TCP/IP stack will detect the connection break when attempting to
send the keepalive message, even when there is no other outbound data.
Configuration:
By default keepalive message is disabled (set to -1). This can be changed using the following configuration option:
keepalive-time
: Idle time in seconds before sending
a keepalive message . A value less than or equal to zero
implies that this option is disabled.
Before this feature is enabled make sure that AmritaVPN 0.99 or higher is installed at both ends.