SSD Nodes Learn 🎉 VPS از $5.50/ماه
راهنماها Matt Connorتوسط Matt Connor

بهترین مدیریت اسرار خودمیزبان برای سرور شخصی

مقایسه فنی OpenBao، Infisical، SOPS با age و systemd credentials برای مدیریت امن اسرار روی یک VPS. بررسی هزینه‌ها و انتخاب ابزار مناسب برای جلوگیری از قطعی سرویس.

تفاوت عملکرد مدیریت رمز عبور خودمیزبان با مدیریت اسرار

یک مدیریت اسرار خودمیزبان، اعتبارنامه‌ها را به پردازش‌ها تحویل می‌دهد. یک مدیریت رمز عبور، اعتبارنامه‌ها را به انسان‌ها تحویل می‌دهد. تمام تفاوت‌های دیگر از همین یک نکته ناشی می‌شوند. یک مدیریت رمز عبور توسط انسانی بازگشایی می‌شود که حضور دارد و توجه می‌کند. یک مدیریت اسرار باید در ساعت 03:00، زمانی که کسی بیدار نیست، رمز عبور پایگاه داده را به برنامه شما ارائه دهد.

حالت‌های شکست در این دو ابزار به شکلی متفاوت است که اهمیت دارد. قفل شدن مدیریت رمز عبور تنها یک دردسر است: شما دوباره رمز عبور اصلی را وارد می‌کنید. اما مهر و موم شدن (sealed) مدیریت اسرار به معنای قطعی سرویس است: هر سرویسی که در زمان مهر و موم بودن ری‌استارت شود، بدون اعتبارنامه بالا می‌آید و از دسترس خارج می‌ماند. اجرای Vaultwarden به عنوان مدیریت رمز عبور شخصی مشکل انسانی را به‌خوبی حل می‌کند. اما این ابزار برای حل مشکل ماشینی ساخته نشده است و چنین کاری هم نمی‌کند.

گزینه‌های واقع‌بینانه برای یک سرور در دو دسته قرار می‌گیرند. OpenBao و Infisical سرویس هستند: شامل یک API، یک پایگاه داده، TLS (امنیت لایه انتقال)، یک مرحله ورود به سیستم و پردازشی که اکنون باید آن را زنده نگه دارید. ابزارهایی مانند SOPS با age، قابلیت systemd credentials و Docker secrets مبتنی بر فایل هستند: در حالت سکون رمزنگاری شده‌اند، توسط چیزی که از قبل در حال اجراست رمزگشایی می‌شوند و هیچ مورد اضافه‌ای برای مانیتور کردن ندارند.

پاسخ صادقانه از همان ابتدا این است: برای یک سرور واحد با یک یا دو کاربر، گزینه‌های مبتنی بر فایل معمولاً انتخاب درست هستند. یک OpenBao که هیچ‌کس به‌درستی آن را از حالت مهر و موم خارج نمی‌کند و هیچ‌کس رمزهایش را تغییر نمی‌دهد، از یک فایل env با دسترسی 600 بدتر است؛ زیرا یک بخش متحرک و یک نسخه پشتیبان به سیستم اضافه می‌کند که احتمالاً در مدیریت آن دچار اشتباه خواهید شد، در حالی که هیچ قابلیت چرخش رمز (rotation) خودکاری که قبلاً به‌صورت دستی انجام نمی‌دادید، برای شما فراهم نمی‌کند.

آیا حالت 600 برای فایل env کافی است؟

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

sudo install -d -m 750 -o root -g myapp /etc/myapp
sudo install -m 640 -o root -g myapp /dev/null /etc/myapp/env
sudoedit /etc/myapp/env

این موضوع را از هر دو سمت بررسی کنید:

sudo -u myapp cat /etc/myapp/env
sudo -u nobody cat /etc/myapp/env

