How to: OpenERP 6.1, Ubuntu 10.04 LTS, nginx SSL Reverse Proxy

This article follows on (hopefully not unsurprisingly) from the basic 6.1 installation howto.

In this post I’ll describe one way of providing SSL encrypted access to your shiny new OpenERP 6.1 server running on Ubuntu 10.04 LTS.

This time I thought I’d use the nginx (pronounced like “Engine X”) webserver to act as a reverse proxy and do SSL termination for web, GTK client and WebDAV/CalDAV access. nginx is gaining in popularity and is now the second most popular web server in the world according to some figures. It has a reputation for being fast and lean – so it seemed like a good choice for a relatively simple job like this.

I’m indebted to xat for this post which provided the main configuration script for a reverse proxy on OpenERP 6.0. The changes I have made to xat’s original configuration are: different port number, some additional rewrite rules to support WebDAV and the new mobile interface, new location for static files.

NB: For the purposes of this how to, we’ll be using self-signed certificates. A discussion of the pros and cons of this choice is beyond the scope of this article.

Step 1. Install nginx

On your server install nginx by typing:

sudo apt-get install nginx

Next, we need to generate a SSL certificate and key.

Step 2. Create your cert and key

I create the files in a temporary directory then move them to their final resting place once they have been built (the first cd is just to make sure we are in our home directory to start with):


cd
mkdir temp
cd temp

Then we generate a new key, you will be asked to enter a passphrase and confirm:

openssl genrsa -des3 -out server.pkey 1024

We don’t really want to have to enter a passphrase every time the server starts up so we remove the passphrase by doing this:

openssl rsa -in server.pkey -out server.key

Next we need to create a signing request which will hold the data that will be visible in your final certificate:

openssl req -new -key server.key -out server.csr

This will generate a series of prompts like this: Enter the information as requested:

You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter ‘.’, the field will be left blank.
—–
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:
Email Address []:

Please enter the following ‘extra’ attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:The Client’s Company

And finally we self-sign our certificate.

openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

We only need two of the files in the working directory, the key and the certificate. But before we can use them they need to have their ownership and access rights altered:


sudo chown root:www-data server.crt server.key
sudo chmod 640 server.crt server.key

And then we put them in a sensible place:


sudo mkdir /etc/ssl/nginx
sudo chown www-data:root /etc/ssl/nginx
sudo chmod 710 /etc/ssl/nginx
sudo mv server.crt server.key /etc/ssl/nginx/

Now the key and certificate are safely stored away, we can tell nginx where they are and what it should be doing…

Step 3. Create the nginx site configuration file

We create a new configuration file

sudo nano /etc/nginx/sites-available/openerp

with the following content:

Note: You will need to change all references to 10.0.0.26 in the following file to either the domain name or static IP address of your server. This was the IP address of the machine I built this test script on. It will not work unless changed to suit your own system!


upstream openerpweb {
    server 127.0.0.1:8069 weight=1 fail_timeout=300s;
}

server {
    listen 80;
    server_name    10.0.0.26;

    # Strict Transport Security
    add_header Strict-Transport-Security max-age=2592000;

    rewrite ^/mobile.*$ https://10.0.0.26/web_mobile/static/src/web_mobile.html permanent;
    rewrite ^/webdav(.*)$ https://10.0.0.26/webdav/$1 permanent;
    rewrite ^/.*$ https://10.0.0.26/web/webclient/home permanent;
}

server {
    # server port and name
    listen        443 default;
    server_name   10.0.0.26;

    # Specifies the maximum accepted body size of a client request, 
    # as indicated by the request header Content-Length. 
    client_max_body_size 200m;

    # ssl log files
    access_log    /var/log/nginx/openerp-access.log;
    error_log    /var/log/nginx/openerp-error.log;

    # ssl certificate files
    ssl on;
    ssl_certificate        /etc/ssl/nginx/server.crt;
    ssl_certificate_key    /etc/ssl/nginx/server.key;

    # add ssl specific settings
    keepalive_timeout    60;

    # limit ciphers
    ssl_ciphers            HIGH:!ADH:!MD5;
    ssl_protocols            SSLv3 TLSv1;
    ssl_prefer_server_ciphers    on;

    # increase proxy buffer to handle some OpenERP web requests
    proxy_buffers 16 64k;
    proxy_buffer_size 128k;

    location / {
        proxy_pass    http://openerpweb;
        # force timeouts if the backend dies
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;

        # set headers
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
       
        # Let the OpenERP web service know that we're using HTTPS, otherwise
        # it will generate URL using http:// and not https://
        proxy_set_header X-Forwarded-Proto https;

        # by default, do not forward anything
        proxy_redirect off;
    }

    # cache some static data in memory for 60mins.
    # under heavy load this should relieve stress on the OpenERP web interface a bit.
    location ~* /web/static/ {
        proxy_cache_valid 200 60m;
        proxy_buffering    on;
        expires 864000;
        proxy_pass http://openerpweb;
    }

}

