SSD Nodes Learn 🎉 VPS $5.50/महिन्यापासून
मार्गदर्शक Matt Connorद्वारे Matt Connor

SELinux आणि firewalld सह SSH पोर्ट कसा बदलावा

Rocky Linux किंवा AlmaLinux मध्ये SSH पोर्ट बदलताना firewalld, SELinux port label आणि sshd_config हा क्रम पाळा. port 22 बंद करण्यापूर्वी session सुरक्षित ठेवा.

येथे SSH पोर्ट बदलण्यासाठी तीन पायऱ्या का आवश्यक आहेत

Rocky Linux, AlmaLinux, CentOS Stream किंवा Fedora वर SSH पोर्ट बदलण्यासाठी केवळ एक संपादन पुरेसे नसते. नवीन पोर्टवरील कनेक्शन कार्य करेल की नाही, हे तीन स्वतंत्र system ठरवतात. firewalld हे packet मशीनपर्यंत पोहोचू द्यायचे की नाही ते ठरवते. SELinux हे sshd ला त्या पोर्ट क्रमांकावर bind करण्याची परवानगी आहे की नाही ते ठरवते. sshd_config daemon ने कोणता पोर्ट वापरायचा अशी विनंती करतो ते ठरवते. SELinux मधील पायरी चुकल्यास daemon सुरू होण्यास नकार देतो. firewalld मधील पायरी चुकल्यास daemon सुरू होतो आणि listen करतो, परंतु त्याच्यापर्यंत कोणीही पोहोचू शकत नाही.

Ubuntu वर हेच काम एक संपादन आणि restart करून पूर्ण होते, कारण Ubuntu मध्ये SELinux ऐवजी AppArmor वापरले जाते आणि sshd कोणत्या पोर्टवर bind करू शकतो यावर मर्यादा घालणारे profile समाविष्ट नसते. तेथे ufw चालू असल्यास, एक rule जोडा. एवढाच मुख्य फरक आहे. RHEL family मध्ये fresh install नंतर firewalld सुरू असते आणि SELinux enforcing mode मध्ये असते. या दोन्ही system ना पोर्ट क्रमांक महत्त्वाचे असतात.

हे काम पुढील क्रमाने करा. त्यामुळे प्रत्येक पायरीनंतर तुमचे सध्याचे session सुरू राहील:

  1. नवीन पोर्ट firewalld मध्ये उघडा आणि सध्या port 22 उघडा ठेवा.
  2. semanage वापरून नवीन पोर्टसाठी SELinux label जोडा.
  3. sshd configuration मध्ये पोर्ट निश्चित करा.
  4. sshd restart करा. त्यानंतर पहिला terminal बंद करण्यापूर्वी दुसऱ्या terminal मधून नवीन पोर्टवर login करा.
सुरू करण्यापूर्वी provider चे web console (VNC किंवा serial) शोधा आणि त्यातून login करता येते का ते तपासा. बदल अयशस्वी झाल्यास त्या console द्वारे पुन्हा server मध्ये प्रवेश करता येईल. नुकताच पैसे देऊन घेतलेल्या server मधून tenant स्वतःला बाहेर लॉक करून घेण्याचे सर्वात सामान्य कारणांपैकी एक म्हणजे पोर्ट बदलणे.

सर्वप्रथम semanage स्थापित करा

semanage हे SELinux धोरण सेटिंग्ज संपादित करणारे साधन आहे. Minimal Rocky Linux किंवा AlmaLinux install मध्ये ते समाविष्ट नसते. ते policycoreutils-python-utils मध्ये उपलब्ध असते.

sudo dnf install -y policycoreutils-python-utils

ते package स्थापित करण्यापूर्वी command चालवल्यास sudo: semanage: command not found दिसते. याच टप्प्यावर अनेक वाचक SELinux स्थापित केलेले नाही असे मानतात आणि हा टप्पा वगळतात. SELinux स्थापित आहे. फक्त management tool उपलब्ध नाही. dnf syntax तुमच्यासाठी नवीन असल्यास, dnf आणि apt command चे समतुल्य तुम्हाला परिचित असलेल्या पद्धतीशी त्याचा संबंध दाखवतात.

पोर्ट निवडा आणि तो आधीपासून वापरात नाही याची पडताळणी करा

1024 ते 65535 मधील कोणताही मोकळा TCP पोर्ट वापरता येतो. एखादा पोर्ट निश्चित करण्यापूर्वी या दोन तपासण्या करा:

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

