پیکربندی سیستم

این سند گام‌های پایه برای راه‌اندازی Odoo در تولید یا روی یک سرور رو به اینترنت را توصیف می‌کند. این سند به دنبال نصب می‌آید و معمولاً برای یک سیستم توسعه که در معرض اینترنت نیست لازم نیست.

هشدار

اگر در حال راه‌اندازی یک سرور عمومی هستید، حتماً توصیه‌های امنیت ما را بررسی کنید!

dbfilter

Odoo یک سیستم multi-tenant است: یک سیستم Odoo می‌تواند چندین نمونه پایگاه داده را اجرا و سرویس‌دهی کند. همچنین به‌شدت قابل سفارشی‌سازی است، با سفارشی‌سازی‌هایی (با شروع از ماژول‌های در حال بارگذاری) که به «پایگاه دادهٔ فعلی» بستگی دارد.

این هنگام کار با backend (web client) به‌عنوان یک کاربر شرکت وارد‌شده مشکلی نیست: پایگاه داده می‌تواند هنگام ورود انتخاب شود و سفارشی‌سازی‌ها پس از آن بارگذاری شوند.

با این حال، این برای کاربران غیر وارد‌شده (portal، website) که به یک پایگاه داده bind نشده‌اند مشکل است: Odoo باید بداند کدام پایگاه داده برای بارگذاری صفحهٔ وب‌سایت یا انجام عملیات استفاده شود. اگر multi-tenancy استفاده نشود این مشکلی نیست، فقط یک پایگاه داده برای استفاده وجود دارد، اما اگر چندین پایگاه دادهٔ قابل دسترسی وجود داشته باشد، Odoo به یک قاعده نیاز دارد تا بداند کدام یک را باید استفاده کند.

این یکی از اهداف --db-filter است: تعیین می‌کند که پایگاه داده باید چگونه بر اساس hostname (دامنه) درخواست‌شده انتخاب شود. این مقدار یک regular expression است که احتمالاً شامل hostname تزریق‌شدهٔ پویا (%h) یا اولین subdomain (%d) که سیستم از طریق آن قابل دسترسی است می‌شود.

برای سرورهایی که چندین پایگاه داده را در تولید میزبانی می‌کنند، به‌ویژه اگر website استفاده شود، dbfilter باید تنظیم شود، در غیر این صورت تعدادی از ویژگی‌ها به‌درستی کار نخواهند کرد.

نمونه‌های پیکربندی

  • فقط پایگاه‌های داده‌ای را نمایش دهید که نام آن‌ها با 'mycompany' شروع می‌شود

در فایل پیکربندی تنظیم کنید:

[options]
dbfilter = ^mycompany.*$
  • فقط پایگاه‌های داده‌ای را نمایش بده که با اولین subdomain پس از www مطابقت دارند: برای مثال پایگاه دادهٔ «mycompany» در صورتی نمایش داده می‌شود که درخواست ورودی به www.mycompany.com یا mycompany.co.uk ارسال شده باشد، اما نه برای www2.mycompany.com یا helpdesk.mycompany.com.

در فایل پیکربندی تنظیم کنید:

[options]
dbfilter = ^%d$

توجه

تنظیم یک --db-filter مناسب بخش مهمی از امن‌سازی استقرار شما است. هنگامی که به‌درستی کار می‌کند و فقط با یک پایگاه دادهٔ منفرد در هر hostname مطابقت دارد، اکیداً توصیه می‌شود دسترسی به صفحات database manager را مسدود کنید و از پارامتر راه‌اندازی --no-database-list برای جلوگیری از فهرست کردن پایگاه‌های داده خود و مسدود کردن دسترسی به صفحات مدیریت پایگاه داده استفاده کنید. همچنین security را ببینید.

PostgreSQL

به‌صورت پیش‌فرض، PostgreSQL فقط اتصال‌ها روی UNIX sockets و اتصال‌های loopback (از «localhost»، همان دستگاهی که سرور PostgreSQL روی آن نصب است) را مجاز می‌داند.

UNIX socket مناسب است اگر می‌خواهید Odoo و PostgreSQL روی همان دستگاه اجرا شوند، و زمانی که هیچ host‌ای ارائه نشده باشد گزینهٔ پیش‌فرض است، اما اگر می‌خواهید Odoo و PostgreSQL روی دستگاه‌های مختلف اجرا شوند 1 باید listen to network interfaces 2 باشد، یا:

  • فقط اتصال‌های loopback را بپذیرید و use an SSH tunnel بین دستگاهی که Odoo روی آن اجرا می‌شود و دستگاهی که PostgreSQL روی آن اجرا می‌شود استفاده کنید، سپس Odoo را پیکربندی کنید تا به انتهای tunnel خود متصل شود

  • اتصال‌ها به دستگاهی که Odoo روی آن نصب است را بپذیرید، احتمالاً روی ssl (برای جزئیات PostgreSQL connection settings را ببینید)، سپس Odoo را پیکربندی کنید تا روی شبکه متصل شود

