踩过数据库死锁的坑,
顺便把官方部署文档翻译下,自已加速,对生产环境是十分必要的
部署Odoo
本文档描述在生产中或在面向Internet的服务器上设置Odoo的基本步骤。它是在安装之后进行的,对于没有在internet上公开的开发系统来说,它通常不是必需的。
警告
如果您正在设置公共服务器,请务必查看我们的安全建议!
Dbfilter
Odoo是一个多租户系统:一个Odoo系统可以运行并服务于多个数据库实例。它也是高度可定制的,定制(从加载的模块开始)取决于“当前数据库”。
作为登录公司用户使用后端(web客户端)时,这不是问题:登录时可以选择数据库,然后加载自定义设置。
但是,对于没有绑定到数据库的未登录用户(门户、网站)来说,这是一个问题:Odoo需要知道应该使用哪个数据库来加载网站页面或执行操作。如果没有使用多租户,这不是问题,只有一个数据库可以使用,但是如果有多个数据库可以访问,Odoo需要一个规则来知道它应该使用哪一个。
这是--db filter的目的之一:它指定如何根据所请求的主机名(域)选择数据库。该值是一个正则表达式,可能包括动态注入的主机名(%h)或访问系统所通过的第一个子域(%d)。
对于生产中托管多个数据库的服务器,特别是在使用网站时,必须设置dbfilter,否则许多功能将无法正常工作。
配置实例
仅显示名称以“mycompany”开头的数据库
在 /etc/odoo.conf
设置:
[options] dbfilter = ^mycompany.*$
仅显示与www之后的第一个子域匹配的数据库:例如,如果传入的请求被发送到www.mycompany.com或mycompany.co.uk,则将显示数据库“mycompany”,而不是www2.mycompany.com或helpdesk.mycompany.com。
[options] dbfilter = ^%d$
如果直接使用域名作为库名,用 ^%h$
设置正确的--db过滤器是确保部署安全的重要部分。一旦它正常工作并且每个主机名只匹配一个数据库,强烈建议阻止对数据库管理器屏幕的访问,并使用--no-database-list 启动参数阻止列出数据库,并阻止对数据库管理界面的访问。另请参见安全性。
PostgreSQL
默认情况下,PostgreSQL只允许通过UNIX套接字和环回连接进行连接(从“localhost”,即安装PostgreSQL服务器的同一台计算机)。
如果希望Odoo和PostgreSQL在同一台计算机上执行,UNIX套接字是可以的,并且在没有提供主机时是默认的,但是如果希望Odoo和PostgreSQL在不同的计算机上执行,则需要侦听网络接口,或者:
/etc/postgresql/9.5/main/pg_hba.conf
# IPv4 local connections: host all all 127.0.0.1/32 md5 host all all 192.168.1.0/24 md5
/etc/postgresql/9.5/main/postgresql.conf
listen_addresses = 'localhost,192.168.1'2'
port = 5432 max_connections = 80
配置Odoo
开箱即用,Odoo通过端口5432通过UNIX套接字连接到本地postgres。当Postgres部署不是本地部署和/或不使用安装默认值时,可以使用数据库选项覆盖此设置。
打包的安装程序将自动创建一个新用户(odoo),并将其设置为数据库用户。
数据库管理界面受管理密码设置保护。此设置只能使用配置文件进行设置,并在执行数据库更改之前进行简单检查。应将其设置为随机生成的值,以确保第三方不能使用此接口。
所有数据库操作都使用数据库选项,包括数据库管理界面。要使数据库管理界面正常工作,PostgreSQL用户必须具有createdb权限。
用户总是可以删除他们拥有的数据库。要使数据库管理界面完全不起作用,需要在不使用createdb的情况下创建PostgreSQL用户,并且数据库必须由其他PostgreSQL用户拥有。
警告
PostgreSQL用户不能是超级用户
配置实例
/etc/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使用从“disable”、“allow”、“prefer”、“require”、“verify ca”或“verify full”中选择的值控制连接的ssl安全性
内置服务器
Odoo包括内置的HTTP服务器,使用多线程或多处理。
对于生产使用,建议使用多处理服务器,因为它增加了稳定性,更好地利用了计算资源,并且可以更好地监视和限制资源。
多处理是通过配置非零数量的工作进程来实现的,工作进程的数量应该基于机器中的核心数量(可能有一些空间供cron工作进程使用,这取决于预测的cron工作量)
可以根据硬件配置配置工作进程限制,以避免资源耗尽
警告
多处理模式当前在Windows上不可用
工作进程数量计算
数量规则:(#CPU * 2) + 1
Cron工作者需要CPU
个工作进程~=6个并发用户
内存大小计算
我们认为20%的请求是繁重请求,而80%是简单请求
一个繁重的工作,当所有的计算字段都设计好了,SQL请求设计好了,…估计要消耗大约1G的RAM
在相同的情况下,一个较轻的工作估计要消耗大约150MB的RAM
Needed RAM = #worker * ( (light_worker_ratio * light_worker_ram_estimation) + (heavy_worker_ratio * heavy_worker_ram_estimation) )
LiveChat
在多处理中,会自动启动一个专用的LiveChat工作进程并监听longpolling端口,但客户端不会连接到它。
相反,必须有一个代理将其URL以/longpolling/开头的请求重定向到longpolling端口。其他请求应被代理到正常的HTTP端口
要实现这一点,您需要在Odoo前面部署一个反向代理,比如nginx或apache。这样做时,您需要将更多的http头转发给Odoo,并在Odoo配置中激活代理模式,让Odoo读取这些头。
配置实例
4 CPU 8线程服务器
60个并发用户
60个用户/6=10<-理论上需要的worker数量
(4×2)+1=9<理论最大worker数
我们将使用8个workers+1作为cron。我们还将使用监控系统来测量cpu负载,并检查它是否在7到7.5之间。
RAM=9*((0.8*150)+(0.2*1024))~=3Go RAM用于Odoo
/etc/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
无论是通过网站/web客户端还是web服务访问,Odoo都以明文形式传输身份验证信息。这意味着Odoo的安全部署必须使用HTTPS。SSL末端可以通过几乎任何SSL末端代理来实现,但需要以下设置: 启用Odoo的代理模式。只有当Odoo在反向代理后面时才应该启用 设置SSL末端代理(Nginx末端示例) 设置代理本身(Nginx代理示例) SSL终止代理还应自动将非安全连接重定向到安全端口 配置实例 重定向http请求到https 代理请求到Odoo /etc/odoo.conf
proxy_mode = True /etc/nginx/sites-enabled/odoo.conf #odoo server upstream odoo { server 127.0.0.1:8069; } upstream odoochat { server 127.0.0.1:8072; } # http -> https server { listen 80; server_name odoo.mycompany.com; rewrite ^(.*) https://$host$1 permanent; } server { listen 443; server_name odoo.mycompany.com; proxy_read_timeout 720s; proxy_connect_timeout 720s; proxy_send_timeout 720s; # 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; # SSL parameters ssl on; ssl_certificate /etc/ssl/nginx/server.crt; ssl_certificate_key /etc/ssl/nginx/server.key; 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-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; ssl_prefer_server_ciphers on; # log access_log /var/log/nginx/odoo.access.log; error_log /var/log/nginx/odoo.error.log; # Redirect longpoll requests to odoo longpolling port location /longpolling { proxy_pass http://odoochat; } # Redirect requests to odoo backend server location / { 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提供了基础。应该自定义该脚本(可能是从安装目录复制后),以便直接在odoo.tools.config中而不是通过命令行或配置文件正确设置配置。 然而,WSGI服务器将只公开web客户端、web站点和webservice API的主要HTTP端点。因为Odoo不再控制workers的创建,所以它不能设置cron或livechat workers cron工作进程 要按照WSGI应用程序的要求运行Odoo部署的cron作业 典型的odoo(通过odoo-bin运行) 连接到必须运行cron作业的数据库(通过odoo-bin -d) 不应该暴露在网络中。为了确保cron运行程序不可通过网络访问,可以使用odoo-bin --no-http完全禁用内置HTTP服务器,或者在配置文件中设置http_enable=False
LiveChat
用于WSGI部署的第二个有问题的子系统是LiveChat:在大多数HTTP连接相对较短的情况下,LiveChat会快速释放其工作进程以供下一个请求使用,为了实现近乎实时的通知,LiveChat需要为每个客户机建立一个长期的连接。
这与基于进程的工作进程模型相冲突,因为它将绑定工作进程并阻止新用户访问系统。然而,这些长期存在的连接做得很少,而且大多停留在等待通知。
在WSGI应用程序中支持livechat/motifications的解决方案有:
部署Odoo的线程版本(代替基于进程的预处理版本),并将请求重定向到以 /longpolling/ 开头的URL,这是最简单的,并且longpolling URL可以作为cron实例。
通过odoo-gevent和以 /longpolling/ 开头的代理请求将事件Odoo部署到longpolling端口。
Serving Static Files
为了便于开发,Odoo直接为其模块中的所有静态文件提供服务。在性能方面,这可能并不理想,静态文件通常应该由静态HTTP服务器提供服务。
Odoo静态文件位于每个模块的static/ 文件夹中,因此可以通过截取对 /module/static/FILE 的所有请求,并在各种插件路径中查找正确的模块(和文件)来提供静态文件。
安全
首先,请记住,保护信息系统是一个连续的过程,而不是一次性的操作。任何时候,你都只会像环境中最薄弱的环节一样安全。
因此,请不要将本节作为防止所有安全问题的措施的最终清单。这只是一个总结,作为第一件重要的事情,你应该确保包括在你的安全行动计划。其余的将来自于操作系统和发行版的最佳安全实践、用户、密码和访问控制管理等方面的最佳实践。
部署面向internet的服务器时,请确保考虑以下安全相关主题:
始终设置一个强大的超级管理员管理密码,并在系统设置以后限制访问数据库管理页面。请参阅数据库管理器安全性。
为所有数据库上的所有管理员帐户选择唯一登录名和强密码。不要使用“admin”作为登录名。不要将这些登录用于日常操作,而只用于控制/管理安装。永远不要使用任何默认密码,如admin/admin,即使对于测试/登台数据库也是如此。
不要在面向internet的服务器上安装演示数据。具有演示数据的数据库包含默认登录名和密码,这些登录名和密码可用于进入您的系统并导致严重问题,甚至在登台/dev系统上也是如此。
使用适当的数据库过滤器(--db-filter)根据主机名限制数据库的可见性。请参见dbfilter。您还可以使用-d来提供您自己的(逗号分隔的)可用数据库列表以进行筛选,而不是让系统从数据库后端获取它们。
一旦配置了db_name和db_filter,并且每个主机名只匹配一个数据库,就应该将list_db配置选项设置为False,以防止完全列出数据库,并阻止对数据库管理界面的访问(此选项还公开为--no-database-list命令行选项)
确保PostgreSQL用户(--db_user)不是超级用户,并且您的数据库归其他用户所有。例如,如果您使用的是专用的非特权db_user,那么它们可以归postgres超级用户所有。另请参阅配置Odoo。
通过定期安装最新版本(通过GitHub或从https://www.odoo.com/page/download或http://nightly.odoo.com下载最新版本)保持安装更新
在多进程模式下配置服务器,使其具有与典型使用(memory/CPU/timeouts)匹配的适当限制。另请参见内置服务器。
在提供带有有效SSL证书的HTTPS终端的web服务器后面运行Odoo,以防止对cleartext通信的窃听。SSL证书是廉价的,并且存在许多自由选项。配置web代理以限制请求的大小,设置适当的超时,然后启用代理模式选项。另请参见HTTPS。
如果需要允许远程SSH访问服务器,请确保为所有帐户设置强密码,而不仅仅是根帐户。强烈建议完全禁用基于密码的身份验证,并且只允许公钥身份验证。还可以考虑限制通过VPN的访问,只允许防火墙中的受信任IP,和/或运行暴力检测系统,如fail2ban或等效系统。
考虑在代理或防火墙上安装适当的速率限制,以防止暴力攻击和拒绝服务攻击。有关具体措施,请参见阻止暴力攻击。
许多网络提供商为分布式拒绝服务攻击(DDOS)提供自动缓解,但这通常是一项可选服务,因此您应该咨询他们。
尽可能在不同的机器上托管面向公众的demo/test/staging实例。并采用与生产相同的安全预防措施。
如果您托管多个客户,请使用容器或适当的“jail”技术将客户数据和文件彼此隔离。
设置数据库和文件存储数据的每日备份,并将它们复制到无法从服务器本身访问的远程存档服务器。
阻止暴力攻击
对于面向internet的部署,对用户密码的暴力攻击非常常见,对于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上的攻击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时顺便提到了管理密码。
此设置用于所有数据库管理界面(用于创建、删除、转储或还原数据库)。
如果不需要访问管理界面,则应将list_db 配置选项设置为False,以阻止对所有数据库选择和管理界面的访问。
警告
强烈建议对任何面向internet的系统禁用数据库管理器!它是一个开发/演示工具,可以方便地快速创建和管理数据库。它不是为在生产中使用而设计的,甚至可能向攻击者暴露危险的特性。它也不是用来处理大型数据库的,可能会触发内存限制。
在生产系统上,数据库管理操作应始终由系统管理员执行,包括提供新数据库和自动备份。
请确保设置适当的db_name参数(也可以选择db_filter),以便系统可以为每个请求确定目标数据库,否则用户将被阻止,因为他们不允许自己选择数据库。
如果管理界面必须只能从选定的一组计算机访问,请使用代理服务器的功能来阻止对以/web/数据库开头的所有路由的访问,但(可能)/web/database/selector (显示数据库选择界面)除外。
如果数据库管理界面需保持可访问状态,则必须从其管理员默认设置更改管理员密码设置:在允许数据库更改操作之前检查此密码。
它应该安全地存储,并且应该随机生成,例如。
$ python3 -c 'import base64, os; print(base64.b64encode(os.urandom(24)))'
它将生成一个32个字符的伪随机可打印字符串。
支持的浏览器
Odoo的每个版本都有多个浏览器支持。为了保持最新,没有根据浏览器版本进行区分。当前浏览器版本支持Odoo。我们支持以下浏览器:
Mozilla Firefox
Google Chrome
Safari
Microsoft Edge
自Odoo13.0以来,支持ES6。因此,不再支持IE。