SSD Nodes Learn 🎉 VPS $5.50/माह से
गाइड Matt Connorलेखक: Matt Connor

Rocky Linux और AlmaLinux पर SSH port कैसे बदलें

Rocky Linux या AlmaLinux पर SSH port बदलने के लिए firewalld, SELinux और sshd_config में बदलाव जरूरी हैं। सही क्रम का पालन करें ताकि आप सर्वर से बाहर न हों और daemon start हो सके।

SSH port बदलने के लिए यहाँ तीन चरणों की आवश्यकता क्यों है

Rocky Linux, AlmaLinux, CentOS Stream या Fedora पर SSH port बदलने के लिए केवल एक बदलाव पर्याप्त नहीं है। तीन अलग-अलग सिस्टम यह तय करते हैं कि नए port पर कनेक्शन काम करेगा या नहीं। firewalld यह तय करता है कि पैकेट मशीन तक पहुँचता है या नहीं। SELinux यह तय करता है कि sshd को उस port number पर bind करने की अनुमति है या नहीं। sshd_config यह तय करता है कि daemon किस port की मांग करता है। यदि आप SELinux वाला चरण छोड़ देते हैं, तो daemon start होने से मना कर देगा। यदि आप firewalld वाला चरण छोड़ देते हैं, तो यह start तो हो जाएगा और listen भी करेगा, लेकिन कोई भी उस तक नहीं पहुँच पाएगा।

Ubuntu पर यही काम एक बदलाव और restart से हो जाता है, क्योंकि Ubuntu SELinux के बजाय AppArmor का उपयोग करता है और ऐसा कोई profile नहीं देता जो यह सीमित करे कि sshd किन ports को bind कर सकता है। यदि वहाँ ufw चल रहा है, तो आपको केवल एक rule जोड़ना होता है। यही पूरा अंतर है। RHEL परिवार के OS में fresh install पर firewalld और SELinux दोनों सक्रिय (enforcing) होते हैं, और ये दोनों ही port numbers पर नज़र रखते हैं।

इस कार्य को इसी क्रम में करें ताकि आपका वर्तमान session हर चरण के दौरान सक्रिय रहे:

  1. firewalld में नया port खोलें, और अभी के लिए port 22 को खुला रहने दें।
  2. semanage का उपयोग करके नए port के लिए SELinux label जोड़ें।
  3. sshd configuration में port सेट करें।
  4. sshd को restart करें, फिर पहले terminal को बंद करने से पहले दूसरे terminal से नए port पर login करें।
शुरू करने से पहले अपने provider का web console (VNC या serial) ढूँढें, और जाँच लें कि आप उसके माध्यम से login कर सकते हैं। यदि बदलाव गलत हो जाता है, तो वह console ही वापस अंदर जाने का आपका एकमात्र रास्ता है। port बदलना उन सबसे सामान्य कारणों में से एक है जिनकी वजह से उपयोगकर्ता खुद को उस सर्वर से बाहर लॉक कर लेते हैं जिसके लिए उन्होंने अभी भुगतान किया है।

सबसे पहले, semanage इंस्टॉल करें

semanage वह टूल है जो SELinux policy सेटिंग्स को एडिट करता है, और Rocky Linux या AlmaLinux के minimal इंस्टॉलेशन में यह शामिल नहीं होता है। यह policycoreutils-python-utils पैकेज में उपलब्ध है।

sudo dnf install -y policycoreutils-python-utils

उस पैकेज को इंस्टॉल किए बिना कमांड चलाने पर sudo: semanage: command not found एरर मिलता है, और यहीं पर कई पाठक यह मान लेते हैं कि SELinux इंस्टॉल नहीं है और वे इस स्टेप को छोड़ देते हैं। SELinux इंस्टॉल होता है। केवल मैनेजमेंट टूल गायब होता है। यदि dnf सिंटैक्स आपके लिए नया है, तो dnf और apt कमांड के समकक्ष इसे आपकी जानी-पहचानी कमांड्स से जोड़ते हैं।

एक पोर्ट चुनें और सुनिश्चित करें कि वह किसी के द्वारा उपयोग में नहीं है