نمونهٔ پیکربندی

  • اجازهٔ اتصال tcp روی localhost

  • اجازهٔ اتصال tcp از شبکهٔ 192.168.1.x

در /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

در /etc/postgresql/<YOUR POSTGRESQL VERSION>/main/postgresql.conf تنظیم کنید:

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

پیکربندی Odoo

به‌صورت out of the box، Odoo از طریق پورت ۵۴۳۲ به یک postgres محلی روی UNIX socket متصل می‌شود. این را می‌توان با استفاده از گزینه‌های پایگاه داده هنگامی که استقرار Postgres شما محلی نیست و/یا از تنظیمات پیش‌فرض نصب استفاده نمی‌کند override کرد.

نصب‌کننده‌های بسته‌بندی‌شده به‌صورت خودکار یک کاربر جدید (odoo) ایجاد می‌کنند و آن را به‌عنوان کاربر پایگاه داده تنظیم می‌کنند.

  • صفحات مدیریت پایگاه داده توسط تنظیم admin_passwd محافظت می‌شوند. این تنظیم فقط می‌تواند با استفاده از فایل‌های پیکربندی تنظیم شود و به‌سادگی پیش از انجام تغییرات پایگاه داده بررسی می‌شود. باید روی یک مقدار تولیدشدهٔ تصادفی تنظیم شود تا اطمینان حاصل شود که اشخاص ثالث نمی‌توانند از این رابط استفاده کنند.

  • تمام عملیات پایگاه داده از گزینه‌های پایگاه داده استفاده می‌کنند، از جمله صفحهٔ مدیریت پایگاه داده. برای کار صفحهٔ مدیریت پایگاه داده، کاربر PostgreSQL باید حق createdb داشته باشد.

  • کاربران همیشه می‌توانند پایگاه‌های داده‌ای را که در اختیار دارند drop کنند. برای اینکه صفحهٔ مدیریت پایگاه داده کاملاً غیرعملیاتی شود، کاربر PostgreSQL باید با no-createdb ایجاد شود و پایگاه داده باید در اختیار یک کاربر PostgreSQL متفاوت باشد.

    هشدار

    کاربر PostgreSQL نباید superuser باشد

نمونهٔ پیکربندی

  • اتصال به یک سرور PostgreSQL در 192.168.1.2

  • پورت ۵۴۳۲

  • با استفاده از حساب کاربری 'odoo'،

  • با 'pwd' به‌عنوان رمز عبور

  • فقط پایگاه‌های داده با نامی که با 'mycompany' شروع می‌شود را فیلتر می‌کند

در فایل پیکربندی تنظیم کنید:

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

SSL بین Odoo و PostgreSQL

از Odoo 11.0 به بعد، می‌توانید اتصال ssl بین Odoo و PostgreSQL را اعمال کنید. در Odoo، db_sslmode امنیت ssl اتصال را با مقداری که از 'disable', 'allow', 'prefer', 'require', 'verify-ca' یا 'verify-full' انتخاب می‌شود کنترل می‌کند

مستندات PostgreSQL

سرور درون‌ساخت

Odoo شامل سرورهای درون‌ساخت HTTP، cron و گفتگوی زنده است که از multi-threading یا multi-processing استفاده می‌کنند.

سرور multi-threaded سرور ساده‌تری است که عمدتاً برای توسعه، نمایش‌ها و سازگاری آن با سیستم‌عامل‌های مختلف (از جمله Windows) استفاده می‌شود. برای هر درخواست HTTP جدید، حتی برای اتصال‌های long-lived مانند websocket، یک thread جدید spawn می‌شود. cron threadهای اضافی daemonic نیز spawn می‌شوند. به دلیل یک محدودیت Python (GIL)، بهترین استفاده از سخت‌افزار را نمی‌کند.

سرور multi-threaded سرور پیش‌فرض است، همچنین برای کانتینرهای docker. با خارج کردن گزینهٔ --workers یا تنظیم آن روی 0 انتخاب می‌شود.

سرور multi-processing یک سرور تمام‌عیار است که عمدتاً برای تولید استفاده می‌شود. در معرض همان محدودیت Python (GIL) روی استفاده از منابع نیست و بنابراین بهترین استفاده را از سخت‌افزار می‌کند. یک pool از workerها هنگام راه‌اندازی سرور ایجاد می‌شود. درخواست‌های HTTP جدید توسط OS صف می‌شوند تا workerها برای پردازش آن‌ها آماده شوند. یک worker HTTP اضافی event-driven برای گفتگوی زنده روی یک پورت جایگزین spawn می‌شود. workerهای cron اضافی نیز spawn می‌شوند. یک process reaper قابل پیکربندی، استفاده از منابع را پایش می‌کند و می‌تواند workerهای ناموفق را kill/راه‌اندازی مجدد کند.

سرور multi-processing به‌صورت اختیاری فعال می‌شود. با تنظیم گزینهٔ --workers به یک عدد صحیح غیرصفر انتخاب می‌شود.

توجه

چون سرور multi-processing به‌شدت برای سرورهای Linux سفارشی شده است، در Windows در دسترس نیست.

