
नया VPS पहले ही घंटे में हार्डन करें
एक पब्लिक IPv4 पता अपने पहले पैकेट के कुछ ही मिनटों के भीतर उन मशीनों द्वारा जाँचा जाने लगता है जिन्होंने आपके बारे में न कभी सुना है, न कभी सुनेंगी। यह अच्छी खबर है: नए सर्वर पर होने वाला लगभग हर हमला सामान्य (generic) होता है, और सोच-समझकर बिताया गया एक घंटा इसमें से लगभग सब कुछ रोक देता है। वही घंटा अगर गलत क्रम में बिताया जाए, तो आपको ऐसी मशीन से बाहर कर देता है जिसमें आपकी जगह कोई और लॉगिन नहीं कर सकता।
पेमेंट क्लियर होने के करीब 47 सेकंड बाद हम आपको root shell थमा देते हैं, और फिर, जान-बूझकर, रुक जाते हैं। हम कोई agent इंस्टॉल नहीं करते, आपका firewall मैनेज नहीं करते, और आपके credentials की कोई कॉपी अपने पास नहीं रखते — जो key हमारे पास होगी, वह वही key है जिसे देने पर हमें मजबूर किया जा सकता है, और यही सिद्धांत पूरे प्लेटफ़ॉर्म में चलता है। नतीजा सीधा है और साफ़ कह देना ज़रूरी है: आपके सर्वर की सुरक्षा वही स्थिति है जिसमें आप उसे पहले घंटे के दौरान छोड़ते हैं।
आगे वही घंटा है, उसी क्रम में जिसमें हम इसे खुद Debian 13 और Ubuntu 24.04 पर चलाते हैं। दो सेटिंग्स ज़्यादातर काम कर देती हैं। इस पेज का बाकी हिस्सा उन तीन चीज़ों की वजह से है जो सही दिखती हैं, हर ट्यूटोरियल की आख़िरी जाँच पास कर जाती हैं, और चुपचाप गलत होती हैं: एक drop-in SSH config जिसे चुपके से override कर दिया जाता है, एक port सेटिंग जिसे socket-activated sshd नज़रअंदाज़ कर देता है, और एक container runtime जो आपके firewall के नीचे से ports पब्लिश कर देता है। इनमें से हर एक ने किसी ऐसे व्यक्ति को काटा है जिसने बाकी सब कुछ सही किया था।
दरवाज़े पर असल में दस्तक कौन दे रहा है
ऐसे सर्वर पर journalctl -u ssh देखें जो एक घंटे से ऑनलाइन है, और जब आप इसे पहली बार देखेंगे तो यह मात्रा चिंताजनक लगेगी। असल में इससे घबराने की ज़रूरत नहीं। जो आप देख रहे हैं वह इंटरनेट का background radiation है: मुट्ठी भर scanning ऑपरेशन — कुछ अकादमिक, कुछ व्यावसायिक, कुछ आपराधिक — जो पूरे IPv4 स्पेस की लगातार गिनती करते हैं और नतीजे credential-guessing bots को थमा देते हैं। आपके पते तक इसलिए पहुँचा गया क्योंकि वह क्रमांक में मौजूद है, और चाहे आप कुछ भी करें, कुछ घंटों में इस तक फिर पहुँचा जाएगा।
इससे समस्या का आकार एक उपयोगी तरीके से बदल जाता है। आप किसी ऐसे विरोधी से नहीं लड़ रहे जिसने आपको चुना हो और जो ढल जाएगा; आप एक ऐसी स्क्रिप्ट से लड़ रहे हैं जिसके पास एक तय भंडार है — root, admin, ubuntu, test, git, oracle, postgres, और वे बीस हज़ार पासवर्ड जो breach dumps में सामने आ चुके हैं। इसमें न धैर्य है, न रचनात्मकता, और न ही उस मशीन में कोई दिलचस्पी जो पहली कोशिश में जवाब न दे। password authentication बंद करने से यह हमलावर धीमा नहीं पड़ता। यह उसे खेल से पूरी तरह बाहर कर देता है।
दो बातें जानने लायक हैं। पहली, IPv6 कहीं ज़्यादा शांत है, क्योंकि /64 को पूरी तरह स्कैन नहीं किया जा सकता — लेकिन जिस पल आपका AAAA रिकॉर्ड सार्वजनिक होता है, या आपकी मशीन का पता किसी mail header या certificate-transparency log में दिख जाता है, यह शांति ख़त्म हो जाती है। IPv6 को कभी छिपने की जगह न मानें; इसे बस एक छोटा-सा haystack मानें। दूसरी, एक IPv4 पते का एक अतीत होता है। आपसे पहले उसका कोई और किरायेदार था, और अगर उसने कोई mail server ख़राब तरीके से चलाया या कुछ ऐसा होस्ट किया जो किसी blocklist में चला गया, तो जब तक वह प्रतिष्ठा धीरे-धीरे घटती नहीं, आप उसे विरासत में पाते हैं। अगर आपके लिए mail मायने रखता है, तो उस पर कुछ बनाने से पहले पते को सामान्य blocklists पर जाँच लें — यह पाँच मिनट की जाँच है जो deliverability डीबग करने में लगने वाला दो हफ़्ते का समय बचा देती है।
वे दो सेटिंग्स जो नब्बे प्रतिशत काम कर देती हैं
किसी छोटे सर्वर का लगभग हर असली compromise दो जगहों में से किसी एक से शुरू होता है: एक ऐसा पासवर्ड जिसका अंदाज़ा लगाया जा सकता था, या एक ऐसी सर्विस जो सुन रही थी और उसे नहीं सुनना चाहिए था। इनके सही जवाब हैं PasswordAuthentication no और डिफ़ॉल्ट drop policy वाला firewall। ये दिखने में साधारण हैं, दोनों मिलाकर पंद्रह मिनट लेते हैं, और इस पेज के बाकी सभी नियंत्रणों को जोड़ने से भी ज़्यादा मूल्यवान हैं।
इसकी वजह सांख्यिकीय नहीं, बल्कि संरचनात्मक (structural) है। दोनों डिफ़ॉल्ट रूप से बंद हैं — इनकी विफलता भी सुरक्षा की ओर ही जाती है। एक keys-only sshd को brute-force नहीं किया जा सकता, चाहे कितने भी प्रयास क्यों न आएँ, क्योंकि कोड में पासवर्ड स्वीकार करने वाला कोई रास्ता ही नहीं बचता। एक default-deny firewall उन सर्विसों की भी रक्षा करता है जिन्हें आपने अभी इंस्टॉल नहीं किया है — जिसमें वह डेटाबेस भी शामिल है जिसे आप तीन महीने बाद जोड़ेंगे और localhost से bind करना भूल जाएँगे। किसी भी hardening checklist में बाकी सब कुछ बुराइयों की गिनती भर है: बंद करने लायक चीज़ों की एक सूची, जो हमेशा उतनी ही पूरी होती है जितनी वह सूची खुद है।
तो अगर आप सिर्फ़ एक सेक्शन पढ़कर टैब बंद करने वाले हैं, तो यही पढ़ें, नीचे दिए स्टेप 2 से 5 तक करें, और मान लें कि यह घंटा सही तरीके से बीता। बाकी हिस्सा वाकई उपयोगी है, लेकिन वाकई गौण (secondary) भी है।
SSH config अब कहाँ रहता है, और उसमें छिपा जाल
Debian 13 और Ubuntu 24.04 पर, /etc/ssh/sshd_config की शुरुआत ही Include /etc/ssh/sshd_config.d/*.conf लाइन से होती है, और cloud images उस डायरेक्टरी में एक फ़ाइल — आमतौर पर 50-cloud-init.conf — के साथ आते हैं, जो पहले से ही PasswordAuthentication सेट कर चुकी होती है। मुख्य फ़ाइल को edit करना और नीचे अपने directives जोड़ देना स्वाभाविक लगता है, लेकिन इससे ऐसा config बनता है जो वह नहीं करता जो वह कहता है।
sshd के बारे में एक नियम है जो लगभग हर किसी को चौंका देता है: हर keyword के लिए, सबसे पहले मिला value जीतता है। यह लगभग हर उस config-merging सिस्टम के उलट है जिसका आपने अब तक इस्तेमाल किया है। Include मुख्य फ़ाइल के ऊपरी हिस्से में होता है, इसलिए कोई drop-in sshd_config के मुख्य भाग से पहले पढ़ा जाता है — और drop-ins के बीच, वर्णानुक्रम (alphabetical order) तय करता है। 10-hardening.conf नाम की फ़ाइल 50-cloud-init.conf को मात दे देती है। जबकि 60-hardening.conf नाम की फ़ाइल उससे चुपचाप हार जाती है, और सफल restart की रिपोर्ट से आपको यह कभी पता नहीं चलेगा।
यही वजह है कि आपको अभी-अभी लिखी अपनी फ़ाइल पर कभी भरोसा नहीं करना चाहिए। daemon से पूछें कि उसने असल में क्या resolve किया:
sshd -t # syntax check — silence means valid
sshd -T | grep -Ei '^(permitrootlogin|passwordauthentication|pubkeyauthentication|kbdinteractive|allowusers|port) 'sshd -T हर include, override और default resolve हो जाने के बाद प्रभावी (effective) configuration प्रिंट करता है। अगर उसका आउटपुट passwordauthentication yes कहता है, तो password authentication चालू है, चाहे डिस्क पर कोई भी फ़ाइल कुछ भी दावा करे। इसके अलावा कुछ भी सत्यापन (verification) नहीं माना जाता।
दूसरा जाल भी उसी परिवार का है। Ubuntu 24.04 पर sshd socket activation के ज़रिए शुरू होता है: ssh.socket ही listening port का मालिक होता है, और sshd_config में Port पूरी तरह नज़रअंदाज़ हो जाता है। इसे systemctl is-enabled ssh.socket से जाँचें; अगर यह enabled है और आपको अलग port चाहिए, तो इसे systemctl edit ssh.socket और ListenStream= override से बदलें — न कि sshd_config में, जहाँ सेटिंग सही दिखेगी लेकिन कुछ नहीं करेगी।
Port 22 से हटना: दिखावा, पर सस्ता दिखावा
इस बारे में ईमानदार रहते हैं, क्योंकि इंटरनेट ईमानदार नहीं है। sshd को port 2222 या 47000 पर ले जाने से एक भी काबिल हमलावर नहीं रुकता। एक host का पूरा TCP scan कुछ ही सेकंड में हो जाता है, सर्विस अपना बैनर खुद ज़ाहिर कर देती है, और जिसने ख़ास तौर पर आप पर हमला करने की ठान ली है, वह अपनी कॉफ़ी ख़त्म करने से पहले ही इसे ढूँढ लेगा।
यह जो असल में करता है वह है आपके authentication log को लगभग पंचानवे प्रतिशत तक घटाना, और इसका वाकई मूल्य है: यही फ़र्क़ है उन logs में जिन्हें आप सरसरी नज़र से देखते हैं और उनमें जिन्हें आप वाकई पढ़ते हैं। जो संकेत (signal) दिख सके वह दबे हुए संकेत से बेहतर है। अगर आप कुछ भी मॉनिटर करते हैं, तो एक शांत auth.log किसी असामान्यता को दिखाई देने लायक बनाने का सबसे सस्ता तरीका है।
इसकी लागत छोटी है पर असली है, और यही वजह है कि हम इसे अनुशंसित (recommended) नहीं, बल्कि वैकल्पिक (optional) कहते हैं। आठ महीने बाद लौटने पर आप port भूल जाएँगे। सिद्धांततः, 1024 से ऊपर का कोई non-standard port किसी unprivileged process द्वारा हथिया लिया जा सकता है, अगर कभी sshd सुन ही न रहा हो। client नेटवर्क्स पर सख़्त outbound firewalls अनजान ports को ब्लॉक कर देते हैं, इसलिए कभी-कभार आप किसी ऑफ़िस या होटल से अपने ही सर्वर तक नहीं पहुँच पाएँगे। और socket-activated सिस्टम पर इसे पिछले सेक्शन के मुताबिक़ सही जगह पर बदलना होगा। अगर शांत logs आपके लिए मायने रखते हैं, तो यह करें। इसे करके सुरक्षित महसूस मत कीजिए, और इसे कभी भी keys-only के बदले मत कीजिए।
Default-deny, और वह ruleset जो हम असल में चलाते हैं
जो firewall यह बताता है कि क्या ब्लॉक करना है, वह एक फ़ाइलिंग सिस्टम है। जो firewall यह बताता है कि किसे allow करना है, वह एक सुरक्षा नियंत्रण (security control) है। यही फ़र्क़ पूरा खेल है, क्योंकि सिर्फ़ दूसरा वाला ही उस सर्विस को कवर करता है जिसे आप अगले महीने इंस्टॉल करेंगे, उस debug port को जिसे आपने किसी शुक्रवार को खोला था, और उस container को जिसने खुद को उजागर करने का फ़ैसला किया।
हमारे प्लेटफ़ॉर्म पर आपके पास दो परतें (layers) हैं, और ये स्वतंत्र हैं। edge filter वैकल्पिक है, जिसे पैनल में प्रति सर्वर कॉन्फ़िगर किया जाता है और hypervisor पर लागू किया जाता है, इसलिए ब्लॉक किया गया ट्रैफ़िक आपके guest तक पहुँचता ही नहीं — यह उन layer-4 rules के लिए उपयोगी है जिन्हें आप अपने kernel के कोई cycle खर्च करने से पहले लागू करवाना चाहते हैं, और किसी compromised guest को उस दौरान पहुँच से बाहर रखने के लिए भी जब आप उस पर काम कर रहे हों। guest firewall पूरी तरह आपका है: nftables, iptables, pf, जो भी आपकी image के साथ आता हो। हम इसे कभी नहीं छूते। अगर मशीन मायने रखती है तो दोनों इस्तेमाल करें; कम से कम दूसरा हमेशा इस्तेमाल करें।
स्टेप 5 के ruleset में दो बातें समझाने लायक हैं, क्योंकि ज़्यादातर copy-paste किए गए rulesets इन्हें ग़लत कर देते हैं। सारे ICMP को drop मत कीजिए। यह साफ़-सुथरा लगता है लेकिन path-MTU discovery को तोड़ देता है, जिससे सबसे बुरी तरह की गड़बड़ पैदा होती है: छोटे requests काम करते हैं, बड़े responses अटक जाते हैं, और आपके logs में firewall का कहीं ज़िक्र तक नहीं होता। कम से कम destination-unreachable, time-exceeded और parameter-problem accept करें। ICMPv6 को type के आधार पर तभी filter करें जब आपको पूरी सूची पता हो। IPv6, neighbour discovery और router advertisement के लिए ICMPv6 पर निर्भर करता है; इसे व्यापक रूप से ब्लॉक करने पर आपकी IPv6 कनेक्टिविटी ऐसे मर जाती है जैसे कोई routing समस्या हो। एक ही host पर सारे ICMPv6 को accept करना एक उचित समझौता (trade) है, और नीचे दिया ruleset ठीक यही करता है।
flush ruleset चलाने से पहले एक चेतावनी: अगर Docker इंस्टॉल है, तो यह लाइन Docker द्वारा लिखे गए NAT और filter rules हटा देती है, और container networking तब तक रुकी रहती है जब तक systemctl restart docker उन्हें वापस नहीं ला देता। पहले अपना ruleset load करें, फिर Docker को restart करें, और किसी भी container port को publish करने से पहले अगला सेक्शन पढ़ें।
वे ports जिनके खुले होने की आपको ख़बर ही नहीं थी
मशीन से पूछें कि वह किस पर सुन रही है। यह नहीं कि आपको क्या लगता है आपने इंस्टॉल किया — बल्कि यह कि अभी इस वक़्त क्या bind है:
ss -tulpn | grep -vE '127\.0\.0\.1|\[::1\]'इस filter से बचकर जो कुछ भी सामने आता है, वह मशीन के अलावा कहीं और से भी पहुँचा जा सकता है। किसी stock image पर आमतौर पर मिलते हैं: 111 पर rpcbind (जिसकी आपके किसी भी प्रोग्राम को ज़रूरत नहीं), base install से बचा हुआ एक exim4 listener, और एक systemd-resolved stub जो loopback पर हानिरहित है लेकिन अगर वैसा न हो तो एक open resolver बन जाता है। ख़तरनाक चीज़ें बाद में आती हैं, उस सॉफ़्टवेयर के साथ जिसे आपने जान-बूझकर इंस्टॉल किया: 0.0.0.0:5432 पर PostgreSQL क्योंकि किसी ट्यूटोरियल ने listen_addresses edit करने को कहा था, बिना पासवर्ड वाला Redis क्योंकि Redis का डिफ़ॉल्ट अपने ज़्यादातर जीवनकाल में पासवर्ड-रहित रहा है, एक Elasticsearch node, एक Prometheus exporter, एक Jupyter notebook। इनमें से हर एक कई बार किसी असली breach का पहला कदम बन चुका है।
अब वह जाल जो सावधान लोगों को भी पकड़ लेता है। Docker आपके firewall से इजाज़त नहीं माँगता। जब आप -p 5432:5432 लिखते हैं, Docker nat टेबल की PREROUTING chain में DNAT rules डाल देता है, जिसका मूल्यांकन kernel आपकी input chain द्वारा पैकेट देखे जाने से पहले ही कर लेता है; इसके बाद ट्रैफ़िक container तक forward कर दिया जाता है। आपकी default-deny input policy से कोई सलाह नहीं ली जाती, ufw status port को बंद दिखाता है, और डेटाबेस पब्लिक इंटरनेट पर होता है। यह Docker का दस्तावेज़ीकृत (documented) व्यवहार है, यह एक दशक से ऐसा ही है, और इसने बेशुमार डेटाबेस उजागर किए हैं।
इसका समाधान एक ही string है, और यह वह आदत है जो बनाने लायक है:
# wrong — reachable from the entire internet, whatever your firewall says
docker run -p 5432:5432 postgres
# right — bound to loopback, reachable only through an SSH tunnel or a proxy
docker run -p 127.0.0.1:5432:5432 postgresआख़िर में, बाहर की राय भी लें। सर्वर से किया गया port scan आपको बताता है कि kernel क्या सोचता है; कहीं और से किया गया scan बताता है कि दुनिया क्या देखती है, और मायने सिर्फ़ यही आँकड़ा रखता है। अपने laptop से — मशीन से नहीं — nmap -Pn -p- <your-ip> चलाएँ, और नतीजे की तुलना उस सूची से करें जिसकी आपको उम्मीद थी।
ऑटोमैटिक अपडेट: उन्हें चालू करें, और उसे निभाएँ भी
छोटे सर्वरों को compromise करने वाली खिड़की zero-day नहीं होती। यह वे चार हफ़्ते होते हैं जो किसी CVE के काम करने वाले proof of concept के साथ सार्वजनिक होने और आपके अगली बार लॉगिन करने के बीच बीतते हैं। हमला करने वाले tools किसी नए remote bug को कुछ ही दिनों में आत्मसात कर लेते हैं; जिस मशीन को आप “जब समय मिलेगा तब” पैच करते हैं, वह पूरे इस अंतराल के दौरान उजागर रहती है, और हर ईमानदार operator जानता है कि यह अंतराल असल में कितना लंबा होता है।
ऑटोमैटिक अपडेट पर आपत्ति यह डर है कि कुछ टूट जाएगा, और इसे गंभीरता से लेना ही चाहिए — फिर इसका दायरा सीमित करना चाहिए। automation को अपने distribution के security हिस्से तक सीमित रखें, जहाँ maintainers नए upstream releases भेजने के बजाय पैकेज किए गए वर्शन में ही फ़िक्स backport करते हैं। openssl के लिए Debian का security update उसी वर्शन का एक पैच किया गया बिल्ड होता है जो आप पहले से चला रहे हैं; इसके व्यवहार बदलने का जोखिम, एक महीने तक कोई remote छेद खुला छोड़ने के जोखिम से कहीं छोटा है। Feature upgrades मैनुअल ही रहने चाहिए, जहाँ उनकी असल जगह है।
जो हिस्सा लोग छोड़ देते हैं वह है reboot। डिस्क पर पैच किया गया libssl उस process के लिए कुछ नहीं करता जिसने start-up के वक़्त पुराना वाला ही मैप किया था, और kernel अपडेट तब तक कुछ नहीं करता जब तक आप उसमें बूट न करें। या तो अपनी चुनी हुई विंडो में unattended reboot स्वीकार करें, या needrestart इंस्टॉल करें और उसे बताने दें कि कौन-सी सर्विसें डिलीट हो चुकी libraries के सहारे चल रही हैं — पर इनमें से कोई एक ज़रूर करें। “ऑटोमैटिक अपडेट चालू हैं” कहना, जबकि uptime 340 दिन दिखा रहा हो, एक आरामदायक भ्रम है, और यह वह सबसे आम भ्रम है जो हम देखते हैं।
fail2ban, CrowdSec, या फिर कुछ भी नहीं
fail2ban आपके logs पढ़ता है, किसी पते से बार-बार होने वाली नाकामियों को नोटिस करता है और उसे कुछ समय के लिए ban कर देता है। CrowdSec भी यही करता है और साथ ही अपने फ़ैसले participants के एक नेटवर्क में साझा करता है, ताकि आप तक पहुँचने से पहले ही किसी ऐसे पते को ब्लॉक कर सकें जो कहीं और बदतमीज़ी कर चुका है। दोनों अच्छे सॉफ़्टवेयर हैं। लेकिन keys-only SSH सर्वर पर इनमें से कोई भी वह नहीं करता जो ज़्यादातर लोग सोचते हैं।
एक बार PasswordAuthentication no हो जाए, तो SSH brute-force कामयाब नहीं हो सकता। यह सिर्फ़ “शायद ही कामयाब हो” जैसी बात नहीं है — यहाँ कोई कोड-पथ बचता ही नहीं। इसलिए पाँच नाकामियों के बाद किसी पते को ban करना कुछ भी नहीं रोकता; यह सिर्फ़ log की मात्रा और थोड़ा-सा CPU घटाता है। यह एक असली फ़ायदा है, बस सुरक्षा वाला फ़ायदा नहीं है, और यह सौदा मुफ़्त भी नहीं है: ग़लत log देखने वाले किसी बुरी तरह लिखे jail ने हमलावरों से ज़्यादा administrators को उन्हीं के सर्वर से बाहर किया है।
जहाँ ये टूल्स वाकई अपनी जगह कमाते हैं, वह एक परत ऊपर है, उन सर्विसों पर जिन्हें आप असल में उजागर करते हैं: एक login फ़ॉर्म, एक WordPress admin, rate limits वाला कोई API, SMTP AUTH वाला mail server। ये पासवर्ड वाकई स्वीकार करते हैं, ये वाकई brute-force किए जा सकते हैं, और यहाँ ban list बिल्कुल सही नियंत्रण है। इसलिए हमारा फ़ैसला संकुचित और सटीक है। SSH jail को छोड़ दें। CrowdSec या fail2ban को उस चीज़ के आगे लगाएँ जिसमें पासवर्ड फ़ील्ड हो। और आप जो भी चुनें, पहले अपना खुद का management पता whitelist करें — ignoreip उसी शाम के लिए है जिसे आप वरना ग़लत वजहों से याद रखेंगे।
मशीन से यह बुलवाना कि वह कब बदलती है
Prevention वह है जो आप एक घंटे में कर सकते हैं। Detection वह है जो आपको बताता है कि वह घंटा काफ़ी नहीं था। इसे जटिल होने की ज़रूरत नहीं, और एक अकेले सर्वर पर तीन सस्ती चीज़ें ज़्यादातर ज़मीन कवर कर लेती हैं।
Logs को बचाकर रखें। कई images पर journal /run में रहता है और reboot होते ही उड़ जाता है, यानी किसी incident का रिकॉर्ड उसके बाद आने वाले reboot में ग़ायब हो जाता है। /var/log/journal बनाना एक-लाइन का फ़िक्स है और इस सेक्शन की सबसे मूल्यवान चीज़ है।
लॉगिन के बारे में सूचना पाएँ। /etc/ssh/sshrc में एक लाइन जो हर session शुरू होने पर logger चलाती है, कुछ भी ख़र्च नहीं करती और आपको sshd की अपनी बकबक से अलग एक साफ़, greppable रिकॉर्ड देती है। एक चेतावनी जो लोगों को पकड़ लेती है: जब user के पास अपनी ~/.ssh/rc हो, तो sshd /etc/ssh/sshrc की बजाय उसे चलाता है, यानी सिस्टम-व्यापी फ़ाइल ठीक उसी अकाउंट के लिए छूट जाती है जिसके पास custom dotfile होने की सबसे ज़्यादा संभावना है। अगर आपको ऐसा hook चाहिए जिसे छिपाया न जा सके, तो इसकी जगह pam_exec इस्तेमाल करें।
जानें कि पहले दिन filesystem कैसा दिखता था। AIDE आपके binaries, libraries और unit files के hashes रिकॉर्ड करता है और बताता है कि तब से क्या बदला। पेच बुनियादी है और आमतौर पर नज़रअंदाज़ कर दी जाती है: जिस मशीन को यह देख रहा है, अगर database उसी पर रखा हो, तो उसे compromise करने वाला उसे फिर से बना सकता है, और फिर जाँच हमेशा के लिए “कोई बदलाव नहीं” बताती रहेगी। database को मशीन से बाहर कॉपी करें, या कम से कम उसका hash कहीं और रिकॉर्ड करें, तभी यह टूल अपने बीस मिनट के लायक बनता है। जगह पर छोड़ दिया जाए, तो यह सिर्फ़ एक दिलासा भर है।
यह सामान्य सिद्धांत अपने आप में कहने लायक है: जिस log पर भरोसा नहीं किया जा सकता, वह वही है जो compromised मशीन पर पड़ा है। जिस भी चीज़ पर आप वाकई भरोसा करने का इरादा रखते हैं — कोई journal, कोई integrity database, कोई backup — उसकी एक कॉपी कहीं ऐसी जगह होनी चाहिए जिसे वही हमलावर नियंत्रित न करता हो। किसी दूसरे jurisdiction में एक और छोटा सर्वर इसका एक वाजिब जवाब है, और पाँच डॉलर वाला भी काफ़ी है।
यह क्या नहीं करता
ऊपर बताया गया सब कुछ सिर्फ़ perimeter का काम है, और इसकी सीमा को सटीक तरीके से समझना ज़रूरी है ताकि आप बंद अगले दरवाज़े को तिजोरी (safe) न समझ बैठें।
यह चलती हुई मशीन पर मौजूद डेटा की रक्षा नहीं करता। hypervisor तक पहुँच रखने वाले किसी के लिए, और मशीन के चालू रहने के दौरान RAM की सामग्री के लिए, एक hardened kernel और बंद firewall बेमानी हैं। अगर आपकी चिंता उस डिस्क को लेकर है जब सर्वर बंद हो, ज़ब्त कर लिया गया हो, या सेवा से हटा दिया गया हो, तो वह disk encryption का मामला है, और यह एक अलग प्रक्रिया है जिसकी विफलता का तरीका भी अलग है — देखें LUKS से VPS डिस्क एन्क्रिप्ट करना।
यह आपको गुमनाम (anonymous) नहीं बनाता। एक सर्वर पूरी तरह से hardened हो सकता है और फिर भी यह ज़ाहिर कर सकता है कि उसका मालिक कौन है — किसी WHOIS रिकॉर्ड, दोबारा इस्तेमाल की गई SSH key, किसी analytics tag, बिना किसी hop के घर से जुड़ने वाले SSH client, या दो पहचानों को आपस में जोड़ने वाले किसी certificate के ज़रिए। Monero से पेमेंट करना और फिर अपने ही पते से लॉगिन कर लेना, उस पेमेंट को बेअसर कर देता है। इस तरह की विफलता का अपना अलग पेज है: वे गलतियाँ जो आपको deanonymize कर देती हैं।
यह आपका application ठीक नहीं करता। एक SQL injection, एक unauthenticated admin endpoint, या backdoor वाली कोई dependency, आपकी sshd सेटिंग्स की परवाह नहीं करती। अच्छी तरह चलाए जा रहे सर्वरों के ज़्यादातर compromise उसी port से होकर आते हैं जिसे आपने जान-बूझकर, इरादतन, किसी ऐसी सर्विस के लिए खोला था जिसे आपने खुद लिखा या इंस्टॉल किया।
यह कोई backup नहीं है। Ransomware, किसी ख़ाली रह गए variable के साथ चला rm -rf, और कोई नाकाम upgrade — ये सभी एक ही तरीके से ख़त्म होते हैं। एक कॉपी लें, उसे कहीं और रखें, और ज़रूरत पड़ने से पहले एक बार उससे restore करके देखें — वही अनुशासन जो किसी दूसरे host पर माइग्रेशन को झेलने लायक बनाता है, वही किसी बुरे मंगलवार को भी झेलने लायक बनाता है।
इनमें से कुछ भी उस घंटे के ख़िलाफ़ दलील नहीं है। यह इस बात की दलील है कि आप ठीक-ठीक जानें कि उस घंटे ने आपको क्या दिया।
- Key से deploy करें, पासवर्ड से कभी नहीं
keypair अपनी ही मशीन पर बनाएँ और उसका public हिस्सा deploy फ़ॉर्म में पेस्ट करें; image इसे इंस्टॉल कर देगी और आपके पास खोने के लिए कोई root पासवर्ड कभी होगा ही नहीं। अगर आप
cloud-initसे चिह्नित किसी image से deploy कर रहे हैं, तो इसकी बजाय पूरा पहला-घंटा वाला configuration user-data के रूप में भेज सकते हैं — 64 KiB तक — और मशीन पहले से ही hardened होकर चालू होगी।# on your laptop, not on the server ssh-keygen -t ed25519 -a 100 -C "$(whoami)@laptop-cvh" cat ~/.ssh/id_ed25519.pub # paste this into the deploy formed25519 इस्तेमाल करें, जब तक कि आपकी toolchain में कुछ इसे मना न कर दे, ऐसी सूरत में 4096-बिट RSA ठीक रहेगा। private key को passphrase से सुरक्षित रखें और उसे किसी agent में लोड करें; laptop पर बिना passphrase वाली key फ़ाइल मॉनिटर पर लिखे पासवर्ड जैसी है। यही key set rescue मोड में भी डाली जाती है, और यही स्टेप 4 को recoverable बनाता है।
- कुछ भी छूने से पहले दूसरा session खोलें
यह वैकल्पिक नहीं है, और न ही यह बेवजह की सावधानी है। यहाँ से आगे आप उस daemon को बदलने वाले हैं जिससे होकर आप जुड़े हैं, और उस firewall को भी जो आपको वहाँ तक पहुँचने देता है। एक session को खुला और निष्क्रिय रहने दें, मशीन में वापसी की एक रस्सी की तरह, और हर बदलाव किसी दूसरे session में करें। अगर कोई बदलाव ग़लत निकले, तो खुला हुआ session अब भी authenticated रहता है और उसे पलट सकता है; जबकि एक नया कनेक्शन अस्वीकार कर दिया जाएगा।
# terminal A — the rope. Log in and leave it alone. ssh -i ~/.ssh/id_ed25519 root@<server-ip> # terminal B — where every command below runs. ssh -i ~/.ssh/id_ed25519 root@<server-ip>हर बदलाव को एक तीसरा कनेक्शन खोलकर टेस्ट करें, कभी भी उसी को दोबारा जोड़कर नहीं जिसमें आप काम कर रहे हैं। अगर तीसरा कनेक्शन फेल हो जाए, तब भी आपके पास दो चालू shells होंगी और सिर्फ़ एक समस्या होगी, कोई संकट नहीं।
- वह अकाउंट बनाएँ जिसे आप असल में इस्तेमाल करेंगे
SSH पर root होना ठीक एक घंटे के लिए सुविधाजनक है। उसके बाद, sudo वाला एक नामित (named) अकाउंट आपको एक audit trail देता है, आपको किसी ग़लती से टाइप हुए कमांड को पूरे privileges के साथ चलने से बचाता है, और आपको मशीन को बंद किए बिना किसी compromised अकाउंट को disable करने देता है।
adduser --disabled-password --gecos "" deploy install -d -m 0700 -o deploy -g deploy /home/deploy/.ssh cp /root/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys chown deploy:deploy /home/deploy/.ssh/authorized_keys chmod 0600 /home/deploy/.ssh/authorized_keys usermod -aG sudo deploy # a long random password, stored in your manager, used only by sudo passwd deployवह पासवर्ड सेट करें। जिस sudo अकाउंट का पासवर्ड कभी सेट ही न हुआ हो, वह sudo इस्तेमाल नहीं कर सकता, और root login बंद करने के बाद यह पता चलना — हर फ़ाइल के सही होते हुए भी खुद को बाहर बंद कर लेने का क्लासिक तरीका है। आगे बढ़ने से पहले जाँच लें: एक नए terminal से,
ssh deploy@<server-ip>, फिरsudo -v। दोनों काम करने चाहिए। - SSH drop-in लिखें, फिर daemon से पूछें कि उसने क्या पढ़ा
ऊपर बताए गए ordering नियम के मुताबिक़, जल्दी sort होने वाला एक क्रमांकित (numbered) drop-in, cloud image के साथ आई किसी भी चीज़ को मात दे देता है। इसे लिखें, syntax जाँचें, प्रभावी (effective) configuration वापस पढ़ें, और उसके बाद ही reload करें।
cat > /etc/ssh/sshd_config.d/10-hardening.conf <<'EOF' PermitRootLogin no PasswordAuthentication no KbdInteractiveAuthentication no PubkeyAuthentication yes AuthenticationMethods publickey PermitEmptyPasswords no AllowUsers deploy MaxAuthTries 3 LoginGraceTime 20 X11Forwarding no AllowAgentForwarding no AllowTcpForwarding no # remove this line if you use ssh -L / -D tunnels ClientAliveInterval 300 ClientAliveCountMax 2 EOF chmod 0644 /etc/ssh/sshd_config.d/10-hardening.conf sshd -t # silence means the syntax is valid sshd -T | grep -Ei '^(permitrootlogin|passwordauthentication|allowusers) ' systemctl reload sshsshd -Tका वह आउटपुट reload करने से पहले पढ़ें, बाद में नहीं। उसमेंpermitrootlogin noऔरpasswordauthentication noलिखा होना चाहिए। अगर ऐसा नहीं है, तो आपकी फ़ाइल को किसी ऐसी फ़ाइल द्वारा override किया जा रहा है जो पहले sort होती है —ls /etc/ssh/sshd_config.d/चलाएँ और अपनी फ़ाइल का नाम बदलकर उसे नीचे कर दें। अब एक तीसरा terminal खोलें औरdeployके तौर पर लॉगिन करें। यह काम करने पर ही रस्सी वाला session बंद करें। - एक default-deny firewall लोड करें
nftables दोनों distributions के साथ आता है और iptables ruleset की जगह एक अकेली, पढ़ने लायक फ़ाइल ले लेता है। accepted ports को उन सर्विसों के मुताबिक़ बदलें जिन्हें आप असल में चलाते हैं — नीचे दी सूची SSH और एक web server मान कर चलती है, और कुछ नहीं।
apt install -y nftables cat > /etc/nftables.conf <<'EOF' #!/usr/sbin/nft -f flush ruleset table inet filter { chain input { type filter hook input priority filter; policy drop; ct state established,related accept ct state invalid drop iif lo accept # ICMP must live: dropping it blackholes path-MTU discovery. ip protocol icmp icmp type { echo-request, echo-reply, destination-unreachable, time-exceeded, parameter-problem } accept ip6 nexthdr icmpv6 accept tcp dport 22 ct state new accept tcp dport { 80, 443 } ct state new accept limit rate 5/minute burst 5 packets log prefix "nft-drop: " level info } chain forward { type filter hook forward priority filter; policy drop; } chain output { type filter hook output priority filter; policy accept; } } EOF nft -c -f /etc/nftables.conf # check before you commit to it systemctl enable --now nftables nft list ruleset | head -40अगर Docker इंस्टॉल है, तो
flush rulesetDocker के rules भी हटा देता है: उसके बादsystemctl restart dockerचलाएँ और पक्का करें कि आपके containers अब भी जवाब दे रहे हैं। फिर, अपने laptop से,nmap -Pn -p- <server-ip>चलाएँ और जाँच लें कि खुली सूची ठीक उन्हीं ports से मेल खाती है जिन्हें आपने अभी allow किया — न ज़्यादा, न कम। - Unattended security upgrades चालू करें
सिर्फ़ security वाला हिस्सा, और एक ऐसी reboot विंडो जिसे आपने खुद चुना है, न कि जिसे आप टालते ही रहेंगे। ऐसा घंटा चुनें जो आपके users के लिए शांत हो और ठीक घंटे पर न हो, ताकि बाकी सबके cron से टकराव न हो।
apt install -y unattended-upgrades needrestart cat > /etc/apt/apt.conf.d/51-cvh-auto <<'EOF' // Debian. On Ubuntu, replace the two Origins-Pattern lines with: // "${distro_id}:${distro_codename}-security"; Unattended-Upgrade::Origins-Pattern { "origin=Debian,codename=${distro_codename}-security,label=Debian-Security"; "origin=Debian,codename=${distro_codename},label=Debian-Security"; }; Unattended-Upgrade::Automatic-Reboot "true"; Unattended-Upgrade::Automatic-Reboot-WithUsers "false"; Unattended-Upgrade::Automatic-Reboot-Time "04:17"; Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Unattended-Upgrade "1"; EOF unattended-upgrade --dry-run --debug | tail -25 systemctl status unattended-upgrades --no-pagerअगर unattended reboot वाकई स्वीकार्य नहीं है, तो इसे
"false"सेट करें औरneedrestart -bको यह बताने दें कि कौन-सी सर्विसें डिलीट हो चुकी libraries के सहारे चल रही हैं और क्या कोई नया kernel इंस्टॉल है — फिर उस पर अमल करें। जो स्वीकार्य नहीं है वह है इनमें से कोई भी न करना। - जो कुछ सुन रहा है उसे बंद करें, और बाहर से जाँचें
पता लगाएँ कि loopback के अलावा और क्या-क्या bind है, जो इस्तेमाल में नहीं है उसे हटाएँ, और नतीजे की पुष्टि किसी ऐसी मशीन से करें जो यह मशीन नहीं है।
ss -tulpn | grep -vE '127\.0\.0\.1|\[::1\]' # the usual leftovers on a base image systemctl disable --now rpcbind.socket rpcbind 2>/dev/null apt purge -y exim4-base exim4-config exim4-daemon-light 2>/dev/null apt autoremove --purge -y # what each running unit is allowed to reach systemd-analyze security --no-pager | head -20ऐसी किसी भी चीज़ के लिए जिसे चलते रहना ज़रूरी है लेकिन जिसे किसी दर्शक की ज़रूरत नहीं — कोई database, कोई cache, कोई admin panel, कोई metrics exporter — उसे अपने ही configuration में
127.0.0.1से bind करें और SSH tunnel के ज़रिए उस तक पहुँचें:ssh -L 5432:127.0.0.1:5432 deploy@<server-ip>। यह किसी port को खोलकर यह उम्मीद करने से कि सर्विस का अपना authentication ठोस होगा, कहीं बेहतर है, और यही वह pattern है जिसे डिफ़ॉल्ट रूप से अपनाना चाहिए। - Baseline रिकॉर्ड करें और अलार्म तैयार करें
दस मिनट जो सिर्फ़ उसी दिन काम आते हैं जब कुछ ग़लत हो जाए — और वही वह दिन है जब आप इनमें से कुछ भी याद्दाश्त के सहारे दोबारा नहीं बना पाएँगे।
# persistent journal, so a reboot stops erasing the evidence mkdir -p /var/log/journal systemd-tmpfiles --create --prefix /var/log/journal systemctl restart systemd-journald # a clean, greppable line per SSH session cat > /etc/ssh/sshrc <<'EOF' logger -t ssh-login "user=$USER from=${SSH_CONNECTION%% *} tty=${SSH_TTY:-none}" EOF # file-integrity baseline — then get the database off the machine apt install -y aide aideinit mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db sha256sum /var/lib/aide/aide.db # copy this hash somewhere else last -n 20 ; lastb -n 20 # who got in, and who triedअंत में, सर्वर से बाहर कहीं, चार चीज़ें लिख लें:
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pubसे मिला SSH host key fingerprint, ऊपर वाला AIDE hash, वे ports जिन्हें आपने जान-बूझकर खोला, और यह कि private key कहाँ रखी है। यही नोट किसी बुरी सुबह को एक जाँच-पड़ताल की बजाय एक checklist में बदल देता है।
नियंत्रण, इस आधार पर क्रमबद्ध कि वे असल में आपको क्या देते हैं
| नियंत्रण | यह क्या रोकता है | यह क्या नहीं रोकता | लागत | फ़ैसला |
|---|---|---|---|---|
| सिर्फ़ Keys वाला SSH (PasswordAuthentication no) | इंटरनेट पर हर credential-guessing bot को, हमेशा के लिए और अपनी बनावट से ही | आपकी private key रखने वाला कोई भी, या ख़ुद sshd में कोई खामी | 5 मिनट, एक बार | अनिवार्य |
| Default-deny firewall (nftables) | वे सर्विसें जो सुन रही थीं और आप भूल गए, और वे भी जिन्हें आप बाद में ग़लती से इंस्टॉल कर देंगे | उन ports पर होने वाले हमले जिन्हें आपने जान-बूझकर खोला | 10 मिनट, एक बार | अनिवार्य |
| Unattended security upgrades | n-day विंडो — किसी सार्वजनिक exploit और आपके अगले लॉगिन के बीच के हफ़्ते | Zero-days, और वह सब कुछ जिसे ऐसे reboot की ज़रूरत हो जिसे आप कभी शेड्यूल ही न करें | 5 मिनट, साथ में एक reboot विंडो | अनिवार्य |
| root की बजाय sudo वाला नामित user | पूरे privileges के साथ ग़लत टाइप हुए कमांड, और बेवजह root के तौर पर चल रहे processes | पहले से अंदर मौजूद किसी के हाथ में local privilege escalation | 3 मिनट | करने लायक |
| File-integrity baseline (AIDE) | सिस्टम binaries, libraries और unit files में चुपचाप हुए बदलाव | अगर database उसी मशीन पर रहे जिसे यह देख रहा है, तो कुछ भी नहीं | 20 मिनट, साथ में off-box storage | करने लायक, अगर मशीन मायने रखती है |
| SSH को port 22 से हटाना | आपके authentication log की मात्रा का लगभग 95% | port scan चलाने वाला कोई भी, यानी वे सभी जो मायने रखते हैं | 2 मिनट, साथ में वह शाम जब आप port भूल जाएँगे | वैकल्पिक, शांत logs के लिए |
| sshd पर fail2ban / CrowdSec | बार-बार अपराध करने वाले, और वह CPU जो वे आप पर बर्बाद करते हैं | कुछ भी नहीं, एक बार password authentication बंद हो जाए तो | 10 मिनट, साथ में खुद को बाहर बंद कर लेने का असली जोखिम | SSH पर छोड़ दें; अपने app पर इस्तेमाल करें |
जवाब देने योग्य प्रश्न
Deploy के कितनी देर बाद scanning शुरू हो जाती है?
आमतौर पर, मिनटों में। इंटरनेट-व्यापी scanners पूरे IPv4 space को लगातार स्कैन करते रहते हैं, इसलिए अगली बार में एक नया पता ज़रूर पहुँच में आ जाता है, चाहे उस पर कुछ भी चल रहा हो। मान कर चलें कि जिस पल मशीन अपना पहला पैकेट जवाब देती है, उसी पल से आपकी जाँच शुरू हो जाती है — यही वजह है कि hardening पहले घंटे में होती है, पहले वीकेंड में नहीं।
अगर पासवर्ड लॉगिन बंद है, तो क्या मुझे फिर भी fail2ban चाहिए?
SSH पर, नहीं। PasswordAuthentication no के साथ कोई ऐसा कोड-पथ नहीं बचता जिसे brute-force जीत सके, इसलिए पाँच नाकामियों के बाद ban करना कुछ भी नहीं रोकता — यह बस log का शोर घटाता है, जिसकी अपनी क़ीमत है, पर वह सुरक्षा नहीं है। इन टूल्स की असली जगह उस हर चीज़ के आगे है जो वाकई पासवर्ड स्वीकार करती है: कोई web login फ़ॉर्म, कोई admin panel, SMTP AUTH। अगर आप इनमें से कोई इंस्टॉल करें, तो पहले अपना ख़ुद का पता whitelist करें।
ufw, firewalld या nftables?
इनमें से कोई भी चलेगा, बशर्ते default policy drop हो और आप समझें कि आपने क्या deploy किया है। ufw सबसे आसान है और मौजूदा Debian व Ubuntu पर नीचे nftables rules ही लिखता है। सादा nftables एक ऐसी पढ़ने लायक फ़ाइल है जिसे आप diff और version-control कर सकते हैं, इसीलिए हम इसे इस्तेमाल करते हैं। यह चुनाव default policy जितना मायने नहीं रखता — और इन तीनों में से कोई भी इस हक़ीक़त को नहीं बदलता कि Docker इन सबके नीचे से होकर ports publish कर देता है।
क्या मुझे SSH को port 22 से हटा देना चाहिए?
सिर्फ़ शांत logs के लिए। यह किसी भी काबिल हमलावर को नहीं रोकता — पूरा scan कुछ ही सेकंड में हो जाता है और बैनर सर्विस को ज़ाहिर कर देता है। यह आपके authentication log का ज़्यादातर शोर ज़रूर हटा देता है, जिससे असली असामान्यताएँ दिखाई देने लगती हैं। इसे log की सफ़ाई मानें, कभी एक नियंत्रण नहीं, और बदलने से पहले जाँच लें कि आपका sshd socket-activated तो नहीं है: Ubuntu 24.04 पर sshd_config में Port directive नज़रअंदाज़ हो जाता है और port ssh.socket का होता है।
क्या ऑटोमैटिक अपडेट सुबह चार बजे मेरी साइट तोड़ देंगे?
अगर सिर्फ़ security वाले हिस्से तक सीमित रखा जाए, तो बहुत ही कम। वे पैकेज उसी वर्शन में backport किए गए फ़िक्स हैं जो आप पहले से चला रहे हैं, कोई नया upstream release नहीं। असली जोखिम patch नहीं, reboot है — इसलिए विंडो ख़ुद चुनें, Automatic-Reboot-WithUsers को false सेट करें ताकि कोई लॉगिन हो तो यह रुक जाए, और अगर सर्विस वाकई unattended restart नहीं झेल सकती, तो needrestart -b को शेड्यूल पर चलाएँ और जो यह बताए उस पर अमल करें। एक ही रुख़ है जिसका कोई बचाव नहीं: ऐसे ऑटोमैटिक अपडेट जिनके साथ uptime सालों में नापा जाए।
मैं खुद को बाहर बंद कर बैठा। अब मेरे पास क्या विकल्प हैं?
पैनल से सर्वर को rescue मोड में बूट करें। यह RAM में एक Alpine environment शुरू करता है, जिसमें आपके अकाउंट वाली ही SSH keys होती हैं और आपकी डिस्क /dev/vda पर unmounted रहती है, ताकि आप उसे mount कर सकें, sshd drop-in या firewall फ़ाइल ठीक कर सकें, unmount करके reboot कर सकें। rescue बूट ख़ुद डिस्क पर कुछ भी नहीं छूता। rescue का host key fingerprint आपके सामान्य वाले से अलग होता है — यह अपेक्षित है, कोई interception नहीं।
क्या इसकी बजाय Lynis या कोई CIS hardening script चलाना अच्छा विचार है?
एक audit के तौर पर, हाँ; किसी विकल्प (substitute) के तौर पर, नहीं। Lynis वाकई एक उपयोगी दूसरी राय है और वह चीज़ें ढूँढ लेगा जिनका ज़िक्र इस पेज में नहीं है। Automated CIS remediation scripts एक अलग ही मामला हैं: वे सैकड़ों बदलाव लागू करते हैं जो किसी corporate workstation fleet के लिए बनाए गए हैं, जिनमें से कई किसी सर्वर को ऐसे तरीकों से तोड़ देते हैं जिन्हें हफ़्तों बाद ढूँढना मुश्किल होता है। पहले यह घंटा ख़ुद हाथ से करें, ताकि आप समझ सकें कि आपकी मशीन क्या कर रही है, फिर कोई auditor चलाएँ और उसके निष्कर्ष एक-एक करके पढ़ें।
क्या hardening मेरे सर्वर को गुमनाम (anonymous) बना देती है?
नहीं, और इन दोनों को एक समझ लेना एक आम और महँगी ग़लती है। Hardening यह नियंत्रित करती है कि कौन अंदर आ सकता है; anonymity यह नियंत्रित करती है कि किसे यह पता चल सकता है कि यह आपका है। पूरी तरह लॉक-डाउन किया गया सर्वर भी WHOIS रिकॉर्ड, दोबारा इस्तेमाल की गई SSH key, किसी analytics tag, या आपके घर के पते से हुए किसी admin login के ज़रिए मालिकाना हक़ लीक कर सकता है। Monero से पेमेंट करना और फिर सीधे अपने ही कनेक्शन से जुड़ जाना, पेमेंट को पूरी तरह बेअसर कर देता है — यह वे गलतियाँ जो आपको deanonymize कर देती हैं में शामिल है।
Keep exploring
LUKS से VPS डिस्क एन्क्रिप्ट करें
आधा काम यहाँ है: यह पेज नेटवर्क बंद करता है, वह पेज डिस्क की रक्षा करता है जब मशीन बंद हो।
वे गलतियाँ जो आपको deanonymize कर देती हैं
एक बेदाग़ hardened सर्वर जो फिर भी सबको बता देता है कि उसका मालिक कौन है। ये गलतियाँ व्यवहार की हैं, तकनीक की नहीं।
WireGuard VPS सेट अप करें
आपने अभी जो firewall बनाया है, उसके पीछे रखने लायक पहली सर्विस — और localhost से bind की गई हर चीज़ तक जाने वाला एक निजी दरवाज़ा।
Deploy your offshore server.
एक क्षेत्र चुनें। एक प्लान चुनें। एक कुंजी पेस्ट करें। भुगतान करें। अगले 47 सेकंड हमारे ज़िम्मे हैं।