1024 से 65535 के बीच कोई भी खाली TCP पोर्ट काम करेगा। किसी एक को चुनने से पहले ये दो जाँचें करें:

sudo ss -tlnp | grep -w 2222
sudo semanage port -l | grep -w 2222

पहली कमांड दिखाती है कि क्या कोई process पहले से ही उस नंबर पर listening है। दूसरी कमांड दिखाती है कि क्या SELinux policy ने इसे पहले से ही किसी अन्य service type के लिए असाइन किया है। एक खाली पोर्ट होने पर दोनों कमांड्स से कोई आउटपुट नहीं मिलेगा। यदि policy ने पहले से ही उस पर दावा किया है, तो चरण 2 में semanage port -a, ValueError: Port tcp/2222 already defined के साथ विफल हो जाएगा, और इसका समाधान एक अलग नंबर चुनना है।

इस गाइड में उदाहरण के तौर पर 2222 का उपयोग किया गया है। यह 22 के बाद किसी scanner द्वारा आजमाया जाने वाला पहला पोर्ट भी है, इसलिए वास्तविक सर्वर पर कुछ कम स्पष्ट पोर्ट चुनें।

चरण 1: firewalld में पोर्ट खोलें

sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-ports

--permanent कमांड नियम को डिस्क पर मौजूद ज़ोन फ़ाइल में लिखता है और चल रहे फ़ायरवॉल में कोई बदलाव नहीं करता है। --reload कमांड डिस्क पर मौजूद कॉन्फ़िगरेशन को चल रहे फ़ायरवॉल में लोड करता है। यदि आप रीलोड करना छोड़ देते हैं, तो नियम मौजूद तो रहेगा लेकिन अगली बार firewalld रीस्टार्ट होने तक प्रभावी नहीं होगा। यह इस पूरी प्रक्रिया के विफल होने का सबसे आम कारण है।

फिलहाल ssh सर्विस एंट्री को न छेड़ें। यह एंट्री पोर्ट 22 को खुला रखती है और परीक्षण के दौरान यह आपका बैकअप विकल्प है।

अपने प्रदाता के कंट्रोल पैनल की भी जाँच करें। कई होस्ट VPS के सामने ऑपरेटिंग सिस्टम के बाहर एक नेटवर्क फ़ायरवॉल चलाते हैं, इसलिए firewalld में खोला गया पोर्ट अपस्ट्रीम पर ड्रॉप किया जा सकता है। VPS के लिए firewalld बेसिक्स गाइड में ज़ोन और रनटाइम बनाम परमानेंट कॉन्फ़िगरेशन के अंतर को समझाया गया है, यदि यह मॉडल आपके लिए नया है।

चरण 2: SELinux के लिए पोर्ट को लेबल करें

sudo semanage port -a -t ssh_port_t -p tcp 2222
sudo semanage port -l | grep ssh_port_t

-a एक नया पोर्ट असाइनमेंट जोड़ता है। -t ssh_port_t वह प्रकार है जिसे SSH पोर्ट्स धारण करते हैं। दूसरा कमांड उन सभी पोर्ट्स की सूची दिखाता है जिन्हें अब ssh_port_t कवर करता है, ताकि आप डेमन (daemon) को छूने से पहले यह पुष्टि कर सकें कि आपका नंबर जुड़ गया है।

SELinux पोर्ट को ब्लॉक क्यों करता है

SELinux (Security-Enhanced Linux) सिस्टम पर मौजूद हर ऑब्जेक्ट को एक लेबल देता है, और TCP पोर्ट नंबर भी अन्य ऑब्जेक्ट्स की तरह ही होते हैं। SSH daemon एक डोमेन में चलता है जिसे sshd_t कहा जाता है। पॉलिसी sshd_t को ssh_port_t लेबल वाले TCP पोर्ट्स पर बाइंड करने की अनुमति देती है, और डिफ़ॉल्ट रूप से केवल 22 पोर्ट पर ही यह लेबल होता है। यदि आप daemon को 2222 पर बाइंड करने के लिए कहते हैं, तो kernel लेबल की जाँच करता है, उस नंबर पर असाइन की गई जेनेरिक पॉलिसी टाइप को देखता है, और सॉकेट पर name_bind अनुमति देने से इनकार कर देता है।

