Create secret and secure web servers; predict the weather using your Pi; surf securely with a VPN; create a mosaic portrait.
1 THE BASICS Here’s the scenario: Imagine you’re running OpenSUSE Leap 42.3 with a website you want to access without anyone knowing it exists. The site is up and running, and working great behind your router.
But now you want to access the server from anywhere in the world. You could go to your router and route HTTP traffic to your Linux machine, but that would expose your computer to every hacker on the planet. Alternatively, you can create an OpenVPN tunnel between your laptop and desktop computer that only you have access to. This keeps your activity hidden, because you’re not connecting to ports 80 or 443, and your traffic is encrypted for maximum security. Let’s see how you can implement this for yourself.
Setting up OpenVPN has lots of steps, and the first time you do it, it’s difficult. There are technical concepts you need to understand, and usually up to 10 files you need to create. Plus, there are lots of configurations that are talked about online, and each one has its own set of steps that may not be applicable to our situation here. If this is new to you, focus on routing tables and OpenSSL’s public key infrastructure to understand what’s going on.
Here’s a summary of what happens: In the configuration files, you designate a network for OpenVPN (such as 10.0.0.0/24), and the OpenVPN software creates a virtual network adapter for it (such as tun0). OpenVPN modifies the Linux routing table to send 10.0.0.0/24 packets through tun0 [ Image A].
2 VIRTUAL AND PHYSICAL ADAPTERS Outgoing packets are encrypted with OpenSSL at the virtual network adapter (tun0), forwarded via the routing table to the physical adapter (eth1), and sent out to the Internet. Incoming packets arrive at the physical adapter (eth1) on port 1194, are forwarded to the virtual adapter (tun0), decrypted with OpenSSL, then sent to local programs, such as Apache. All you have to do is interact with the IP address of the virtual network adapter created when OpenVPN starts. In other words, you treat 10.0.0.0/24 as any other external network, but with the confidence that your packets are secure.
The OpenVPN documentation says you may need to tell Linux to forward traffic between Ethernet devices:
sysctl -w net.ipv4.ip_ forward=1 gets forwarding working between your physical and virtual adapters.
It’s important to note that the firewall sits between your virtual network adapter and local programs, such
as Apache, and between the virtual adapter and the physical adapter [ Image B]. The diagram shows the Input, Output, and Forward chains in the filter table, but Prerouting and Postrouting chains can also impact your configuration if you’re not careful.
The OpenVPN authentication, encryption, and decryption occurring at tun0 [ Image C] is handled by OpenSSL. OpenSSL is a general-purpose cryptography library for creating and managing a public key infrastructure (PKI). While this may be familiar, let’s review it, because it’s a major component of OpenVPN, and a big step in the configuration process.
When two people want to communicate privately, they create private and public keys, then exchange their public keys while keeping their private keys secret. Messages are encrypted with public keys, and can only be decrypted with the matching private key. Messages can be signed with a private key and verified with a public key. This means messages can be encrypted and authenticated in one easy framework. Public keys are often referred to as a certificate, or cert for short.
The situation is usually complicated by adding a certificate authority, or CA for short. The CA is a person or business with their own private key and corresponding certificate. The purpose of the CA is to sign other people’s certificates. In other words, the CA adds another layer of validation and verification. For OpenVPN, it means you can revoke access to your OpenVPN server at any time.
It’s useful to remember what happens with HTTPS traffic. When calling a secure website via https://, the server sends its certificate signed by a CA to your browser. The browser verifies the signed certificate using the public certificate of the CA. Then the browser generates a key, encrypts it with the server’s public certificate, and sends it to the server. Going forward, communication between browser and website is encrypted symmetrically with that key.
In OpenVPN, both the server and client machines have a CA cert, as well as public and private keys. (You’ll see how those are created below.) When a client machine connects to an OpenVPN server, both machines exchange their public certificates and verify them with the CA certificate. Then both computers randomly generate keys, encrypt them with each other’s certificates, and exchange them with each other. Data is then encrypted with these keys. These keys are never used bidirectionally, because they are in HTTPS traffic.
3 OPENING MOVES WITH OPENVPN Now, with all this explanation behind us, let’s get you up and running with a real OpenVPN configuration. You need two computers to do this. One acts as a server and the other acts as a client. In this example, the OpenVPN server is an OpenSUSE 42.3 desktop, and the client is a laptop also running OpenSUSE 42.3. Apache should be running and serving up the website you want to keep hidden. Both computers need OpenVPN installed (there’s no difference between server and client OpenVPN software), so either download it or install it through your distribution’s package manager. On OpenSUSE, run the command zypper install openvpn .
4 DIFFIE-HELLMAN Creating the private keys and certificates turns out to be easy. The OpenSSL commands can be complicated, so there’s a program called easy-rsa that makes building the keys and certs quick and simple. Run the command zypper install easy-rsa to install it.
>> Once installed, navigate to “/etc/easy-rsa” and modify the “vars” file if you want to change any defaults. If this is your first time, leave it alone until you’re more comfortable with OpenVPN. Next, run the command
easyrsa init-pki . This creates the directory “/etc/easyrsa/pki,” where your keys and certs will be created.
>> Now run the command easyrsa build-ca to create a CA key and cert. Make sure you enter a password and record it in your password manager. Once the command is finished, you’ll find you’ve created “/etc/easy-rsa/pki/ ca.crt” and “/etc/easy-rsa/pki/private/ca.key.” >> Next, run the command easyrsa build-server-full
server nopass . It asks for the password to your CA key. This creates “issued/server.crt” and “private/server. key” in the “/etc/easy-rsa/pki” directory. These are your server key and certificate, respectively. Doing this automatically signs your “server.crt” with the “ca.key” file above.
>> To create the client key and certificate, run the command easyrsa build-client-full client nopass . This
creates “issued/client.crt” and “private/client.key” in the “/etc/ easy-rsa/pki” directory. The “client.crt” file is automatically signed by the “ca.key” file.
Now let’s build the Diffie-Hellman parameters with the command easyrsa gen-dh . This creates “/etc/easy-rsa/pki/ dh.pem.” This is important, because the RSA certificates are used for authentication, but not for encrypting data across the tunnel. It’s too slow. With Diffie-Hellman parameters, keys can be quickly created to encrypt data. This is faster and allows for re-keying persistent connections.
Finally, there’s an optional command that adds an additional signature to all SSL/ TLS handshake packets for integrity verification. Run “openvpn > genkey > secret ta.key,” and place “ta.key” in “/etc/easy-rsa/pki.”
Notice all the keys and certificates have been created on the same machine. It doesn’t have to be this way. Ideally, the machine with “ca.key” is designated as a key signing machine, and should be separate from the OpenVPN server. For maximum security, the key signing machine should be off the network. In addition, we could have created “client.key” on the client machine, and submitted a Certificate Signing Request to the key signing machine. After signing, the “client.crt” file would be sent to the client machine. This would be more secure, because “client.key” would never have to leave the client machine.
5 SECURE YOUR SERVER Copy “ca.crt,” “server.key,” “server.crt,” and “ta.key” to “/etc/openvpn.” Now, let’s look at a typical configuration. Call the file below “server.conf “and put it in “/etc/openvpn.” server 10.0.0.0 255.255.255.0 proto udp port 1194 dev tun topology subnet persist-key persist-tun keepalive 10 60 remote-cert-tls client tls-auth /etc/openvpn/ta.key 0 dh /etc/openvpn/dh.pem ca /etc/openvpn/ca.crt cert /etc/openvpn/server.crt key /etc/openvpn/server.key cipher AES-256-CBC user nobody group nobody verb 3 daemon log-append /var/ log/openvpn.log comp-lzo yes
This file opens UDP port 1194 for the physical VPN connection, and creates a virtual “tun” Ethernet device with subnet 10.0.0.0/24. Notice that it references the four files we created. After starting, OpenVPN changes the user and group ID to nobody, for additional protection of the server in case someone manages to get control of an OpenVPN session. A log file is defined, and the recommended verbosity level of 3 is selected. Finally, we LZO compress the data across the tunnel.
Now let’s start the OpenVPN server. If you have a firewall running, open port 1194 with something like
iptables -A INPUT -p udp -m udp --dport 1194 -j ACCEPT . You can manually start OpenVPN with the
command openvpn --config /etc/openvpn/server.conf . To start it automatically at a reboot, place the command in “/etc/rc.d/after.local.”
You can verify OpenVPN is running in several ways: 1. Use the top command to find OpenVPN running under user “nobody.”
2. Use ifconfig or ip addr show to see that tun0 is attached to IP address 10.0.0.1.
3. Use the route or ip route command to see that 10.0.0.0 is routed to tun0.
6 CLIENT CONFIG Configuring your client laptop is almost identical and quick to do. Use the following configuration file: client remote openvpn-server-hostname-or-ip 1194 proto udp nobind dev tun persist-key persist-tun remote-cert-tls server tls-auth /etc/openvpn/ta.key 1 ca /etc/openvpn/ca.crt cert /etc/openvpn/client.crt key /etc/openvpn/client.key cipher AES-256-CBC user nobody group nobody verb 3 log-append /var/ log/openvpn.log comp-lzo yes
Here we’re declaring the laptop as a client machine, with the remote option pointing to the OpenVPN server. Make sure you replace openvpn-server-hostname-or-ip with the IP address of your server. Call this “client.conf” and put it in “/etc/openvpn.” Next, transfer “ca.crt,” “ta. key,” “client.crt,” and “client.key” to the laptop, and put them in “/etc/openvpn.” Finally, start OpenVPN with
openvpn --config /etc/openvpn/client.conf . You can verify OpenVPN is running with the same three methods mentioned above. But to make sure both machines are connected, run ping 10.0.0.1 , which pings the OpenVPN server from the client. If this works, the two machines are connected via OpenVPN.
7 APACHE ACTION Remember that the goal is to connect to Apache running on a Linux server through
OpenVPN. There are four more problems that need to be overcome, and it turns out they’re easy to solve.
First, make sure the firewall has a port open with the command iptables -A INPUT -s 10.0.0.0/24 -p tcp -m tcp --dport 80
-j ACCEPT . Remember, you specified 10.0.0.0/24 as the OpenVPN network in the “server.conf” file above. This makes sure Apache receives the packets from the OpenVPN network.
The second problem is configuring Apache to respond to requests coming over the OpenVPN virtual network. Because we don’t want anybody to know about this server, we can’t rely on DNS to identify it. This means requests to Apache won’t have a server name associated with them. To get Apache to respond without a server name, create the virtual host VirtualHost 10.0.0.1:80> by putting a file called “myserver.conf” in “/etc/ apache/vhosts.d,” with the same directives that currently work for the host you want to access. You should have Apache up and running, and serving up your website locally, so just use the same directives with the new VirtualHost. However, you need to remove the ServerName entry, because you aren’t accessing the website with a server name. Now go to your laptop, start OpenVPN, and type “http://10.0.0.1” into your browser’s navigation bar. Your super-secret website should appear.
However, we’ve only done this from behind the router. The third problem is being able to reach the server from outside our network. For example, from a local bar or diner. Usually, a hostname and IP address are connected though a DNS zone file. Or maybe you use a dynamic DNS service. But we don’t want anybody to know about this server, so we can’t use either of these solutions. In principle, you can look at your router’s WAN IP address, but what if it changes? Here’s a slick way to access your server’s WAN IP address, even if it’s behind a router: dig
+short myip.opendns.com @resolver1.opendns.com . Try it now on your own Linux machine.
This command is useful because it can be put into your cron table and executed periodically. Once a day is usually more than enough, as ISPs don’t change their IP addresses more frequently than that. Ours changes every few months. You can ssh into your server at any time, run the command, then update the “remote” option in the “client.conf” file if it changes.
Furthermore, the output can be placed into a file and
transferred to another server. For example, 0 */4 * * * dig +short myip.opendns.com @resolver1.opendns.com >> ~/myip.txt; scp
~/myip.txt [email protected]server: is a crontab entry that grabs your IP address every four hours, puts it in a file, then sends the file to another server whose IP address doesn’t change—a VPS defined in your SSH config file. This assumes a passwordless SSH key, and that the server is trusted.
Additional security can be obtained by using GPG to encrypt the file before transmission. Now the file can be put on public servers without your IP address being compromised. For example, the encrypted file can be emailed to you automatically or put into Dropbox. Or indeed, both. However you want to do it, you can now determine the IP address of your router at any time and change the remote option in “/etc/openvpn/client. conf” to point to it.
When testing at home behind your router, use the 192.168.0.0/16 address assigned to your desktop server. This enables testing with both the server and laptop right in front of you. Once this is working properly, go outside your home (or use a cell phone hotspot), connect to a public Wi-Fi, then test the connection by changing the IP address in the remote option to the WAN IP address obtained from the dig command above. Doing this leads us to problem four: making sure you can access your server when it’s behind a router. For routers running DD-WRT, it’s easy to set up. Go to the NAT/QoS table and look at the “Port Forwarding” tab. Port 1194 can be forwarded to the server running OpenVPN [ Image D].
You’ve now set up a super-secret web server that nobody knows about and can’t be observed, because of the OpenVPN encryption. Note that this doesn’t forward all your Internet traffic to your OpenVPN server—only the traffic between your laptop and the server.