Odoo community is not protected against brute force attack by default, the system is vulnerable over internet, however Odoo store provides auth_brute_force App which can handle this task, it’s available through this link. But it doesn’t work correctly behind a reverse proxy such as Caddy or Nginx. In the second part of this post, i’ll explain the little tip to make it work.
Download and install the module
Download the file corresponding to your version of Odoo. Unzip the file “auth_brute_force-9.0.1.1.0.zip”. Move the folder “auth_brute_force” to your module folder: “/usr/lib/python2.7/dist-packages/openerp/addons/“.
Enable the developper mode through “About” popup. Then go to Apps menu and click on “Update apps lists”, search for the new app and process to the installation. You’re good to go if you reach your system directly to port 8069 without ssl. This module will be able to ban the remote ip address. Depending on the version you’re using, more or less options are available to add in “System parameters” in settings, then parameters menu. Documentation can be find on the module download page. But if your system is behind a reverse proxy, the next part of this post is for you. By default the localhost IP 127.0.0.1 will only be the IP banned.
Odoo through ssl (Certificate provided by Let’s encrypt) behind reverse proxy (Caddy or Nginx)
Let’s encrypt is a free, open Certificate Authority which needs a reverse proxy to convert your unsecured into ssl connection. I won’t describe how to set it up in this article, maybe later in another post. However with this config and module, the only ip the system will be able to ban is the localhost IP (127.0.0.1) wherever your connection is coming from. It could put potentially your server offline, and make it unreachable for all of your users. So to ban computer client’s real IP address, we need to customize first the reverse proxy.
Caddy proxy
Those lines will force the proxy to forward the remote ip address into X-Real-IP and X-Forwarded-For variables, we will be able then to get their value in your Python code.
header_upstream X-Real-IP {remote} header_upstream X-Forwarded-For {remote} header_upstream X-Forwarded-Proto {scheme}
vi /et/caddy/CaddyFile
Your file should look like this after modification.
odoo.numberspeaks.com { proxy / http://127.0.0.1:8069 { header_upstream Host {host} header_upstream X-Real-IP {remote} header_upstream X-Forwarded-For {remote} header_upstream X-Forwarded-Proto {scheme} } proxy /longpolling http://127.0.0.1:8072 { header_upstream Host {host} header_upstream X-Real-IP {remote} header_upstream X-Forwarded-For {remote} header_upstream X-Forwarded-Proto {scheme} } gzip log syslog }
restart caddy daemon.
NGINX PROXY
Lines to add in your site conf file:
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https;
vi /etc/nginx/sites-enabled/default
This part of your file should be like this after modification
location / { proxy_pass http://openerp; # force timeouts if the backend dies proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; proxy_redirect off; # set headers proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; } location /longpolling { proxy_pass http://127.0.0.1:8072; proxy_redirect off; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; }
Update the auth_brute_force module
The right way to bring those updates should be by creating a new module that will override functions in “auth_brute_force” module, but i’m a bit too lazy. Depending on the version of your Odo you’re using, modification we will make might be a bit different. I will just show you the additional code to add for Odoo 8, 9 modules, it should be quite similar for newer version (Odoo 10, 11)
Odoo 8 module
Edit controller.py file in controller folder of auth_brute_force module and copy and paste lines bellow into your file. If the proxy is set correctly, now the real remote ip address is stored in HTTP_X_FORWARDED_FOR key in request.httprequest.environ array, we just need to set a new value of remote variable if HTTP_X_FORWARDED_FOR exists.
if 'HTTP_X_FORWARDED_FOR' in request.httprequest.environ: _logger.critical(request.httprequest.environ["HTTP_X_FORWARDED_FOR"]) remote = request.httprequest.environ["HTTP_X_FORWARDED_FOR"]
Your file should be like this after modification
Save your modification and restart odoo to apply the update, after a login attempt failure you should see now your ip address instead of 127.0.0.1 ip.
odoo 9, 11 module
Open res_users.py file in models folder. Add those lines bellow into your file. HTTP_X_FORWARDED_FOR variable is stored in curren_thread().environ dictionary.
if 'HTTP_X_FORWARDED_FOR' in current_thread().environ: x_forwarded_for_addr = current_thread().environ["HTTP_X_FORWARDED_FOR"] if x_forwarded_for_addr: remote_addr = x_forwarded_for_addr
This part of your file should be like this.
Save and restart odoo to apply the update. After a login attempt failure, you should see your remote ip address.
Your system is now protected against brute force attack.
Exactly what I was looking for.
Thanks!