यही कारण है कि यह विफलता firewall की समस्या जैसी नहीं लगती। Kernel listening सॉकेट के बनने से पहले ही इसे अस्वीकार कर देता है, इसलिए sshd त्रुटि की रिपोर्ट करता है और बंद हो जाता है। Firewall की समस्या इसके विपरीत होती है: daemon चल रहा होता है और ठीक होता है, लेकिन आने वाले पैकेट रास्ते में ही हटा दिए जाते हैं।

getenforce आपको बताता है कि बॉक्स किस मोड में है। Permissive पर, इनकार (denial) को रिकॉर्ड तो किया जाता है लेकिन लागू नहीं किया जाता, इसलिए पोर्ट परिवर्तन काम करता हुआ प्रतीत होता है, लेकिन जिस दिन कोई setenforce 1 चलाता है या बॉक्स enforcing मोड में रीबूट होता है, उस दिन यह काम करना बंद कर देता है। पोर्ट को किसी भी स्थिति में लेबल करें। सर्वर के लिए SELinux बेसिक्स गाइड में मोड्स, कॉन्टेक्स्ट और बूलियन्स के बारे में विस्तार से बताया गया है।

चरण 3: sshd configuration में port सेट करें

Rocky Linux 9 और 10, AlmaLinux 9 और 10, तथा वर्तमान Fedora पर, /etc/ssh/sshd_config एक include लाइन के साथ शुरू होता है, इसलिए आपके बदलाव के लिए सबसे सही जगह एक drop-in फाइल है। इससे package updates के दौरान आपके द्वारा किए गए बदलाव सुरक्षित रहते हैं।

grep -n '^Include' /etc/ssh/sshd_config
echo 'Port 2222' | sudo tee /etc/ssh/sshd_config.d/10-port.conf
sudo sshd -t

यदि grep में कोई Include लाइन नहीं मिलती है, जो कि Rocky Linux 8 और अन्य पुराने images के मामले में होता है, तो Port 2222 को सीधे /etc/ssh/sshd_config में डालें। sshd -t पूरी configuration को, drop-ins सहित, पार्स करता है और syntax errors की रिपोर्ट करता है। restart करने से पहले यह सुनिश्चित करें कि कोई error न हो, क्योंकि यदि configuration पार्स होने में विफल रहती है, तो daemon दोबारा start नहीं होगा।

Port एक से अधिक बार आ सकता है, और sshd सूचीबद्ध प्रत्येक port पर listen करता है। पहले दिन के लिए Port 22 को Port 2222 के साथ रखना एक आसान सुरक्षा उपाय है, बशर्ते आप इसे बाद में हटाना याद रखें।

क्या आपका sshd एक socket unit द्वारा शुरू किया गया है?

कुछ images SSH को long-running service के बजाय systemd socket activation के माध्यम से शुरू करती हैं। जहाँ ऐसा सेटअप होता है, वहाँ systemd listening socket को नियंत्रित करता है और connections को sshd को सौंपता है, इसलिए sshd_config में मौजूद Port लाइन पूरी तरह से अनदेखी कर दी जाती है। कुछ भी restart करने से पहले जाँच लें:

systemctl is-enabled sshd.socket

enabled उत्तर का अर्थ है कि port socket unit पर सेट है, न कि sshd_config में:

sudo systemctl edit sshd.socket
[Socket]
ListenStream=
ListenStream=2222

खाली ListenStream= की आवश्यकता होती है। मान drop-ins में जुड़ते जाते हैं, इसलिए सूची को पहले खाली किए बिना, socket 22 के साथ-साथ 2222 पर भी listen करना जारी रखेगा। इसे sudo systemctl daemon-reload और फिर sudo systemctl restart sshd.socket के साथ लागू करें। यदि unit disabled है या आपके सर्वर पर मौजूद नहीं है, तो यह अनुभाग आप पर लागू नहीं होता है।

