WIUNIX ACADEMY
چرخش کلید در SOPS و age؛ گیرنده، کلید داده و دسترسی بازیابی
صفحهٔ 2 از 4؛ قبل از ادامه، مراحل قبلی و چیزهایی رو که لازم داری مرور کن.
آموزش متناسب با محیط تو
کجا اجرا میکنی؟
سیستمعامل و نسخهٔ سرورت رو انتخاب کن تا مراحل، دستورها و راهحلهای همون محیط رو ببینی.
آموزش متناسب با مقادیر تو
تنظیمات این آموزش
مقادیر نمونه رو با مشخصات سرورت عوض کن تا متن و دستورها با هم تغییر کنن. رمز، کلید خصوصی و توکن اینجا وارد نکن. مقدارها فقط توی همین زبانه میمونن و به سرور یا لینک اشتراکگذاری فرستاده نمیشن. قبل از اجرا، DNS، گواهیها و تنظیمات دسترسی شبکه رو روی سرورت بررسی کن.
اگر آیپی، دامنه یا پورتهای نمونه با سرورت فرق دارن، بخش تنظیمات پایین رو باز کن. مقدارها رو عوض کن و «اعمال در آموزش» رو بزن؛ بعد دستورهای تازه رو کپی کن.
تنظیم مقادیر برای محیط من2 مقدار قابلتغییر
قدم بعدی
اول ناشر checksum و بعد خود باینری SOPS رو تأیید کنیم
Cosign بستهٔ امضای checksum رو با صادرکنندهٔ GitHub OIDC و هویت مخزن getsops/sops بررسی میکنه. بعد فقط مدخل همان باینری دانلودشده رو انتخاب و SHA256 آن رو تطبیق میدیم. نبودن یا تکراریبودن این مدخل، پنل رو متوقف میکنه؛ موفقیت بررسی یک فایل نامرتبط کافی نیست.
اگر امضا، هویت، صادرکننده یا digest ناسازگار بود، خطا رو نگه دار و ادامه نده. برای موفق نشاندادن بررسی، کنترل امضا یا transparency رو خاموش نکن. اول مشکل ابزار معتبر یا دسترسی شبکه رو حل کن.
همان نشست Bash با حساب عادی در محیط مدیریت آزمایشی جدا
cosign verify-blob sops-v3.13.3.checksums.txt \
--bundle sops-v3.13.3.checksums.sigstore.json \
--certificate-identity-regexp='^https://github.com/getsops/sops/' \
--certificate-oidc-issuer=https://token.actions.githubusercontent.com || exit 1
awk -v file="$sops_artifact" '$2==file {print; n++} END {if(n!=1) exit 1}' sops-v3.13.3.checksums.txt > sops-selected.sha256 || exit 1
sha256sum --check sops-selected.sha256 || exit 1ناشر موردنظرِ checksum و digest دقیق همان باینری SOPS با موفقیت تأیید شدن.
قدم بعدی
مدرک Sigsum آرشیو age رو بررسی کنیم
دو خط پایین کلید عمومیِ بررسی ناشر از SIGSUM.md همان نسخهٔ age هستن، نه identity رمزگشایی. آنها رو با مرجع رسمی و روال اعتماد تیم تطبیق بده. Sigsum امضا و ثبتشدن مدرک آرشیو رو با سیاست اعتماد نامبرده بررسی میکنه؛ SHA256 بعدی فقط اثرانگشت مدرک محلیه و امضای مستقل ناشر نیست.
اگر verifier مورد اعتماد این سیاست رو نمیشناسه یا proof خطا داد، توقف کن. این کلیدهای عمومی رو با کلیدی که از خود آرشیو تأییدنشده گرفتهای جایگزین نکن.
همان نشست Bash با حساب عادی در محیط مدیریت آزمایشی جدا
cat > age-sigsum-key.pub <<'PUBLIC_KEYS'
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM1WpnEswJLPzvXJDiswowy48U+G+G1kmgwUE2eaRHZG
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAz2WM5CyPLqiNjk7CLl4roDXwKhQ0QExXLebukZEZFS
PUBLIC_KEYS
sigsum-verify -k age-sigsum-key.pub -P sigsum-generic-2025-1 "$age_archive.proof" < "$age_archive" || exit 1
sha256sum "$age_archive"proof آرشیو با کلیدهای ناشر و سیاست مصوب Sigsum تأیید شده و digest مدرک محلی ثبت میشه.
قدم بعدی
فقط فایل اجرایی خصوصی و تأییدشده رو آماده کنیم
فهرست آرشیو age تأییدشده رو ببین و فقط دو فایل اجرایی نامبرده رو استخراج کن. SOPS و age رو در bin خصوصی همین تمرین میذاریم؛ فایل سیستم، مسیر متعلق به بسته و سرویس دیگری جایگزین نمیشه.
فقط بعد از تأیید، خروجی نسخه رو اجرا کن. باید همان دو release مشخص دیده بشن و مسیر مطلق ابزارها رو هم نگه داری. این ابزارهای تمرین جدا هستن؛ نه کلاینت production رو ارتقا دادیم و نه هر نسخهٔ آینده رو معتبر اعلام کردیم.
همان نشست Bash با حساب عادی در محیط مدیریت آزمایشی جدا
tar -tzf "$age_archive" || exit 1
tar -xzf "$age_archive" -C "$lab/vendor" --no-same-owner --no-same-permissions age/age age/age-keygen || exit 1
install -m 0755 -- "$sops_artifact" "$lab/bin/sops" || exit 1
install -m 0755 -- "$lab/vendor/age/age" "$lab/bin/age" || exit 1
install -m 0755 -- "$lab/vendor/age/age-keygen" "$lab/bin/age-keygen" || exit 1
sops_bin="$lab/bin/sops"
age_bin="$lab/bin/age"
keygen_bin="$lab/bin/age-keygen"
"$sops_bin" --disable-version-check --version
"$age_bin" --version
"$keygen_bin" --versionابزار خصوصی بعد از موفقیت هر دو روش بررسی upstream، نسخهٔ SOPS 3.13.3 و age/age-keygen 1.3.2 رو گزارش میکنه.
قدم بعدی
identity قدیمی و جدید و بازیابی رو جدا بسازیم
سه identity تازهٔ کلاسیک X25519 رو مستقیم داخل فایل خصوصی میسازیم، نه روی خروجی ترمینال. وقتی age-keygen در فایل مینویسه، recipient عمومی رو چاپ میکنه و گزینهٔ -y هم فایلهای فقطعمومی رو به دست میده. مجوز رو ببین، ولی محتوای کلید خصوصی رو چاپ نکن. identity رو به مرورگر، متغیر پوسته، مخزن یا چت کپی نکن.
این نمونهٔ کلاسیک برای فهم مهاجرت و سازگاریه و ادعای حفاظت پساکوانتومی نداره. age 1.3 کلید hybrid هم داره که مصرفکنندهٔ سازگار و سیاست جداگانهٔ نوع کلید لازم داره. identity واقعی رو باید مسئول واقعی آن بسازه و نگه داره، نه اینکه برای راحتی روی میزبان مشترک ساخته بشه.
همان نشست Bash با حساب عادی در محیط مدیریت آزمایشی جدا
"$keygen_bin" -o "$lab/keys/old.txt" || exit 1
"$keygen_bin" -o "$lab/keys/new.txt" || exit 1
"$keygen_bin" -o "$lab/keys/recovery.txt" || exit 1
"$keygen_bin" -y "$lab/keys/old.txt" > "$lab/keys/old-recipient.txt" || exit 1
"$keygen_bin" -y "$lab/keys/new.txt" > "$lab/keys/new-recipient.txt" || exit 1
"$keygen_bin" -y "$lab/keys/recovery.txt" > "$lab/keys/recovery-recipient.txt" || exit 1
old_recipient=$(cat "$lab/keys/old-recipient.txt")
new_recipient=$(cat "$lab/keys/new-recipient.txt")
recovery_recipient=$(cat "$lab/keys/recovery-recipient.txt")
stat -c '%a %n' "$lab/keys/old.txt" "$lab/keys/new.txt" "$lab/keys/recovery.txt"سه فایل خصوصیِ متفاوت و recipientهای عمومی آنها آمادهاند؛ مجوزها خصوصی است و identity روی صفحه نیومده.
قدم بعدی
فایل کنترل غیرمحرمانه بسازیم و کشف کلید رو محدود کنیم
فایل تمرین فقط مقدار عمومی non-secret-rotation-demo رو داره و اول برای قدیمی و بازیابی رمز میشه. تابع کمکی، SOPS رو با محیط ارثرسیدهٔ خالی، پوشهٔ XDG خالی و فقط فایل identity انتخابشده اجرا میکنه. صرف تنظیم SOPS_AGE_KEY_FILE کافی نیست؛ SOPS ممکنه کلید پیشفرض یا فرمان دریافت کلید رو هم پیدا کنه.
HOME و تنظیمات کاربر رو عوض نمیکنیم. این فایل فقط recipientهای native تازهٔ age رو داره و KMS و plugin و SSH در آن نیستن. قدیمی و بازیابی رو جدا برای رمزگشایی امتحان میکنیم؛ SOPS در همان مسیر عادی، یکپارچگی فایل رو با MAC هم بررسی میکنه. خروجی مستقیم به /dev/null میره تا نه متن رمزگشاییشده روی صفحه بیاد و نه فایل تازهای از آن نوشته بشه.
همان نشست Bash با حساب عادی در محیط مدیریت آزمایشی جدا
with_identity() {
selected_identity=$1
shift
env -i PATH=/usr/bin:/bin LANG=C \
XDG_CONFIG_HOME="$lab/empty-config" \
SOPS_AGE_KEY_FILE="$selected_identity" \
"$sops_bin" "$@"
}
cd "$lab/work" || exit 1
test ! -e "$doc.enc.yaml" || exit 1
cat > .sops.yaml <<POLICY
creation_rules:
- path_regex: ^rotation-demo\.enc\.yaml$
age:
- $old_recipient
- $recovery_recipient
POLICY
printf 'message: non-secret-rotation-demo\n' | \
with_identity "$lab/keys/old.txt" --config "$lab/work/.sops.yaml" \
encrypt --filename-override "$doc.enc.yaml" --input-type yaml --output-type yaml > "$doc.enc.yaml" || exit 1
cp -- "$doc.enc.yaml" "$lab/before-old.enc.yaml" || exit 1
with_identity "$lab/keys/old.txt" decrypt --output /dev/null "$doc.enc.yaml" || exit 1
with_identity "$lab/keys/recovery.txt" decrypt --output /dev/null "$doc.enc.yaml" || exit 1فایل رمزشدهٔ اولیه، با کشف کنترلشدهٔ کلید، جداگانه با قدیمی و بازیابی باز میشه.
قدم بعدی
گیرندهٔ جدید رو اضافه کنیم و راه بازیابی رو نگه داریم
از سه recipient عمومی یک سیاست مخصوص همین فایل میسازیم، آن رو میخونیم و updatekeys رو با identity قدیمی اجرا میکنیم. مسیر صریح config نمیذاره سیاست مخزن والد اتفاقی انتخاب بشه. پیشنهاد تغییر گیرندهها رو بخون و فقط افزودن موردنظر همین تمرین رو تأیید کن.
در این مرحله همان کلید داده رو دوباره برای گیرندهها میپوشونیم؛ کلید داده عوض نشده. ویرایش فایل سیاست بهتنهایی سند رمزشدهٔ موجود رو تغییر نمیده؛ فرمان روی همین فایل این کار رو انجام میده. حلقهٔ کل مخزن یا نوشتن زنده در Git جزو تمرین نیست.
همان نشست Bash با حساب عادی در محیط مدیریت آزمایشی جدا
cd "$lab/work" || exit 1
cat > .sops.yaml <<POLICY
creation_rules:
- path_regex: ^rotation-demo\.enc\.yaml$
age:
- $old_recipient
- $new_recipient
- $recovery_recipient
POLICY
cat .sops.yaml
with_identity "$lab/keys/old.txt" --config "$lab/work/.sops.yaml" updatekeys "$doc.enc.yaml" || exit 1بعد از تغییر بررسیشدهٔ updatekeys، فایل تمرین گیرندهٔ قدیمی، جدید و بازیابی رو داره.