دستور اول فایل را چاپ می‌کند. دستور دوم cat: /etc/myapp/env: Permission denied را چاپ می‌کند، زیرا nobody در گروه myapp نیست و فایل هیچ مجوز دسترسی برای world ندارد. این کل مدل امنیتی است و یک مدل واقعی محسوب می‌شود.

نشت اطلاعات زمانی رخ می‌دهد که مرحله بعدی اتفاق می‌افتد. یک unit در systemd با استفاده از EnvironmentFile=، آن مقادیر را در محیط (environment) پردازش کپی می‌کند و محیط پردازش قابل خواندن است.

[Service]
User=myapp
EnvironmentFile=/etc/myapp/env
ExecStart=/usr/local/bin/myapp
sudo cat /proc/$(pgrep -n myapp)/environ | tr '\0' '\n'

این دستور اسرار شما را به صورت متن ساده (cleartext) چاپ می‌کند، زیرا /proc/<pid>/environ توسط root و کاربری که پردازش با آن اجرا می‌شود، قابل خواندن است. یک گزارش‌گر خرابی (crash reporter) که محیط را به گزارش پیوست می‌کند نیز همین اطلاعات را می‌بیند. هر ابزاری که تحت همان حساب کاربری اجرا شود نیز همین‌طور است؛ به همین دلیل است که دور نگه داشتن اسرار از AI agents با خارج کردن آن‌ها از محیط (environment) آغاز می‌شود. این فایل را با یک کاربر سرویس اختصاصی با دسترسی محدود جفت کنید تا «کاربری که پردازش با آن اجرا می‌شود» همان root نباشد.

استفاده از SOPS به همراه age: رمزنگاری اسرار برای commit در git

ابزار SOPS (مخفف secrets operations) مقادیر موجود در فایل‌های YAML یا JSON را رمزنگاری می‌کند و کلیدها را به صورت متن ساده (cleartext) باقی می‌گذارد. age یک ابزار رمزنگاری سبک است که یک جفت‌کلید در اختیار شما می‌گذارد و نیازی به سرور کلید ندارد. ترکیب این دو به شما اجازه می‌دهد secrets.enc.yaml را در کنار کد خود commit کنید و git diff همچنان به شما نشان می‌دهد که کدام تنظیم تغییر کرده است، بدون آنکه محتوای تغییر را برای خواننده فاش کند.

ابزار age در مخازن Ubuntu 24.04 موجود است. اما SOPS در مخازن نیست، بنابراین .deb را از صفحه release دریافت کنید. نسخه 3.13.3 در آگوست 2026 نسخه جاری بوده است.

sudo apt update && sudo apt install -y age
curl -LO https://github.com/getsops/sops/releases/download/v3.13.3/sops_3.13.3_amd64.deb
sudo apt install -y ./sops_3.13.3_amd64.deb
sops --version

یک جفت‌کلید تولید کنید. age-keygen کلید خصوصی را در فایل می‌نویسد و کلید عمومی را چاپ می‌کند، بنابراین خطی را خواهید دید که با Public key: age1... شروع می‌شود.

mkdir -p ~/.config/sops/age
age-keygen -o ~/.config/sops/age/keys.txt
chmod 600 ~/.config/sops/age/keys.txt
age-keygen -y ~/.config/sops/age/keys.txt

کلید عمومی را در .sops.yaml در ریشه مخزن قرار دهید تا دیگر نیازی نباشد گیرنده را در خط فرمان به خاطر بسپارید.

creation_rules:
  - age: age1s3cqcks5genc6ru8chl0hkkd04zmxvczsvdxq99ekffe4gmvjpzsedk23c
sops encrypt secrets.yaml > secrets.enc.yaml
sops decrypt secrets.enc.yaml

قانونی که path_regex ندارد با همه چیز مطابقت پیدا می‌کند، که همان چیزی است که در ابتدا به آن نیاز دارید. اگر بعداً قانونی اضافه کردید، آن را طوری بنویسید که با فایلی که به sops می‌دهید مطابقت داشته باشد، زیرا قوانین بر اساس مسیر ورودی بررسی می‌شوند، نه فایلی که خروجی را به آن هدایت می‌کنید.

