Generic setup of a https nginx/Apache reverse proxy
Assume we have a web site engine (web server, blog, shellinabox, you name it) running in your private network at ip 10.10.10.10 port 3500, serving http.
We want to expose this local/intern web service to the internet, without giving the internet access to our local machine. We want to use the https-protocol and proxy via web server nginx or Apache, using a (sub)domain that we own, let’s assume for simplifying reasons that this is https://sub.example.com
.
Here we look at two very basic proxy setups to realize this task.
nginx
So, given that nginx is already installed, for the proxy functionality, at the server that serves https://sub.example.com
, we configure a nginx site as /etc/nginx/sites-available/sub.example.com
:
#
# Virtual Host configuration nginx
#
server {
listen 80;
server_name sub.example.com;
location / {
proxy_pass http://10.10.10.10:3500/;
proxy_set_header Host $host;
}
}
Next, we install certbot
for obtaining SSL certificates for our server:
sudo apt-get install certbot python3-certbot-nginx
Now we have to make our website public, in order that certbot
can obtain a certificate from Let’s Encrypt via the ACME protocol. We do that by making the site available:
sudo ln -s /etc/nginx/sites-available/sub.example.com /etc/nginx/sites-enabled
After that, we have to reload the nginx configuration:
sudo service nginx reload
Now we should be able to access our server via http://sub.example.com
which is internally served by http://10.10.10.10:3500
.
To obtain the certificate, we now run
sudo certbot --nginx -d sub.example.com
This will provide our server with a Let’s Encrypt certificate, create and enable a new nginx ssl configuration /etc/nginx/sites-available/sub.example.com-ssl
, and modify the original config enable SSL. The automatically changed config file should now read like
#
# Virtual Host configuration nginx
#
server {
server_name sub.example.com;
location / {
proxy_pass http://10.10.10.10:3500/;
proxy_set_header Host $host;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/sub.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/sub.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = sub.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name sub.example.com;
return 404; # managed by Certbot
}
That’s it! Now we have a local/intern web service exposed to the internet using the https-protocol via nginx.
Apache
Again we assume that the web server itself is already installed. So we configure at the server that serves https://sub.example.com
an Apache site as /etc/apache2/sites-available/sub.example.com.conf
:
#
# Virtual Host configuration Apache
#
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName sub.example.com
ServerAlias sub.example.com
ProxyPreserveHost On
ProxyPass / http://10.10.10.10:3500/
ProxyPassReverse / http://10.10.10.10:3500/
</VirtualHost>
For the proxy configuration to work, we want to be sure to have proxy functionality enabled:
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo systemctl restart apache2
Next, we install certbot
for obtaining SSL certificates for our server:
sudo apt-get install certbot python3-certbot-apache
Now we have to make our website public, in order that certbot
can obtain a certificate from Let’s Encrypt via the ACME protocol. We do that by making the site available:
sudo a2ensite sub.example.com.conf
After that, we have to restart Apache:
sudo service apache2 restart
Now we should be able to access our server via http://sub.example.com
which is internally served by http://10.10.10.10:3500
.
To obtain the certificate, we now run
sudo certbot --apache -d sub.example.com
This will provide our server with a Let’s Encrypt certificate, create and enable a new Apache ssl configuration /etc/apache/sites-available/sub.example.com-le-ssl.conf
, and modify the original config to redirect from http to https. The automatically created config file should read like
#
# Virtual Host configuration Apache
#
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin webmaster@localhost
ServerName sub.example.com
ServerAlias sub.example.com
ProxyPreserveHost On
ProxyPass / http://10.10.10.10:3500/
ProxyPassReverse / http://10.10.10.10:3500/
SSLCertificateFile /etc/letsencrypt/live/sub.example.com/fullchain.pem;
SSLCertificateKeyFile /etc/letsencrypt/live/sub.example.com/privkey.pem;
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
That’s it! Now we have a local/intern web service exposed to the internet using the https-protocol via Apache.