Nginx is an open-source web server used mainly for reverse proxy, load balancing, caching, etc. It is mainly designed for stability and maximum performance. It is like the Apache web server, and the main difference is that, nginx has an event-driven architecture (using a single thread, it handles multiple requests). On the other hand, Apache is process-driven (handles each request using a single thread). SSL (Secure Socket Layer) is a networking protocol that helps secure connections between web servers and web clients over an insecure network like the Internet.
In this blog, we are going to discuss how we can set up an SSL certificate in Nginx for running Odoo instances on our local servers.
Let’s first set up Nginx as a reverse proxy. In order to access our Odoo instance, we need to use the port number along with the IP address. After setting the reverse proxy, we can make use of the specified domain without mentioning the Port separately. Here we are focused on the Ubuntu operating system.
Before installing Nginx, we need to first check other web servers like Apache is not running for better performance. To stop the service of the Apache web server, we can make use of the following command;
systemctl stop apache2
And to remove Apache, use the following commands;
apt-get purge apache2*
apt autoremove
Now it's safe to install and run nginx. To install nginx, use the following commands;
sudo apt-get update
sudo apt-get install nginx
After running the above commands, nginx will be installed, and to run the nginx service, run
sudo service nginx start
Or
sudo systemctl start nginx
To run Odoo using nginx as a reverse proxy, we have to do some configuration in the Nginx configuration file. The configuration file of nginx can be found using the path /etc/nginx/sites-enabled. There will be a default configuration file name default. Move to the path using,
cd /etc/nignx/sites-enabled
And open the configuration file using,
sudo nano default
Edit the existing server block or add a new one if it is not already created. Add the following code to the conf file.
server {
server_name odoo.lvh.me; # specifying localhost, can also use localhost
listen 80;
access_log /var/log/nginx/testing-access.log;
error_log /var/log/nginx/testing-error.log;
location /longpolling {
proxy_connect_timeout 3600;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
send_timeout 3600;
proxy_pass http://127.0.0.1:8072;
}
location / {
proxy_connect_timeout 3600;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
send_timeout 3600;
# proxy_redirect off;
proxy_pass http://127.0.0.1:8016/; #8016 refers to Odoo's running port
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
gzip on;
gzip_min_length 1000;
}
In the above code, I used odoo.lvh.me instead of localhost. It is also possible to use localhost, and in case of multiple instances of Odoo, we can use lvh.me, which makes it possible to handle subdomains as localhost will not have top-level domains. And in the case of lvh.me, we can test virtual subdomains using
any_name.lvh.me without editing /etc/hosts or setting up our own DNS.
As we have successfully configured nginx, we now have to update our Odoo configuration file. This step is a good security practice, even though this is optional. Also, in order to avoid direct access to the Odoo instance, as the Odoo server by default listens to port 8069, add the following commands to the Odoo configuration file.
xmlrpc_interface = 127.0.0.1
netrpc_interface = 127.0.0.1
Let’s now restart the services for Odoo and nginx using the following commands.
systemctl restart odoo.service = > service for Odoo
systemctl restart nginx.service = > service for nginx
On searching odoo.lvh.me on any browser, we will be redirected to Our Odoo instance.
For setting up a reverse proxy using nginx for multiple instances, we can specify it on different server blocks as shown below.
server {
server_name odoo1.lvh.me;
listen 80;
access_log /var/log/nginx/testing-access.log;
error_log /var/log/nginx/testing-error.log;
location /longpolling {
proxy_connect_timeout 3600;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
send_timeout 3600;
proxy_pass http://127.0.0.1:8072;
}
location / {
proxy_connect_timeout 3600;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
send_timeout 3600;
# proxy_redirect off;
proxy_pass http://127.0.0.1:8014/;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
gzip on;
gzip_min_length 1000;
}
server {
server_name odoo2.lvh.me;
listen 80;
access_log /var/log/nginx/testing-access.log;
error_log /var/log/nginx/testing-error.log;
location /longpolling {
proxy_connect_timeout 3600;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
send_timeout 3600;
proxy_pass http://127.0.0.1:8072;
}
location / {
proxy_connect_timeout 3600;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
send_timeout 3600;
# proxy_redirect off;
proxy_pass http://127.0.0.1:8012/;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
gzip on;
gzip_min_length 1000;
}
As we have configured a reverse proxy for Our Odoo instance using Nginx, it's time to set up our SSL certificate to make the connection secure. Here we are using certbot to generate the self-signed SSL certificates.
openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
After entering the above command, provide the extra details for the questions prompted, like in the below image.
In the current folder, there will be two new files, certificate.pem, and key.pem, which is the self-signed SSL certificate and the key file. We can move these folders to /etc/ssl/nginx (if the nginx folder is not existing in /etc/ssl create one) folder by,
sudo mv certificate.pem /etc/ssl/nginx
sudo mv key.pem /etc/ssl/nginx
Now let’s update our Nginx configuration.
Update the default configuration file like the one below.
server {
server_name odoo.lvh.me;
return 301 https://$server_name$request_uri;
}
server {
server_name odoo.lvh.me;
listen 443 ssl;
access_log /var/log/nginx/testing-access.log;
error_log /var/log/nginx/testing-error.log;
location /longpolling {
proxy_connect_timeout 3600;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
send_timeout 3600;
proxy_pass http://127.0.0.1:8072;
}
location / {
proxy_connect_timeout 3600;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
send_timeout 3600;
proxy_redirect off;
proxy_pass http://127.0.0.1:8016/;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
ssl on;
ssl_certificate /etc/ssl/nginx/certificate.pem;
ssl_certificate_key /etc/ssl/nginx/key.pem;
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-RS$';
ssl_prefer_server_ciphers on;
gzip on;
gzip_min_length 1000;
}
In order to check all the nginx configuration is good, just type the command in the terminal,
sudo nginx -t
Restart the nginx service, and while searching odoo.lvh.me on any browser, we will be redirected to a page as follows.
This is because our certificate is self-signed, which means our certificate is not signed by any trusted certificate authority. Proceeding with the advanced option, we will be redirected to our Odoo instance.
For configuring multiple instances with SSL certificates configured, we can specify them in different server blocks after specifying the SSL certificates on each server block.
server {
server_name odoo1.lvh.me www.odoo1.lvh.me;
return 301 https://$server_name$request_uri;
}
server {
server_name odoo2.lvh.me www.odoo2.lvh.me;
return 301 https://$server_name$request_uri;
}
server {
server_name odoo1.lvh.me;
listen 443 ssl;
access_log /var/log/nginx/testing-access.log;
error_log /var/log/nginx/testing-error.log;
location /longpolling {
proxy_connect_timeout 3600;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
send_timeout 3600;
proxy_pass http://127.0.0.1:8072;
}
location / {
proxy_connect_timeout 3600;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
send_timeout 3600;
proxy_redirect off;
proxy_pass http://127.0.0.1:8016/;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
ssl on;
ssl_certificate /etc/ssl/nginx/certificate.pem;
ssl_certificate_key /etc/ssl/nginx/key.pem;
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-RS$';
ssl_prefer_server_ciphers on;
gzip on;
gzip_min_length 1000;
}
server {
server_name odoo15.lvh.me;
listen 443 ssl;
access_log /var/log/nginx/testing-access.log;
error_log /var/log/nginx/testing-error.log;
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1; # Only allow requests from localhost
deny all; # Deny all other requests
}
location /longpolling {
proxy_connect_timeout 3600;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
send_timeout 3600;
proxy_pass http://127.0.0.1:8072;
}
location / {
proxy_connect_timeout 3600;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
send_timeout 3600;
proxy_redirect off;
proxy_pass http://127.0.0.1:8017/;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
ssl on;
ssl_certificate /etc/ssl/nginx/15certificate.pem;
ssl_certificate_key /etc/ssl/nginx/15key.pem;
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-RS$';
ssl_prefer_server_ciphers on;
gzip on;
gzip_min_length 1000;
}
And that’s how we configure nginx for reverse proxying and SSL certificates for secure connections.