در زمان اجرا، مقادیر را فقط به یک پردازش بدهید و نه هیچ چیز دیگر:

sops exec-env secrets.enc.yaml './myapp'

sops exec-env رمزگشایی را در حافظه انجام می‌دهد و مقادیر را در محیط پردازش فرزند تنظیم می‌کند، بنابراین هیچ متن ساده‌ای روی دیسک نوشته نمی‌شود. هشدار مربوط به محیط (environment) از بخش قبلی، همچنان برای آن پردازش فرزند صادق است.

دو مورد معمولاً باعث بروز مشکل برای کاربران می‌شود. خطای Failed to get the data key required to decrypt the SOPS file در systemd تقریباً همیشه به این معنی است که SOPS در دایرکتوری home اشتباهی جستجو کرده است، زیرا یک unit متغیر HOME شما را به ارث نمی‌برد. مسیر را به صورت صریح با Environment=SOPS_AGE_KEY_FILE=/etc/sops/age.txt در unit تنظیم کنید. علاوه بر این، ویرایش .sops.yaml باعث رمزنگاری مجدد آنچه قبلاً وجود داشته نمی‌شود: افزودن کلید عمومی یک همکار فقط بر فایل‌های جدید تأثیر می‌گذارد، بنابراین sops updatekeys secrets.enc.yaml را روی هر فایل موجود اجرا کنید. اگر پیکربندی شما از قبل توسط Ansible اجرا می‌شود، رمزنگاری مقادیر مشابه با Ansible Vault بدون نیاز به ابزار دوم به همان نتیجه می‌رسد.

اعتبارنامه‌های systemd: اسراری که هرگز به محیط (environment) نمی‌رسند

نسخه Ubuntu 24.04 شامل systemd 255 است، بنابراین نیازی به نصب هیچ موردی نیست. systemd-creds یک راز را روی میزبان رمزگذاری می‌کند و systemd آن را در یک دایرکتوری خصوصی که فقط همان سرویس خاص قادر به خواندن آن است، رمزگشایی می‌کند.

sudo systemd-creds setup
sudo install -d -m 700 /etc/myapp
echo -n 'hunter2' | sudo systemd-creds encrypt --name=db_password - /etc/myapp/db_password.cred
[Service]
User=myapp
LoadCredentialEncrypted=db_password:/etc/myapp/db_password.cred
ExecStart=/usr/local/bin/myapp

سرویس، مقدار را از فایلی به نام db_password در داخل دایرکتوری که توسط $CREDENTIALS_DIRECTORY تعیین شده است، می‌خواند. این مقدار در محیط (environment) قرار ندارد، بنابراین /proc/<pid>/environ هیچ چیز مفیدی را نشان نمی‌دهد و متن ساده (plaintext) هرگز روی فایل‌سیستم root قرار نمی‌گیرد.

پیش از آنکه یک unit را به سمت آن هدایت کنید، بررسی کنید که فایل به درستی رمزگشایی می‌شود:

sudo systemd-creds decrypt /etc/myapp/db_password.cred -

بدانید کدام کلید آن را رمزگذاری کرده است، زیرا این موضوع تعیین می‌کند که آیا نسخه پشتیبان شما قابل استفاده است یا خیر. مقدار پیش‌فرض --with-key=auto در صورت وجود و قابل استفاده بودن، از تراشه TPM2 (ماژول پلتفرم مورد اعتماد نسخه 2) استفاده می‌کند و در غیر این صورت از کلید میزبان بهره می‌برد. اکثر نمونه‌های VPS فاقد TPM2 هستند.

systemd-analyze has-tpm2