UPDATE: 04/04/2012. I have added a line to the above file: client_max_body_size 200m; thanks to Praxi for reminding me about this. The default setting is just 1MB which will stop users from uploading any files larger than that, including databases!

And then we can enable the new site configuration by creating a symbolic link in the /etc/nginx/sites-enabled directory.

sudo ln -s /etc/nginx/sites-available/openerp /etc/nginx/sites-enabled/openerp

Step 4. Change the OpenERP server configuration file

The next step is to re-configure the OpenERP server so that non-encrypted services are not accessible from the outside world.

In /etc/openerp-server.conf the non-encrypted services will only listen on localhost, i.e. not from external connections so in effect only traffic from nginx will be accepted.

After opening the file for editing, just add 127.0.0.1 to the xmlrpc and netrpc interface lines as shown below.

sudo nano /etc/openerp-server.conf


xmlrpc_interface = 127.0.0.1
netrpc_interface = 127.0.0.1

That’s it. Everything is now configured.

Step 5. Try it out

Restart the services to load the new configurations


sudo service openerp-server restart
sudo service nginx restart

You should not be able to connect to the web client on port 8069 and the GTK client should not connect on either the NetRPC (8070) or XMLRPC (8069) services.

For web access you just need to visit https://your-ip-or-domain and in the GTK client you will need to use port 443 (https) and choose the XMLRPC (Secure) protocol.

The nginx configuration above will also redirect any incoming requests for port 80 to port 443 (https) and it also makes sensible redirects for the mobile and WebDAV/CalDAV services. (From what I can gather however WebDAV clients really don’t handle redirects so this bit is probably not that useful). I think the best bet for WebDAV/CalDAV is just to provide the correct URL in the first place.

For CalDAV access then, the URL to a calendar will be something like this:

https://your-ip-or-domain/webdav/DB_NAME/calendars/users/USERNAME/c/CALENDAR_NAME

There you have it. In OpenERP 6.1 this job actually proved to be a little simpler than the previous version largely due to the integrated web interface. There are also fewer configuration changes required in openerp-server.conf.

Finally, I really wanted to try and make use of the WSGI support in OpenERP 6.1 instead of the method above, but my efforts to get this to work from nginx or Apache have so far ended in failure 🙁 Obviously if anyone wants to provide a working config for that please feel free to add a comment and link.

Tags: , , , , ,

102 Comments

  • nexo says:

    So sorry to hear that Alan, but thanks any way.

    Any suggestion about the logs I should check?

    Regards

  • Arnaud says:

    Hi Alan,
    I have installed OpenERP 7.0 with Nginx .
    Until now it has worked . I did an update of openERP and since , I couldn’ connect to my OpenERP
    NGINX works but there is white screen behind.
    I can connect to my OERP if I launch it manually and with the http://IP:8069 .

    Thanks for your help.

    Arnaud

  • TheBrush says:

    Hello Alan, thanks for your guide, always useful!
    My question about reverse proxy file is, is correct the 2 proxy_pass definitions in it?

    proxy_pass http://openerpweb;

    What is openerpweb, I have to substitute with IP address?
    Thanks for any reply
    Nicola

  • TheBrush says:

    I’ve got a problem during login operation (403 Request Forbidden – You are not allowed to access this resource Traceback …/web/lib/cherrypy/_cprequest.py line 653 in respond…) that require this hacks:

    Changed openerp-web config line :
    replace –> tools.csrf.on = True
    by –> tools.csrf.on = False

    As indicated here: http://forum.openerp.com/forum/topic29027.html

  • TheBrush says:

    I’ve got an error if, in one dashboard graph, I click on a column to see details, nginx says:
    414 Request-URI Too Large
    nginx/1.1.19

    Yes, the uri is 20K char long… 🙂

    I add this extra parameter after: client_max_body_size 200m;
    large_client_header_buffers 8 20k;

  • TheDude says:

    how does the outgoing email get fixed for this? my footers still say openerpserver.mydomain.com:8069 …. the email template files don’t address it appropriately.

  • Praxi says:

    Just wanted to share, I did this for version 7 with a few minor modifications and it worked fine. I already had my cert, so I skipped most of the cert creation steps. I added a nginx listen for 8069 to handle any odd requests. I had to bind it to a specific IP so as not to interfere with the openerp instance running on localhost. I also commented out all the webdav and mobile rewrites.


    server {
    listen 80;
    server_name servername.com;

    # Strict Transport Security
    add_header Strict-Transport-Security max-age=2592000;

    rewrite ^/.*$ https://servername.com/ permanent;
    }

    server {
    listen 172.31.35.71:8069;
    server_name servername.com;

    # Strict Transport Security
    add_header Strict-Transport-Security max-age=2592000;

    rewrite ^/.*$ https://servername.com/ permanent;
    }

Leave a Reply to Nathan

XHTML: You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>