系統配置?

本文檔介紹在生產環境或互聯網服務器上設置Odoo的基本步驟。它遵循 installation ,對于未在互聯網上公開的開發系統通常不需要。

警告

如果您正在設置公共服務器,請務必查看我們的 安全性 建議!

數據庫過濾器?

Odoo是一個多租戶系統:一個Odoo系統可以運行和服務于多個數據庫實例。它也是高度可定制的,自定義(從加載的模塊開始)取決于“當前數據庫”。

當作為已登錄的公司用戶使用后端(Web客戶端)時,這不是問題:可以在登錄時選擇數據庫,然后加載自定義設置。

然而,對于未登錄的用戶(門戶網站),這是一個問題,因為他們沒有綁定到數據庫:Odoo需要知道應該使用哪個數據庫來加載網頁或執行操作。如果不使用多租戶,那么這不是問題,只有一個數據庫可用,但如果有多個可訪問的數據庫,Odoo需要一條規則來知道應該使用哪個。

這就是 --db-filter 的一個目的:它指定了如何基于請求的主機名(域名)選擇數據庫。該值是一個 正則表達式,可能包括動態注入的主機名( %h )或通過系統訪問的第一個子域名( %d )。

對于在生產環境中托管多個數據庫的服務器,特別是如果使用了 website ,必須設置dbfilter,否則一些功能將無法正常工作。

配置示例?

  • 僅顯示名稱以’mycompany’開頭的數據庫

/etc/odoo.conf 中設置:

[options]
dbfilter = ^mycompany.*$
  • 僅顯示與 www 后的第一個子域名匹配的數據庫:例如,如果傳入請求發送到 www.mycompany.commycompany.co.uk ,則將顯示數據庫 “mycompany”,但不適用于 www2.mycompany.comhelpdesk.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’

PostgreSQL文檔

內置服務器?

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_namedb_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。

1

要讓多個Odoo安裝使用同一個PostgreSQL數據庫,或為兩個軟件提供更多的計算資源。

2

技術上,可以使用類似 socat 的工具將 UNIX 套接字代理到網絡上,但這主要是針對只能在 UNIX 套接字上使用的軟件

3

或者僅在內部分組交換網絡中可訪問,但這需要安全交換機的保護,防止 ARP 欺騙,并且不允許使用 WiFi。即使在安全的分組交換網絡上,也建議通過 HTTPS 進行部署,并且可能的成本降低,因為“自簽名”證書比在互聯網上更容易在受控環境中部署。