系統配置?
本文檔介紹在生產環境或互聯網服務器上設置Odoo的基本步驟。它遵循 installation ,對于未在互聯網上公開的開發系統通常不需要。
警告
如果您正在設置公共服務器,請務必查看我們的 安全性 建議!
數據庫過濾器?
Odoo是一個多租戶系統:一個Odoo系統可以運行和服務于多個數據庫實例。它也是高度可定制的,自定義(從加載的模塊開始)取決于“當前數據庫”。
當作為已登錄的公司用戶使用后端(Web客戶端)時,這不是問題:可以在登錄時選擇數據庫,然后加載自定義設置。
然而,對于未登錄的用戶(門戶網站),這是一個問題,因為他們沒有綁定到數據庫:Odoo需要知道應該使用哪個數據庫來加載網頁或執行操作。如果不使用多租戶,那么這不是問題,只有一個數據庫可用,但如果有多個可訪問的數據庫,Odoo需要一條規則來知道應該使用哪個。
這就是 --db-filter
的一個目的:它指定了如何基于請求的主機名(域名)選擇數據庫。該值是一個 正則表達式,可能包括動態注入的主機名( %h
)或通過系統訪問的第一個子域名( %d
)。
對于在生產環境中托管多個數據庫的服務器,特別是如果使用了 website
,必須設置dbfilter,否則一些功能將無法正常工作。
配置示例?
僅顯示名稱以’mycompany’開頭的數據庫
在 /etc/odoo.conf
中設置:
[options]
dbfilter = ^mycompany.*$
僅顯示與
www
后的第一個子域名匹配的數據庫:例如,如果傳入請求發送到www.mycompany.com
或mycompany.co.uk
,則將顯示數據庫 “mycompany”,但不適用于www2.mycompany.com
或helpdesk.mycompany.com
。
在 /etc/odoo.conf
中設置:
[options]
dbfilter = ^%d$
注解
設置正確的 --db-filter
是保護您的部署的重要部分。一旦它正確地工作并且只匹配每個主機名的單個數據庫,強烈建議阻止訪問數據庫管理屏幕,并使用 --no-database-list
啟動參數防止列出您的數據庫,并阻止訪問數據庫管理屏幕。另請參見 security。
PostgreSQL?
默認情況下,PostgreSQL僅允許通過UNIX套接字和回環連接(從”localhost”,即安裝PostgreSQL服務器的同一臺機器)進行連接。
如果您希望Odoo和PostgreSQL在同一臺機器上執行,則UNIX套接字很好,并且在未提供主機時是默認設置,但是如果您希望Odoo和PostgreSQL在不同的機器上執行[#different-machines]_,它將需要 `監聽網絡接口`_[#remote-socket]_,可以選擇以下方式:
僅接受回環連接并在運行Odoo的計算機和運行PostgreSQL的計算機之間 使用SSH隧道,然后配置Odoo連接到隧道的一端
接受連接到安裝Odoo的機器,可能通過ssl連接(有關詳細信息,請參見 PostgreSQL連接設置),然后配置Odoo通過網絡連接
配置示例?
允許本地主機上的 TCP 連接
允許來自192.168.1.x網絡的TCP連接
在 /etc/postgresql/<YOUR POSTGRESQL VERSION>/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
in /etc/postgresql/<YOUR POSTGRESQL VERSION>/main/postgresql.conf
設置:
listen_addresses = 'localhost,192.168.1.2'
port = 5432
max_connections = 80
配置Odoo?
默認情況下,Odoo通過端口5432連接到本地的UNIX套接字上的Postgres。當您的Postgres部署不是本地的或者不使用安裝默認值時,可以使用 數據庫選項 進行覆蓋。
打包安裝程序 會自動創建一個新用戶( odoo
),并將其設置為數據庫用戶。
數據庫管理界面受
admin_passwd
設置的保護。此設置只能使用配置文件設置,并在執行數據庫更改之前進行簡單檢查。應將其設置為隨機生成的值,以確保第三方無法使用此界面。所有數據庫操作都使用 數據庫選項 ,包括數據庫管理界面。要使數據庫管理界面正常工作,需要 PostgreSQL 用戶具有
createdb
權限。用戶始終可以刪除他們擁有的數據庫。為了使數據庫管理屏幕完全無法使用,需要使用“no-createdb”創建PostgreSQL用戶,并且數據庫必須由不同的PostgreSQL用戶擁有。
警告
PostgreSQL用戶 不能 是超級用戶
配置示例?
連接到位于192.168.1.2的PostgreSQL服務器
端口 5432
使用 ‘odoo’ 用戶賬戶,
使用’pwd’作為密碼
僅篩選名稱以’mycompany’開頭的數據庫
在 /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控制連接的SSL安全性,可選值為’disable’、’allow’、’prefer’、’require’、’verify-ca’或’verify-full’
內置服務器?
Odoo 包含內置的 HTTP 服務器,可以使用多線程或多進程。
對于生產環境使用,建議使用多進程服務器,因為它可以提高穩定性,更好地利用計算資源,并且可以更好地監控和限制資源。
通過配置
非零數量的工作進程
,可以啟用多進程,工作進程的數量應該基于機器的核心數(可能還要考慮一些cron工作)可以根據硬件配置來配置工作進程限制,以避免資源耗盡
警告
當前 Windows 系統不支持多進程模式
工作進程數量計算?
經驗法則:(#CPU * 2) + 1
Cron工作進程需要CPU
1個工作進程 ~= 6個并發用戶
內存大小計算?
我們認為20%的請求是重型請求,而80%的請求是較簡單的請求
當所有計算字段和 SQL 請求都設計良好時,一個繁重的工作進程預計會消耗約 1GB 的 RAM。
在相同的場景中,一個輕量級的工作進程預計會消耗大約150MB的內存。
所需內存 = #worker * ( (輕型工作進程比率 * 輕型工作進程內存估算) + (重型工作進程比率 * 重型工作進程內存估算) )
在線聊天?
在多進程中,會自動啟動一個專用的LiveChat工作進程,并在 gevent端口
上監聽,但客戶端不會連接它。
相反,您必須使用代理將以 /websocket/
開頭的請求重定向到gevent端口。其他請求應該被代理到 正常的HTTP端口
要實現這樣的功能,您需要在Odoo前部署一個反向代理,如nginx或apache。在這樣做時,您需要將一些更多的http頭轉發到Odoo,并在Odoo配置中激活proxy_mode,以使Odoo讀取這些頭。
配置示例?
帶有4個CPU和8個線程的服務器
60個并發用戶
60個用戶 / 6 = 10 <- 理論上需要的工作人員數量
(4 * 2) + 1 = 9 <- 理論上的最大工作人數
我們將使用8個工作進程+1個cron。我們還將使用監控系統來測量CPU負載,并檢查它是否在7到7.5之間。
內存 = 9 * ((0.8* 150) + (0.2*1024)) ~= 為Odoo分配3GB內存
在 /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服務訪問,Odoo都會以明文形式傳輸身份驗證信息。這意味著Odoo的安全部署必須使用HTTPS3。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;
}
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
。該腳本應該進行自定義(可能需要從設置目錄中復制),以便直接在 odoo.tools.config
中正確設置配置,而不是通過命令行或配置文件。
然而,WSGI服務器僅會為Web客戶端、網站和Web服務API公開主要的HTTP端點。因為Odoo不再控制工作進程的創建,所以它無法設置cron或livechat工作進程。
定時任務工作者?
要將Odoo部署作為WSGI應用程序運行cron作業,需要
傳統的Odoo(通過
odoo-bin
運行)已連接到需要運行cron作業的數據庫(通過
odoo-bin -d
)不應該暴露在網絡中。為確保cron運行程序不可訪問網絡,可以通過
odoo-bin --no-http
或在配置文件中設置http_enable = False
來完全禁用內置的HTTP服務器。
在線聊天?
第二個對于WSGI部署有問題的子系統是LiveChat:在大多數HTTP連接相對較短且很快釋放其工作進程以處理下一個請求的情況下,LiveChat需要為每個客戶端提供長時間的連接,以實現近實時通知。
這與基于進程的工作模型相沖突,因為它會占用工作進程并阻止新用戶訪問系統。然而,這些長時間存在的連接幾乎不做任何事情,大多數時間都是等待通知。
在WSGI應用程序中支持實時聊天/通知的解決方案有:
部署一個線程版本的Odoo(而不是基于進程的預分叉版本),并將僅以“/websocket/”開頭的URL請求重定向到該Odoo,這是最簡單的方法,websocket URL可以充當cron實例。
使用
odoo-gevent
部署事件驅動的Odoo,并將以/websocket/
開頭的請求代理到gevent端口
。
提供靜態文件和附件服務?
為了開發方便,Odoo直接在其模塊中提供所有靜態文件和附件。但是,這在性能方面可能不是理想的,靜態文件通常應該由靜態HTTP服務器提供。
提供靜態文件服務?
Odoo靜態文件位于每個模塊的 static/
文件夾中,因此可以通過攔截所有請求到 /MODULE/static/FILE
,并在各種插件路徑中查找正確的模塊(和文件)來提供靜態文件。
Example
假設Odoo已通過社區版和企業版的 Debian軟件包 安裝,并且 --addons-path
的路徑為 '/usr/lib/python3/dist-packages/odoo/addons'
。
使用上述NGINX(https)配置,應添加以下位置塊以通過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
假設Odoo已通過 源代碼 安裝。社區版和企業版的兩個git倉庫分別克隆到: /opt/odoo/community
和 /opt/odoo/enterprise
,并且 --addons-path
為 '/opt/odoo/community/odoo/addons,/opt/odoo/community/addons,/opt/odoo/enterprise'
。
使用上述NGINX(https)配置,應添加以下位置塊以通過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;
}
警告
您實際需要的NGINX配置高度依賴于您自己的安裝。上述兩個片段僅突出了兩種可能的配置,不能直接使用。
附件服務?
附件是存儲在文件存儲中的文件,其訪問受Odoo管理。無法通過靜態Web服務器直接訪問它們,因為訪問它們需要在數據庫中進行多次查找,以確定文件存儲的位置以及當前用戶是否可以訪問它們。
然而,一旦文件被Odoo定位并且訪問權限得到驗證,最好使用靜態Web服務器而不是Odoo來提供文件服務。為了讓Odoo將文件服務委托給靜態Web服務器,必須在靜態Web服務器上啟用和配置 X-Sendfile (apache) 或 X-Accel (nginx) 擴展。設置完成后,使用 --x-sendfile
命令行標志啟動Odoo(此唯一標志用于X-Sendfile和X-Accel)。
注解
Apache(和兼容的Web服務器)的X-Sendfile擴展不需要任何補充配置。
NGINX 的 X-Accel 擴展 確實 需要以下額外配置:
location /web/filestore { internal; alias /path/to/odoo/data-dir/filestore; }
如果您不知道文件存儲路徑是什么,請使用
--x-sendfile
選項啟動Odoo,并直接通過Odoo導航到/web/filestore
URL(不要通過NGINX導航到URL)。這將記錄一個警告,消息包含您需要的配置。
安全性?
首先,請記住,保護信息系統是一個持續的過程,而不是一次性操作。在任何時候,您的安全性只能與您環境中最薄弱的環節一樣安全。
因此,請不要將本節視為可防止所有安全問題的終極措施清單。它僅旨在總結您應該確保包含在安全行動計劃中的首要重要事項。其余的措施將來自于操作系統和發行版的最佳安全實踐,用戶、密碼和訪問控制管理方面的最佳實踐等。
在部署面向互聯網的服務器時,請務必考慮以下與安全相關的主題:
始終設置一個強大的超級管理員密碼,并在系統設置完成后立即限制對數據庫管理頁面的訪問。請參閱 數據庫管理器安全性 。
為所有數據庫的所有管理員賬戶選擇唯一的登錄名和強密碼。不要使用 ‘admin’ 作為登錄名。不要將這些登錄名用于日常操作,僅用于控制/管理安裝。 永遠不要 使用任何默認密碼,如 admin/admin,即使是用于測試/暫存數據庫。
不要在面向互聯網的服務器上安裝演示數據。帶有演示數據的數據庫包含默認的登錄名和密碼,可以用于進入您的系統并造成重大麻煩,即使是在暫存/開發系統上也是如此。
使用適當的數據庫過濾器(
--db-filter
)根據主機名限制數據庫的可見性。請參閱 數據庫過濾器 。您還可以使用-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下載最新版本來保持安裝程序更新。
使用適當的限制配置多進程模式的服務器,以匹配您的典型使用情況(內存/CPU/超時)。另請參閱: 內置服務器 。
在Web服務器后面運行Odoo,提供HTTPS終止功能,并使用有效的SSL證書,以防止明文通信被竊聽。SSL證書價格便宜,許多免費選項可用。配置Web代理以限制請求大小,設置適當的超時時間,然后啟用
proxy mode
選項。另請參見 HTTPS 。如果您需要允許遠程SSH訪問您的服務器,請確保為 所有 賬戶設置強密碼,而不僅僅是
root
。強烈建議完全禁用基于密碼的身份驗證,僅允許公鑰身份驗證。還應考慮通過VPN限制訪問,僅允許受信任的IP在防火墻中,和/或運行類似于fail2ban
的暴力破解檢測系統。考慮在您的代理或防火墻上安裝適當的速率限制,以防止暴力攻擊和拒絕服務攻擊。另請參閱 阻止暴力攻擊 以獲取具體措施。
許多網絡提供商提供分布式拒絕服務攻擊(DDOS)的自動緩解,但這通常是一項可選服務,因此您應該與他們咨詢。
如果可能的話,請將公共演示/測試/暫存實例托管在與生產實例不同的機器上。并采取與生產相同的安全預防措施。
如果您的公共Odoo服務器可以訪問敏感的內部網絡資源或服務(例如通過私有VLAN),請實施適當的防火墻規則來保護這些內部資源。這將確保Odoo服務器不能被意外使用(或由于惡意用戶行為)來訪問或破壞這些內部資源。通??梢酝ㄟ^在防火墻上應用出站默認DENY規則,然后僅明確授權訪問Odoo服務器需要訪問的內部資源來實現。 `Systemd IP traffic access control <http://0pointer.net/blog/ip-accounting-and-access-lists-with-systemd.html>`_也可能有助于實現進程級網絡訪問控制。
如果您的公共Odoo服務器位于Web應用程序防火墻、負載均衡器、透明DDoS保護服務(如CloudFlare)或類似的網絡級設備后面,您可能希望避免直接訪問Odoo系統。通常很難保持Odoo服務器的終端IP地址的機密性。例如,當從Odoo查詢公共系統或發布電子郵件時,它們可能出現在Web服務器日志中或郵件頭中。在這種情況下,您可能希望配置防火墻,使終端點除了來自WAF、負載均衡器或代理服務的特定IP地址外,不可公開訪問。像CloudFlare這樣的服務提供商通常為此維護其IP地址范圍的公共列表。
如果您正在托管多個客戶,請使用容器或適當的“監獄”技術將客戶數據和文件彼此隔離。
設置每日備份數據庫和文件存儲數據,并將其復制到遠程歸檔服務器,該服務器無法從服務器本身訪問。
阻止暴力攻擊?
對于面向互聯網的部署,對用戶密碼進行暴力攻擊非常普遍,因此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 =
這可以與監獄定義一起使用,以在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
,以阻止訪問所有數據庫選擇和管理屏幕。
警告
強烈建議禁用數據庫管理器用于任何面向互聯網的系統!它是作為開發/演示工具而設計的,以便快速創建和管理數據庫。它不適用于生產環境,甚至可能向攻擊者公開危險功能。它也不適用于處理大型數據庫,可能會觸發內存限制。
在生產系統中,數據庫管理操作應該由系統管理員執行,包括新數據庫的配置和自動備份。
請務必設置適當的 db_name
參數(可選地,也可以設置 db_filter
參數),以便系統可以確定每個請求的目標數據庫,否則用戶將被阻止,因為他們將無法自己選擇數據庫。
如果管理界面只能從一組特定的機器訪問,請使用代理服務器的功能來阻止訪問所有以“/web/database”開頭的路由,除了(也許)顯示數據庫選擇屏幕的“/web/database/selector”。
如果要保留數據庫管理界面的訪問權限,則必須更改 admin_passwd
設置,以避免使用默認的 admin
密碼。在允許數據庫更改操作之前,將檢查此密碼。
應該安全地存儲,并隨機生成,例如:
$ python3 -c 'import base64, os; print(base64.b64encode(os.urandom(24)))'
這將生成一個32個字符的偽隨機可打印字符串。
支持的瀏覽器?
Odoo支持市場上所有主要的桌面和移動瀏覽器,只要它們得到其發布商的支持。
以下是支持的瀏覽器:
谷歌瀏覽器
Mozilla Firefox
微軟 Edge
蘋果Safari
警告
請在提交錯誤報告之前確保您的瀏覽器是最新的,并且仍然得到其發布者的支持。
注解
自Odoo 13.0起,支持ES6。因此,不再支持IE。