系统配置与安全

本文档介绍了在生产环境中或在面向互联网的服务器上设置Odoo的基本步骤。它遵循 安装,对于未在互联网上公开的开发系统通常不是必需的。

警告

如果您正在设置公共服务器,请务必查看我们的:ref:`安全 <security>`建议!

数据库过滤器

Odoo是一个多租户系统:单一Odoo系统可以运行并启用若干数据库实例。Odoo也是高度可定制的,定制(如模块加载)依赖“当前数据库”。

以登录公司用户身份使用后端(Web 客户端)时,这不是问题:登录时可以选择数据库,然后加载自定义项。

但是,对于未绑定到数据库的非登录用户(门户,网站)来说,这是一个问题:Odoo需要知道应该使用哪个数据库来加载网站页面或执行操作。如果不使用多租户,这不是问题,只有一个数据库可以使用,但是如果有多个数据库可访问,Odoo需要一个规则来知道它应该使用哪一个。

这是其目标之一 --db-filter:它指定应如何根据所请求的主机名(域)选择数据库。该值是一个“正则表达式”_,可能包括动态注入的主机名(%h)或访问系统的第一个子域(%d)。

对于在生产环境中托管多个数据库的服务器,尤其是在使用“网站”的情况下,必须设置 dbfilter**,否则许多功能将无法正常工作。

配置示例

  • 仅显示名称以“mycompany”开头的数据库

odoo.conf 配置文件 中设置:

[options]
dbfilter = ^mycompany.*$
  • 仅显示与“www”之后的第一个子域匹配的数据库:例如,如果传入的请求发送到“www.mycompany.com”或“mycompany.co.uk”,则不会显示“www2.mycompany.com”或“helpdesk.mycompany.com”的数据库“ mycompany”。

odoo.conf 配置文件 中设置:

[options]
dbfilter = ^%d$

注解

设置适当的 --db-filter 是保护部署安全的重要部分。一旦它正常工作并且每个主机名只匹配一个数据库,强烈建议阻止对数据库管理器屏幕的访问,并使用 --no-database-list 参数来阻止列出数据库,并阻止对数据库管理界面的访问。另请参见 security.

PostgreSQL

默认情况下,PostgreSQL只允许通过UNIX套接字和环回连接进行连接(来自“localhost”,PostgreSQL服务器安装在同一台机器上)。

如果您希望Odoo和PostgreSQL在同一台主机上执行,UNIX套接字是可以的,并且在没有提供主机时是默认值,但是如果您希望Odoo和PostgreSQL在不同的主机 1 上执行,它将需要 `监听网络接口 `_ 2, 或者:

  • 只接受环回连接,并在运行Odoo的计算机和运行PostgreSQL的计算机之间 使用 SSH 加密通道 ,然后将Odoo配置为通过SSH连接

  • 接受与安装Odoo的计算机的连接,可能通过ssl(有关详细信息,请参阅“PostgreSQL连接设置”_),然后将Odoo配置为通过网络连接

配置示例

  • 允许在本地主机上进行 tcp 连接

  • 允许来自 192.168.1.x 网络的 tcp 连接

in /etc/postgresql/<YOUR POSTGRESQL VERSION>/main/pg_hba.conf set:

# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
host    all             all             192.168.1.0/24          md5

in /etc/postgresql/<YOUR POSTGRESQL VERSION>/main/postgresql.conf set:

listen_addresses = 'localhost,192.168.1.2'
port = 5432
max_connections = 80

配置 Odoo

开箱即用,Odoo通过UNIX套接字通过端口5432连接到本地postgres。当您的 Postgres 部署不是本地部署和/或不使用安装默认值时,可以使用 数据库选项 来覆盖它。