चरण 4: restart करें, फिर दूसरे terminal से test करें

sudo systemctl restart sshd
systemctl status sshd
sudo ss -tlnp | grep sshd

इस terminal को खुला रखें। इससे log out न करें। अपनी machine पर एक दूसरा terminal खोलें और नए port पर connect करें:

ssh -p 2222 youruser@203.0.113.10

पहले session को केवल तभी बंद करें जब वह दूसरा login सफल हो जाए। यदि यह काम नहीं करता है, तो आपके पास अभी भी एक shell मौजूद है जिससे आप सब कुछ undo कर सकते हैं। यह एक आदत ही पांच मिनट के बदलाव और provider console पर बिताए गए पूरे दोपहर के समय के बीच का अंतर है।

Firewall drop या SELinux denial? दोनों में अंतर कैसे पहचानें

आपके लैपटॉप से ये दोनों विफलताएं लगभग एक जैसी दिखती हैं। सर्वर पर ये बिल्कुल अलग होती हैं।

  • यदि systemctl status sshd यह दिखाता है कि यूनिट विफल हो गई है, तो डेमन को उसका सॉकेट कभी नहीं मिला। यह एक कॉन्फ़िगरेशन त्रुटि या SELinux denial है।
  • यदि यूनिट सक्रिय है और ss -tlnp यह दिखाता है कि sshd नए पोर्ट से बाइंड हो गया है, तो डेमन ठीक है और समस्या नेटवर्क पथ पर है: firewalld, प्रदाता का अलग फायरवॉल, या वह पता और पोर्ट जिसे आपने डायल किया है।

SELinux मामले के लिए, अनुमान लगाने के बजाय ऑडिट रिकॉर्ड पढ़ें:

sudo ausearch -m AVC -ts recent
sudo journalctl -u sshd -n 50 --no-pager

एक name_bind denial, क्लास tcp_socket पर, comm="sshd" में प्रोसेस का नाम, src= में पोर्ट नंबर, और tcontext= में वह लेबल बताता है जो पोर्ट पर वास्तव में लगा है। वह अंतिम फ़ील्ड ही उत्तर है। ssh_port_t के अलावा कुछ भी होने का मतलब है कि चरण 2 आपके द्वारा उपयोग किए जा रहे पोर्ट पर लागू नहीं हुआ, आमतौर पर नंबर में टाइपिंग की गलती या गलत प्रोटोकॉल के कारण। यदि आप चाहते हैं कि sealert रिकॉर्ड को एक वाक्य में बदल दे, तो setroubleshoot-server इंस्टॉल करें।

जब कर्नल बाइंड करने से मना कर देता है, तो sshd स्वयं जो संदेश लिखता है वह इस प्रकार है:

error: Bind to port 2222 on 0.0.0.0 failed: Permission denied.

1024 से ऊपर के पोर्ट पर Permission denied, जहाँ बाइंड करने के लिए root विशेषाधिकार की आवश्यकता नहीं होती, SELinux का संकेत है। उसी लाइन में Address already in use एक अलग दोष है: कोई अन्य प्रोसेस पोर्ट को होल्ड किए हुए है। क्लाइंट साइड से, connection refused और connection timed out के बीच का अंतर दोनों नेटवर्क मामलों को अलग करता है, क्योंकि refusal का मतलब है कि आपका पैकेट होस्ट तक पहुँच गया और वहाँ कुछ भी लिसन नहीं कर रहा था, जबकि timeout का मतलब है कि किसी ने कोई जवाब नहीं दिया।

Port 22 को बंद करें और अपने clients को अपडेट करें

जब नए port पर कई बार login सफलतापूर्वक हो जाए, तो port 22 को बंद कर दें:

sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

Port 22 पर SELinux label को न बदलें। यह base policy से आता है, और जब firewall packets को अंदर आने से रोक देता है, तो यह label कोई access नहीं देता।

इसके बाद clients को ठीक करें, क्योंकि जिन tools ने default port मान रखा था, उन्हें अब नया port बताना होगा। हर बार -p टाइप करने के बजाय, इसे एक बार अपनी मशीन पर ~/.ssh/config में डाल दें:

