← شروع آموزش

WIUNIX ACADEMY

راه‌اندازی رجیستری خصوصی Docker با HTTPS و Nginx

صفحهٔ 3 از 5؛ مراحل قبلی و پیش‌نیازها را پیش از ادامه مرور کن.

آموزش متناسب با محیط تو

کجا اجرا می‌کنی؟

سیستم‌عامل و نسخه را انتخاب کن تا مراحل، دستورها و راه‌حل‌ها برای همان محیط نمایش داده شوند.

Ubuntu 26.10بررسی‌شده با مستندات رسمی ·

آموزش متناسب با مقادیر تو

تنظیمات این آموزش

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

آی‌پی، دامنه یا پورت مثال‌ها با محیط تو فرق دارد؟ دکمهٔ زیر را باز کن، مقادیر را تغییر بده و «اعمال در آموزش» را بزن؛ سپس دستورهای به‌روز‌شده را کپی کن.

تنظیم مقادیر برای محیط من8 مقدار قابل‌تغییر
08

قدم بعدی

گواهی معتبر موجود را در مسیر محافظت‌شده بگذارید

با روش امن انتقال یا ویرایشگر root، زنجیرهٔ گواهی معتبر موجود و کلید سرویس را در دو فایل زیر قرار دهید. هر دو باید فایل واقعی و متعلق به root باشند؛ کلید 0600، پوشهٔ TLS برابر 0700 و زنجیرهٔ عمومی 0644 باشد. کلید را در فرم مرورگر وارد نکنید و برای رفع خطای اعتماد، گواهی عمومی خودامضا نسازید.

bash

VM رجیستری

sudo python3 - <<'PY'
import os
for name in ('fullchain.pem','privkey.pem'):
    f='/srv/academy-registry/tls/'+name
    fd=os.open(f,os.O_WRONLY|os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW,0o600)
    os.close(fd)
PY
sudo nano '/srv/academy-registry/tls/fullchain.pem' '/srv/academy-registry/tls/privkey.pem'
sudo chmod 0644 '/srv/academy-registry/tls/fullchain.pem'
از کجا بدانم درست انجام شد؟

فایل‌های خالی با زنجیره و کلید معتبر پر شده‌اند؛ کلید خصوصی نمایش داده نمی‌شود.

09

قدم بعدی

نام دامنه، انقضا و تطبیق کلید را کنترل کنید

این کنترل‌ها نام دامنه، باقی‌ماندن حداقل هفت روز اعتبار و برابر بودن کلید عمومی را بررسی می‌کنند؛ اعتماد تمام کلاینت‌ها را ثابت نمی‌کنند. پس از فعال‌کردن HTTPS، اتصال را از کلاینت تمیز هم بسنجید. در تمدید، فقط موفقیت ابزار صدور کافی نیست؛ گواهی واقعاً سرو‌شده پس از reload را نیز بررسی کنید.

bash

VM رجیستری

sudo openssl x509 -in '/srv/academy-registry/tls/fullchain.pem' -noout -checkhost 'registry.example.net'
sudo openssl x509 -in '/srv/academy-registry/tls/fullchain.pem' -noout -checkend 604800
sudo python3 - <<'PY'
import subprocess
base='/srv/academy-registry/tls/'
a=subprocess.check_output(['openssl','x509','-in',base+'fullchain.pem','-pubkey','-noout'])
b=subprocess.check_output(['openssl','pkey','-in',base+'privkey.pem','-pubout'])
assert a==b, 'Certificate and private key do not match'
print('Public-key match: OK')
PY
از کجا بدانم درست انجام شد؟

نام و زمان اعتبار درست است و دو کلید عمومی تطبیق دارند.

10

قدم بعدی

Nginx را اعتبارسنجی و HTTPS را فعال کنید

فایل سایت باید تازه باشد. اگر تست syntax شکست بخورد، فقط همین فایل به recovery منتقل می‌شود و تنظیمات جاری سرویس اجراشده تغییر نمی‌کند. شکست reload را بررسی و فایل تازه را برگردانید؛ restart سرویس‌های دیگر راه‌حل نیست. بازکردن TCP443 باید طبق سیاست شبکهٔ خودتان انجام شود؛ این دستورها فایروال را عوض نمی‌کنند.

پاسخ سالم بدون ورود، 401 همراه Basic challenge و هدر registry/2.0 است. پاسخ 200 بدون رمز برای این طراحی خطای امنیتی محسوب می‌شود. مسیر /v2/ را به صفحهٔ ورود مرورگری یا SSO ریدایرکت نکنید.

bash

VM رجیستری

