Skip to content

Odoo Security Best Practices for Production

DeployMonkey Team · March 11, 2026 10 min read

A default Odoo installation is configured for convenience, not security. Before your instance handles real customer data, you need to close the gaps that attackers actively exploit. This guide covers the essential hardening steps every production Odoo deployment must complete.

1. Disable the Database Manager

The Odoo database manager at /web/database/manager is one of the most dangerous exposed endpoints. It allows anyone with the master password to create, drop, duplicate, or restore databases — directly from a browser, no authentication required beyond the master password.

Disable it in /etc/odoo/odoo.conf:

list_db = False

After restarting Odoo, the database manager is inaccessible. If you need to create or restore a database, use pg_restore from the command line (see restoring an Odoo database).

Also restrict the /web/database/ path in Nginx as a defense-in-depth measure:

location ~ ^/web/database/ {
deny all;
return 403;
}

2. Set a Strong Master Password

The Odoo master password (also called the admin password) controls access to the database manager and must be changed from the default immediately. In odoo.conf:

admin_passwd = a_very_long_random_string_here

Generate a strong one: openssl rand -base64 32. Never use admin, odoo, or any dictionary word.

3. Block Direct Access to Port 8069

Odoo's application server should never be directly accessible from the internet. All traffic must go through your Nginx reverse proxy. Block port 8069 at the firewall:

# UFW (Ubuntu)
sudo ufw deny 8069/tcp
sudo ufw deny 8072/tcp  # longpolling port

# firewalld (RHEL/AlmaLinux)
sudo firewall-cmd --permanent --remove-port=8069/tcp
sudo firewall-cmd --permanent --remove-port=8072/tcp
sudo firewall-cmd --reload

Also bind Odoo to localhost only in odoo.conf:

xmlrpc_interface = 127.0.0.1
netrpc_interface = 127.0.0.1

4. SSH Key-Only Authentication

Password-based SSH is brute-forced constantly on any public-facing server. Disable it:

sudo nano /etc/ssh/sshd_config

Set or confirm these values:

PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin prohibit-password
AuthorizedKeysFile .ssh/authorized_keys
sudo systemctl restart sshd

Warning: Ensure your public key is in ~/.ssh/authorized_keys before disabling password auth, or you will be locked out.

5. Configure a Restrictive Firewall

Only expose the ports your server actually needs:

# UFW example
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp     # SSH
sudo ufw allow 80/tcp     # HTTP (for Let's Encrypt challenge)
sudo ufw allow 443/tcp    # HTTPS
sudo ufw enable

All other ports — including PostgreSQL (5432), Odoo (8069/8072), and any monitoring agents — should be accessible only from specific IP addresses or over VPN.

6. Keep Odoo and the OS Updated

Unpatched software is the most common attack vector. Establish an update process:

  • OS packages: Enable automatic security updates with unattended-upgrades (Ubuntu) or dnf-automatic (RHEL)
  • Odoo patches: Subscribe to the Odoo security advisory list and apply patches promptly
  • Python dependencies: Regularly run pip list --outdated in your Odoo virtualenv and update packages with known CVEs

7. Restrict Odoo User Permissions

Run Odoo as a dedicated, non-root, non-sudo system user:

# Create dedicated user (if not already done)
sudo useradd -r -s /bin/false odoo

# Verify Odoo process owner
ps aux | grep odoo

The Odoo user should have no sudo privileges, no write access outside of /var/lib/odoo and /var/log/odoo, and no shell access.

8. Enable Audit Logging in Odoo

Odoo's built-in logging tracks login attempts, record changes, and field updates. Enable it in Settings > General Settings > Logging. For compliance requirements, consider a dedicated audit log module that records who changed what and when.

Also configure Odoo's Python log level to capture authentication events:

log_level = warn
log_handler = :WARNING,odoo.addons.base_setup:INFO

9. Enforce HTTPS and Security Headers

Set up Let's Encrypt SSL (see our Odoo SSL guide) and add these security headers to Nginx:

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy strict-origin-when-cross-origin;

10. Disable Unused Odoo Apps

Every installed Odoo app increases the attack surface. Uninstall apps you don't use — particularly apps that expose public-facing routes (website, e-commerce, surveys) if you don't need them. Go to Apps, filter by Installed, and remove anything unnecessary.

Security Hardening Checklist

  • [ ] list_db = False in odoo.conf
  • [ ] Strong admin_passwd set (32+ character random string)
  • [ ] Port 8069 blocked from external access
  • [ ] SSH password authentication disabled
  • [ ] Firewall allows only 22, 80, 443
  • [ ] OS automatic security updates enabled
  • [ ] Odoo runs as dedicated non-root user
  • [ ] HTTPS enabled with HSTS header
  • [ ] Unused Odoo apps uninstalled

How DeployMonkey Handles Security by Default

DeployMonkey applies all of these hardening measures automatically on every instance. The database manager is disabled, firewall rules are pre-configured, SSL is provisioned, and Odoo runs in an isolated Docker container with no host access. Security best practices are enforced at the infrastructure level — not left to manual configuration. Start your hardened Odoo instance free.

Frequently Asked Questions

Is it safe to expose the Odoo database manager to the internet?

No. The database manager should never be accessible from the internet in production. Set list_db = False in odoo.conf and block the path in Nginx. Database operations should be performed via the command line by authorized administrators only.

How do I change the Odoo master password if I've forgotten it?

Edit /etc/odoo/odoo.conf and set a new value for admin_passwd. Restart Odoo. The new password takes effect immediately. If you're using a hashed password (the UI hashes it on save), you can replace it with a plaintext value in the config file — Odoo will hash it on next use.

Should I use Fail2ban with Odoo?

Yes. Fail2ban can parse Odoo's login failure logs and temporarily ban IPs that exceed a threshold of failed logins. This provides brute-force protection for the Odoo login page. Odoo also has its own brute-force protection built in since version 13, but Fail2ban adds an extra layer.

What ports should I open for Odoo multi-company or multi-database setups?

The same rule applies: only 80 and 443 externally, routed through Nginx. Use Nginx server_name directives to route different domains to different databases. No additional ports need to be opened.

How do I audit who made changes in Odoo?

Enable the Tracking feature on models you want to audit (Settings > Technical > Fields — set Tracking to true on important fields). For comprehensive auditing, install a dedicated audit trail module. Odoo's chatter on most records shows field change history for tracked fields.