खुला छोड़ा और भुला दिया गया पोर्ट सर्वर में घुसने का क्लासिक रास्ता है: सार्वजनिक पते पर डेटाबेस, डिबग डैशबोर्ड, ऐसा कंटेनर जिसने वह पोर्ट पब्लिश कर दिया जो कोई नहीं चाहता था। अगर आप दो कमांड और एक जाल जानते हैं तो जाँच में एक मिनट लगता है। नीचे का सब कुछ हमने अपनी इमेज से बने नए Ubuntu 24.04 सर्वर पर किया और दूसरी मशीन से स्कैन किया, इसलिए आउटपुट वही हैं जो आप अपने सर्वर पर देखेंगे।
1. क्या सुन रहा है
कमांड ss है। अक्षरों का मतलब है TCP, UDP, सुनने वाले सॉकेट, पोर्ट नंबर और प्रोसेस का नाम:
sudo ss -tulpn
नए सर्वर पर यह छह लाइनें छापता है:
Netid State Local Address:Port Process
udp UNCONN 127.0.0.54:53 systemd-resolve
udp UNCONN 127.0.0.53%lo:53 systemd-resolve
tcp LISTEN 127.0.0.54:53 systemd-resolve
tcp LISTEN 127.0.0.53%lo:53 systemd-resolve
tcp LISTEN 0.0.0.0:22 sshd
tcp LISTEN [::]:22 sshd
अहम कॉलम Local Address है। यह बताता है कि कौन जुड़ सकता है:
| पता | कौन पहुँच सकता है |
|---|---|
127.0.0.1:… या 127.0.0.53 | सिर्फ़ इसी सर्वर के प्रोग्राम |
0.0.0.0:… | IPv4 से कोई भी, जब तक फ़ायरवॉल न रोके |
[::]:… | IPv6 से कोई भी (आमतौर पर IPv4 से भी) |
10.0.0.5:… (कोई ख़ास पता) | कोई भी जो उस पते तक पहुँच सके |
यानी नया सर्वर बाहर सिर्फ़ एक चीज़ खोलता है: पोर्ट 22 पर SSH, IPv4 और IPv6 दोनों पर। 127.0.0.53 पर DNS रिज़ॉल्वर निजी है।
सिर्फ़ वही दिखाने के लिए जो इंटरनेट देख सकता है, loopback पतों को फ़िल्टर करें:
sudo ss -tlnp | awk 'NR>1 && $4 !~ /^(127\.|\[::1\])/ {print $4, $6}'
इसे हर इंस्टॉलेशन के बाद चलाएँ। हमने nginx, Docker और एक छोटा Python ऐप इंस्टॉल किया, और सूची 2 लाइनों से बढ़कर 10 हो गई, जिनमें 0.0.0.0:8081 पर docker-proxy और एक रैंडम localhost पोर्ट पर containerd का सॉकेट था।
2. कौन सी प्रोसेस पोर्ट घेरे हुए है
जब पोर्ट व्यस्त हो और आप जानना चाहें कि किसने लिया है:
sudo lsof -i :80 -P -n
sudo fuser 80/tcp
sudo ss -tlnp 'sport = :80'
पढ़ने में सबसे आसान lsof है। nginx के लिए इसने root के रूप में एक मास्टर प्रोसेस और www-data के रूप में एक वर्कर दिखाया, दोनों *:80 पर, IPv4 और IPv6 के लिए। fuser सिर्फ़ PID छापता है, जो स्क्रिप्ट में काम आता है। अगर पोर्ट खाली करना हो तो PID मारने के बजाय सेवा रोकें, वरना systemd उसे फिर चला देगा: sudo systemctl stop nginx।
3. इंटरनेट क्या देखता है
ss सर्वर का नज़रिया दिखाता है। इंटरनेट का नज़रिया अलग हो सकता है, क्योंकि बीच में फ़ायरवॉल है या सेवा 127.0.0.1 से बँधी है। असली तस्वीर देखने के लिए सर्वर को किसी दूसरी मशीन से स्कैन करें, अपने लैपटॉप या दूसरे सर्वर से। टूल nmap है (apt install nmap, या Windows और macOS पर nmap.org का इंस्टॉलर)।
nmap your-server-ip
nmap -p- your-server-ip
nmap -p 22,80,443,3306 your-server-ip
पहला रूप सबसे आम 1,000 पोर्ट जाँचता है, दूसरा सभी 65,535 और तीसरा एक सूची। हमारे नए सर्वर पर, किसी भी फ़ायरवॉल से पहले:
Not shown: 999 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
Nmap done: 1 IP address (1 host up) scanned in 6.83 seconds
सभी 65,535 पोर्ट के पूरे स्कैन में 8.9 सेकंड लगे और वही एक पोर्ट मिला। बंद पोर्ट तुरंत reset से जवाब देते हैं, इसलिए उनका स्कैन तेज़ होता है।
तीन स्थितियाँ मायने रखती हैं:
- open: किसी प्रोग्राम ने कनेक्शन स्वीकार किया। यही आपकी हमले की सतह है।
- closed: सर्वर ने जवाब दिया कि वहाँ कुछ नहीं सुन रहा। सुरक्षित है, पर यह पुष्टि करता है कि सर्वर मौजूद है और क्या नहीं चला रहा।
- filtered: कोई जवाब नहीं। फ़ायरवॉल ने पैकेट गिरा दिया। स्कैनर नहीं जान सकता कि पीछे कोई सेवा है या नहीं।
कुछ इंस्टॉल किए बिना एक पोर्ट के लिए nc -zv सर्वर-ip 443 जवाब में succeeded या refused देता है, और फ़िल्टर किए गए पोर्ट पर टाइमआउट तक अटका रहता है। UDP के लिए nmap में -sU जोड़ें और इंतज़ार के लिए तैयार रहें; हमारे सर्वर पर तीन आम UDP पोर्ट 53, 123 और 161 सभी closed थे।
NAT प्लान के लिए एक नोट: इंटरनेट से सिर्फ़ वह SSH पोर्ट पहुँचता है जो हमने आपके लिए फ़ॉरवर्ड किया है। साझा पते का स्कैन हमारा किनारा दिखाता है, आपका सर्वर नहीं, और बाकी पोर्ट पहुँच से बाहर हैं चाहे उन पर कुछ भी सुन रहा हो। अपने IPv4 पते वाले प्लान पर हर खुला पोर्ट आप ख़ुद संभालते हैं।
4. जो ज़रूरी नहीं उसे बंद करें
तीन तरीके, सबसे अच्छे से सबसे व्यापक तक।
localhost से बाँधें। अगर कोई सेवा सिर्फ़ सर्वर के प्रोग्राम इस्तेमाल करते हैं तो उसे 127.0.0.1 पर सुनने दें। हमने एक छोटा वेब ऐप --bind 127.0.0.1 8080 के साथ चलाया: ss ने उसे 127.0.0.1:8080 पर दिखाया और बाहर से nmap ने 8080/tcp closed बताया। डेटाबेस के लिए यही सही डिफ़ॉल्ट है: Ubuntu पर Redis, MySQL और PostgreSQL शुरू से ही localhost पर सुनते हैं, और Redis और MySQL के लिए हमारी गाइड इसे ऐसा ही रहने देती हैं।
सेवा रोकें। sudo systemctl disable --now नाम सुनने वाले को हमेशा के लिए हटा देता है। ss से जाँचें कि वह चला गया।
फ़ायरवॉल चालू करें। पहले SSH, फिर जो आप देते हैं उसे अनुमति दें, फिर चालू करें:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw enable
sudo ufw status verbose
बाहर से स्कैन पूरी तरह बदल गया:
Not shown: 997 filtered tcp ports (no-response)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
8081/tcp open blackice-icecap
Nmap done: 1 IP address (1 host up) scanned in 10.18 seconds
हर बिना अनुमति वाला पोर्ट closed से filtered हो गया, और 65,535 पोर्ट का पूरा स्कैन अब 8.9 की जगह 110 सेकंड लेने लगा। स्कैनर के लिए हर पोर्ट पर ज़्यादा समय, आपके सर्वर के बारे में कम जानकारी। हमारी UFW गाइड रेट लिमिट, एक IP को अनुमति देने और IPv6 को कवर करती है।
पर तीसरी लाइन देखें।
5. Docker का सरप्राइज़
पोर्ट 8081 फ़ायरवॉल चालू होने और उसे अनुमति देने वाले किसी नियम के बिना खुला रहा। यह पोर्ट उस कंटेनर का है जिसे हमने docker run -p 8081:80 nginx:alpine से चलाया था। Docker कर्नेल फ़ायरवॉल में अपने नियम जोड़ता है, और वे ufw के नियमों से पहले जाँचे जाते हैं। हमारे सर्वर पर उसने यह नियम लिखा:
-A DOCKER ! -i docker0 -p tcp --dport 8081 -j DNAT --to-destination 172.17.0.2:80
पोर्ट 8081 के लिए हर पैकेट ufw के कुछ कहने से पहले ही कंटेनर में भेज दिया जाता है। -p या ports: एंट्री वाला हर कंटेनर यही करता है, और ss इसे ईमानदारी से 0.0.0.0:8081 पर docker-proxy के रूप में दिखाता है।
समाधान है सिर्फ़ localhost पर पब्लिश करना:
docker rm -f web
docker run -d --name web -p 127.0.0.1:8081:80 nginx:alpine
Compose में ports: के नीचे "127.0.0.1:8081:80" लिखें। बदलाव के बाद ss ने 127.0.0.1:8081 दिखाया, Docker के नियम में -d 127.0.0.1/32 जुड़ गया, और बाहर से स्कैन ने 8081/tcp filtered बताया। सार्वजनिक हिस्से के लिए HTTPS के साथ nginx को reverse proxy के रूप में आगे रखें, ताकि सर्वर पर सिर्फ़ पोर्ट 22, 80 और 443 खुले हों।
हर बदलाव के बाद चेकलिस्ट
sudo ss -tulpn: क्या0.0.0.0या[::]वाली हर लाइन वही है जो आप खोलना चाहते थे?- लैपटॉप से
nmap सर्वर-ip: क्या खुले पोर्ट मेल खाते हैं? - सार्वजनिक पते पर डेटाबेस, कैश या एडमिन पैनल: आज ही
127.0.0.1या फ़ायरवॉल के पीछे ले जाएँ। - Docker की हर
ports:एंट्री: अगर सार्वजनिक वेब पोर्ट नहीं है तो क्या वह127.0.0.1:से शुरू होती है? - SSH सबके लिए खुला है: fail2ban या सिर्फ़ कुंजी से लॉगिन जोड़ें।
Windows Server पर यही जाँच Get-NetTCPConnection -State Listen से होती है, और नियम Windows Firewall में रहते हैं। $3 वाले Nano से शुरू होकर हर Linux प्लान का एक वर्ज़न अपने IPv4 पते के साथ है, और वहाँ जो आप ss में देखते हैं वही पूरी दुनिया देखती है, सिवाय उसके जिसे आपका फ़ायरवॉल रोकता है।
टिप्पणियाँ
अभी तक कोई टिप्पणी नहीं। पहले बनें।