软件包安装程序 将自动创建一个新用户(odoo)并将其设置为数据库用户。

  • 数据库管理界面受 admin_passwd 设置保护。此设置只能使用配置文件进行设置,并且在执行数据库更改之前只需进行检查即可。应将其设置为随机生成的值,以确保第三方无法使用此接口。

  • 所有数据库操作都使用 数据库选项,包括数据库管理界面。要使数据库管理界面正常工作,需要 PostgreSQL 用户具有“createdb”权限。

  • 用户始终可以删除他们拥有的数据库。为了使数据库管理界面完全不起作用,需要使用 no-createdb 来创建PostgreSQL用户,并且数据库必须由其他 PostgreSQL 用户拥有。

    警告

    PostgreSQL用户 必须不是 超级用户,例如不能是 root 或 Adiministrator

配置示例

  • 连接到 192.168.1.2 上的 PostgreSQL 服务器

  • 端口 5432

  • 使用“odoo”用户账户,

  • 使用“pwd”作为密码

  • 仅筛选名称以“mycompany”开头的数据库名

odoo.conf 配置文件 中设置:

[options]
admin_passwd = mysupersecretpassword
db_host = 192.168.1.2
db_port = 5432
db_user = odoo
db_password = pwd
dbfilter = ^mycompany.*$

在 Odoo 和 PostgreSQL 之间使用 SSL

从Odoo 11.0开始,您可以在Odoo和PostgreSQL之间强制实施ssl连接。在Odoo中,db_sslmode通过从“禁用”,“允许”,“首选”,“要求”,“验证-ca”或“验证完全”中选择的值来控制连接的ssl安全性

PostgreSQL Doc

内置服务器

Odoo包含内置的HTTP服务器,应用多线程或多进程模式任选其一。

用于生产环境,推荐采用多进程模式的服务器,因为它可以增强稳定性,更好地使用计算资源,并且可以更好地监控和资源限制。

  • 通过配置 启用多线程,工作线程的数量应基于机器中的核心数量(可能为cron工作线程提供一些空间,具体取决于预测的cron工作量)

  • 可以根据硬件配置配置辅助角色限制,以避免资源耗尽

警告

多进程模式目前在 Windows 上不可用