no به این معنی است که از کلید میزبان استفاده شده است و آن کلید در /var/lib/systemd/credential.secret قرار دارد که فقط توسط root قابل خواندن است. اگر db_password.cred را روی یک VPS جدید بدون آن فایل بازیابی کنید، هیچ چیزی هرگز رمزگشایی نخواهد شد. فایل credential.secret را در همان نسخه پشتیبان کپی کنید یا متن ساده را در جایی که همچنان به آن دسترسی دارید، نگهداری کنید.

Docker secrets: فایل‌های موجود در مسیر /run/secrets

ابزار Compose یک فایل را از روی میزبان (host) می‌خواند و آن را در مسیر /run/secrets/<name> درون کانتینر mount می‌کند.

services:
  app:
    image: myapp:latest
    environment:
      DB_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password
secrets:
  db_password:
    file: ./db_password.txt
docker compose exec app cat /run/secrets/db_password
docker compose exec app env | grep -i password

دستور اول مقدار secret را چاپ می‌کند. دستور دوم فقط DB_PASSWORD_FILE=/run/secrets/db_password را نمایش می‌دهد که نکتهٔ اصلی همین است: مقدار secret هرگز در متغیرهای محیطی (environment) کانتینر قرار نمی‌گیرد، بنابراین در خروجی docker inspect نیز دیده نمی‌شود. بسیاری از ایمیج‌های رسمی از قبل با این ساختار سازگار هستند و برای مثال، ایمیج Postgres فایل POSTGRES_PASSWORD_FILE را دقیقاً به همین روش می‌خواند.

در مورد ماهیت این قابلیت شفاف باشید. خارج از حالت Swarm، هیچ‌گونه رمزنگاری در هیچ لایه‌ای وجود ندارد: ./db_password.txt یک فایل متنی ساده (plaintext) روی میزبان است و تنها محافظت آن، سطح دسترسی (mode) و مالک (owner) فایل است. این دو مورد را خودتان تنظیم کنید، زیرا Compose بدون هیچ هشداری، فایلی که برای همه قابل خواندن است را mount می‌کند. بررسی جامع‌تر مزایا و معایب این روش در مقایسه با میان‌بر سادهٔ env_file در راهنمای فایل‌های env و secrets در Compose آمده است.

هزینه‌های واقعی اجرای OpenBao و Vault

پروژه OpenBao انشعابی (fork) از HashiCorp Vault تحت نظر Linux Foundation است که پس از تغییر مجوز Vault توسط HashiCorp به Business Source License در سال 2023 ایجاد شد. OpenBao همچنان تحت مجوز MPL 2.0 (Mozilla Public License) باقی مانده است. نسخه 2.6.2 در اوت 2026 نسخه جاری بود. تقریباً تمام موارد زیر در مورد Vault نیز صدق می‌کند، زیرا این انشعاب رابط کاربری و دستورات مشابهی را حفظ کرده است.

docker pull docker.io/openbao/openbao

اگر ترجیح می‌دهید مدیریت به‌روزرسانی‌ها توسط apt انجام شود، بسته‌های Debian و Ubuntu در صفحه دانلود OpenBao موجود هستند. سرور به یک فایل پیکربندی نیاز دارد که شامل یک listener و یک storage backend باشد:

listener "tcp" {
  address       = "127.0.0.1:8200"
  tls_cert_file = "/path/to/full-chain.pem"
  tls_key_file  = "/path/to/private-key.pem"
}

storage "raft" {
  path = "/path/to/raft/data"
  node_id = "raft_node_1"
}

سپس آن را یک بار اجرا کنید:

bao operator init

به‌صورت پیش‌فرض، این کار کلید ریشه (root key) را به 5 سهم تقسیم می‌کند و برای unseal کردن به 3 سهم از آن‌ها نیاز دارد که توسط فلگ‌های -key-shares و -key-threshold تعیین می‌شوند. این برنامه سهم‌ها و توکن ریشه اولیه را تنها یک بار نمایش می‌دهد و دیگر هرگز آن‌ها را تکرار نخواهد کرد.