पहिल्या तपासणीत त्या क्रमांकावर एखादी प्रक्रिया आधीपासून listening आहे का ते दिसते. दुसऱ्या तपासणीत SELinux policy ने तो पोर्ट इतर कोणत्यातरी service type ला आधीच नियुक्त केला आहे का ते दिसते. मोकळ्या पोर्टसाठी दोन्ही तपासण्यांमध्ये कोणतेही output मिळत नाही. Policy ने तो पोर्ट आधीच ताब्यात घेतला असल्यास, पायरी 2 मधील semanage port -a कमांड ValueError: Port tcp/2222 already defined सह अयशस्वी होते. अशा वेळी दुसरा पोर्ट क्रमांक निवडा.

या मार्गदर्शकात सर्वत्र 2222 हे उदाहरण म्हणून वापरले आहे. 22 नंतर scanner प्रथम तपासत असलेल्या पोर्टपैकी हा एक आहे. त्यामुळे प्रत्यक्ष server वर कमी स्पष्ट दिसणारा पोर्ट निवडा.

पायरी 1: firewalld मध्ये पोर्ट उघडा

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

--permanent डिस्कवरील zone file मध्ये नियम लिहितो आणि चालू firewall मध्ये कोणताही बदल करत नाही. --reload डिस्कवरील configuration चालू firewall मध्ये लोड करतो. Reload टाळल्यास नियम अस्तित्वात राहतो, पण firewalld पुढील वेळी restart होईपर्यंत त्याचा कोणताही परिणाम होत नाही. या संपूर्ण प्रक्रियेत कोणतेही स्पष्ट कारण नसताना अपयश दिसण्याचे हे सर्वात सामान्य कारणांपैकी एक आहे.

सध्या ssh service entry मध्ये बदल करू नका. या entry मुळे port 22 उघडा राहतो आणि चाचणी करताना तो तुमचा fallback असतो.

तुमच्या provider चे control panel देखील तपासा. अनेक hosts VPS च्या पुढे, operating system च्या बाहेर, network firewall चालवतात. त्यामुळे firewalld मध्ये उघडलेला पोर्ट upstream स्तरावर अद्याप drop होऊ शकतो. हे मॉडेल तुमच्यासाठी नवीन असल्यास VPS साठी firewalld मूलभूत मार्गदर्शक मध्ये zones आणि runtime वि. permanent विभागणीचे स्पष्टीकरण दिले आहे.

पायरी 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) प्रणालीवरील प्रत्येक ऑब्जेक्टला एक label देते. TCP port numbers हे इतर कोणत्याही ऑब्जेक्टप्रमाणेच ऑब्जेक्ट असतात. SSH daemon sshd_t नावाच्या domain मध्ये confined असतो. Policy sshd_t ला ssh_port_t असे labelled असलेले TCP ports bind करण्याची परवानगी देते. सुरुवातीच्या configuration मध्ये हे label असलेला एकमेव port 22 असतो. Daemon ला 2222 वर bind करण्यास सांगितल्यावर kernel त्या port चे label तपासतो. त्या क्रमांकाला policy ने दिलेला generic type आढळतो. त्यामुळे socket वर name_bind permission नाकारली जाते.

म्हणून ही त्रुटी firewall समस्येसारखी दिसत नाही. Listening socket अस्तित्वात येण्यापूर्वीच kernel विनंती नाकारतो. त्यामुळे sshd त्रुटी नोंदवून बंद होते. Firewall समस्येत याच्या उलट परिस्थिती असते. Daemon सुरू आणि व्यवस्थित चालू असतो. Packets आत येताना discard केले जातात.

getenforce प्रणाली कोणत्या mode मध्ये आहे ते दाखवते. Permissive मध्ये denial नोंदवला जातो, पण तो लागू केला जात नाही. त्यामुळे port change कार्यरत असल्याचे दिसते. नंतर कोणी setenforce 1 चालवले किंवा प्रणाली enforcing mode मध्ये reboot झाली की ते काम करणे थांबवते. दोन्ही परिस्थितींमध्ये port ला योग्य label द्या. सर्व्हरसाठी SELinux मूलभूत मार्गदर्शक modes, contexts आणि booleans यांचे सविस्तर स्पष्टीकरण देते.

पायरी 3: sshd configuration मध्ये पोर्ट सेट करा

