WIUNIX ACADEMY
راهاندازی Vaultwarden با HTTPS، مدیریت محدود و بکاپ هماهنگ
صفحهٔ 4 از 5؛ مراحل قبلی و پیشنیازها را پیش از ادامه مرور کن.
آموزش متناسب با محیط تو
کجا اجرا میکنی؟
سیستمعامل و نسخه را انتخاب کن تا مراحل، دستورها و راهحلها برای همان محیط نمایش داده شوند.
آموزش متناسب با مقادیر تو
تنظیمات این آموزش
مقادیر نمونه را برای محیط خودت تنظیم کن؛ متن و دستورهای مرتبط با هم تغییر میکنند. رمز، کلید خصوصی و توکن وارد نکن. مقادیر فقط در همین زبانه نگهداری میشوند و به سرور یا لینک اشتراکگذاری فرستاده نمیشوند. پیش از اجرا، DNS، گواهیها و سیاست شبکهٔ واقعی را بررسی کن.
آیپی، دامنه یا پورت مثالها با محیط تو فرق دارد؟ دکمهٔ زیر را باز کن، مقادیر را تغییر بده و «اعمال در آموزش» را بزن؛ سپس دستورهای بهروزشده را کپی کن.
تنظیم مقادیر برای محیط من7 مقدار قابلتغییر
بکاپ هماهنگ برای پایگاه داده و فایلها
SQLite ممکن است کنار db.sqlite3، WAL فعال داشته باشد. کپی فایل اصلی هنگام نوشتن میتواند وضعیت ثبتشده را از دست بدهد. API بکاپ SQLite یا فرمان داخلی، پایگاه دادهٔ سازگار میسازد اما همزمانی آن با پیوستها، Sends و تنظیمات را تضمین نمیکند.
اینجا تنها نویسنده متوقف و مجموعهٔ هماهنگ داده، تنظیمات، فایل محرمانه و TLS آرشیو میشود. پایگاه داده و WAL متناظر، پیوستها، Sends موجود و کلیدهای RSA حفظ میشوند. نبود Sends در نصب تازه طبیعی است؛ اگر از قبل داده دارید آن را از قلم نیندازید. cache آیکن ضروری نیست. کلید RSA و config حساساند؛ بکاپ خارج میزبان باید محدود و رمزگذاریشده باشد و کلید بازیابی جدا بماند.
آرشیو روی همان دیسک فقط نقطهٔ بازگشت محلی است. با سامانهٔ بکاپ موجود، نسخهٔ رمزگذاریشده را بیرون میزبان ببرید، بازیابی و checksum را کنترل و تازگی و نگهداری را پایش کنید. توقف سرویس قطعی برنامهریزیشده ایجاد میکند؛ ابتدا sync کاربران را هماهنگ کنید.
قدم بعدی
گرفتن بکاپ با توقف هماهنگ
در بازهٔ نگهداری اجرا کنید. symlink رد میشود، توقف کانتینر کنترل و پوشهٔ بکاپ تازه ساخته میشود؛ آرشیو قبلی جایگزین نمیشود. در پایان همان کانتینر دوباره شروع میشود، حتی اگر آرشیو شکست بخورد. کپی ناموفق را بکاپ قابل بازیابی حساب نکنید.
ماشین اختصاصی Vaultwarden
sudo python3 - <<'PY'
import os,stat,subprocess,tarfile,tempfile,hashlib
from pathlib import Path
r=Path('/srv/academy-vaultwarden');name='academy_vaultwarden'
assert r.resolve()==r and not any(p.is_symlink() for p in r.rglob('*')), 'Symlink refused'
state=subprocess.check_output(['docker','inspect','--format','{{.State.Running}}',name],text=True).strip()
assert state=='true', 'Review unexpected stopped state first'
subprocess.run(['docker','stop','--time','60',name],check=True,stdout=subprocess.DEVNULL)
assert subprocess.check_output(['docker','inspect','--format','{{.State.Running}}',name],text=True).strip()=='false'
dest=Path(tempfile.mkdtemp(prefix='stopped-',dir=r/'backups'));os.chmod(dest,0o700)
archive=dest/'vaultwarden.tar'
try:
fd=os.open(archive,os.O_WRONLY|os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW,0o600)
with os.fdopen(fd,'wb') as out,tarfile.open(fileobj=out,mode='w') as tar:
for item in ('data','config','secrets','tls'): tar.add(r/item,arcname=item,recursive=True)
with archive.open('rb') as source: digest=hashlib.file_digest(source,'sha256').hexdigest()
(dest/'SHA256').write_text(digest+' vaultwarden.tar\n')
os.chmod(dest/'SHA256',0o600)
print('Stopped consistent archive:',archive,'SHA256:',digest)
finally:
subprocess.run(['docker','start',name],check=True,stdout=subprocess.DEVNULL)
PY
آرشیو و checksum تازه ساخته شده و سرویس بازگشته است؛ اتکا به بکاپ پس از انتقال رمزگذاریشده و آزمون بازیابی است.
تمرین بازیابی در مقصد خالی و جدا
checkpoint انتخابشده را در فضای خصوصی تازه روی میزبان ایزوله بازیابی و رمزگشایی کنید. پیش از استخراج، checksum و اعضای tar را کنترل کنید: فقط مسیر نسبی موردانتظار، فایل و پوشهٔ معمولی؛ بدون symlink، hardlink، traversal و بازنویسی. سرویس و دادهٔ اصلی را دستنخورده نگه دارید، مالکیت و مجوزها را برگردانید و ابتدا همان digest را اجرا کنید.
در تمرین، پورت میزبان منتشر نکنید و ایمیل، push و DNS عمومی را وصل نکنید. داده در مقصد خالی مستقل و DOMAIN در تنظیمات خصوصی fixture باشد. بکاپ کاملِ توقفدار، پایگاه داده و WAL متناظر را با هم برمیگرداند؛ خروجی online backup فقط در مقصد تازه و بدون WAL/SHM کهنه بازیابی میشود. این دو روش را مخلوط نکنید و پیوست، Sends، config و RSA متناظر را نگه دارید.
سلامت SQLite، checksum فایلها و ورود، رمزگشایی و sync حساب ساختگی را پیش از تصمیم انتقال کنترل کنید. checksum یا /alive کافی نیست. برای بازگشت از ارتقا، مجموعهٔ کامل پیش از ارتقا را در مقصد تازه برگردانید؛ نسخهٔ قدیمی ممکن است schema جدید را نشناسد. دو نویسنده را به یک پوشه وصل نکنید.
قدم بعدی
عیبیابی بدون افشای اطلاعات
برای 502 سلامت لوپبک، وضعیت کانتینر، مجوز فایل و error log خصوصی را بررسی کنید. 403 مدیریت را با مبدأ واقعی و 203.0.113.10/32 مقایسه کنید و allow همگانی نگذارید. خطای رمزنگاری معمولاً نیازمند بررسی HTTPS و DOMAIN است. در خطای ورود یا sync، نسخهٔ دقیق کلاینت و یادداشت انتشار را ببینید؛ روی دادهٔ مهاجرتیافته downgrade نکنید. log را محلی بخوانید و پیش از اشتراک محرمانهزدایی کنید.
ماشین اختصاصی Vaultwarden
curl --fail --silent --show-error 'http://127.0.0.1:8159/alive'
sudo docker inspect --format '{{.State.Status}} {{.State.ExitCode}}' 'academy_vaultwarden'
sudo nginx -t
sudo stat -c '%a %u:%g %n' '/srv/academy-vaultwarden/data' '/srv/academy-vaultwarden/secrets/admin.phc'
مرز خطا با سلامت، وضعیت و مجوزها مشخص میشود و هیچ secret dump انجام نمیشود.
قدم بعدی
توقف امن در صورت شکست پذیرش
اگر HTTPS، ثبتنام یا بازیابی پذیرفته نشد، سرویس تازه را متوقف و دادهٔ خصوصی را برای بررسی نگه دارید. پوشهها را حذف و vault واقعی را جایگزین نکنید. فایل پراکسی تازه فقط با حفظ نسخه و تشخیص مالکیت دقیق از include خارج میشود؛ روند بازگشت موجود Nginx را اجرا، اعتبارسنجی و سپس reload کنید. سایتهای دیگر را تغییر ندهید.
ماشین اختصاصی Vaultwarden
sudo docker stop --time 60 'academy_vaultwarden'
sudo docker inspect --format '{{.State.Status}}' 'academy_vaultwarden'
فقط academy_vaultwarden متوقف است و وضعیت خصوصی برای بازیابی حفظ شده است.
شواهد محدود و کارهای آزمودهنشده
۲۸ کنترل ایزوله در کانتینر موقت Debian13 با ایمیج رسمی Vaultwarden1.37.4، وبوالت همراه 2026.7.0، Nginx1.26.3 و Python3.13 گذشت؛ پورت میزبان منتشر نشد. بدنهٔ دقیق Python ساخت پوشه و Argon2 با ورودی مخفی و TTY شبیهسازیشدهٔ fixture اجرا شد. دستورهای پراکسی حفظ شدند و فقط TLS مبتنی بر CA خصوصی، listener لوپبک، مبدأ مجاز و سقف یک مگابایتی برای آزمون محدود تغییر کردند. TLS مورداعتماد و نامعتبر، Host421، رد مدیریت با هدر جعلی و تغییر حروف مسیر، رمز درست و غلط، cookie امن، diagnostics احرازشده، رد sync بدون ورود، بستهبودن ثبتنام و 413 واقعاً بررسی شدند.
آرشیوِ پس از توقف در مقصد خصوصی خالی و مستقل بازیابی شد. فایلهای واقعی SQLite و RSA برنامه، نشانگر ساختگی پایگاه داده و فایلهای ساختگی پیوست و Send دقیقاً برابر ماندند؛ integrity_check گذشت، نسخهٔ بازیابی بالا آمد و رمز مدیریتی موقت قبلی پذیرفته شد. دادهٔ اصلی تغییر نکرد. این شاهد بازیابی ذخیرهسازی و PHC است، نه رمزگشایی یا sync یک vault کاربریِ ساختهشده از API.
انتشار پورت و ریشهٔ فقطخواندنی در Docker Engine، نصب تکتک سیستمها، ورود و رمزگشایی و sync کاربر، SMTP و دعوت، MFA و SSO و passkey، اپ و افزونه، WebSocket101 احرازشده، ACME و تمدید عمومی، رمزگذاری و بازیابی خارج میزبان، systemd و reboot و HA اجرا نشدهاند. فرضهای اولیهٔ fixture دربارهٔ CA، version در API و ثبتنام با پاسخ واقعی اصلاح شدند و سپس ۲۸ کنترل نهایی گذشتند. هیچ حساب، سرویس، رمز، فایروال یا شبکهٔ production تغییر نکرد.