اکنون به بخشی می‌رسیم که اکثر مقایسه‌ها از آن عبور می‌کنند. سرور راه‌اندازی‌شده (restarted)، یک سرور sealed است. OpenBao کلید ریشه را فقط در حافظه نگه می‌دارد، بنابراین پس از راه‌اندازی مجدد، تا زمانی که فردی حد نصاب سهم‌ها را ارائه نکند، نمی‌تواند فضای ذخیره‌سازی خود را رمزگشایی کند. بنابراین، یک به‌روزرسانی هسته (kernel) یا توقف سرویس توسط OOM Killer منجر به یک سرور sealed و برنامه‌هایی می‌شود که قادر به ورود نیستند.

در یک VPS تک‌کاربره، تقسیم Shamir عملاً چیزی را محافظت نمی‌کند، زیرا هر پنج سهم در نهایت در همان مدیریت‌کننده رمز عبوری قرار می‌گیرند که متعلق به همان شخص است. قابلیت Auto unseal کلید را به یک دستگاه یا سرویس مورد اعتماد منتقل می‌کند؛ این در یک فضای ابری بزرگ به معنای استفاده از یک سرویس مدیریت کلید است و در VPS شما معمولاً به معنای قرار دادن یک فایل کلید روی همان دیسکی است که داده‌های محافظت‌شده در آن قرار دارند. این یک کاهش واقعی در امنیت است که در ازای بازگشت خودکار سرور پس از راه‌اندازی مجدد پذیرفته می‌شود. این معامله را آگاهانه انجام دهید و یادداشت کنید که کدام روش را انتخاب کرده‌اید.

Infisical: یک رابط کاربری، یک پایگاه داده و یک کلید اصلی که نزد شما باقی می‌ماند

Infisical یک پلتفرم مدیریت اسرار (secrets) است که شامل رابط وب، پروژه‌ها، محیط‌های مختلف و کنترل دسترسی بر اساس کاربر می‌باشد. میزبانی آن با استفاده از Compose بسیار کوتاه است:

curl -o docker-compose.prod.yml https://raw.githubusercontent.com/Infisical/infisical/main/docker-compose.prod.yml
curl -o .env https://raw.githubusercontent.com/Infisical/infisical/main/.env.example
docker compose -f docker-compose.prod.yml up -d

پیش از اجرای دستور آخر، فایل .env را ویرایش کنید. دو مقدار باید توسط شما تعیین شوند و یکی از آن‌ها پس از تنظیم نباید تغییر کند:

openssl rand -hex 16
openssl rand -base64 32

مقدار اول ENCRYPTION_KEY است، یک رشته هگزادسیمال 16 بایتی. این همان کلیدی است که اسرار شما با آن در PostgreSQL رمزنگاری می‌شوند؛ بنابراین گم کردن آن باعث می‌شود نسخه پشتیبان پایگاه داده به مجموعه‌ای از متن‌های رمزنگاری‌شده غیرقابل استفاده تبدیل شود و تغییر آن در یک نمونه در حال اجرا، مانع از رمزگشایی اسرار موجود می‌گردد. مقدار دوم AUTH_SECRET است، یک رشته base64 32 بایتی که برای نشست‌ها (sessions) استفاده می‌شود. SITE_URL باید دقیقاً همان URL مطلق باشد که از طریق آن به سرویس دسترسی خواهید داشت (شامل پروتکل)، در غیر این صورت تغییر مسیر (redirect) ورود به سیستم با خطا مواجه می‌شود.

زمانی که نیاز اصلی شما مدیریت کاربران است، Infisical گزینه مناسب‌تری نسبت به OpenBao محسوب می‌شود: رابط کاربری وب برای یک تیم کوچک و تفکیک محیط‌ها، به جای اعتبارنامه‌های پایگاه داده‌ای که به‌طور خودکار منقضی می‌شوند. استفاده از این ابزار مستلزم مدیریت PostgreSQL، Redis و یک گواهی TLS است که اکنون وظیفه وصله‌کردن و پشتیبان‌گیری از آن‌ها بر عهده شماست.