Host myvps
  HostName 203.0.113.10
  Port 2222
  User youruser

scp, sftp, rsync और Ansible सभी इस file को पढ़ते हैं। Backup jobs, monitoring checks और cron scripts जिनमें port 22 hardcode किया गया है, वे इसे नहीं पढ़ते, इसलिए जब तक बदलाव आपके दिमाग में ताज़ा है, उन्हें ढूँढकर ठीक कर लें।

पोर्ट बदलने से क्या लाभ होता है और क्या नहीं

यह लॉग के शोर (log noise) को कम करता है। स्वचालित स्कैनर्स लगातार port 22 पर हमला करते हैं, और इसे बदलने से उनमें से अधिकांश लाइन्स जर्नल से हट जाती हैं, जिससे वास्तविक घटनाओं को देखना आसान हो जाता है। यह कोई सुरक्षा नियंत्रण (security control) नहीं है। पोर्ट की पूरी रेंज को स्कैन करने वाला कोई भी स्कैनर आपके daemon को ढूंढ लेगा और उसका version banner पढ़ लेगा। पोर्ट बदलने को केवल रखरखाव (housekeeping) का काम मानें, और वास्तविक सुरक्षा के लिए key-only authentication का उपयोग करें और password logins को बंद कर दें, जैसा कि VPS के लिए SSH hardening गाइड में चरण-दर-चरण समझाया गया है।

ऊपर दी गई हर बात दोनों प्रमुख RHEL rebuilds पर समान रूप से काम करती है, क्योंकि वे एक ही source से बनी हैं। यदि आप अभी भी उनके बीच चयन कर रहे हैं, तो Rocky Linux और AlmaLinux की तुलना देखें। किसी भी पुरानी गाइड का पालन करने से पहले cat /etc/os-release के साथ यह जांच लें कि आपको वास्तव में कौन सा release दिया गया है। Rocky Linux 8 के लिए लिखी गई गाइड अभी भी अच्छी रैंक करती हैं और उनके semanage और firewall-cmd चरण सही हैं, लेकिन Rocky 8 में कोई sshd_config.d include लाइन नहीं है और न ही इसमें कोई socket unit है जिसके बारे में सोचना पड़े, इसलिए उन गाइड का sshd वाला हिस्सा वर्तमान सिस्टम से मेल नहीं खाता है।

fail2ban को नए पोर्ट के बारे में सूचित करना होगा

fail2ban बेस रिपॉजिटरी में उपलब्ध नहीं है। यह EPEL (extra packages for enterprise Linux) से आता है:

sudo dnf install -y epel-release
sudo dnf install -y fail2ban fail2ban-firewalld

fail2ban-firewalld सबपैकेज fail2ban को firewalld के माध्यम से बैन लागू करने की सुविधा देता है, जो कि ऐसे सर्वर के लिए सही है जहाँ firewalld ही ruleset को नियंत्रित करता है।

स्टॉक sshd जेल port = ssh को सेट करता है, और यह नाम /etc/services के माध्यम से 22 पर रिजॉल्व होता है। आपके बदलाव के बाद, जेल ऐसे पोर्ट की निगरानी कर रही है जिस पर कोई हमला नहीं हो रहा है, इसलिए जब 2222 पर लॉगिन विफलताओं की संख्या बढ़ती है, तो यह किसी को बैन नहीं करती। /etc/fail2ban/jail.local में पोर्ट को नंबर द्वारा सेट करें:

[sshd]
enabled = true
port = 2222
backend = systemd
maxretry = 5
bantime = 3600

backend = systemd विफलताओं को /var/log/secure के बजाय journal से पढ़ता है, जो कि minimal install पर एक सुरक्षित विकल्प है जहाँ rsyslog मौजूद नहीं हो सकता है। इसे sudo systemctl enable --now fail2ban के साथ शुरू करें और sudo fail2ban-client status sshd के साथ जेल का निरीक्षण करें। जेल का सिंटैक्स वही है जो Ubuntu 24.04 पर SSH के लिए fail2ban सेटअप में उपयोग किया गया है। केवल पैकेज का स्रोत और बैन एक्शन अलग हैं।