Rocky Linux 9 आणि 10, AlmaLinux 9 आणि 10 तसेच सध्याच्या Fedora मध्ये /etc/ssh/sshd_config ची सुरुवात include line ने होते. त्यामुळे तुमचा बदल drop-in file मध्ये करणे योग्य ठरते. त्यानंतर 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 line सापडली नाही, तर Rocky Linux 8 आणि इतर जुन्या images मध्ये असे आढळते. अशा वेळी Port 2222 थेट /etc/ssh/sshd_config मध्ये जोडा. sshd -t संपूर्ण configuration चे parsing करते. यात drop-ins चा देखील समावेश असतो आणि syntax errors दाखवते. ती दाखवणारी प्रत्येक समस्या restart करण्यापूर्वी दुरुस्त करा. Configuration चे parsing अयशस्वी झाल्यास daemon पुन्हा सुरू होत नाही.

Port एकापेक्षा अधिक वेळा दिसू शकते. sshd दिलेल्या प्रत्येक पोर्टवर ऐकते. पहिल्या दिवसासाठी Port 22 हे Port 2222 सोबत ठेवणे सुरक्षिततेसाठी सोपे अतिरिक्त उपाय आहे. मात्र ते नंतर काढून टाकायचे लक्षात ठेवा.

sshd socket unit द्वारे सुरू होत आहे का?

काही images दीर्घकाळ चालणाऱ्या service ऐवजी systemd socket activation द्वारे SSH सुरू करतात. अशी रचना असल्यास listening socket systemd च्या नियंत्रणाखाली असतो आणि connections sshd कडे सोपवल्या जातात. त्यामुळे sshd_config मधील Port ओळ पूर्णपणे दुर्लक्षित केली जाते. कोणतीही सेवा restart करण्यापूर्वी तपासा:

systemctl is-enabled sshd.socket

enabled उत्तराचा अर्थ port sshd_config मध्ये नसून socket unit मध्ये निश्चित केला आहे:

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

रिकामे ListenStream= आवश्यक आहे. drop-ins मधील values एकत्र साठवल्या जातात. त्यामुळे यादी प्रथम रिकामी करण्यासाठी रिकामी assignment न दिल्यास socket 2222 सोबत 22 वरही listening ठेवतो. sudo systemctl daemon-reload वापरून हा बदल लागू करा आणि त्यानंतर sudo systemctl restart sshd.socket चालवा. तुमच्या server वर unit disabled असेल किंवा अस्तित्वात नसेल, तर हा विभाग लागू होत नाही.

पायरी 4: रीस्टार्ट करा आणि त्यानंतर दुसऱ्या टर्मिनलमधून चाचणी घ्या

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

हे टर्मिनल उघडे ठेवा. त्यातून लॉग आउट करू नका. स्वतःच्या मशीनवर दुसरे टर्मिनल उघडा आणि नवीन पोर्टवर कनेक्ट करा:

ssh -p 2222 youruser@203.0.113.10

दुसऱ्या लॉगिनने यशस्वीपणे काम केल्यानंतरच पहिले सत्र बंद करा. ते काम झाले नाही, तरी सर्व बदल पूर्ववत करण्यासाठी तुमच्याकडे एक shell सुरू असेल. ही एक सवय पाच मिनिटांच्या बदलात आणि provider console वर दुपारभर कराव्या लागणाऱ्या कामात फरक करते.

फायरवॉलने केलेला drop की SELinux denial? दोन्ही कसे ओळखावे

तुमच्या laptop वरून हे दोन्ही अपयश जवळजवळ सारखेच दिसतात. सर्व्हरवर मात्र त्यांचे स्वरूप पूर्णपणे वेगळे दिसते.

  • `systemctl status sshd` मध्ये unit failed असे दिसत असेल, तर daemon ला त्याचा socket मिळालेलाच नाही. हे configuration error किंवा SELinux denial असते.
  • unit active असेल आणि `ss -tlnp` मध्ये sshd नवीन port वर bound असल्याचे दिसत असेल, तर daemon व्यवस्थित आहे. समस्या network path मध्ये आहे: firewalld, provider चा स्वतंत्र firewall किंवा तुम्ही वापरलेला address आणि port.

SELinux ची स्थिती असल्यास अंदाज न लावता audit record वाचा:

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

`name_bind denial मधील class tcp_socket मध्ये comm="sshd" मधील process, src= मधील port number आणि tcontext= मध्ये त्या port वर प्रत्यक्ष लागू असलेला label नमूद असतो. शेवटचे field हेच उत्तर देते. ssh_port_t व्यतिरिक्त काहीही दिसत असल्यास, तुम्ही वापरत असलेल्या port वर step 2 लागू झालेला नाही. याचे नेहमीचे कारण म्हणजे number मधील typo किंवा चुकीचा protocol. Record चे वाक्यात रूपांतर करण्यासाठी setroubleshoot-server install करायचे असल्यास sealert` वापरा.

