<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xml:base="https://esolitos.com"  xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
 <title>esolitos.com - nginx</title>
 <link>https://esolitos.com/tags/nginx</link>
 <description></description>
 <language>en</language>
<item>
 <title>Apache, Varnish, Nginx SSL and Let&#039;s Encrypt</title>
 <link>https://esolitos.com/items/2017/02/apache-varnish-nginx-ssl-and-lets-encrypt</link>
 <description>&lt;div class=&quot;field field-name-field-byline field-type-entityreference field-label-hidden&quot;&gt;
      &lt;div  class=&quot;ds-1col node node-profile view-mode-byline clearfix&quot;&gt;

  
  &lt;div class=&quot;field field-name-field-photo field-type-image field-label-hidden&quot;&gt;
    
      &lt;a href=&quot;/profile/esolitos-marlon&quot;&gt;&lt;img src=&quot;https://esolitos.com/sites/default/files/styles/byline/public/field/image/screen_shot_2015-05-08_at_20.22.00.png?itok=cCjKAYpk&quot; width=&quot;50&quot; height=&quot;50&quot; /&gt;&lt;/a&gt;    
&lt;/div&gt;
&lt;div class=&quot;field field-name-title field-type-ds field-label-hidden&quot;&gt;
    
      &lt;strong class=&quot;profile-name&quot;&gt;&lt;a href=&quot;/profile/esolitos-marlon&quot;&gt;Esolitos Marlon&lt;/a&gt;&lt;/strong&gt;    
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-profession field-type-text field-label-hidden&quot;&gt;
    
      Web Developer and Duck Slayer    
&lt;/div&gt;
&lt;/div&gt;

  &lt;/div&gt;
&lt;div class=&quot;field field-name-post-date field-type-ds field-label-hidden&quot;&gt;
    
      Friday, 10 February, 2017 - 15:58    
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-image field-type-image field-label-hidden&quot;&gt;
    
      &lt;img src=&quot;https://esolitos.com/sites/default/files/styles/large/public/field/image/le-logo-wide.png?itok=V0aw1B3g&quot; width=&quot;480&quot; height=&quot;141&quot; alt=&quot;Let&amp;#039;s Encrypt Logo&quot; title=&quot;Let&amp;#039;s Encrypt Logo&quot; /&gt;    
&lt;/div&gt;
&lt;div class=&quot;field field-name-body field-type-text-with-summary field-label-hidden&quot;&gt;
    
      &lt;p&gt;So, the title gives it sway, I just wanted to get what is simple setup working.... &lt;br /&gt;