محاسبهٔ تعداد workerها

  • قاعدهٔ سرانگشتی: (#CPU * 2) + 1

  • workerهای cron به CPU نیاز دارند

  • ۱ worker ≈ ۶ کاربر هم‌زمان

محاسبهٔ اندازهٔ حافظه

  • ما در نظر می‌گیریم ۲۰٪ درخواست‌ها سنگین و ۸۰٪ ساده‌تر هستند

  • یک worker سنگین، در حالی که تمام فیلدهای computed به‌خوبی طراحی شده و درخواست‌های SQL به‌خوبی طراحی شده‌اند و ...، تخمین زده می‌شود حدود ۱ گیگابایت RAM مصرف کند

  • یک worker سبک‌تر در همین سناریو تخمین زده می‌شود حدود ۱۵۰ مگابایت RAM مصرف کند

RAM موردنیاز = #worker * ( (light_worker_ratio * light_worker_ram_estimation) + (heavy_worker_ratio * heavy_worker_ram_estimation) )

گفتگوی زنده

در multi-processing، یک worker اختصاصی LiveChat به‌صورت خودکار راه‌اندازی می‌شود و روی --gevent-port گوش می‌دهد. به‌صورت پیش‌فرض، درخواست‌های HTTP به جای LiveChat به workerهای HTTP عادی دسترسی پیدا می‌کنند. باید یک proxy جلوی Odoo مستقر کنید و درخواست‌های ورودی که مسیر آن‌ها با /websocket/ شروع می‌شود را به worker LiveChat بازهدایت کنید. همچنین باید Odoo را در --proxy-mode راه‌اندازی کنید تا از سرصفحه‌های واقعی client (مانند hostname، scheme و IP) به جای سرصفحه‌های proxy استفاده کند.

نمونهٔ پیکربندی

  • سرور با ۴ CPU و ۸ Thread

  • ۶۰ کاربر هم‌زمان

  • ۶۰ کاربر / ۶ = ۱۰ ← تعداد نظری workerهای موردنیاز

  • (۴ * ۲) + ۱ = ۹ ← بیشینهٔ نظری تعداد workerها

  • ما از ۸ worker به‌علاوهٔ ۱ worker برای cron استفاده می‌کنیم. همچنین از یک سامانهٔ پایش برای اندازه‌گیری بار CPU استفاده می‌کنیم تا بررسی کنیم آیا بین ۷ تا ۷٫۵ است.

  • RAM = ۹ * ((۰٫۸*۱۵۰) + (۰٫۲*۱۰۲۴)) ≈ ۳ گیگابایت RAM برای Odoo

در فایل پیکربندی:

[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

چه از طریق website/web client یا web service به آن دسترسی پیدا شود، Odoo اطلاعات احراز هویت را به‌صورت cleartext منتقل می‌کند. این به این معنی است که یک استقرار امن Odoo باید از HTTPS استفاده کند3. SSL termination را می‌توان از طریق تقریباً هر SSL termination proxy پیاده‌سازی کرد، اما به تنظیمات زیر نیاز دارد:

  • proxy mode در Odoo را فعال کنید. این گزینه فقط زمانی باید فعال باشد که Odoo پشت یک reverse proxy قرار گرفته است

  • پراکسی SSL termination را تنظیم کنید (Nginx termination example)

  • خود proxying را تنظیم کنید (Nginx proxying example)

  • پراکسی SSL termination شما همچنین باید به‌صورت خودکار اتصال‌های ناامن را به پورت امن هدایت کند

نمونهٔ پیکربندی

  • هدایت درخواست‌های http به https

  • Proxy کردن درخواست‌ها به odoo

در فایل پیکربندی تنظیم کنید:

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 $http_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;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
    proxy_cookie_flags session_id samesite=lax secure;  # requires nginx 1.19.8
  }

  # Redirect requests to odoo backend server
  location / {
    # Add Headers for odoo proxy mode
    proxy_set_header X-Forwarded-Host $http_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;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
    proxy_cookie_flags session_id samesite=lax secure;  # requires nginx 1.19.8
  }

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

تقویت HTTPS

سرصفحهٔ Strict-Transport-Security را به تمام درخواست‌ها اضافه کنید تا از ارسال یک درخواست HTTP ساده توسط مرورگرها به این دامنه جلوگیری شود. باید همیشه یک سرویس HTTPS کارا با یک گواهی معتبر روی این دامنه نگه دارید، در غیر این صورت کاربران شما هشدارهای امنیتی خواهند دید یا به‌طور کامل قادر به دسترسی به آن نخواهند بود.

اتصال‌های HTTPS را برای یک سال برای هر بازدیدکننده در NGINX با این خط اجباری کنید:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

پیکربندی اضافی می‌تواند برای cookie session_id تعریف شود. flag Secure می‌تواند اضافه شود تا اطمینان حاصل شود هرگز روی HTTP منتقل نمی‌شود و SameSite=Lax برای جلوگیری از CSRF احراز هویت‌شده.

# requires nginx 1.19.8
proxy_cookie_flags session_id samesite=lax secure;

Odoo به‌عنوان یک برنامهٔ WSGI

همچنین می‌توان Odoo را به‌عنوان یک اپلیکیشن استاندارد WSGI mount کرد. Odoo پایه‌ای برای یک اسکریپت راه‌انداز WSGI به‌صورت odoo-wsgi.example.py ارائه می‌دهد. آن اسکریپت باید سفارشی‌سازی شود (احتمالاً پس از کپی آن از دایرکتوری setup) تا پیکربندی را به‌درستی مستقیماً در odoo.tools.config تنظیم کند نه از طریق command-line یا یک فایل پیکربندی.

با این حال، سرور WSGI فقط main HTTP endpoint را برای web client، website و webservice API expose می‌کند. چون Odoo دیگر ایجاد workerها را کنترل نمی‌کند، نمی‌تواند workerهای cron یا livechat را راه‌اندازی کند

Workerهای Cron

راه‌اندازی یکی از سرورهای built-in Odoo در کنار سرور WSGI برای پردازش jobهای cron لازم است. آن سرور باید پیکربندی شود تا فقط cronها را پردازش کند و نه درخواست‌های HTTP، با استفاده از گزینهٔ cli --no-http یا تنظیم فایل پیکربندی http_enable = False.

در سیستم‌های شبه‌Linux، استفاده از سرور multi-processing بر سرور multi-threading توصیه می‌شود تا از استفادهٔ بهتر از سخت‌افزار و افزایش پایداری بهره‌مند شوید، یعنی با استفاده از گزینه‌های cli --workers=-1 و --max-cron-threads=n.

گفتگوی زنده

استفاده از یک سرور WSGI سازگار با gevent برای عملکرد صحیح ویژگی گفتگوی زنده لازم است. آن سرور باید بتواند بسیاری از اتصال‌های long-lived هم‌زمان را مدیریت کند اما به قدرت پردازش زیادی نیاز ندارد. تمام درخواست‌هایی که مسیر آن‌ها با /websocket/ شروع می‌شود باید به آن سرور هدایت شوند. یک سرور WSGI معمولی (thread/process-based) باید برای تمام درخواست‌های دیگر استفاده شود.

سرور cron Odoo را همچنین می‌توان برای سرویس‌دهی به درخواست‌های گفتگوی زنده استفاده کرد. کافی است گزینهٔ cli --no-http را از سرور cron حذف کنید و مطمئن شوید درخواست‌هایی که مسیر آن‌ها با /websocket/ شروع می‌شود به این سرور هدایت می‌شوند، یا روی --http-port (سرور multi-threading) یا روی --gevent-port (سرور multi-processing).

ارائهٔ فایل‌های static و پیوست‌ها

برای راحتی توسعه، Odoo مستقیماً تمام فایل‌های static و پیوست‌ها را در ماژول‌های خود سرویس‌دهی می‌کند. این ممکن است از نظر عملکرد ایده‌آل نباشد و فایل‌های static به‌طور کلی باید توسط یک سرور HTTP static سرویس‌دهی شوند.

ارائهٔ فایل‌های static

فایل‌های static Odoo در پوشهٔ static/ هر ماژول قرار دارند، بنابراین فایل‌های static را می‌توان با رهگیری تمام درخواست‌ها به /MODULE/static/FILE و یافتن ماژول (و فایل) صحیح در addons pathهای مختلف سرویس‌دهی کرد.

توصیه می‌شود سرصفحهٔ Content-Security-Policy: default-src 'none' را روی تمام تصاویر تحویل‌داده‌شده توسط سرور وب تنظیم کنید. این کاملاً ضروری نیست زیرا کاربران نمی‌توانند محتوا را در داخل پوشهٔ static/ ماژول‌ها اصلاح/تزریق کنند و تصاویر موجود نهایی هستند (آن‌ها به‌خودی‌خود منابع جدیدی fetch نمی‌کنند). با این حال، این روش خوبی است.

با استفاده از پیکربندی NGINX (https) بالا، بلوک‌های map و location زیر باید برای ارائهٔ فایل‌های static از طریق NGINX اضافه شوند.

map $sent_http_content_type $content_type_csp {
    default "";
    ~image/ "default-src 'none'";
}

server {
    # the rest of the configuration

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

    # Serve static files right away
    location ~ ^/[^/]+/static/.+$ {
        # root and try_files both depend on your addons paths
        root ...;
        try_files ... @odoo;
        expires 24h;
        add_header Content-Security-Policy $content_type_csp;
    }
}

directiveهای واقعی root و try_files به نصب شما بستگی دارند، به‌ویژه به --addons-path شما.

Example

فرض کنید Odoo از طریق بسته‌های debian برای Community و Enterprise نصب شده، و --addons-path برابر با '/usr/lib/python3/dist-packages/odoo/addons' است.

مقادیر root و try_files باید چنین باشند:

root /usr/lib/python3/dist-packages/odoo/addons;
try_files $uri @odoo;

ارائهٔ پیوست‌ها

پیوست‌ها فایل‌هایی هستند که در filestore ذخیره می‌شوند و دسترسی به آن‌ها توسط Odoo تنظیم می‌شود. آن‌ها را نمی‌توان مستقیماً از طریق یک سرور وب static دسترسی کرد زیرا دسترسی به آن‌ها نیازمند چندین lookup در پایگاه داده برای تعیین محل ذخیره‌سازی فایل‌ها و اینکه آیا کاربر فعلی می‌تواند به آن‌ها دسترسی داشته باشد یا نه است.

با این حال، هنگامی که فایل توسط Odoo یافت شد و حقوق دسترسی تأیید شد، ایدهٔ خوبی است که فایل را با استفاده از سرور وب static به جای Odoo سرویس‌دهی کنید. برای اینکه Odoo سرویس‌دهی فایل‌ها را به سرور وب static واگذار کند، افزونه‌های X-Sendfile (apache) یا X-Accel (nginx) باید فعال و روی سرور وب static پیکربندی شوند. هنگامی که تنظیم شد، Odoo را با flag CLI --x-sendfile راه‌اندازی کنید (این flag منحصربه‌فرد برای هر دو X-Sendfile و X-Accel استفاده می‌شود).

توجه

  • افزونهٔ X-Sendfile برای apache (و سرورهای وب سازگار) نیازی به پیکربندی اضافی ندارد.

  • افزونهٔ X-Accel برای NGINX به پیکربندی اضافی زیر نیاز دارد:

    location /web/filestore {
        internal;
        alias /path/to/odoo/data-dir/filestore;
        add_header Content-Security-Policy $upstream_http_content_security_policy;
        add_header X-Content-Type-Options nosniff;
    }
    

    در صورتی که نمی‌دانید مسیر filestore شما کجاست، Odoo را با گزینهٔ --x-sendfile راه‌اندازی کنید و مستقیماً از طریق Odoo به URL /web/filestore بروید (از طریق NGINX به URL نروید). این یک هشدار را در لاگ ثبت می‌کند، پیام شامل پیکربندی موردنیاز شما است.

امنیت

ابتدا، در نظر داشته باشید که امن‌سازی یک سیستم اطلاعاتی یک فرایند پیوسته است، نه یک عملیات یک‌باره. در هر لحظه، شما فقط به اندازهٔ ضعیف‌ترین حلقهٔ محیط خود امن خواهید بود.

بنابراین لطفاً این بخش را به‌عنوان فهرست نهایی اقداماتی که از همهٔ مشکلات امنیتی جلوگیری می‌کند در نظر نگیرید. این فقط به‌عنوان خلاصه‌ای از اولین موارد مهمی که باید مطمئن شوید در طرح اقدام امنیتی خود گنجانده‌اید در نظر گرفته شده است. باقی از بهترین روش‌های امنیتی برای سیستم‌عامل و توزیع شما، بهترین روش‌ها از نظر کاربران، رمزهای عبور و مدیریت کنترل دسترسی و غیره می‌آید.

هنگام استقرار سروری که به اینترنت متصل می‌شود، لطفاً موضوعات امنیتی زیر را در نظر بگیرید:

  • همیشه یک رمز عبور super-admin قوی تنظیم کنید و به محض راه‌اندازی سیستم، دسترسی به صفحات مدیریت پایگاه داده را محدود کنید. به امنیت مدیر پایگاه داده مراجعه کنید.

  • loginهای منحصربه‌فرد و رمزهای عبور قوی برای تمام حساب‌های administrator روی تمام پایگاه‌های داده انتخاب کنید. از 'admin' به‌عنوان login استفاده نکنید. از این loginها برای عملیات روزمره استفاده نکنید، فقط برای کنترل/مدیریت نصب. هرگز از هیچ رمز عبور پیش‌فرضی مانند admin/admin استفاده نکنید، حتی برای پایگاه‌های دادهٔ test/staging.

  • روی سرورهای رو به اینترنت داده‌های دموی نصب نکنید. پایگاه‌های دادهٔ دارای داده‌های دمو شامل loginها و رمزهای عبور پیش‌فرضی هستند که می‌توانند برای ورود به سیستم‌های شما و ایجاد مشکلات قابل توجه استفاده شوند، حتی روی سیستم‌های staging/dev.

  • از فیلترهای پایگاه دادهٔ مناسب ( --db-filter) برای محدود کردن visibility پایگاه‌های داده خود بر اساس hostname استفاده کنید. به dbfilter مراجعه کنید. همچنین می‌توانید از -d برای ارائهٔ فهرست (با کاما جداشدهٔ) خودتان از پایگاه‌های دادهٔ در دسترس برای فیلتر، به جای اجازه دادن به سیستم برای fetch همهٔ آن‌ها از backend پایگاه داده استفاده کنید.

  • هنگامی که db_name و dbfilter شما پیکربندی شدند و فقط با یک پایگاه دادهٔ منفرد در هر hostname مطابقت داشتند، باید گزینهٔ پیکربندی list_db را روی False تنظیم کنید تا از فهرست‌کردن کامل پایگاه‌های داده جلوگیری شود و دسترسی به صفحات مدیریت پایگاه داده مسدود شود (این به‌عنوان گزینهٔ command-line --no-database-list نیز در دسترس است)

  • اطمینان حاصل کنید که کاربر PostgreSQL (--db_user) یک super-user نیست و پایگاه‌های دادهٔ شما در اختیار کاربر متفاوتی هستند. برای مثال اگر از یک db_user اختصاصی غیرامتیازی استفاده می‌کنید، آن‌ها می‌توانند در اختیار super-user postgres باشند. همچنین به پیکربندی Odoo مراجعه کنید.

  • با نصب منظم آخرین ساخت‌ها، یا از طریق GitHub یا با دانلود آخرین نسخه از https://www.odoo.com/page/download یا http://nightly.odoo.com ، نصب‌ها را به‌روز نگه دارید

  • سرور خود را در حالت multi-process با محدودیت‌های مناسب که با استفادهٔ معمول شما (memory/CPU/timeouts) مطابقت داشته باشد پیکربندی کنید. همچنین به سرور درون‌ساخت مراجعه کنید.

  • Odoo را پشت یک سرور وب که HTTPS termination با یک گواهی SSL معتبر ارائه می‌دهد اجرا کنید تا از eavesdropping روی ارتباطات cleartext جلوگیری شود. گواهی‌های SSL ارزان هستند و گزینه‌های رایگان زیادی وجود دارد. proxy وب را پیکربندی کنید تا اندازهٔ درخواست‌ها را محدود کند، timeoutهای مناسب تنظیم کنید و سپس گزینهٔ proxy mode را فعال کنید. همچنین به HTTPS مراجعه کنید.

  • اگر باید دسترسی SSH راه‌دور را به سرورهای خود مجاز کنید، اطمینان حاصل کنید که یک رمز عبور قوی برای تمام حساب‌ها تنظیم کنید، نه فقط root. اکیداً توصیه می‌شود احراز هویت مبتنی بر رمز عبور را به‌طور کامل غیرفعال کنید و فقط احراز هویت کلید عمومی را مجاز کنید. همچنین محدود کردن دسترسی از طریق یک VPN، اجازه دادن فقط به IPهای مورد اعتماد در firewall، و/یا اجرای یک سیستم تشخیص brute-force مانند fail2ban یا معادل را در نظر بگیرید.

  • نصب rate-limiting مناسب روی proxy یا firewall خود را در نظر بگیرید تا از حملات brute-force و denial of service جلوگیری شود. برای اقدامات خاص همچنین به مسدودسازی حملات Brute Force مراجعه کنید.

    بسیاری از ارائه‌دهندگان شبکه برای حملات Distributed Denial of Service (DDOS) کاهش خودکار ارائه می‌دهند، اما این اغلب یک سرویس اختیاری است، بنابراین باید با آن‌ها مشورت کنید.

  • هر زمان ممکن است، نمونه‌های public-facing demo/test/staging خود را روی دستگاه‌هایی متفاوت از دستگاه‌های تولید میزبانی کنید. و همان احتیاطات امنیتی مشابه تولید را اعمال کنید.

  • اگر سرور Odoo public-facing شما به منابع یا سرویس‌های شبکهٔ داخلی حساس دسترسی دارد (مثلاً از طریق یک VLAN خصوصی)، قوانین firewall مناسب را برای محافظت از آن منابع داخلی پیاده‌سازی کنید. این تضمین می‌کند که سرور Odoo نتواند به‌صورت تصادفی (یا در نتیجهٔ اقدامات کاربر مخرب) برای دسترسی یا اختلال در آن منابع داخلی استفاده شود. معمولاً این را می‌توان با اعمال یک قاعدهٔ outbound default DENY روی firewall، سپس فقط مجاز کردن صریح دسترسی به منابع داخلی که سرور Odoo باید به آن‌ها دسترسی داشته باشد انجام داد. Systemd IP traffic access control نیز ممکن است برای پیاده‌سازی کنترل دسترسی شبکهٔ per-process مفید باشد.

  • اگر سرور Odoo public-facing شما پشت یک Web Application Firewall، یک load-balancer، یک سرویس محافظت شفاف DDoS (مانند CloudFlare) یا یک دستگاه مشابه در سطح شبکه قرار دارد، ممکن است بخواهید از دسترسی مستقیم به سیستم Odoo اجتناب کنید. به‌طور کلی نگه داشتن آدرس‌های IP endpoint سرورهای Odoo شما به‌صورت محرمانه دشوار است. برای مثال آن‌ها می‌توانند در لاگ‌های سرور وب هنگام query سیستم‌های عمومی، یا در سرصفحه‌های ایمیل‌های پست‌شده از Odoo ظاهر شوند. در چنین موقعیتی ممکن است بخواهید firewall خود را پیکربندی کنید تا endpointها به‌صورت عمومی قابل دسترسی نباشند به‌جز از آدرس‌های IP خاص WAF، load-balancer یا سرویس proxy شما. ارائه‌دهندگان سرویس مانند CloudFlare معمولاً یک فهرست عمومی از بازه‌های آدرس IP خود را برای این هدف نگه می‌دارند.

  • اگر چندین مشتری را میزبانی می‌کنید، داده‌ها و فایل‌های مشتریان را با استفاده از کانتینرها یا تکنیک‌های مناسب «jail» از یکدیگر ایزوله کنید.

  • پشتیبان‌گیری روزانه از پایگاه‌های داده و داده‌های filestore خود را راه‌اندازی کنید و آن‌ها را به یک سرور archiving راه‌دور که از خود سرور قابل دسترس نیست کپی کنید.

  • استقرار Odoo روی Linux اکیداً بر روی Windows توصیه می‌شود. در صورتی که با این حال انتخاب کنید روی یک پلتفرم Windows مستقر کنید، باید یک بررسی جامع امن‌سازی سرور انجام شود که خارج از حوزهٔ این راهنما است.

مسدودسازی حملات Brute Force

برای استقرارهای رو به اینترنت، حملات brute force روی رمزهای عبور کاربران بسیار رایج است و این تهدید نباید برای سرورهای Odoo نادیده گرفته شود. Odoo هر بار که یک تلاش ورود انجام می‌شود یک ورودی لاگ منتشر می‌کند و نتیجه را گزارش می‌دهد: موفقیت یا شکست، به همراه login هدف و 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 برای مسدود کردن IP مهاجم در HTTP(S) استفاده شود.

در ادامه می‌توانید ببینید این چگونه می‌تواند برای مسدود کردن IP به مدت ۱۵ دقیقه زمانی که ۱۰ تلاش ورود ناموفق از همان IP در ۱ دقیقه تشخیص داده شود به نظر برسد:

[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 اشاره کرده است.

این تنظیم در تمام صفحات مدیریت پایگاه داده (برای ایجاد، حذف، dump یا بازیابی پایگاه‌های داده) استفاده می‌شود.

اگر صفحات مدیریت اصلاً نباید قابل دسترسی باشند، باید گزینهٔ پیکربندی list_db را روی False تنظیم کنید تا دسترسی به تمام صفحات انتخاب و مدیریت پایگاه داده مسدود شود.

هشدار

اکیداً توصیه می‌شود Database Manager را برای هر سیستم رو به اینترنت غیرفعال کنید! این به‌عنوان یک ابزار development/demo در نظر گرفته شده است تا ایجاد و مدیریت سریع پایگاه‌های داده را آسان کند. برای استفاده در تولید طراحی نشده و حتی ممکن است ویژگی‌های خطرناکی را در معرض مهاجمان قرار دهد. همچنین برای مدیریت پایگاه‌های دادهٔ بزرگ طراحی نشده و ممکن است محدودیت‌های memory را trigger کند.

روی سیستم‌های تولید، عملیات مدیریت پایگاه داده باید همیشه توسط system administrator انجام شوند، از جمله provisioning پایگاه‌های دادهٔ جدید و پشتیبان‌گیری خودکار.

حتماً پارامتر db_name مناسب (و به‌صورت اختیاری dbfilter نیز) را راه‌اندازی کنید تا سیستم بتواند پایگاه دادهٔ هدف را برای هر درخواست تعیین کند، در غیر این صورت کاربران مسدود خواهند شد زیرا اجازهٔ انتخاب پایگاه داده به خودشان داده نخواهد شد.

اگر صفحات مدیریت باید فقط از یک مجموعهٔ منتخب دستگاه‌ها قابل دسترسی باشند، از ویژگی‌های سرور proxy برای مسدود کردن دسترسی به تمام مسیرهایی که با /web/database شروع می‌شوند استفاده کنید، به‌جز (شاید) /web/database/selector که صفحهٔ database-selection را نمایش می‌دهد.

اگر صفحهٔ مدیریت پایگاه داده باید قابل دسترسی باقی بماند، تنظیم admin_passwd باید از پیش‌فرض admin خود تغییر کند: این رمز عبور پیش از اجازهٔ عملیات تغییر پایگاه داده بررسی می‌شود.

باید به‌صورت امن ذخیره شود و باید به‌صورت تصادفی تولید شود، برای مثال:

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

که یک رشتهٔ شبه‌تصادفی قابل چاپ ۳۲ کاراکتری تولید می‌کند.

بازنشانی رمز عبور master

ممکن است مواردی پیش بیاید که master password جابه‌جا یا compromise شده و نیاز به بازنشانی داشته باشد. فرایند زیر برای system administratorهای یک پایگاه دادهٔ on-premise Odoo است که جزئیات نحوهٔ این کار را توضیح می‌دهد.

همچنین ببینید

حساب Odoo.com

هنگام ایجاد یک پایگاه دادهٔ on-premise جدید، یک master password تصادفی تولید می‌شود. Odoo توصیه می‌کند از این رمز عبور برای امن‌سازی پایگاه داده استفاده کنید. این رمز عبور به‌صورت پیش‌فرض پیاده‌سازی می‌شود، بنابراین یک امنیت وجود دارد.

هشدار

هنگام ایجاد یک پایگاه دادهٔ on-premise Odoo، نصب برای همه در اینترنت قابل دسترس است، تا زمانی که این رمز عبور برای امن‌سازی پایگاه داده تنظیم شود.

master password در فایل پیکربندی Odoo (odoo.conf یا odoorc (فایل پنهان)) مشخص می‌شود. master password Odoo برای اصلاح، ایجاد یا حذف یک پایگاه داده از طریق رابط GUI لازم است.

یافتن فایل پیکربندی

ابتدا فایل پیکربندی Odoo را باز کنید (odoo.conf یا odoorc (فایل پنهان)).

فایل پیکربندی در این مسیر قرار دارد: c:\ProgramFiles\Odoo{VERSION}\server\odoo.conf

تغییر رمز عبور قدیمی

پس از باز کردن فایل مناسب، رمز عبور قدیمی را در فایل پیکربندی به یک رمز عبور موقت تغییر دهید.

پس از یافتن فایل پیکربندی، آن را با استفاده از یک (GUI) باز کنید. این کار را می‌توان با دوبار کلیک ساده روی فایل انجام داد. سپس، دستگاه باید یک پیش‌فرض داشته باشد.

سپس خط master password admin_passwd = $pbkdf2-sha… را به admin_passwd = newpassword1234 تغییر دهید، برای مثال. این رمز عبور می‌تواند هر چیزی باشد، تا زمانی که به‌صورت موقت ذخیره شود. حتماً آن را اصلاح کنید.

Example

خط به این شکل ظاهر می‌شود: admin_passwd = $pbkdf2-sh39dji295.59mptrfW.9z6HkA$w9j9AMVmKAP17OosCqDxDv2hjsvzlLpF8Rra8I7p/b573hji540mk/.3ek0lg%kvkol6k983mkf/40fjki79m

خط اصلاح‌شده به این شکل ظاهر می‌شود: admin_passwd = newpassword1234

مهم

ضروری است که رمز عبور به چیز دیگری تغییر کند، به جای trigger کردن یک password reset جدید با افزودن یک semicolon ; در ابتدای خط. این تضمین می‌کند که پایگاه داده امن است.

راه‌اندازی مجدد سرور Odoo

پس از تنظیم رمز عبور موقت، راه‌اندازی مجدد سرور Odoo الزامی است.

برای راه‌اندازی مجدد سرور Odoo، ابتدا services را در نوار جستجو Windows تایپ کنید. سپس اپلیکیشن محصولات را انتخاب کنید و به پایین scroll کنید تا به سرویس اودو برسید.

سپس روی اودو راست‌کلیک کنید و آغاز یا Restart را انتخاب کنید. این عمل به‌صورت دستی سرور Odoo را راه‌اندازی مجدد می‌کند.

استفاده از رابط وب برای رمزگذاری مجدد رمز عبور

ابتدا به /web/database/manager یا http://server_ip:port/web/database/manager در یک مرورگر بروید.

توجه

server_ip را با آدرس IP پایگاه داده جایگزین کنید. port را با پورت عددی که پایگاه داده از آن قابل دسترسی است جایگزین کنید.

سپس روی Set Master Password کلیک کنید و رمز عبور موقت قبلی‌انتخاب‌شده را در فیلد Master Password وارد کنید. پس از این گام، یک New Master Password وارد کنید. New Master Password پس از کلیک روی دکمهٔ ادامه هش (یا رمزگذاری) می‌شود.

در این مرحله، رمز عبور با موفقیت بازنشانی شده و نسخهٔ hash‌شدهٔ رمز جدید اکنون در فایل پیکربندی ظاهر می‌شود.

همچنین ببینید

برای اطلاعات بیشتر دربارهٔ امنیت پایگاه دادهٔ Odoo، به این مستندات مراجعه کنید: امنیت مدیر پایگاه داده.

مرورگرهای پشتیبانی‌شده

Odoo از آخرین نسخهٔ مرورگرهای زیر پشتیبانی می‌کند.

  • Google Chrome

  • Mozilla Firefox

  • Microsoft Edge

  • Apple Safari

1

برای اینکه چندین نصب Odoo از یک پایگاه دادهٔ PostgreSQL مشترک استفاده کنند، یا برای فراهم کردن منابع محاسباتی بیشتر برای هر دو نرم‌افزار.

2

از نظر فنی یک ابزار مانند socat می‌تواند برای proxy کردن UNIX sockets در شبکه‌ها استفاده شود، اما این عمدتاً برای نرم‌افزاری است که فقط می‌توان از UNIX sockets استفاده کرد

3

یا فقط از طریق یک شبکهٔ packet-switched داخلی قابل دسترس باشد، اما این نیازمند switchهای امن، محافظت در برابر ARP spoofing است و استفاده از WiFi را منع می‌کند. حتی روی شبکه‌های امن packet-switched، استقرار روی HTTPS توصیه می‌شود و هزینه‌های احتمالی پایین‌تر هستند زیرا گواهی‌های «self-signed» در یک محیط کنترل‌شده آسان‌تر از روی اینترنت قابل استقرار هستند.