Kernel ने bind नाकारल्यावर sshd स्वतः लिहिणारा message असा दिसतो:

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

1024 पेक्षा मोठ्या port वर `Permission denied दिसणे, जिथे bind करण्यासाठी root privilege आवश्यक नसतो, हे SELinux चे लक्षण आहे. त्याच line मधील Address already in use` हा वेगळा fault दर्शवतो: दुसरा process तो port वापरत आहे. Client कडून पाहिल्यास, connection refused आणि connection timed out यांतील फरक या दोन्ही network स्थिती वेगळ्या करतो. Refusal म्हणजे तुमचे packet host पर्यंत पोहोचले आणि कोणताही process listening नव्हता. Timeout म्हणजे कोणत्याही process ने उत्तर दिले नाही.

पोर्ट 22 बंद करा आणि clients अपडेट करा

नवीन पोर्टवर अनेक login यशस्वी झाल्यानंतर पोर्ट 22 वरील प्रवेश काढून टाका:

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

पोर्ट 22 वरील SELinux label तसाच ठेवा. तो base policy मधून येतो. Firewall packets स्वीकारणे थांबवल्यानंतर तो कोणताही प्रवेश देत नाही.

त्यानंतर clients मध्ये बदल करा, कारण default port गृहीत धरणाऱ्या प्रत्येक tool ला आता पोर्ट स्पष्टपणे सांगावा लागेल. प्रत्येक वेळी -p टाइप करण्याऐवजी आपल्या मशीनवरील ~/.ssh/config मध्ये ही नोंद एकदाच करा:

Host myvps
  HostName 203.0.113.10
  Port 2222
  User youruser

scp, sftp, rsync आणि Ansible हे सर्व ही file वाचतात. मात्र port 22 hardcode केलेली backup jobs, monitoring checks आणि cron scripts ही file वाचत नाहीत. त्यामुळे बदलाची माहिती अजून लक्षात असतानाच त्या सर्व नोंदी शोधून अपडेट करा.

पोर्ट बदलल्याने काय मिळते आणि काय मिळत नाही

यामुळे log मधील अनावश्यक नोंदी कमी होतात. Automated scanners पोर्ट 22 वर सतत हल्ले करतात. पोर्ट बदलल्याने या नोंदींपैकी बहुतांश नोंदी journal मधून दूर होतात. त्यामुळे खऱ्या घटना ओळखणे सोपे होते. हा सुरक्षा नियंत्रणाचा उपाय नाही. संपूर्ण port range तपासणाऱ्या कोणत्याही scanner ला तुमचा daemon सापडतो आणि त्याचा version banner वाचता येतो. पोर्ट बदलण्याकडे housekeeping म्हणून पाहा. प्रत्यक्ष संरक्षणासाठी password login बंद करून केवळ key-based authentication वापरा. याची प्रक्रिया VPS साठीच्या SSH hardening मार्गदर्शकात टप्प्याटप्प्याने दिली आहे.

वरील सर्व प्रक्रिया दोन्ही प्रमुख RHEL rebuilds वर अगदी त्याच प्रकारे कार्य करते, कारण ते समान sources पासून तयार केलेले आहेत. तुम्ही अजूनही यापैकी एक निवडत असाल, तर Rocky Linux आणि AlmaLinux ची तुलना पहा. कोणत्याही जुन्या मार्गदर्शकाचे अनुसरण करण्यापूर्वी तुम्हाला प्रत्यक्षात कोणता release देण्यात आला आहे ते cat /etc/os-release वापरून तपासा. Rocky Linux 8 साठी लिहिलेली मार्गदर्शके अजूनही उपयुक्त आहेत. त्यांतील semanage आणि firewall-cmd पायऱ्या अद्याप योग्य आहेत. मात्र Rocky 8 मध्ये sshd_config.d include line नाही आणि socket unit चाही विचार करावा लागत नाही. त्यामुळे त्या मार्गदर्शकांतील sshd संबंधी भाग सध्याच्या सिस्टमशी जुळत नाही.

fail2ban ला नवीन पोर्टबद्दल माहिती द्यावी लागते

fail2ban बेस repositories मध्ये उपलब्ध नाही. ते EPEL (extra packages for enterprise Linux) मधून मिळते:

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

fail2ban-firewalld subpackage fail2ban ला firewalld मार्फत bans लागू करण्यास सांगते. firewalld ruleset नियंत्रित करत असलेल्या server वर हीच पद्धत योग्य आहे.