وقتی سرویس secrets از دسترس خارج می‌شود و برنامه شما ری‌استارت می‌شود چه اتفاقی می‌افتد

این پرسش تعیین می‌کند که آیا یک سرویس secrets باید روی یک سرور واحد قرار بگیرد یا خیر. فایل‌ها پیش از راه‌اندازی شبکه قابل خواندن هستند، اما یک سرویس این‌گونه نیست.

سرور را ری‌بوت کنید؛ برنامه شما و OpenBao در یک لحظه شروع به کار می‌کنند. برنامه رمز عبور دیتابیس خود را درخواست می‌کند، OpenBao هنوز در حالت sealed است، درخواست با شکست مواجه می‌شود و systemd برنامه را در یک حلقه تکرار ری‌استارت می‌کند تا زمانی که یک انسان unseal shares را وارد کند. هیچ‌چیز خراب نشده است، اما هیچ‌چیز هم در دسترس نیست.

دو راه صادقانه برای مدیریت این وضعیت وجود دارد. واحدها (units) را مرتب کنید و به برنامه اجازه دهید دوباره تلاش کند: After= سرویس secrets، به همراه Restart=on-failure و یک RestartSec= که به اندازه کافی طولانی باشد تا به API فشار نیاورید. یا اینکه به جای زمان بوت، در زمان deploy اطلاعات را دریافت کنید: secret را در یک فایل با دسترسی 600 یا یک systemd credential رندر کنید تا سیستم در حال اجرا به جای API، به یک فایل وابسته باشد.

انقضای توکن (Token expiry) همان مشکل را با سرعت کمتری ایجاد می‌کند. توکن‌ها و leaseهای OpenBao دارای زمان بقا (TTL) هستند، بنابراین یک پردازش طولانی‌مدت که هرگز تمدید نمی‌شود، در لحظه‌ای که هیچ ارتباطی با deploy ندارد، دسترسی خود را از دست می‌دهد. این خطا دقیقاً به این دلیل گیج‌کننده است که در آن روز هیچ تغییری رخ نداده است.

پشتیبان‌گیری از خودِ مخزن (store)

هر گزینه در اینجا یک کلید دارد و پشتیبان بدون آن کلید، بی‌ارزش است. محل نگهداری کلید خود را یادداشت کنید.

برای یک فایل env، خودِ فایل همان راز است، بنابراین پشتیبان باید رمزنگاری‌شده باشد. برای SOPS، فایل رمزنگاری‌شده می‌تواند در هر فضای عمومی قرار بگیرد، اما کلید خصوصی age در ~/.config/sops/age/keys.txt چیزی است که نباید آن را گم کنید. برای credentials در systemd، از /var/lib/systemd/credential.secret در کنار فایل‌های .cred پشتیبان تهیه کنید. برای Infisical، یک خروجی (dump) از PostgreSQL بگیرید و ENCRYPTION_KEY را در محلی جدا از آن ذخیره کنید.

OpenBao با استفاده از فضای ذخیره‌سازی raft، اسنپ‌شات مخصوص به خود را می‌گیرد:

bao operator raft snapshot save backup.snap
bao operator raft snapshot restore backup.snap

این اسنپ‌شات حاوی فضای ذخیره‌سازی رمزنگاری‌شدهٔ شماست، بنابراین بازیابی آن در یک سرور جدید همچنان به unseal shares از bao operator init نیاز دارد. یک وظیفهٔ شبانه (nightly job) که اسنپ‌شات‌ها را به object storage کپی می‌کند، در حالی که sharesها در هیچ‌جا ذخیره نشده‌اند، پشتیبان از هیچ است. پیش از آنکه به آن وابسته شوید، بازیابی را روی یک VPS موقت تست کنید.