set -eu
sudo test ! -e '/etc/nginx/conf.d/academy-registry.conf'
sudo test ! -L '/etc/nginx/conf.d/academy-registry.conf'
sudo python3 - <<'PY'
import os,stat
from pathlib import Path
src=Path('/srv/academy-registry/config/nginx.conf')
assert stat.S_ISREG(src.lstat().st_mode) and src.stat().st_uid==0
fd=os.open('/etc/nginx/conf.d/academy-registry.conf',os.O_WRONLY|os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW,0o644)
with os.fdopen(fd,'wb') as out: out.write(src.read_bytes())
os.chmod('/etc/nginx/conf.d/academy-registry.conf',0o644)
PY
if sudo nginx -t; then
  sudo systemctl reload nginx
else
  sudo mv '/etc/nginx/conf.d/academy-registry.conf' '/srv/academy-registry/recovery/failed-nginx.conf'
  exit 1
fi
curl --silent --show-error --dump-header - --output /dev/null 'https://registry.example.net/v2/'
از کجا بدانم درست انجام شد؟

تست و reload موفق‌اند و HTTPS معتبر بدون رمز، challenge و 401 می‌دهد.

11

قدم بعدی

ورود Docker را با helper انجام دهید

روی کلاینت لینوکسی و با کاربر عادی اجرا کنید. pass، کلید GPG و helper رسمی باید از قبل آماده باشند. پوشهٔ تازهٔ کلاینت فقط نگاشت helper را در JSON می‌نویسد؛ رمز را در درخواست تعاملی خصوصی Docker وارد کنید. اگر helper یا اعتماد گواهی مشکل دارد، همان را رفع کنید و ذخیرهٔ رمز در JSON را جایگزین نکنید.

bash

کلاینت لینوکسی

set -eu
command -v docker-credential-pass
pass ls >/dev/null
python3 - <<'PY'
import json, os
from pathlib import Path
p=Path.home()/'.config'/'academy-registry-client'
assert not p.is_symlink() and not p.exists(), 'Choose a fresh client directory'
p.parent.mkdir(mode=0o700,exist_ok=True)
assert not p.parent.is_symlink()
p.mkdir(mode=0o700)
f=p/'config.json'
with f.open('x',encoding='utf-8') as out:
    json.dump({'credHelpers':{'registry.example.net':'pass'}},out)
os.chmod(f,0o600)
print('Only helper routing written; no password in JSON')
PY
docker --config "$HOME/.config/academy-registry-client" login 'registry.example.net' --username 'academy-publisher'
از کجا بدانم درست انجام شد؟

ورود موفق است و JSON فقط مسیر helper دارد، نه رمز یا auth ذخیره‌شده.

12

قدم بعدی

یک ایمیج آزمایشی بدون اطلاعات حساس push کنید

کلاینت در پوشه‌ای تازه ایمیج کوچکی با یک فایل متنی می‌سازد. این ایمیج scratch برنامهٔ اجرایی ندارد و فقط برای انتقال است. digest نهایی manifest را در رکورد غیرمحرمانه ثبت کنید. از ایمیج حاوی کلید، رمز یا دادهٔ واقعی برای آزمون استفاده نکنید.

bash

کلاینت لینوکسی

set -eu
test ! -e "$HOME/academy-registry-image"
mkdir -m 0700 "$HOME/academy-registry-image"
printf 'WIUNIX Academy registry pilot\n' > "$HOME/academy-registry-image/marker.txt"
printf 'FROM scratch\nCOPY marker.txt /marker.txt\n' > "$HOME/academy-registry-image/Dockerfile"
docker --config "$HOME/.config/academy-registry-client" build \
  --tag 'registry.example.net/academy/academy-registry:pilot' "$HOME/academy-registry-image"
docker --config "$HOME/.config/academy-registry-client" push 'registry.example.net/academy/academy-registry:pilot'
از کجا بدانم درست انجام شد؟

push کامل می‌شود و digest نهایی sha256 نمایش داده می‌شود.

13

قدم بعدی

pull را از کلاینت مستقل بسنجید

روی کلاینت دوم که این ایمیج را ندارد، ابتدا helper و ورود را جدا آماده و سپس pull کنید. RepoDigest باید با digest ثبت‌شدهٔ push برابر باشد. کش کلاینت اول شاهد کافی نیست. برای استقرار، مرجع شامل digest ثبت‌شده را به کار ببرید؛ برابری digest به‌تنهایی ایمنی یا اصالت ناشر را ثابت نمی‌کند.

bash

کلاینت لینوکسی

docker --config "$HOME/.config/academy-registry-client" pull 'registry.example.net/academy/academy-registry:pilot'
docker image inspect 'registry.example.net/academy/academy-registry:pilot' --format '{{json .RepoDigests}}'
از کجا بدانم درست انجام شد؟

ایمیج روی کلاینت تمیز دریافت می‌شود و digest با رکورد push برابر است.

همهٔ آموزش‌های آکادمی ↗