स्टॉक sshd jail मध्ये port = ssh सेट केलेले असते. हे नाव /etc/services द्वारे 22 वर resolve होते. बदल केल्यानंतर jail अशा पोर्टवर लक्ष ठेवते ज्यावर कोणीही हल्ला करत नाही. त्यामुळे 2222 वरील failed logins वाढत असतानाही कोणालाही ban केले जात नाही. /etc/fail2ban/jail.local मध्ये पोर्ट क्रमांकानुसार सेट करा:

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

backend = systemd failures /var/log/secure ऐवजी journal मधून वाचते. Minimal install मध्ये rsyslog उपलब्ध नसेल, तेव्हा हा अधिक सुरक्षित पर्याय आहे. sudo systemctl enable --now fail2ban ने ते सुरू करा आणि sudo fail2ban-client status sshd ने jail तपासा. Jail syntax Ubuntu 24.04 वरील fail2ban SSH सेटअप मध्ये वापरलेल्या syntax प्रमाणेच आहे. फक्त package source आणि ban action वेगळे आहेत.

पोर्ट बदलण्यापेक्षा patching अधिक महत्त्वाचे आहे

SSH पोर्ट बदललेला असला, तरी चार महिन्यांपासून security updates लागू केलेले नसतील, तर तो सर्व्हर port 22 वर चालणाऱ्या आणि दररोज रात्री स्वतःचे patches लागू करणाऱ्या सर्व्हरपेक्षा अधिक असुरक्षित असतो. तुम्ही आधीच root म्हणून काम करत असताना, त्याच सत्रात unattended updates सुरू करा: Rocky Linux आणि AlmaLinux वर automatic dnf updates मध्ये timer आणि updates डाउनलोड करायचे की लागू करायचे, यांमधील निवड स्पष्ट केली आहे.

FAQ

Rocky Linux वर port बदलल्यानंतर sshd सुरू होण्यात अडचण का येते?

बहुतेक वेळा कारण SELinux port label गहाळ असतो. sshd हे sshd_t domain मध्ये confined स्वरूपात चालते. Policy त्याला फक्त ssh_port_t label असलेल्या port वर bind करण्याची परवानगी देते. डीफॉल्टनुसार हा फक्त port 22 असतो. Kernel bind नाकारतो. त्यामुळे daemon listening सुरू करण्याऐवजी बंद होतो. 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 नोंदवला जातो आणि bind ला तरीही परवानगी मिळते. त्यामुळे बदल यशस्वी झाल्यासारखा दिसतो. मात्र label अद्याप गहाळ असतो. कोणी setenforce 1 चालवताच किंवा box /etc/selinux/config मध्ये SELINUX=enforcing सह boot होताच, sshd त्या port वर सुरू होणे थांबवते. Label जोडण्यासाठी एक command पुरेसा आहे. त्यामुळे अन्यथा काही आठवड्यांनी, स्पष्ट कारण न दिसता उद्भवणारी अडचण टाळता येते.

Port ला label आहे आणि sshd चालू आहे, तरी माझे connection timeout का होते?

Daemon चालू असल्याने SELinux ची अट पूर्ण झाली आहे. त्यामुळे येणारे packet मार्गातच drop होत आहे. तुमच्या port साठी sudo firewall-cmd --list-ports तपासा. --permanent rule नंतर firewall-cmd --reload चालवले आहे याची खात्री करा. कारण permanent rule एकट्याने running firewall वर लागू होत नाही. त्यानंतर VPS च्या समोरील स्वतंत्र network firewall साठी host चे control panel तपासा. लोकांना अडवणारे हे दुसरे ठिकाण आहे. Operating system मधील कोणतीही तपासणी ते दाखवणार नाही.

22 ऐवजी कोणता port वापरावा?

1024 ते 65535 मधील कोणताही उपलब्ध TCP port वापरा. प्रत्यक्ष server वर 2222 आणि 22222 टाळा. कारण 22 नंतर scanners हे ports लगेच तपासतात. sudo ss -tlnp वापरून number उपलब्ध आहे याची खात्री करा. sudo semanage port -l वापरून SELinux policy ने तो आधीच वापरलेला नाही याची पडताळणी करा. तसेच पुढे install करू शकणाऱ्या service साठी नेमलेला कोणताही port टाळा. लक्षात ठेवण्यास कठीण असलेला मोठा number चालतो. ~/.ssh/config मध्ये तो एकदाच लिहिल्यानंतर तो पुन्हा manually type करावा लागणार नाही.