工人数计算

  • 经验法则 : (#CPU * 2) + 1

  • Cron workers 需要 CPU

  • 1 个工作线程 ~= 6 个并发用户

内存大小计算

  • 我们认为 20% 的请求是繁重请求,而 80% 是简单请求

  • 一个繁重的工作,当所有计算字段都设计得很好,SQL请求设计得很好,…估计消耗约1GB的内存

  • 在相同的情况下,较轻的工作线程估计会消耗大约150MB的RAM。

所需 RAM = #worker * ( (light_worker_ratio * light_worker_ram_estimation) + (heavy_worker_ratio * heavy_worker_ram_estimation) )

在线客服

In multiprocessing, a dedicated LiveChat worker is automatically started and listening on the gevent port but the client will not connect to it.

Instead you must have a proxy redirecting requests whose URL starts with /websocket/ to the gevent port. Other request should be proxied to the normal HTTP port

要实现这样的事情,你需要在Odoo前面部署一个反向代理,比如nginx或apache。这样做时,您需要将更多的http标头转发到Odoo,并在Odoo配置中激活proxy_mode,以使Odoo读取这些标头。

配置示例

  • 具有 4 个 CPU、8 个线程的服务器

  • 60 个并发用户

  • 60 个用户 / 6 = 10 < - 理论上的线程数量

  • (4 * 2) + 1 = 9 <- 理论的最大线程数

  • 我们将应用 8 线程 + 1 计划任务。我们还将使用监视系统来测量CPU负载,并检查它是否在7和7.5之间。

  • RAM = 9 * ((0.8*150) + (0.2*1024)) ~= 3Go RAM 用于 Odoo

配置为 odoo.conf 配置文件:

[options]
limit_memory_hard = 1677721600
limit_memory_soft = 629145600
limit_request = 8192
limit_time_cpu = 600
limit_time_real = 1200
max_cron_threads = 1
workers = 8

HTTPS

无论是通过网站/网络客户端还是网络服务访问,Odoo都会以明文形式传输身份验证信息。这意味着Odoo的安全部署必须使用HTTPS3。SSL 终止可以通过几乎任何 SSL 终止代理实现,但需要以下设置:

配置示例

  • 将 http 请求重定向到 https

  • 对 odoo 的代理请求

odoo.conf 配置文件 中设置:

proxy_mode = True

/etc/nginx/sites-enabled/odoo.conf set中:

#odoo server
upstream odoo {
  server 127.0.0.1:8069;
}
upstream odoochat {
  server 127.0.0.1:8072;
}
map $http_upgrade $connection_upgrade {
  default upgrade;
  ''      close;
}

# http -> https
server {
  listen 80;
  server_name odoo.mycompany.com;
  rewrite ^(.*) https://$host$1 permanent;
}

server {
  listen 443 ssl;
  server_name odoo.mycompany.com;
  proxy_read_timeout 720s;
  proxy_connect_timeout 720s;
  proxy_send_timeout 720s;

  # SSL parameters
  ssl_certificate /etc/ssl/nginx/server.crt;
  ssl_certificate_key /etc/ssl/nginx/server.key;
  ssl_session_timeout 30m;
  ssl_protocols TLSv1.2;
  ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
  ssl_prefer_server_ciphers off;

  # log
  access_log /var/log/nginx/odoo.access.log;
  error_log /var/log/nginx/odoo.error.log;

  # Redirect websocket requests to odoo gevent port
  location /websocket {
    proxy_pass http://odoochat;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    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;
  }

  # Redirect requests to odoo backend server
  location / {
    # Add Headers for odoo proxy mode
    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_redirect off;
    proxy_pass http://odoo;
  }

  # common gzip
  gzip_types text/css text/scss text/plain text/xml application/xml application/json application/javascript;
  gzip on;
}

Odoo 作为 WSGI 应用程序

也可以将Odoo作为标准WSGI_应用。Odoo为WSGI启动器脚本提供了“odoo-wsgi.example.py”的基础。应该自定义该脚本(可能是在从安装目录复制它之后)以直接在:mod:`odoo.tools.config`中正确设置配置,而不是通过命令行或配置文件。

但是,WSGI 服务器将仅公开 Web 客户端、网站和 Web 服务 API 的主 HTTP 终结点。因为Odoo不再控制工人的创建,所以它无法设置cron或livechat工人

Cron Workers

要将 Odoo 部署的 cron 作业作为 WSGI 应用程序运行,需要

  • 一个经典的Odoo(通过“odoo-bin”运行)

  • 连接到必须运行 cron 作业的数据库(通过 odoo-bin -d

  • 这不应该暴露给网络。为了确保 cron 运行器无法通过网络访问,可以使用 odoo-bin --no-http 或在配置文件中设置 http_enable = False 完全禁用内置 HTTP 服务器

在线客服

WSGI部署的第二个有问题的子系统是LiveChat:大多数HTTP连接相对较短,并且可以快速释放其工作进程以用于下一个请求,LiveChat需要为每个客户端建立长期连接,以实现近乎实时的通知。

这与基于流程的工作线程模型相冲突,因为它会占用工作线程并阻止新用户访问系统。但是,这些长期存在的连接作用很小,并且大多停留在等待通知的状态。

在WSGI应用程序中支持实时聊天/motization的解决方案包括:

  • Deploy a threaded version of Odoo (instead of a process-based preforking one) and redirect only requests to URLs starting with /websocket/ to that Odoo, this is the simplest and the websocket URL can double up as the cron instance.

  • Deploy an evented Odoo via odoo-gevent and proxy requests starting with /websocket/ to the gevent port.

Serving static files and attachments

For development convenience, Odoo directly serves all static files and attachments in its modules. This may not be ideal when it comes to performances, and static files should generally be served by a static HTTP server.

Serving static files

Odoo static files are located in each module’s static/ folder, so static files can be served by intercepting all requests to /MODULE/static/FILE, and looking up the right module (and file) in the various addons paths.

Example

Say Odoo has been installed via the debian packages for Community and Enterprise and the --addons-path is '/usr/lib/python3/dist-packages/odoo/addons'.

Using the above NGINX (https) configuration, the following location block should be added to serve static files via NGINX.

location @odoo {
    # copy-paste the content of the / location block
}

# Serve static files right away
location ~ ^/[^/]+/static/.+$ {
    root /usr/lib/python3/dist-packages/odoo/addons;
    try_files $uri @odoo;
    expires 24h;
}

Example

Say Odoo has been installed via the source. The two git repositories for Community and Enterprise have been cloned in /opt/odoo/community and /opt/odoo/enterprise respectively and the --addons-path is '/opt/odoo/community/odoo/addons,/opt/odoo/community/addons,/opt/odoo/enterprise'.

Using the above NGINX (https) configuration, the following location block should be added to serve static files via NGINX.

location @odoo {
    # copy-paste the content of the / location block
}

# Serve static files right away
location ~ ^/[^/]+/static/.+$ {
    root /opt/odoo;
    try_files /community/odoo/addons$uri /community/addons$uri /enterprise$uri @odoo;
    expires 24h;
}

警告

The actual NGINX configuration you need is highly dependent on your own installation. The two above snippets only highlight two possible configurations and may not be used as-is.

Serving attachments

Attachments are files stored in the filestore which access is regulated by Odoo. They cannot be directly accessed via a static web server as accessing them requires multiple lookups in the database to determine where the files are stored and whether the current user can access them or not.

Nevertheless, once the file has been located and the access rights verified by Odoo, it is a good idea to serve the file using the static web server instead of Odoo. For Odoo to delegate serving files to the static web server, the X-Sendfile (apache) or X-Accel (nginx) extensions must be enabled and configured on the static web server. Once it is set up, start Odoo with the --x-sendfile CLI flag (this unique flag is used for both X-Sendfile and X-Accel).

注解

  • The X-Sendfile extension for apache (and compatible web servers) does not require any supplementary configuration.

  • The X-Accel extension for NGINX does require the following additionnal configuration:

    location /web/filestore {
        internal;
        alias /path/to/odoo/data-dir/filestore;
    }
    

    In case you don’t know what is the path to your filestore, start Odoo with the --x-sendfile option and navigate to the /web/filestore URL directly via Odoo (don’t navigate to the URL via NGINX). This logs a warnings, the message contains the configuration you need.

安全

首先,请记住,保护信息系统是一个连续的过程,而不是一次性操作。在任何时候,您都只能像环境中最薄弱的环节一样安全。

因此,请不要将此部分视为防止所有安全问题的最终措施列表。它仅作为安全行动计划中应确保包含的第一个重要事项的摘要。其余的将来自操作系统和发行版的最佳安全实践,用户,密码和访问控制管理等方面的最佳实践。

部署面向互联网的服务器时,请务必考虑以下与安全相关的主题:

  • 始终设置强超级管理员密码,并在系统设置后立即限制对数据库管理页面的访问。请参阅:数据库管理器安全性

  • 为所有数据库上的所有管理员账户选择唯一登录名和强密码。不要使用“admin”作为登录名。不要将这些登录名用于日常操作,仅用于控制/管理安装。*从不*使用任何默认密码,如管理员/管理员,即使对于测试/临时数据库也是如此。

  • 不要 ****面向互联网的服务器上安装演示数据。包含演示数据的数据库包含默认登录名和密码,可用于进入系统并造成重大麻烦,即使在暂存/开发系统上也是如此。

  • 使用适当的数据库筛选器 ( --db-filter) 来根据主机名限制数据库的可见性。请参阅:数据库过滤器。您还可以使用 -d 来提供您自己的(逗号分隔的)可用数据库列表,以便从中进行筛选,而不是让系统从数据库后端获取所有数据库。

  • 一旦配置了 db_namedb_filter ,并且每个主机名只匹配一个数据库,则应将 list_db 配置选项设置为 False ,以防止完全列出数据库,并阻止对数据库管理界面的访问(这也显示为 --no-database-list 命令行选项)

  • 确保 PostgreSQL 用户 ( --db_user) 不是超级用户,并且您的数据库由其他用户拥有。例如,如果您使用的是专用的非特权“db_user”,则可以由“postgres”超级用户拥有。另请参阅 :odoo

  • 通过 GitHub 定期安装最新版本,或者从 https://www.odoo.com/page/downloadhttp://nightly.odoo.com 下载最新版本,从而保持安装更新

  • 在多进程模式下配置服务器,并具有与典型使用(内存/CPU/超时)匹配的适当限制。另请参阅:内建服务器

  • 在提供HTTPS终止的Web服务器后面运行Odoo,并提供有效的SSL证书,以防止窃听明文通信。SSL证书很便宜,并且存在许多免费选项。将 Web 代理配置为限制请求的大小,设置适当的超时,然后启用 proxy mode 选项。另请参阅:Https 代理

  • 如果需要允许对服务器进行远程 SSH 访问,请确保为 all 账户设置强密码,而不仅仅是“root”。强烈建议完全禁用基于密码的身份验证,并且仅允许公钥身份验证。还要考虑限制通过VPN的访问,仅允许防火墙中的受信任IP,和/或运行暴力检测系统,如“fail2ban”或等效系统。

  • 请考虑在代理或防火墙上安装适当的速率限制,以防止暴力攻击和拒绝服务攻击。另请参阅:ref:`login_brute_force`了解具体措施。

    许多网络提供商为分布式拒绝服务攻击 (DDOS) 提供自动缓解措施,但这通常是一项可选服务,因此您应该咨询他们。

  • 只要有可能,就将面向公众的演示/测试/过渡实例托管在与生产计算机不同的计算机上。并应用与生产相同的安全预防措施。

  • 如果您面向公众的 Odoo 服务器可以访问敏感的内部网络资源或服务(例如,通过专用 VLAN),请实施适当的防火墙规则来保护这些内部资源。这将确保 Odoo 服务器不会被意外使用(或由于恶意用户操作)来访问或破坏这些内部资源。通常,这可以通过在防火墙上应用出站默认的DENY规则来完成,然后仅显式授权访问Odoo服务器需要访问的内部资源。“systemd IP 流量访问控制<http://0pointer.net/blog/ip-accounting-and-access-lists-with-systemd.html>”_ 对于实现每个进程的网络访问控制也可能很有用。

  • 如果您的面向公众的Odoo服务器位于Web应用程序防火墙,负载平衡器,透明DDoS保护服务(如CloudFlare)或类似的网络级设备后面,您可能希望避免直接访问Odoo系统。通常很难对Odoo服务器的端点IP地址保密。例如,当查询公共系统时,它们可以出现在Web服务器日志中,或者出现在从Odoo发布的电子邮件的标题中。在这种情况下,您可能需要配置防火墙,以便除了从 WAF、负载均衡器或代理服务的特定 IP 地址访问终结点外,无法公开访问终结点。为此,像CloudFlare这样的服务提供商通常会维护其IP地址范围的公共列表。

  • 如果您托管多个客户,请使用容器或适当的“jail”技术将客户数据和文件彼此隔离。

  • 设置数据库和文件存储数据的每日备份,并将它们复制到无法从服务器本身访问的远程存档服务器。

阻止暴力破解攻击

对于面向互联网的部署,对用户密码的暴力攻击非常普遍,对于Odoo服务器来说,这种威胁不容忽视。每当执行登录尝试时,Odoo都会发出日志条目,并报告结果:成功或失败,以及目标登录和源IP。

日志条目将具有以下形式。

登录失败::

2018-07-05 14:56:31,506 24849 INFO db_name odoo.addons.base.res.res_users: Login failed for db:db_name login:admin from 127.0.0.1

登录成功:

2018-07-05 14:56:31,506 24849 INFO db_name odoo.addons.base.res.res_users: Login successful for db:db_name login:admin from 127.0.0.1

这些日志可以通过入侵防御系统(如“fail2ban”)轻松分析。

例如,以下 fail2ban 筛选器定义应与失败的登录相匹配:

[Definition]
failregex = ^ \d+ INFO \S+ \S+ Login failed for db:\S+ login:\S+ from <HOST>
ignoreregex =

这可以与 jail 定义一起使用,以阻止 HTTP(S) 上的攻击 IP。

以下是在 1 分钟内从同一 IP 检测到 10 次登录尝试失败时,阻止 IP 15 分钟的情况:

[odoo-login]
enabled = true
port = http,https
bantime = 900  ; 15 min ban
maxretry = 10  ; if 10 attempts
findtime = 60  ; within 1 min  /!\ Should be adjusted with the TZ offset
logpath = /var/log/odoo.log  ;  set the actual odoo log path here

数据库管理器安全性

配置 Odoo 以及 admin_passwd

此设置用于所有数据库管理界面(用于创建、删除、转储或还原数据库)。

如果管理屏幕根本无法访问,则应将“list_db”配置选项设置为“False”,以阻止访问所有数据库选择和管理屏幕。

警告

强烈建议对任何面向 Internet 的系统禁用数据库管理器!它旨在作为开发/演示工具,以便于快速创建和管理数据库。它不是为在生产中使用而设计的,甚至可能向攻击者暴露危险的功能。它也不是为处理大型数据库而设计的,并且可能会触发内存限制。

在生产系统上,数据库管理操作应始终由系统管理员执行,包括预配新数据库和自动备份。

请务必设置适当的 db_name 参数(也可以选择 db_filter ),以便系统可以确定每个请求的目标数据库,否则用户将被阻止,因为他们将不被允许自己选择数据库。

如果只能从一组选定的计算机访问管理屏幕,请使用代理服务器的功能阻止访问以 /web/database 开头的所有路由,但(可能) /web/database/selector 除外,它显示数据库选择屏幕。

如果数据库管理界面应保持可访问状态,则必须将 admin_passwd 设置从其默认值 admin 更改掉。此密码将允许数据库重要操作。

它应该安全地存储,并且应该随机生成,例如

$ python3 -c 'import base64, os; print(base64.b64encode(os.urandom(24)))'

这将生成一个32个字符的伪随机可打印字符串。

将图像的 WebP 版本用于受支持的浏览器,并且对于不支持 WebP 的浏览器,请优雅地回退 JPEG 和 PNG。

Odoo支持市场上所有主要的桌面和移动浏览器,只要它们得到出版商的支持。

以下是支持的浏览器:

  • 谷歌浏览器

  • 火狐浏览器

  • Microsoft Edge

  • 苹果浏览器

警告

在提交错误报告之前,请确保您的浏览器是最新的,并且仍然受其发布者的支持。

注解

从Odoo 13.0开始,支持ES6。 因此,将删除 IE 支持。

1

让多个Odoo安装使用相同的PostgreSQL数据库,或者为两个软件提供更多的计算资源。

2

从技术上讲,像socat_这样的工具可以用来跨网络代理UNIX套接字,但这主要用于只能通过UNIX套接字使用的软件。

3

或者只能通过内部分组交换网络访问,但这需要安全的交换机,防止“ARP欺骗”_并排除使用WiFi。即使在安全的分组交换网络上,也建议通过 HTTPS 进行部署,并且可能的成本也会降低,因为“自签名”证书在受控环境中比通过 Internet 更容易部署。