पोर्ट से अधिक महत्वपूर्ण पैचिंग है

एक सर्वर जिसका SSH पोर्ट बदल दिया गया है लेकिन जिसमें चार महीनों से सुरक्षा अपडेट लागू नहीं किए गए हैं, वह उस सर्वर से अधिक असुरक्षित है जो पोर्ट 22 पर चल रहा है और हर रात खुद को पैच करता है। जब आप root के रूप में लॉग इन हों, तो उसी सत्र में unattended updates को सक्षम करें: Rocky Linux और AlmaLinux पर automatic dnf updates में टाइमर और अपडेट डाउनलोड करने व उन्हें लागू करने के विकल्पों के बारे में जानकारी दी गई है।

FAQ

Rocky Linux पर port बदलने के बाद sshd start क्यों नहीं होता है?

इसका कारण लगभग हमेशा SELinux port label का न होना होता है। sshd, sshd_t domain में confined होकर चलता है, और policy इसे केवल उन ports पर bind होने देती है जो ssh_port_t के रूप में label किए गए हैं, जिसमें डिफ़ॉल्ट रूप से केवल port 22 शामिल है। Kernel bind करने से मना कर देता है, इसलिए daemon listen करने के बजाय exit हो जाता है, और journalctl -u sshd में error: Bind to port 2222 on 0.0.0.0 failed: Permission denied. के रूप में एक लाइन दिखाई देती है। अपना port number डालकर sudo semanage port -a -t ssh_port_t -p tcp 2222 चलाएं, फिर service को restart करें। यदि semanage नहीं मिलता है, तो पहले policycoreutils-python-utils install करें।

यदि SELinux permissive mode में है, तो क्या मुझे अभी भी semanage की आवश्यकता है?

हाँ। Permissive mode में denial को record किया जाता है लेकिन bind की अनुमति दे दी जाती है, इसलिए ऐसा लगता है कि बदलाव सफल रहा। Label अभी भी गायब होता है। जिस क्षण कोई setenforce 1 चलाता है, या मशीन /etc/selinux/config में SELINUX=enforcing के साथ boot होती है, sshd उस port पर start होना बंद कर देता है। Label जोड़ने में केवल एक command लगती है और यह उस विफलता को दूर करता है जो अन्यथा हफ्तों बाद बिना किसी स्पष्ट कारण के सामने आ सकती है।

Port label किया गया है और sshd चल रहा है, तो मेरा connection time out क्यों हो रहा है?

Daemon के चलने का मतलब है कि SELinux संतुष्ट है, इसलिए packet रास्ते में ही drop हो रहा है। अपने port के लिए sudo firewall-cmd --list-ports की जाँच करें, और पुष्टि करें कि आपने --permanent rule के बाद firewall-cmd --reload चलाया है, क्योंकि केवल permanent rule कभी भी चल रहे firewall तक नहीं पहुँचता है। फिर VPS के सामने किसी अलग network firewall के लिए अपने host के control panel की जाँच करें। यह दूसरी जगह है जहाँ लोग block हो जाते हैं, और operating system के अंदर कुछ भी इसे नहीं दिखाएगा।

मुझे 22 के बजाय किस port का उपयोग करना चाहिए?

1024 से 65535 के बीच कोई भी खाली TCP port। वास्तविक सर्वर पर 2222 और 22222 से बचें, क्योंकि scanners 22 के तुरंत बाद इन्हें ही try करते हैं। sudo ss -tlnp के साथ पुष्टि करें कि वह number खाली है, sudo semanage port -l के साथ पुष्टि करें कि SELinux policy ने पहले से ही उस पर दावा नहीं किया है, और ऐसी किसी भी चीज़ को छोड़ दें जो भविष्य में install की जाने वाली किसी service के लिए निर्धारित हो। एक बड़ा, याद न रहने वाला number ठीक है, क्योंकि आप इसे एक बार ~/.ssh/config में लिख देंगे और फिर कभी इसे type नहीं करेंगे।