NixOS और secrets
(isabelroses.com)- अगर NixOS में secrets को Nix config, private Git repository, या
git-cryptमें plaintext के रूप में रखा जाए, तो Nix store सभी के लिए readable होने की वजह से मशीन एक्सेस रखने वाला कोई भी व्यक्ति secrets पढ़ सकता है - sops-nix
.sops.yamlrules औरsopsediting flow के साथ secret files को encrypt करता है, और activation के समय host SSH key से decrypt करके plaintext को/run/secrets/<name>के tmpfs में रखता है - agenix
secrets.nixमें हर secret के लिए recipient public keys तय करता है और.agefiles को/run/agenix/<name>के tmpfs में decrypt करता है; नया host जोड़ने या key rotate करने पर rekeying करनी पड़ती है - filesystem पर secrets को सीधे रखना single server या laptop पर संभव है, लेकिन अगर
builtins.readFile "/var/lib/myservice/token"की तरह evaluation time पर पढ़ा जाए तो value Nix store में चली जाती है, इसलिए इससे बचना चाहिए - अगर आप अभी शुरुआत कर रहे हैं और केवल कुछ independent tokens हैं, तो agenix में steps कम हैं; लेकिन mail server जैसे host पर जहाँ कई related secrets हों, वहाँ कई values को एक file में bundle करने वाला sops-nix ज्यादा उपयुक्त है
NixOS में secrets संभालते समय मूल जोखिम
- NixOS में secret management को मोटे तौर पर
sops-nix,agenix/ragenix, filesystem का उपयोग, private Git repository,git-crypt, और सीधे Nix config में लिखने जैसी विधियों में बाँटा जा सकता है - private Git repository,
git-crypt, और सीधे Nix config में secrets लिखने वाली विधियाँ तब इस्तेमाल नहीं करनी चाहिए जब मशीन shared हो या config को public करने की योजना हो- Nix store सभी के लिए readable है, इसलिए मशीन तक पहुँच रखने वाला कोई भी व्यक्ति secrets पढ़ सकता है
- यह जोखिम खास तौर पर तब महत्वपूर्ण है जब CVE-2026-31431(copyfail) और CVE-2026-43284 तथा CVE-2026-43500(dirtyfrag) जैसी vulnerabilities मौजूद हों
- public configs में secrets कम-से-कम दो बार leak हुए हैं, और उदाहरण 1, 2 में देखे जा सकते हैं
sops-nix
- sops-nix पहली बार देखने पर configure करना मुश्किल लग सकता है, लेकिन इसकी documentation में काफी सुधार हुआ है और
sopsमें SSH keys के साथ secret encryption/decryption का built-in support एक बड़ा सुधार है - हालांकि,
sops-nixअभी इस SSH key support में पीछे है और sops-nix#779, sops-nix#922 में इस पर काम चल रहा है - इसका workflow
.sops.yamlमें encryption/decryption rules बनाना औरsopscommand से secret files edit करना है- उदाहरण के तौर पर
secrets/*.yamlpath के लिएagerecipients के रूप में SSH public keys तय की जाती हैं sops secrets/shush.yamlचलाने पर आपका चुना हुआ editor खुलता है, जहाँhello: sopsजैसी YAML values लिखी जा सकती हैं- editor बंद करते ही values
ENC[AES256_GCM,...]जैसे रूप में encrypt हो जाती हैं, और उसी command से फिर से edit की जा सकती हैं
- उदाहरण के तौर पर
- NixOS config में
sops-nixmodule ज़्यादातर काम संभाल लेता हैdefaultSopsFile = ./secrets/shush.yaml;से default secret file तय होती हैage.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];से host SSH key तय की जाती हैsecrets."hello"मेंowner,group,modeदेकर file permissions सेट की जा सकती हैं
- activation के समय
sops-nixhost की SSH key से file को decrypt करता है और plaintext को/run/secrets/<name>में रखता है- यह path tmpfs पर होता है, इसलिए secrets disk तक नहीं पहुँचते
- जिस service को value चाहिए, वह बस उस path को पढ़ सकती है
- template feature shared configs या दूसरे users द्वारा refer की जाने वाली settings में उपयोगी है
- जब service config file में plaintext और कुछ secrets साथ चाहिए हों, तब पूरी file को encrypt करने की ज़रूरत नहीं होती
- उदाहरण के लिए
SMTP_USER=isabelplaintext रह सकता है, औरSMTP_PASSWORD=${config.sops.placeholder."mailserver/smtp_password"}की तरह secret placeholder डाला जा सकता है
agenix
- agenix
sops-nixसे अलगsecrets.nixमें secrets और accessible keys को configure करता है, इसलिए इसका अनुभव Nix के ज्यादा करीब लगता है secrets.nixमें users और hosts की SSH public keys bind की जाती हैं, और हर.agefile के लिए तय किया जाता है कि किन public keys को access मिलेगा- उदाहरण के लिए
"secret1.age".publicKeys = [ isabel host1 ];,"secret2.age".publicKeys = [ isabel host2 ];जैसी per-secret recipient lists बनाई जा सकती हैं
- उदाहरण के लिए
- secret files
agenixCLI से बनानी पड़ती हैंagenix -e secret1.agecommand सेsecret1.ageबनाई जा सकती है या बाद में फिर edit की जा सकती है
- इसे host config से जोड़ने का तरीका
sops-nixजैसा है, लेकिन हर secret अलग file में होने से surface area छोटा रहता हैage.secrets.secret1.file = ./secrets/secret1.age;से file तय की जाती हैowner,group,modeसे ownership और permissions सेट की जाती हैं
- boot पर host की SSH key से हर
.agefile decrypt होकर/run/agenix/<name>में रखी जाती है- यह path भी tmpfs पर होता है
- सबसे आम अटकने वाली चीज़ rekeying है
- नया host जोड़ने या key बदलने पर
secrets.nixमें जिन secrets कीpublicKeyslist बदली है, उन सबको फिर से encrypt करना पड़ता है agenix --rekeyयह काम करता है, लेकिन मौजूदा ciphertext पढ़ने के लिए वर्तमान recipients में से किसी एक की private key चाहिए होती है- व्यवहार में, rekeying उस नए host पर नहीं बल्कि आपके सबसे trusted machine पर की जाती है
- नया host जोड़ने या key बदलने पर
केवल filesystem इस्तेमाल करने का तरीका
- filesystem पर सीधे secrets रखने की कीमत यह है कि config अब मशीन को पूरी तरह describe नहीं करती
- reinstall के समय सभी files को सही location और ownership के साथ फिर से रखना पड़ता है
- recovery के काम में, जैसे रात 2 बजे server restore करना हो, यह बड़ी मुसीबत बन सकता है
- जिस pattern से बचना चाहिए वह
builtins.readFile "/var/lib/myservice/token"जैसा है- यह तरीका file को evaluation time पर पढ़ता है और उसका content Nix store में शामिल कर देता है
- चूँकि Nix store सभी के लिए readable है, यह ठीक वही failure mode बन जाता है जिसकी शुरुआत में चेतावनी दी गई थी
- इसकी जगह service को value नहीं बल्कि path देना चाहिए
- उदाहरण के लिए services.*.environmentFiles जैसे options इस्तेमाल किए जा सकते हैं
- single server या laptop पर यह ठीक हो सकता है, लेकिन अगर आपके पास fleet है या आप केवल config से शुरू से rebuild करना चाहते हैं, तो
sops-nixयाagenixज्यादा उपयुक्त हैं - जब हर मशीन पर केवल एक-दो ऐसे values हों जिन्हें सचमुच repository में नहीं रखना चाहिए, तब यह तरीका चल सकता है, लेकिन बाद में उन्हें फिर से डालने की ज़िम्मेदारी भविष्य के अपने ऊपर ही आएगी
sops-nix और agenix की तुलना
sops-nixचुनने की मुख्य वजह यह है कि यह ज़्यादा-से-ज़्यादा data को एक file में bundle करने देता है- mail server जैसे मामलों में, जहाँ related secrets बहुत हों,
agenixकी तरह लगभग 5 अलग files में बाँटने के बजाय एक file में अधिक secrets रखे जा सकते हैं - यह एक powerful tool है जिसे लंबे समय तक इस्तेमाल किया जा सकता है, और mail server जैसे ऐसे hosts के लिए पहले विकल्प के रूप में देखा जा सकता है जहाँ secrets बहुत ज़्यादा हों
- mail server जैसे मामलों में, जहाँ related secrets बहुत हों,
agenixकी ताकत simplicity है- सीखने के लिए कोई YAML schema नहीं है
- sync करने के लिए कोई
.sops.yamlनहीं है secrets.nixसाधारण Nix है, इसलिए hosts और users के लिए इस्तेमाल होने वालेlet ... inbindings को keys पर भी वैसे ही लागू किया जा सकता है- इसका mental model है “एक secret, एक file, एक recipient list”, जो access control के तरीके से अच्छी तरह मेल खाता है
- moving parts सबसे कम होने के बावजूद यह host-wise key access control देता है, इसलिए NixOS machines पर secret management के बारे में पहली बार पूछने वालों को recommend करने के लिए यह एक अच्छा विकल्प है
- दोनों tools समस्या हल करते हैं, और फिलहाल अंतर ज़्यादातर usability का है
- अगर आप शुरुआत कर रहे हैं और कई services को related secrets के bundles चाहिए, तो
sops-nixबेहतर scale करता है - अगर आप शुरुआत कर रहे हैं और ज़्यादातर केवल कुछ independent tokens हैं, तो
agenixकम steps में काम पूरा कर देता है - अगर पहला secret tool चुनना हो, तो
agenixसे workflow की आदत डालना बेहतर है, और जब “एक secret per file” वाला तरीका वास्तव में असुविधाजनक लगे तबsops-nixपर जाना ठीक रहेगा
- अगर आप शुरुआत कर रहे हैं और कई services को related secrets के bundles चाहिए, तो
- quantum resistance से जुड़ी जानकारी को corrected किया गया है
1 टिप्पणियां
Lobste.rs की राय
क्या encrypted secret और उसकी key दोनों ही डिस्क पर नहीं होते? या इनमें से कोई एक TPM जैसी किसी जगह पर स्टोर होता है?
मैंने अभी-अभी Nix इस्तेमाल करना शुरू किया है, और छोटे self-hosting deployment में सादगी के लिए
scpसे filesystem में फ़ाइल डालने का तरीका इस्तेमाल कर रहा हूँथोड़ा खोजने पर लगा कि SSH private key को TPM से सुरक्षित किया जा सकता है, और मैं सोच रहा था कि क्या यह VM में भी संभव है; फिर vTPM सपोर्ट हो सकता है, यह देखकर लगा कि जवाब खुद ही मिल गया
सर्वर साइड पर NixOps जैसा access भी है। Colmena इसे कैसे करता है, वह देख सकते हैं: https://colmena.cli.rs/0.4/features/keys.html
मुख्य बात यह है कि secrets रखने वाली trusted machine उन्हें remote server पर push करती है। यह अभी
scpसे जो आप कर रहे हैं, उसके जैसा है, बस उस प्रक्रिया को ज़्यादा Nix-style में चलाता हैपिछले कुछ रातों में मैंने अपने system flake में agenix परिवार की चीज़ें फिर से सेट की हैं, इसलिए मैं सिर्फ agenix के बारे में ही बोल सकता हूँ। जिसे दिलचस्पी हो, उसके लिए मैंने agenix-rekey चुना, क्योंकि इसमें secrets वाली
.ymlfiles रखने की ज़रूरत नहीं होती और पहले से किए गए सेटअप की तरह सभी secrets को सीधे Nix के अंदर define किया जा सकता हैencrypted secrets Nix store में रहते हैं, और Nix store की बाकी चीज़ों की तरह globally readable होते हैं। उन secrets को खोलने वाली SSH private key आमतौर पर असली SSH server की private key होती है, हालाँकि चाहें तो ऐसा न भी करें। secrets activation के समय, लगभग boot के समय, डिक्रिप्ट होकर
/run/agenix/<user>में रखे जाते हैंsecrix नाम का एक टूल इससे भी आगे जाता है और secrets को systemd services से बाँधता है, फिर उन services को उन services से जोड़ता है जिन्हें secrets की ज़रूरत होती है। इसलिए secret सिर्फ उसी समय डिक्रिप्ट होता है जब वह service चल रही हो। हालाँकि व्यवहार में NixOS उपयोगकर्ता services को बार-बार start/stop कम ही करते हैं, इसलिए इसका मतलब अक्सर यह हो जाता है कि वे ज़्यादातर समय चलती रहती हैं। user creation जैसे system activation secrets के लिए यह सही हो सकता है
agenix-rekey rekeying को कम झंझट वाला बनाता है, और
secrets.nixकी जगह flake outputs दे देता है। key के एक आधे हिस्से के लिए यह YubiKey split identity का इस्तेमाल करता है। rekeying की प्रक्रिया यह है कि उस key और दूसरे आधे से authenticate करके secrets को डिक्रिप्ट किया जाए, फिर सर्वर की SSH public key से दोबारा key किया जाए। public key system install के समय बनाई जाती है, और मैं nixos-anywhere में--copy-host-keysइस्तेमाल करके install closure में बनी keys ले आता हूँ। encrypted secrets को मैं repository में रखता हूँ, लेकिन एक अलग submodule में, जहाँ सिर्फ trusted builders की पहुँच होती हैवैसे vTPM आम तौर पर hardware-based नहीं होता, और कई providers TPM देने पर भी ज़्यादातर TPM v2 नहीं बल्कि TPM v1.2 ही देते हैं। मेरा provider BinaryLane भी ऐसा ही है। यह सच है कि इससे security की एक अतिरिक्त layer मिलती है, लेकिन यह किसी असली HSM जैसा जादुई समाधान नहीं है, और provider या host node compromise से सुरक्षा नहीं देता। असली HSM-backed vTPM देना provider के लिए काफ़ी महँगा होगा, और AWS शायद इसे AWS वाली कीमत पर देता है
agenix+agenix-rekey+age-plugin-1pइस्तेमाल करता हूँmaster key 1Password में है, इसलिए मैं अपने laptop की डिस्क पर कोई credentials रखे बिना किसी भी server का password edit, देख, और rekey कर सकता हूँ
जिन servers को runtime key access चाहिए, उन्हें access दिया जा सकता है। agenix-rekey को बता दीजिए कि कौन-सा server कौन-सी key देख सकता है और
agenix rekeyचलाइए, फिर उस server द्वारा डिक्रिप्ट की जा सकने वाली encrypted key version Nix store में लिख दी जाती है। उस server की SSH private key सिर्फ उसी server पर रहती है और कभी बाहर नहीं जाती। agenix-rekey को rekeying के लिए सिर्फ public key चाहिएइसलिए secrets के लीक होने की स्थिति या तो मेरे 1Password account के hack होने पर बनेगी, या फिर उस server के hack होने पर जो उस secret का इस्तेमाल करता है
/etc/ssh/ssh_host_ed25519_keyसे डिक्रिप्ट किया जाता है, फिर उन्हें/run/agenix.dपर mounted ramfs में रखा जाता हैइसलिए हाँ, encrypted content, encryption key, और decrypted content — तीनों ही filesystem से accessible होते हैं
https://github.com/oddlama/agenix-rekey
ऊपर से, लंबे समय तक चलने वाले credentials भी अब कम होते जा रहे हैं। मैं long-lived credentials की copy से दूर जाकर hardware-based credentials की ओर बढ़ रहा हूँ, और या तो उन्हें सीधे इस्तेमाल करने या उन्हें short-lived credentials से exchange करने की दिशा में जा रहा हूँ