Reverse Proxy with SSL and Authentication

SSL encryption and authentication for websites accessed through a reverse proxy

Websites that are accessed via a reverse proxy only need to be secured as far as the proxy using an SSL certificate. This means that access is also protected via authentication.

Another article in this blog described how to set up a web server as a reverse proxy to enable access to websites, even if they are located on a workstation computer in a private network.

In this article, access to the website on the workstation computer is to be protected with authentication and therefore also encrypted with SSL.

Prerequisites

It is assumed that the basic setup of the proxy as well as the workstation according to the article cited above has been completed.

In the following, the laptop named Caboto and the server on the Internet named Cayenne are used again. The website for a customer at the address http://customer1.mydomain.de/ can be accessed both on the laptop and customer's computer.

Set up SSL Encryption

Without question, you will only want to enable access to the customer1.mydomain.de website under https – especially if you use forms (e.g. for a login) or want to protect the entire website from unauthorized access with authentication. Last but not least, the latter should also be in the interest of the customer – at least as long as the website is still under development.

Fortunately, thanks to Let's Encrypt, issuing a certificate is nowadays associated with neither great effort nor costs. The exact procedure is described for all possible operating systems and web servers on the Let's Encrypt website, but of course it is also possible to use a certificate from another certification authority.

For the scenario described here, the only question that arises is whether the SSL encryption should be set up on the workstation computer (Caboto), the proxy server (Cayenne) or on both.

Actually, only the setup on the proxy server is necessary and reasonable, since only the path of the request from the client's browser to the proxy server needs to be protected by a certificate. From the proxy server to the actual web server on Caboto, the request runs through the SSH-encrypted tunnel anyway and does not have to and should not be additionally encrypted.

Thus, the configuration of the web server or the virtual host only needs to be adjusted only on the proxy server Cayenne so that requests with http are redirected to https and requests with https are correctly served.

To do this, the Apache modules mod_alias and mod_ssl must be activated on the proxy server. When using a certificate from Let's Encrypt, the configuration from above would be expanded as follows:

<VirtualHost <IP>:80>
 ServerName customer1.mydomain.de
 RedirectPermanent / https://customer1.mydomain.de/
</VirtualHost>

<VirtualHost <IP>:443>
 ServerName customer1.mydomain.de

 SSLEngine on
 SSLCertificateFile /etc/letsencrypt/live/customer1.mydomain.de/fullchain.pem
 SSLCertificateKeyFile /etc/letsencrypt/live/customer1.mydomain.de/privkey.pem
 SSLCACertificatePath /etc/ssl/certs/

 ProxyRequests Off
 ProxyPass / http://localhost:8881/
 ProxyPassReverse / http://localhost:8881/
 ProxyPreserveHost On

</VirtualHost>

The first virtual host now only serves to redirect unencrypted requests to encrypted requests. The proxy instructions are accommodated in a second virtual host, whose communication with the client's browser is encrypted with the aid of the additional SSL instructions.

After restarting the web server on Cayenne, the website can only be accessed from outside the Caboto computer with https. However, if a call is made with http, it is forwarded directly to its https counterpart.

So-called "SSL termination" takes place on the proxy, i.e. the web server on Cayenne decrypts the request and forwards it unencrypted, but through the existing SSH tunnel to the web server on Caboto. The unencrypted response from the web server on Caboto is encrypted again on Cayenne before it is passed on to the client.

Force Authentication

The customer's website can now be protected with authentication without the unencrypted transmission of passwords in clear text. The best way to do this is to set up a simple authentication on the web server, the so-called "basic authentication".

Here, too, the question arises as to whether this should be set up on the workstation computer, the proxy server or both. The answer here, however, cannot be so clear. Rather, it depends on the framework conditions.

In any case, you will want to protect access from outside the local computer, i.e. if this takes place via the proxy, which speaks in favor of setting up access protection on the proxy server. However, if you want to serve several virtual hosts on the underlying web server with just one proxy, and not all of which should be protected by authentication, it would make sense to relocate the authentication there. Such a scenario will be presented in a later article.

Simple authentication is possible on the web server after activating the modules mod_auth_basic, mod_authn_file and mod_authz_user. These modules are usually already activated in the standard. The configuration would look like this:

<VirtualHost <IP>:80>
 ServerName customer1.mydomain.de
 RedirectPermanent / https://customer1.mydomain.de/
</VirtualHost>

<VirtualHost <IP>:443>
 ServerName customer1.mydomain.de

 SSLEngine on
 SSLCertificateFile /etc/letsencrypt/live/customer1.mydomain.de/fullchain.pem
 SSLCertificateKeyFile /etc/letsencrypt/live/customer1.mydomain.de/privkey.pem
 SSLCACertificatePath /etc/ssl/certs/

 ProxyRequests Off
 ProxyPass / http://localhost:8881/
 ProxyPassReverse / http://localhost:8881/
 ProxyPreserveHost On

 <Location "/">
  AuthType Basic
  AuthName "Restricted"
  AuthUserFile "/etc/apache2/credentials"
  Require valid-user
 </Location>

</VirtualHost>

In this example, authentication is performed using the information stored in the /etc/apache2/credentials file. The file contains user names and the associated passwords. The htpasswd program is used to create and manage this file and is automatically installed when the Apache web server is installed.

To create the file for the first time and to create the user kunde1 with the password geheim, the call would look like this:

$ sudo htpasswd -c /etc/apache2/credentials kunde1
New password: 
Re-type new password: 
Adding password for user kunde1

$ cat /etc/apache2/credentials
kunde1:$apr1$Z9YgFwA.$RhglifUzDRxUu/Z6VaQjI1

As you can see, the password is stored encrypted in the file.

After restarting the web server again, calling up the website from outside the Caboto computer is not only encrypted, but can only be reached after successful authentication. From the Caboto workstation computer, you can still access the website unencrypted and without authentication.

Exceptions to authentication

Eventually, it may make sense to set up exceptions to authentication for specific use cases, e.g. for renewing the Let's Encrypt certificate issued with certbot.

Assuming that the certificate was issued using HTTP validation and is therefore to be renewed by the same, an exception must first be set up for the proxy so that requests for the URL /.well-known are not answered by the proxy:

ProxyPass /.well-known !

However, the web server must then know how requests to URLs that begin with .well-known must be handled. To do this, another location block and an alias must be added to the configuration:

Alias "/.well-known" "/home/uwe/vhosts/uwe-gehring.de/customer1/htdocs/.well-known"

 <Location "/.well-known">
  AuthType None
  Require all granted
 </Location>

It is important that this location block is added to the configuration after the first block, as it is an exception to the previous block.

Overall, the configuration would look like this now:

<VirtualHost <IP>:80>
 ServerName customer1.mydomain.de
 RedirectPermanent / https://customer1.mydomain.de/
</VirtualHost>
<VirtualHost <IP>:443>
 ServerName customer1.mydomain.de

 SSLEngine on
 SSLCertificateFile /etc/letsencrypt/live/customer1.mydomain.de/fullchain.pem
 SSLCertificateKeyFile /etc/letsencrypt/live/customer1.mydomain.de/privkey.pem
 SSLCACertificatePath /etc/ssl/certs/

 ProxyRequests Off
 ProxyPass /.well-known !
 ProxyPass / http://localhost:8881/
 ProxyPassReverse / http://localhost:8881/
 ProxyPreserveHost On

 <Location "/">
  AuthType Basic
  AuthName "Restricted"
  AuthUserFile "/etc/apache2/credentials"
  Require valid-user
 </Location>

 Alias "/.well-known" "/home/uwe/vhosts/uwe-gehring.de/customer1/htdocs/.well-known"

 <Location "/.well-known">
  AuthType None
  Require all granted
 </Location>

</VirtualHost>

After another restart of the web server, the renewal of the certificate can be carried out with certbot, which can easily be checked with a test run of certbot.

Summary and Outlook

Access to websites via a reverse proxy enables the connection to be encrypted without the website having to be secured with SSL on the workstation itself, which saves resources on the workstation. At the same time, the connection from the Internet is encrypted, which makes the transmission of a password as part of an authentication secure.

Later articles deal with other aspects such as:

  • Make multiple websites available
  • Caching of content on the reverse proxy
  • Content filter for complex websites
Top