ثبت لاگ‌های حسابرسی: چه کسی کدام secret را خوانده است

فایل‌ها هیچ مسیر حسابرسی (audit trail) در اختیار شما نمی‌گذارند. مجوزها و مالک فایل فقط به شما می‌گویند چه کسی می‌توانست secret را بخواند، اما هرگز نمی‌گویند چه کسی واقعاً این کار را انجام داده است. استفاده از auditd با نظارت بر یک مسیر، نزدیک‌ترین جایگزین است، اما این ابزار فقط گزارش می‌دهد که فایلی باز شده است، نه اینکه کدام مقدار خوانده شده است.

OpenBao هر درخواست را در یک دستگاه حسابرسی که به‌طور صریح فعال کرده‌اید، ثبت می‌کند:

bao audit enable file file_path=/var/log/openbao_audit.log

دو نکته درباره این لاگ وجود دارد که نحوه اجرای سرور را تغییر می‌دهد. اکثر رشته‌ها در درخواست‌ها و پاسخ‌ها با HMAC-SHA256 و یک salt هش می‌شوند؛ بنابراین می‌توانید مقداری را که از قبل می‌دانید با لاگ تطبیق دهید، بدون اینکه خودِ لاگ حاوی متن ساده (plaintext) باشد. اعداد صحیح و مقادیر بولی به‌صورت شفاف (cleartext) نوشته می‌شوند، بنابراین یک secret عددی از این هش‌سازی محافظتی دریافت نمی‌کند.

سپس یک تله عملیاتی وجود دارد: OpenBao زمانی که هیچ دستگاه حسابرسی فعالی نتواند درخواست‌ها را ثبت کند، به آن‌ها پاسخ نمی‌دهد و دستگاهی که به‌صورت مسدودکننده (blocking) دچار خطا شود، باعث می‌شود درخواست‌ها تا زمانی که مشکل رفع نشود، معلق بمانند. پر شدن دیسک در مسیر /var/log طبق طراحی، API مربوط به secretهای شما را از دسترس خارج می‌کند. از همان روز اول، برای لاگ حسابرسی فضای اختصاصی در نظر بگیرید و یک قانون logrotate تنظیم کنید؛ نه پس از وقوع اولین قطعی.

کدام مدیریت‌کننده اسرار (secrets manager) خودمیزبان را باید اجرا کنید؟

تعداد ماشین‌ها و افراد را بشمارید، سپس انتخاب کنید.

  1. یک ماشین، یک نفر: یک فایل env با دسترسی 600 که مالک آن root است و توسط یک کاربر سرویس خوانده می‌شود. زمانی که می‌خواهید مقدار را از محیط پردازش خارج کنید، از systemd credentials استفاده کنید.
  2. یک ماشین، دو تا پنج نفر، پیکربندی از قبل در git موجود است: از SOPS به همراه age استفاده کنید. هر فرد یک جفت کلید دریافت می‌کند و .sops.yaml تمام کلیدهای عمومی مجاز برای رمزگشایی را لیست می‌کند.
  3. چندین ماشین، یک مخزن پیکربندی، بدون نیاز به اعتبارنامه‌های دارای تاریخ انقضا: همچنان از SOPS به همراه age استفاده کنید، با یک کلید گیرنده برای هر میزبان؛ به این ترتیب، سرقت کلید یک میزبان تنها منجر به رمزگشایی فایل‌های همان میزبان می‌شود.
  4. چندین ماشین و چندین تیم که واقعاً به اعتبارنامه‌های پایگاه داده با طول عمر مشخص نیاز دارند، به علاوه یک مسیر حسابرسی (audit trail) که توسط شخصی بررسی می‌شود: از OpenBao استفاده کنید و در بودجه خود، ماهیانه یک ساعت زمان اپراتور برای بازگشایی (unseal) و تمرین‌های بازیابی در نظر بگیرید.

