{"id":2178,"date":"2021-06-03T00:16:50","date_gmt":"2021-06-03T00:16:50","guid":{"rendered":"https:\/\/dft.wiki\/?p=2178"},"modified":"2022-06-02T17:00:32","modified_gmt":"2022-06-02T17:00:32","slug":"reverse-proxy-with-nginx-and-ssl-tls-lets-encrypt","status":"publish","type":"post","link":"https:\/\/dft.wiki\/?p=2178","title":{"rendered":"Reverse Proxy with NGINX and SSL\/TLS (Let&#8217;s Encrypt)"},"content":{"rendered":"<p>In this tutorial, we will go through:<\/p>\n<ul>\n<li>Install and configure NGINX,<\/li>\n<li>Install and configure SSL\/TLS,<\/li>\n<li>Configure NGINX as a reverse proxy for:\n<ul>\n<li>A whole site,<\/li>\n<li>A directory of a site.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Requirements:<\/p>\n<pre>sudo apt update &amp;&amp; sudo apt upgrade -y\r\nsudo apt install nginx -y\r\nsudo nano \/etc\/nginx\/sites-available\/default<\/pre>\n<p>Change the following configuration with your domain:<\/p>\n<pre>server {\r\n    listen 80 default_server;\r\n    listen [::]:80 default_server;\r\n    root \/var\/www\/html;\r\n    <strong>server_name<\/strong> <span style=\"color: #ff0000;\"><strong>example.com www.example.com<\/strong><\/span>;\r\n}<\/pre>\n<p>Check the configuration and restart the server.<\/p>\n<pre>nginx -t &amp;&amp; nginx -s reload<\/pre>\n<p>Access your website using your web browser and note that is labeled as an insecure connection.<\/p>\n<hr \/>\n<p><strong>SSL\/TLS<\/strong><\/p>\n<p>Install the Cerbot and execute it against your :<\/p>\n<pre>sudo apt-get install certbot python3-certbot-nginx -y\r\nsudo certbot --nginx<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2179\" src=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2021\/06\/Screenshot_2021-06-02_19-26-45.png\" alt=\"\" width=\"688\" height=\"814\" srcset=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2021\/06\/Screenshot_2021-06-02_19-26-45.png 688w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2021\/06\/Screenshot_2021-06-02_19-26-45-254x300.png 254w\" sizes=\"auto, (max-width: 688px) 100vw, 688px\" \/><\/p>\n<p>Only on the first time it will ass that many questions.<\/p>\n<p>Alternatively, the domain could be specified to skip one step.<\/p>\n<pre>sudo certbot --nginx <strong>-d <span style=\"color: #ff0000;\">example.com<\/span> -d <span style=\"color: #ff0000;\">example2.com<\/span><\/strong><\/pre>\n<p>Reload the server and refresh the browser to verify that it was automatically redirected to a secure connection.<\/p>\n<pre>nginx -s reload<\/pre>\n<p>The browser will hop from <strong>HTTP<\/strong>:\/\/example.com to <strong>HTTP<span style=\"color: #ff0000;\">S<\/span><\/strong>:\/\/example.com.<\/p>\n<p>Create a cron job using the root user to automatically renew the certificate that will expire every 90 days:<\/p>\n<pre>sudo su\r\ncrontab -e<\/pre>\n<p>Append:<\/p>\n<pre>0 12 * * * \/usr\/bin\/certbot renew --quiet<\/pre>\n<hr \/>\n<p><strong>REVERSE PROXY<\/strong><\/p>\n<p>To prevent CPU overload with multiple encrypted sessions it is recommended to use regular HTTP connection internally when possible (restricted VLAN for example).<\/p>\n<p>Edit the virtual server configuration:<\/p>\n<pre>sudo nano \/etc\/nginx\/sites-available\/default<\/pre>\n<p><strong>Applying the reverse proxy to the root of the website.<\/strong><\/p>\n<p>Edit the virtual server configuration:<\/p>\n<pre>sudo nano \/etc\/nginx\/sites-available\/default<\/pre>\n<p>Look for the <strong>location { &#8230; }<\/strong> block.<\/p>\n<pre><strong>location \/ {<\/strong>\r\n    proxy_pass <strong>http:\/\/<span style=\"color: #ff0000;\">127.0.0.1:5000<\/span><\/strong>;\r\n<span style=\"color: #ff6600;\">    proxy_set_header Host $host;\r\n    proxy_set_header X-Forwarded-Proto $scheme;\r\n    proxy_set_header X-Real-IP $remote_addr;\r\n    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;<\/span>\r\n<strong>}<\/strong><\/pre>\n<p>This configuration will forward the traffic to the host and port defined. The example above will forward to localhost under port 5000, which could be a docker application listening on this port.<\/p>\n<p>All the lines in <span style=\"color: #ff6600;\">orange<\/span> are optional and will provide metadata to the hidden application if necessary.<\/p>\n<p><strong>Applying the reverse proxy to a directory of the website.<\/strong><\/p>\n<p>Create a location block to the desired directory.<\/p>\n<pre><strong>location <span style=\"color: #ff0000;\">\/proxied_page\/<\/span> {<\/strong>\r\n    proxy_pass <strong>http:\/\/192.168.1.7<\/strong>;\r\n<strong>}<\/strong><\/pre>\n<p>In the example above the reverse proxy is applied only to the directory <span style=\"color: #ff0000;\"><strong>proxied_page<\/strong><\/span> to another host (<strong>192.168.1.7<\/strong>) in the private network on the default HTTP port.<\/p>\n<hr \/>\n<p>BONUS: Reverse Proxy with Apache<\/p>\n<pre>sudo a2enmod proxy\r\nsudo a2enmod proxy_http\r\nsudo a2enmod proxy_balancer\r\nsudo a2enmod lbmethod_byrequests<\/pre>\n<p>Include the following lines accordingly to your need in the site configuration file:<\/p>\n<pre>ProxyPreserveHost On\r\nProxyPass \/ http:\/\/10.1.1.1:8080\/\r\nProxyPass \/directory http:\/\/192.168.1.1\/\r\nProxyPass \/another_directory http:\/\/172.16.1.1\/dir\/<\/pre>\n<p>Restart the service.<\/p>\n<pre>sudo apachectl configtest\r\nsudo systemctl restart apache2.service<\/pre>\n<p>Additionally, the reverse proxy can also act as a load balancer:<\/p>\n<pre>&lt;Proxy balancer:\/\/cluster&gt;\r\n    BalancerMember http:\/\/webserver1\r\n    BalancerMember http:\/\/webserver2\r\n&lt;\/Proxy&gt;\r\n\r\nProxyPreserveHost On\r\nProxyPass \/ balancer:\/\/cluster\/\r\nProxyPassReverse \/ balancer:\/\/cluster\/<\/pre>\n<p>You can also apply health checks to the nodes of the members of the cluster:<\/p>\n<pre>&lt;Proxy balancer:\/\/cluster&gt;\r\n    BalancerMember \"http:\/\/webserver1\" hcmethod=HEAD hcinterval=1 hcpasses=9 hcuri=\/app\/status\r\n    BalancerMember \"http:\/\/webserver2\" hcmethod=HEAD hcinterval=1 hcpasses=9 hcuri=\/app\/status\r\n&lt;\/Proxy&gt;<\/pre>\n<p>Moreover, on the host side (where the web application is running) if it is running Apache too:<\/p>\n<ul>\n<li>The logs will contain the Remore Address IP of the reverse proxy server for all clients.<\/li>\n<li><span style=\"color: #777777; font-size: 1rem;\">To fix this issue the module <strong>mod_remoteip<\/strong> must be enabled and configured as follows.<\/span><\/li>\n<\/ul>\n<pre>sudo a2enmod remoteip\r\nsudo nano \/etc\/apache2\/apache2.conf<\/pre>\n<p>Append the line:<\/p>\n<pre>RemoteIPHeader X-Forwarded-For<\/pre>\n<p>Change the following line.<\/p>\n<p>From:<\/p>\n<pre>LogFormat \"%<span style=\"color: #ff0000;\"><strong>h<\/strong><\/span> %l %u %t \\\"%r\\\" %&gt;s %O \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\" combined<\/pre>\n<p>To:<\/p>\n<pre>LogFormat \"%<span style=\"color: #00aa00;\"><strong>a<\/strong><\/span> %l %u %t \\\"%r\\\" %&gt;s %O \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\" combined<\/pre>\n<p>Then, check the configuration and apply the changes:<\/p>\n<pre>sudo apachectl configtest &amp;&amp; sudo systemctl restart apache2<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, we will go through: Install and configure NGINX, Install and configure SSL\/TLS, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,6],"tags":[],"class_list":["post-2178","post","type-post","status-publish","format-standard","hentry","category-linux","category-raspberry-pi"],"_links":{"self":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts\/2178","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2178"}],"version-history":[{"count":9,"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts\/2178\/revisions"}],"predecessor-version":[{"id":2948,"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts\/2178\/revisions\/2948"}],"wp:attachment":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2178"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2178"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2178"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}