Setup Odoo with Nginx and Letsencrypt certificates

< / / / / / >
Specialist
Deployment Security
V13.0
V 13.0
+/- 17 minutes
Written by Yenthe Van Ginneken
(0)

Quick scroll

1. Introduction

Running a web application behind Nginx and running it on SSL for security reasons has become very important. If you don't run your web application on a secured connection you will even be sanctioned by Google, resulting in your web application dropping in the search results. Since Chrome 68 you will even get not secure warnings. Since running secure web applications and running them smooth and fast has become so important this tutorial is here to help you.

In this tutorial you will learn how to install Nginx, how to configure Nginx and how to add your own free SSL certificate to your website thanks to Letsencrypt. Letsencrypt is the worlds leading free certificate issues and allows you to generate SSL certificates in seconds. In this tutorial I host my server at DigitalOcean, my website at a Dutch hosting provider (Antagonist and the SSL certificate will be generated with Letsencrypt.

2. Configuring your DNS/server

The first step is to configure both your DNS at your domain provider and your server its domain settings at your hosting provider. Your server needs to know that it should point to an URL and the DNS needs to know that your URL should load content from your server. Go to your hosting provider its platform and setup a DNS record there. It is different for every hosting provider but most of them have a networking tab where you can setup a hostname and value. I will create a new URL named letsencryptdemo.oocademy.com in this tutorial. An example from my own provider with the configuration:

Example configuration DNS hosting provider

Now go to your domain provider and setup DNS records that will tell the DNS which IP it should get data from when you go to the URL. The DNS record should be an 'A' record which points from the domain name to the IP of your server. An example from my own domain provider with the configuration:

Example configuration DNS domain provider

Technically speaking you could just have one rule from 'mywebsite.com' to the IP of the server. I usually setup two just in case if some redirect on the server is not right then it will still work on DNS as you also have www.letsencryptdemo.oocademy.com listed.

3. Installing & configuring Nginx

3.1 Installing Nginx

Now that both the DNS and the server can find eachother we can start on the server. SSH to your server and install Nginx on it:

                    sudo apt-get install nginx                                    

3.2 Configuring Nginx defaults

The next step is to configure the default file from Nginx. You can find it under /etc/nginx/sites-available/default and under /etc/nginx/sites-enabled/default. Edit both of these files and make sure that they have the following configuration set:

                    server {   listen 80;   rewrite ^(.*) https://$host$1 permanent;}                                    

This will make sure that Nginx listens on port 80 (the default web port) and that it rewrites all your URL's to HTTPS. Now we just need to create a configuration file for our Odoo instance.

3.3 Creating an Nginx config for Odoo

Our Nginx is installed and configured but there is still nothing that tells Nginx to connect our Odoo - which runs on some port - to the default port 80 in order to load it when you surf to the website URL. Lets create a new configuration file for this under /etc/nginx/sites-available/odoo.conf:

                    sudo nano /etc/nginx/sites-enabled/odoo.conf                                    

Copy the following configuration in your file, go through it and I will explain it afterwards.

                    # odoo serverupstream odoo { server 127.0.0.1:8069;}upstream odoochat { server 127.0.0.1:8072;}# Expires mapmap $sent_http_content_type $expires {    default                    off;    text/html                  epoch;    text/css                   max;    application/javascript     max;    ~image/                    max;}server { listen 443 ssl default_server; proxy_read_timeout 7200s; proxy_connect_timeout 7200s; proxy_send_timeout 7200s; client_max_body_size 500m; expires $expires; proxy_max_temp_file_size 5924m; # Add Headers for odoo proxy mode proxy_set_header Host $host; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Client-IP $remote_addr; proxy_set_header HTTP_X_FORWARDED_HOST $remote_addr; # SSL parameters # Make sure that this points to the folder that holds your custom crt and key file (created later in this tutorial) # ssl_certificate /etc/ssl/your_folder/YourDomainValidationSecureServerCA_Bundle.crt; # ssl_certificate_key /etc/ssl/your_folder/some_website_com.key; ssl_session_timeout 30m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; ssl_prefer_server_ciphers on; # log access_log /var/log/nginx/odoo.access.log; error_log /var/log/nginx/odoo.error.log; # Redirect requests to odoo backend server location / {   proxy_redirect off;   proxy_pass http://odoo; location ~* .(js|css|png|jpg|jpeg|gif|ico)$ {   expires 2d;   proxy_pass http://odoo;   add_header Cache-Control "public, no-transform"; } } location /longpolling {     proxy_pass http://odoochat; } location /web/static/ { # cash static data proxy_cache_valid 200 60m; proxy_buffering on; # How quick static data expires (and is reloaded on the next request) in seconds expires 864000; proxy_pass http://odoo; } # common gzip gzip_types text/css text/less text/plain text/xml application/xml application/json application/javascript; gzip on;}                                    

Did you notice that 'ssl_certificate' and 'ssl_certificate_key' are commented out? That is because we still need to generate those keys with Letsencrypt. We'll get back to this part later on. Let us first try to understand the Nginx configuration.

3.4 Understanding the Nginx config

Quite a block of code right? Let us split it up block by block so I can explain it in more detail. The first block, the 'upstream Odoo', will tell Nginx that the Odoo instance is running locally on port 8069. Thanks to this Nginx knows where the Odoo is at and can redirect the content.

The second block, 'upstream odoochat' will tell Nginx that the Odoo chat is running on port 8072.

The third block, 'map', will tells Nginx what the default action is. It will tell Nginx how long it takes before content expires, in our example it tries to keep the content as long as possible. The 'max' value corresponds to 10 years.

The fourth block, 'server' is where most of the configuration is done. It will tell Nginx the following things:

  • listen: we want Nginx to listen on port 443 for SSL content.
  • proxy_read_timeout: how long it will take before Nginx gives back a timeout for reading a response from the proxied server. This means that if our Odoo is taking longer than 2 hours for a response that Nginx will kill it.
  • proxy_connect_timeout: how long it will take before Nginx gives back a timeout for trying to establish a connection.
  • proxy_send_timeout: how long it will take before Nginx will set a timeout for transmitting a request to the proxied server.
  • client_max_body_size: sets the maximum allowed size of the client request body. If the request is bigger Nginx will return a "413 Request entity too long".
  • expires: links back to the map block and will define how long it takes for the resources to expire.
  • proxy_max_temp_file_size: will tell Nginx how much content is allowed to be buffered on the server. This is important for your backups! If the Nginx configuration has a smaller number than your database its size the backup will fail from the frontend.
The rest of the configuration file is quite standard. There is just one more thing to do and that is to generate our SSL keys!

4. Installing certbot & generating the SSL certificate

4.1 Installing certbot

Before you can request and generate SSL certificates with Letsencrypt you'll need to add the package and install it. Lets first add it so that we can install it on Ubuntu:

                    sudo add-apt-repository ppa:certbot/certbot                                    

Now install the certbot. Certbot is the software behind Letsencrypt which will handle all the details to issue certificates and it will respond with the Letsencrypt servers to generate safe SSL certificates. You can install it as any other Ubuntu package:

                    sudo apt install python-certbot-nginx                                    

4.2 Generating an SSL certificate

Now that we have the software installed we can generate our SSL certificate and key. With Letsencrypt you have two options: generating SSL for a subdomain or for a top domain. In this tutorial I'm creating a Letsencrypt certificate for letsencryptdemo.oocademy.com, which is a subdomain. You can ask the certbot to generate a new certificate with the following code:

                    sudo certbot certonly --nginx -d letsencryptdemo.oocademy.com                                    

If you'd like to generate a certificate for a top domain you can do it with the following command:

                    sudo certbot --nginx -d yourwebsite.com -d www.yourwebsite.com                                    

Wait a minute and you will see that certbot gives you feedback about the certificate that you've requested. In this response you will see that two files are mentioned. The 'fullchain.pem' path (which is your certificate) and the privkey.pem (which holds your private key):

Feedback from Letsencrypt for your certificate request

These two paths should be configured in your Nginx configuration so that Nginx knows where to load the certificate from.

4.3 Adding the paths to Nginx

Open up your odoo.conf file to add in the paths to these two files:

                    sudo nano /etc/nginx/sites-enabled/odoo.conf                                    

Uncomment the 'ssl_certificate' and 'ssl_certificate_key' lines and change the paths to the paths that you got back from the certbot. Your two lines should look like this:

                    ssl_certificate /etc/letsencrypt/live/letsencryptdemo.oocademy.com/fullchain.pem;ssl_certificate_key /etc/letsencrypt/live/letsencryptdemo.oocademy.com/privkey.pem;                                    

5. Reloading Nginx & testing the certificate

5.1 Reloading Nginx

Great! Everything is setup and configured now for your website to run on SSL. You just have to reload the Nginx to apply the new configurations now:

                    sudo service nginx reload                                    

Open up your webbrowser and surf to your website. You will see that it runs on HTTPS now with a certificate from Letsencrypt:

Result: website running on SSL

5.2 Testing the certificate

What about the expiration of the certificate though? You can see that in my example it will expire on the 13'th of july 2019. Letsencrypt luckily automatically handles the renewal of certificates. When a certificate is close to expiring Letsencrypt will generate a new one for you out of the box. You can test if Letsencrypt is configured correctly and if it can generate new certificates for you from the command line. You can do this with the following command:

                    sudo certbot renew --dry-run                                    

If everything is well then you should get a result from the certbot saying that all renewals have succeeded:

Succesfull certbot dry-run result

That's if! You've now configured your own Odoo instance to run on SSL with free certificates from Letsencrypt!

6. Conclusion

While configuring your Odoo to run with SSL from Letsencrypt is not the easiest thing to do it adds quite some benefits. Your website is more secure, better trusted by people, it runs faster and you'll be higher in the Google search results. Thanks to Letsencrypt the SSL certificates are even free and updated automatically when they are about to expire. While Nginx has a lot of configuration options and you might feel overwhelmed by the code it is still worth it to run your Odoo instances on Nginx. Tip: Take some extra time to learn more about Nginx. Almost two third of the worlds biggest websites run on it and Nginx is growing fast.