The objective of this project was to install a vpn server on one of the boxes in the cloud (initially asafoetida, then moved to tarragon), in order to provide a VPN server service for a friend who was traveling. My friend uses the name Darrell for his client, so in what follows the vpn is called by this name.
Create a Certificate Authority
A lot of the instructions, even from openvpn site, say to use the “easyrsa” package to generate the certificates for openvpn. This package seems to be put out by the openvpn boys, or at least with their cooperation. But I didn’t do that. I created a ca with raw openssl.
I built the ca on my laptop in /etc/ssl/mycerts/ca. The root ca is in that directory, but a subdirectory called intermediate has an intermediate ca, and that is where the actual signing is done. I probably won’t leave it on the laptop. Not sure yet what I will do with the ca.
Generate the private keys and certificates
Once the ca is in place, we generate the certificates for server and client as follows:
First I generated 2048 private keys, one for server, one for client, with:
openssl genrsa -aes256 -out client.key 2048
openssl genrsa -aes256 -out server.key 2048
and generated the csr (one for each), using those keys with:
openssl req -new -sha256 -key client.key -out client.csr
openssl req -new -sha256 -key server.key -out server.csr
There are directories within /etc/ssl/mycerts/ca/intermediate, certs/ for the certs, and csr/ for the requests:
Now use the csr to generate the certs (one for each):
openssl ca -config openssl.cnf -days 365 -notext -md sha256 -extensions server_cert -in csr/server.csr -out certs/darrell_server.cert.pem
openssl ca -config openssl.cnf -days 365 -notext -md sha256 -extensions usr_cert -in csr/client.csr -out certs/darrell_client.cert.pem
I also created a diffie-hellman parameter for the link:
openssl dhparam -out dhparams.pem 4096
And I generated a “ta key”, which is apparently a shared key used to resist certain attacks:
openvpn --genkey --secret /etc/openvpn/ta.key
Also on both server and client sides, I had to build the config files for openvpn. They are called, respectively, darrell.server.conf and darrell.vpn.conf. Maybe I should have called the latter darrell.client.conf. The client side is shown later on. Here is the server side configuration file:
[root@tarragon server]# cat darrell.server.conf
server 10.8.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 126.96.36.199"
push "dhcp-option DNS 188.8.131.52"
keepalive 10 120
tls-auth /etc/openvpn/server/ta.key 0
push "compress lz4-v2"
tls-auth ta.key 0
Ok, so on the server (asafoetida initially, later moved to tarragon), in /etc/openvpn/server, I have the following files:
The file ca-chain.cert.pem has in it both the certificate for the intermediate ca and the certificate for the root ca which signed the intermediate. Both of these are needed on the server side, for sending to the client. Later, when we build the client side, it really only needs the root ca cert.
Initially, I started the openvpn server manually, with:
But see below discussion of automatic startup.
On the client side (on lemongrass), in /etc/openvpn/client, I have these files:
And on lemongrass also, I (initially) started the client manually with:
Here is the entire client config file /etc/openvpn/client/darrell.vpn.conf:
remote 184.108.40.206 1194
# 2048 bit OpenVPN static key
—–BEGIN OpenVPN Static key V1—–
—–END OpenVPN Static key V1—–
The server is an amazon ec2 instance, and all ec2 instances have a firewall, called a “security group” provided by amazon. I used the same “security group” rules at the amazon level for asafoetida as for tarragon (http+mail+ssh, etc), but with an additional rule to admit udp 1194.
On asafoetida proper, there was not an additional iptables firewall – it had a default Accept-Accept-Accept filter table and no nat table. I added a couple of forward rules to filter, to accept forwarding of tun+ to eth0 and eth0 to tun+. Also I added a nat table postrouting rule to masquerade all output through eth0 to the vpn address.
On tarragon, the default redhat firewall sends forward traffic through the input chain (?), and I only had to accept udp 1194, and accept tun+., and add the nat table postrouting, so in /etc/sysconfig/iptables I added:
-A RH-Firewall-1-INPUT -i tun+ -j ACCEPT
-A RH-Firewall-1-INPUT -i eth0 -m state --state NEW -p udp --dport 1194 -j ACCEPT
I had not previously had a nat table in the tarragon firewall, so I had to put one in:
:PREROUTING ACCEPT [4:240]
:INPUT ACCEPT [4:240]
:OUTPUT ACCEPT [2:135]
:POSTROUTING ACCEPT [2:135]
-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
The link gets made, and the routing table on both client and server seem to be adjusted properly, but traffic doesn’t flow out of the server. The problem turned out to be that I had failed to turn on ip forwarding on the box.
echo “1” > /proc/sys/net/ipv4/ip_forward
And to make that last, I put it in /etc/sysctl
net.sys.ipv4.ip_forward = 1
There are systemd instance scripts for starting a client (openvpn-client@) and for starting a server (openvpn-server@). So if you put a conf file in the /etc/openvpn/client directory named fred.conf, you can then do:
systemctl enable openvpn-client@fred
And similarly, for an openvpn server config named darrell.conf in /etc/openvpn/server:
systemctl enable openvpn-server@darrell
This is just a parenthetical note, to record one additional bit of experience, to help me remember. I had to reissue the certs because I failed the first time to specify the “extensions” part. However, you cannot reissue a cert with the same common_name (i.e. you can’t generate a new cert using the same csr) until you remove the old cert, which is a better practice anyway.
openssl ca -config openssl.cnf -revoke certs/darrell_server.cert.pem
Then I reissued the 2 certs, with the names server2 and client2. But that isn’t relavent to these instructions, and so in the instructions above I continued to reference the certs as darrell_server.cert.pem and darrell_client.cert.pem, even though on the box the names really had the “2” appended.