Well... It turned out to be not such a simple setup afterall, so I will share my experience!&lt;/p&gt;
&lt;!--break--&gt;&lt;h3&gt;Background&lt;/h3&gt;
&lt;p&gt;In the company I work we serve numerous Drupal websites using a &quot;traditional&quot; LAMP stack in the backend with Varnish for caching proxy and optionally Nginx when the SSL termiantion is needed.&lt;br /&gt;
If you&#039;re interested You can see &lt;a href=&quot;https://github.com/ramsalt/varnish-configs&quot;&gt;on github&lt;/a&gt; the bolerplate for our varnish congifuration, and here below a simple schema of our network, as you can see it&#039;s nothing crazy, just an usual setup.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;https://esolitos.com/sites/esolitos.com/files/screenshot_2017-02-10_16.19.16.png&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Let&#039;s Encrypt, Certbot and &lt;code&gt;.well-known&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;At this point we needed to add SSL to some small services and we decided that we would use Let&#039;s Encrypt for it. Since I am in charge of the infrastructure I did the only thing i could do: &lt;strong&gt;RTFM!&lt;/strong&gt;&lt;br /&gt;
I decided to use the suggested &lt;a href=&quot;https://certbot.eff.org&quot;&gt;&lt;code&gt;certbot&lt;/code&gt;&lt;/a&gt; to manage the certificate and actually &lt;code&gt;certbot-auto&lt;/code&gt; since we run Ubuntu 14.04.&lt;/p&gt;
&lt;p&gt;Since the certbot wouldn&#039;t be able to bind to neither port &lt;strong&gt;80&lt;/strong&gt; (in use by &lt;u&gt;varnish&lt;/u&gt;) nor on port &lt;strong&gt;443&lt;/strong&gt; (in use by &lt;u&gt;nginx&lt;/u&gt;) I decided to use the &lt;a href=&quot;https://certbot.eff.org/docs/using.html#webroot&quot;&gt;webroot&lt;/a&gt; plugin to validate the domain and get the certificates.&lt;br /&gt;
In this way the certboots creates the acme-challenge file into the &lt;code&gt;.well-known&lt;/code&gt; directory in the document root of your virtual-host. Rather quickly then I realised that, once more, I encountered an issue with this approach: the document root of ell sites was on a completely differet machine and in the current server where the nginx deamon runs (which needed the certificate) I had nothing but that and varnish, both running as reverse proxy.&lt;/p&gt;
&lt;h2&gt;The solution: Varnish and Nginx magic!&lt;/h2&gt;
&lt;p&gt;Any request for files inside .well-known coming to Varnish (listening on port 80) would be redirected to the local nginx which would attempt to serve them from the local webroot. Follows here my Nginx + Varnish + Certbot configuration, keep in mind that Varnish config si based on the boilerplate i mentioned before (&lt;a href=&quot;https://github.com/ramsalt/varnish-configs&quot;&gt;available on github&lt;/a&gt;).&lt;/p&gt;
&lt;h3&gt;1. Nginx .well-known host.&lt;/h3&gt;
&lt;p&gt;Port 80 is already taken from Varnish, so i decided to have nginx locally listening on port 8080, this would be available only for local connection sicne i would serve it via varnish. Also I wanted to have a single virtual host for all the small services that we had running so I decided to use the domain *.ssl.example.com&lt;/p&gt;
&lt;p&gt;Create the nginx virtual-host configuration: &lt;code&gt;​# vim /etc/nginx/sites-available/star.ssl.example.com-8080&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;
# This server is used to get the SSL certificates from Let&#039;s Encrypt
server {
    listen 8080;
    server_name ~^(?&amp;lt;shortname&amp;gt;.+)\.ssl\.example\.com$;

    # Use the host domain as directory webroot.
    location /.well-known {
            alias /var/www/nginx-letsencrypt/$shortname/.well-known;
    }
}&lt;/pre&gt;&lt;p&gt;This allows me to simply have one single virtual host for all the domain, and for example if I need to have ssl on the subdomain esolitos.ssl.example.com I can just run mkdir -p /var/www/nginx-letsencrypt/widget/.well-known and use the certboot (see below) to get the cerficate.&lt;/p&gt;
&lt;h3&gt;2. Varnish catch and redirect .well-known requests&lt;/h3&gt;
&lt;p&gt;Next step is to have varnish redirecting the ACME requests to the nginx host. This is a simple matter of defining a backend and redirecting the request to that.&lt;/p&gt;
&lt;p&gt;First I needed to define the backend: # vim /etc/varnish/backends/local-acme-catcher.vcl&lt;/p&gt;
&lt;pre&gt;
# Custom local backend to handle theb ACME requests
# from Let&#039;s Encrypt
backend local_acme_catcher {
  .host = &quot;127.0.0.1&quot;;
  .port = &quot;8080&quot;;
}&lt;/pre&gt;&lt;p&gt;Remember that the backend should be loaded and included: # echo &#039;include &quot;backends/local-acme-catcher.vcl&quot;;&#039; &amp;gt;&amp;gt; /etc/varnish/backends.vcl&lt;/p&gt;
&lt;p&gt;Then somewhere in the config I had to catch the request and select this appropriate backend, i decided to do this in hosts.vcl since it&#039;s where I was already switching backends: # /etc/varnish/hosts.vcl&lt;/p&gt;
&lt;pre&gt;
#
# Virtual Host Definition
#
# Switch the backend / director based on the required host

sub virtualhost__recv {

  #
  # [...] Several if/then/else to switch backends based
  # on hostname and other arbitrary parameters
  #

  # And finally catch ACME requests and set the local acme catcher as backend.
  if ( req.http.host ~ &quot;.+\.ssl\.example\.com&quot; &amp;amp;&amp;amp; req.url ~ &quot;^/.well-known/.*&quot; ) {
    set req.backend = local_acme_catcher;
  }
}
&lt;/pre&gt;&lt;h3&gt;3. Reload services, run Certbot and get the certificate!&lt;/h3&gt;
&lt;p&gt;It is now all set, I jsut nedeed to reload nginx and varnish (using the test/reload script budled in our bolierplate)&lt;/p&gt;
&lt;pre&gt;
root@varnish-acme:~# service nginx reload
 * Reloading nginx configuration nginx
[ OK ]

root@varnish-acme:~# /etc/varnish/extra/varnishconfigtest.sh /etc/varnish/default.vcl
Config Check: All good!
Do you want to reload Varnish? [y/n]: y
 * Reloading HTTP accelerator varnishd
   ...done.
&lt;/pre&gt;&lt;p&gt;The last step is to gather the certificate and setup the final nginx virtualhost with it!&lt;/p&gt;
&lt;pre&gt;
root@varnish-acme:~# /usr/local/bin/certbot-auto certonly --webroot -w /var/www/nginx-letsencrypt/esolitos/ -d esolitos.ssl.example.com&lt;/pre&gt;&lt;p&gt;This will create the csr, key and certificate in the &lt;code&gt;/etc/letsencrypt/live/$HOSTNAME&lt;/code&gt; directory.&lt;/p&gt;
&lt;pre&gt;
root@varnish-acme:~# ls /etc/letsencrypt/live/esolitos.ssl.example.com
cert.pem  chain.pem  fullchain.pem  privkey.pem  README&lt;/pre&gt;&lt;p&gt;Now it&#039;s just a matter of creating the actual virtual host for the site, I normally use the great Mozilla SSL Configuration Generator as bolierplate: # vim /etc/nginx/sites-available/esolitos.ssl.example.com&lt;/p&gt;
&lt;pre&gt;
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name esolitos.ssl.example.com;

    ssl_certificate /etc/letsencrypt/live/esolitos.ssl.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/esolitos.ssl.example.com/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    # modern configuration. tweak to your needs.
    ssl_protocols TLSv1.2;
    ssl_ciphers &#039;ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256&#039;;
    ssl_prefer_server_ciphers on;

    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security max-age=15768000;

    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;

}&lt;/pre&gt;&lt;p&gt; &lt;/p&gt;
&lt;p&gt;This is basically all there is to know!&lt;/p&gt;
    
&lt;/div&gt;
&lt;div class=&quot;field field-name-field-tags field-type-taxonomy-term-reference field-label-inline clearfix&quot;&gt;
  &lt;div class=&quot;field-label&quot;&gt;Tags:&amp;nbsp;&lt;/div&gt;

  &lt;ul class=&quot;inline-list&quot;&gt;
          &lt;li&gt;&lt;a href=&quot;/tags/nginx&quot;&gt;nginx&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;/tags/letsencrypt&quot;&gt;letsencrypt&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;/tags/reverse-proxy&quot;&gt;reverse proxy&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
&lt;/div&gt;
</description>
 <pubDate>Fri, 10 Feb 2017 14:58:38 +0000</pubDate>
 <dc:creator>esolitos</dc:creator>
 <guid isPermaLink="false">12 at https://esolitos.com</guid>
</item>
</channel>
</rss>