قانون حاکم بر هر چهار مورد یکسان است. کوچک‌ترین ابزاری را اجرا کنید که نیازی را که می‌توانید به زبان بیاورید، برآورده کند؛ زیرا یک مدیریت‌کننده اسرار که از دسترس خارج شده، از یک مدیریت‌کننده اسرار خالی غیرقابل تشخیص است.

FAQ

آیا استفاده از یک secrets manager شخصی‌سازی‌شده (self-hosted) برای یک VPS تکی ارزشش را دارد؟

معمولاً خیر، اگر منظور شما سرویسی مانند OpenBao یا Infisical باشد. روی یک سرور با یک یا دو کاربر، یک فایل env با دسترسی 600 یا استفاده از قابلیت encrypted credential در systemd، همان سطح محافظت در برابر سایر کاربران محلی را فراهم می‌کند، بدون اینکه نیاز به مرحله unseal داشته باشد یا سرویس اضافه‌ای برای وصله‌کردن (patch) ایجاد کند. یک سرویس مدیریت اسرار زمانی توجیه اقتصادی پیدا می‌کند که چندین ماشین و چندین کاربر داشته باشید، یا نیاز واقعی به اعتبارنامه‌هایی داشته باشید که بدون دخالت دستی، منقضی شوند.

تفاوت بین یک password manager و یک secrets manager چیست؟

یک password manager اعتبارنامه‌هایی را ذخیره می‌کند که یک انسان تایپ می‌کند و در حضور او بازگشایی می‌شود. یک secrets manager اعتبارنامه‌ها را به پردازش‌ها ارائه می‌دهد، بنابراین باید در ساعت 03:00 صبح و بدون حضور هیچ ناظری کار کند. نتیجه این تفاوت، مرز بین آن‌هاست: یک password manager قفل‌شده از شما می‌خواهد رمز عبور اصلی را دوباره وارد کنید، اما یک secrets manager قفل‌شده (sealed) باعث توقف تمام سرویس‌هایی می‌شود که هنگام قفل بودن آن، ری‌استارت می‌شوند.

اگر OpenBao پس از reboot قفل (sealed) شود، چه اتفاقی برای برنامه‌های من می‌افتد؟

برنامه‌ها نمی‌توانند اسرار خود را دریافت کنند، بنابراین در شروع کار شکست می‌خورند و systemd آن‌ها را به‌صورت حلقه‌ای ری‌استارت می‌کند تا زمانی که شخصی حد نصاب unseal را تأمین کند، که به‌صورت پیش‌فرض 3 از 5 سهم (share) است. OpenBao کلید ریشه را فقط در حافظه نگه می‌دارد، بنابراین هر بار ری‌استارت، آن را دوباره قفل می‌کند. یا قابلیت auto unseal را فعال کنید (با پذیرش این واقعیت که در یک VPS تکی، کلید unseal روی همان دیسکی قرار می‌گیرد که داده‌ها هستند)، یا در زمان deploy، اسرار را به یک فایل تبدیل کنید تا بالا آمدن سیستم هرگز به API وابسته نباشد.

آیا می‌توانم فایل‌های رمزنگاری‌شده با SOPS را در یک مخزن عمومی (public repository) commit کنم؟

مقادیر رمزنگاری شده‌اند، بنابراین از دسترسی هر کسی که کلید خصوصی age را ندارد، در امان هستند. کلیدها رمزنگاری نشده‌اند: یک خواننده می‌تواند ببیند که شما STRIPE_SECRET_KEY و SMTP_PASSWORD را دارید و هر کدام چند وقت یک‌بار تغییر می‌کنند. این متادیتا برای اکثر پروژه‌ها قابل‌قبول و برای تعداد کمی غیرقابل‌قبول است. کلید خصوصی age را خارج از مخزن نگه دارید و هر زمان که گیرنده‌ای را اضافه یا حذف می‌کنید، sops updatekeys را روی تمام فایل‌های موجود اجرا کنید.