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.
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.
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 key.pem 2048
and generated the csr (one for each), using those keys with:
openssl req -new -sha256 -key key.pem -out csr.pem
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/darrell_server.csr -out certs/darrell_server2.cert.pem
openssl ca -config openssl.cnf -days 365 -notext -md sha256 -extensions usr_cert -in csr/darrell_client.csr -out certs/darrell_client2.cert.pem
I had to reissue the certs because I failed to specify the “extensions” part, but 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.
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
Ok, so on the server (asafoetida initially, later moved to tarragon), in /etc/openvpn/server, I have:
private/server.key ← this is the private key for darrell_server2.cert.pem
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 openvpn manually, with:
But see below discussion of automatic startup.
On the client side (on lemongrass), in /etc/openvpn/client, I have these files:
And I start the client manually with:
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
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—–
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