SELinux मुळे nginx 403: permissions योग्य असतानाही का?
nginx 403 देतो आणि permissions योग्य दिसतात? SELinux denial वाचा, semanage आणि restorecon वापरून label दुरुस्त करा, आणि enforcing सुरूच ठेवा.
फाइलच्या permissions योग्य असतानाही nginx 403 का परत करतो
फाइलचे permission bits योग्य असूनही nginx 403 परत करत असेल, तर जवळजवळ नेहमी SELinux (security-enhanced Linux) फाइल वाचण्यास नकार देत असतो. सामान्य permissions तपासणी यशस्वी झाल्यानंतर SELinux नियमांचा दुसरा संच तपासतो. Web server ला फक्त web content label असलेल्या फाइल्स वाचण्याची परवानगी असते. तुमच्या फाइलला वेगळा label असल्यामुळे open अयशस्वी होते आणि nginx कडे पाठवण्यासाठी काहीही राहत नाही.
फक्त mode न पाहता label तपासा:
ls -ldZ /data/www /data/www/index.htmldrwxr-xr-x. root root unconfined_u:object_r:default_t:s0 /data/www
-rw-r--r--. root root unconfined_u:object_r:default_t:s0 /data/www/index.htmldrwxr-xr-x नंतर दिसणारा dot म्हणजे फाइलला SELinux label आहे. default_t हा label policy ने त्या path ची कधीही नोंद घेतलेली नसताना मिळतो. Web server च्या नियमांमध्ये हा type वाचण्याची कोणतीही परवानगी नसते. Error log मध्ये सामान्य Unix error दिसतो. त्यामुळे ही समस्या permissions मधील असल्यासारखी वाटते:
2026/08/11 09:14:02 [error] 1183#1183: *1 open() "/data/www/index.html" failed (13: Permission denied), client: 203.0.113.9, server: _, request: "GET / HTTP/1.1"सामान्य नकार आणि SELinux नकार या दोन्ही प्रकारांसाठी kernel 13: Permission denied परत करतो. त्यामुळे प्रथम कोणत्या स्तराने नकार दिला हे निश्चित करा. setenforce 0 पासून सुरुवात करू नका.
मॉडेलचा आवश्यक भाग
SELinux ही mandatory access control व्यवस्था आहे. तिला सामान्यतः MAC असे लिहितात. प्रत्येक process एखाद्या domain मध्ये चालतो. उदाहरणार्थ, web server साठी httpd_t domain असतो. प्रत्येक file आणि प्रत्येक network port ला एक type असतो. उदाहरणार्थ, httpd_sys_content_t. Policy म्हणजे domain, type आणि action यांच्या अनुमत संयोजनांची यादी. या यादीत नसलेली कोणतीही कृती नाकारली जाते. हे classic Unix check नंतर लागू होते. त्यामुळे drwxr-xr-x मधील permission bits आधी access ला परवानगी देत असणे आवश्यक आहे. दोन्ही स्तरांनी परवानगी दिली पाहिजे.
पूर्ण context मध्ये colon ने विभक्त केलेली चार fields असतात. उदाहरणार्थ, system_u:system_r:httpd_t:s0. या fields म्हणजे SELinux user, role, type आणि level. Server वर तुम्ही जवळजवळ नेहमी तिसऱ्या field वर, म्हणजे type वर, काम करता. Live values दाखवण्यासाठी दोन commands आहेत:
ps -eZ | grep nginx
id -Znginx workers चा context httpd_t ने समाप्त होतो. तुमच्या login shell चा context unconfined_u:unconfined_r:unconfined_t:s0 असतो. याचे कारण default targeted policy services वर मर्यादा घालते आणि interactive users वर तशा मर्यादा लागू करत नाही. हे लक्षात ठेवणे महत्त्वाचे आहे, कारण SELinux services least-privilege users अंतर्गत चालवण्याची पद्धत बदलत नाही. एखाद्याने service मध्ये घुसखोरी केल्यानंतर service कोणत्या resources पर्यंत पोहोचू शकते, यावर ते मर्यादा घालते.
तीन मोड आणि कोणत्या images मध्ये SELinux आहे
sestatus
getenforceEnforcing मोड विनंती अवरोधित करतो आणि log मध्ये नोंद करतो. Permissive मोड सर्वकाही अनुमत करतो आणि त्याने काय अवरोधित केले असते याची नोंद करतो. Disabled मोड कोणतेही policy लोड करत नाही. getenforce सध्याचा मोड दाखवते. sestatus /etc/selinux/config मधील मोडदेखील दाखवते. रीबूटनंतर हाच मोड पुन्हा लागू होतो.
Rocky Linux, AlmaLinux, Fedora आणि RHEL हे targeted policy सह SELinux enforcing मोडमध्ये उपलब्ध होतात. Ubuntu आणि Debian यामध्ये त्याऐवजी AppArmor उपलब्ध असते. ते वेगळ्या mechanism द्वारे समान काम करते. शेवटच्या section मध्ये त्याचे वर्णन आहे. त्यामुळे तुमच्या एका server वर एखादे application कोणत्याही अडचणीशिवाय install होऊ शकते, तर दुसऱ्या server वर ते 403 प्रतिसाद देऊ शकते.
तुम्हाला त्यांची गरज पडण्यापूर्वी साधने स्थापित करा
sudo dnf install -y policycoreutils-python-utils setroubleshoot-serverकिमान image वर semanage: command not found चालत नाही, कारण policycoreutils-python-utils उपलब्ध नसते: त्या package मध्ये semanage आणि audit2allow असतात. setroubleshoot-server sealert जोडते आणि प्रत्येक नकाराचा साध्या इंग्रजीतील सारांश journal मध्ये लिहिते. नवीन server वर ही दोन्ही साधने आधीच स्थापित करा, कारण त्यांची गरज भासते तेव्हा काहीतरी आधीच बिघडलेले असते.
audit log मधील SELinux denial कसे वाचावे
प्रत्येक नकार audit daemon कडून AVC (access vector cache) संदेश म्हणून नोंदवला जातो:
sudo ausearch -m AVC,USER_AVC,SELINUX_ERR -ts recenttype=AVC msg=audit(1754896442.881:412): avc: denied { read } for pid=1183 comm="nginx" name="index.html" dev="vda1" ino=17203 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=file permissive=0चार fields मधून संपूर्ण माहिती मिळते. comm हा block केलेला program आहे. scontext हा source context आहे; म्हणजे process ज्या domain मध्ये चालू होता तो domain. tcontext हा target context आहे; म्हणजे process ने access करण्याचा प्रयत्न केलेल्या वस्तूवरील label. tclass हा object चा प्रकार आहे; येथे तो file आहे. हे एकत्र वाचल्यास अर्थ असा होतो: httpd_t मधील process ने default_t label असलेली file वाचण्याचा प्रयत्न केला आणि permissive=0 यावरून विनंती केवळ log न करता प्रत्यक्ष block केली गेली हे दिसते.
ausearch काहीही print करत नसेल, तर audit daemon चालू नसण्याची शक्यता आहे. अशा वेळी denials kernel ring buffer मध्ये नोंदवल्या जातात:
sudo journalctl -k | grep -i avcआता या record चे English वाक्यात रूपांतर करा:
sudo ausearch -m AVC -ts recent | audit2why
sudo journalctl -t setroubleshoot --since today
sudo sealert -a /var/log/audit/audit.logaudit2why त्याच records वाचते आणि तिला ओळखता येणारे कारण सांगते: बंद असलेला boolean, policy शी जुळत नसलेला label किंवा कोणताही rule उपलब्ध नसणे. sealert संपूर्ण log तपासते आणि प्रत्येक denial साठी एक सुचवलेली command print करते. ही सूचना केवळ मार्गदर्शक म्हणून वापरा. वेगवेगळ्या releases मध्ये तिची मांडणी बदलते. तसेच, योग्य उपाय एका ओळीतील label fix असताना sealert कधी कधी custom policy module सुचवते.
आणखी एक गोष्ट लक्षात ठेवा. Policy मध्ये harmless मानल्या जाणाऱ्या denials लपवणारे dontaudit rules असतात. त्यामुळे log रिकामा असतानाही एखादा program चुकीचे वर्तन करू शकतो. एका test च्या कालावधीपुरते हे denials पुन्हा दाखवा:
sudo semodule -DB
# reproduce the problem, then read the log again
sudo semodule -Bsemanage fcontext आणि restorecon वापरून चुकीचा label असलेला path दुरुस्त करा
दोन commands आहेत आणि त्यांचा क्रम महत्त्वाचा आहे. semanage fcontext -a एखाद्या path साठी label कोणता असावा हे नोंदवते. restorecon disk वरील files वर तो नोंदवलेला default लागू करते.
sudo semanage fcontext -a -t httpd_sys_content_t "/data/www(/.*)?"
sudo restorecon -Rv /data/www
ls -ldZ /data/www/index.htmlPath हा regular expression असतो. (/.*)? directory स्वतःला आणि तिच्या आतील सर्व गोष्टींना लागू होते. Document root साठी हेच आवश्यक असते. बदल करण्यापूर्वी काय बदलेल ते पाहा: sudo restorecon -Rvn /data/www नियोजित relabels दाखवते, कारण -n म्हणजे कोणतीही कृती करू नका. प्रत्यक्ष restorecon केल्यानंतर label httpd_sys_content_t असा दिसतो आणि service restart न करता 403 नाहीसा होतो.
chcon फक्त चाचणीसाठी वापरा. chcon -t httpd_sys_content_t index.html label थेट सेट करते. पुढील restorecon, package update किंवा पूर्ण relabel केल्यावर तो reset होतो, कारण policy नुसार त्या path साठी अजूनही दुसरा label असायला हवा. टिकून राहणारी आवृत्ती semanage fcontext आहे. नोंदवलेले नियम sudo semanage fcontext -l | grep '^/data' वापरून यादीत पाहा.
Service ने लिहिणे आवश्यक असलेल्या content साठी वेगळा type आवश्यक असतो. Upload directory किंवा cache साठी httpd_sys_rw_content_t वापरा आणि तो फक्त त्या paths पर्यंत मर्यादित ठेवा. Writable type अंतर्गत read-only site ठेवल्यास application ला आवश्यकतेपेक्षा जास्त access मिळतो.
Label चुकीचा का होता? जवळजवळ नेहमीच कारण files कशा आणल्या गेल्या हे असते. mv file चा विद्यमान label कायम ठेवते. त्यामुळे /root मधून हलवलेली site admin_home_t label सह येते आणि तशीच राहते. साधे cp नवीन file ला destination directory चा default label देते. बहुतेक वेळा हेच अपेक्षित असते. मात्र cp -a आणि rsync -X source labels file सोबत copy करतात. नवीन top-level directory मध्ये केलेले git clone default_t तयार करते. /usr/share/nginx/html मधून page व्यवस्थित load होते पण तुमच्या स्वतःच्या directory मधून fail होते, तेव्हा याचे कारण हेच असते.
बूलियन वापरून वर्तनाचा वर्ग दुरुस्त करा
काही अपयश label मुळे होत नाहीत. नव्याने स्थापित केलेल्या Rocky किंवा AlmaLinux सर्व्हरवरील reverse proxy 502 परत करतो आणि error log मध्ये असे दिसते:
2026/08/11 10:02:55 [crit] 1183#1183: *3 connect() to 127.0.0.1:3000 failed (13: Permission denied) while connecting to upstreamतुमचा upstream योग्य आहे. httpd_t domain ला default नुसार outbound network connections उघडण्याची परवानगी नसते. त्यामुळे connect() call loopback interface पर्यंत पोहोचण्यापूर्वीच नाकारला जातो. हे संपूर्ण वर्तन एका switch ने नियंत्रित होते:
getsebool -a | grep httpd_can_network
sudo setsebool -P httpd_can_network_connect on-P हा महत्त्वाचा flag आहे. तो value disk वर लिहितो. -P शिवाय पुढील reboot वेळी हा बदल नष्ट होतो. त्यामुळे मशीन restart होईपर्यंतच चालणारी service मिळते. semanage boolean -l | grep httpd_can_network_connect वापरून खात्री करा. तो running value आणि stored value शेजारी छापतो.
जेव्हा boolean उपलब्ध असेल, तेव्हा स्वतः लिहिलेल्या rule ऐवजी boolean वापरा. Booleans distribution policy सोबत येतात. त्यामुळे त्यांची देखभाल आणि documentation केलेली असते आणि पुढील व्यक्तीला ते सहज सापडतात. getsebool -a सिस्टमवरील सर्व booleans सूचीबद्ध करते.
सेवेला non-standard port वर listen करू द्या
Ports ला labels देखील लागू असतात. nginx ला 8081 वर हलवल्यावर ते सुरू होण्यास नकार देते:
nginx: [emerg] bind() to 0.0.0.0:8081 failed (13: Permission denied)httpd_t ला http_port_t labels असलेल्या ports वर bind करता येते आणि 8081 त्यापैकी एक नाही. ते जोडा:
sudo semanage port -l | grep -w http_port_t
sudo semanage port -a -t http_port_t -p tcp 8081आधी यादी तपासा. 8008 आणि 8443 यांसह अनेक high ports आधीपासून अनुमत आहेत. एखादा port दोनदा जोडल्यास ValueError: Port tcp/8081 already defined त्रुटी येते. तो port आधीपासून वेगळ्या type शी संबंधित असल्यास, तो जोडण्याऐवजी semanage port -m -t http_port_t -p tcp 8081 वापरून type बदला.
SSH port हलवल्यानंतर तो कार्यान्वित करण्यासाठीही हीच command वापरावी लागते. journalctl -u sshd मधील Bind to port 2222 on 0.0.0.0 failed: Permission denied याचा अर्थ 2222 हा ssh_port_t मध्ये उपलब्ध नाही. त्यामुळे daemon restart करण्यापूर्वी आणि तुमचे session बंद करण्यापूर्वी sudo semanage port -a -t ssh_port_t -p tcp 2222 चालवा. Red Hat family image वर VPS वरील SSH hardening साठी generic guide अनुसरताना लोक ही पायरी वगळतात. SELinux firewall नाही. त्यामुळे port अद्याप open करावा लागतो: येथे sudo firewall-cmd --permanent --add-port=8081/tcp && sudo firewall-cmd --reload, किंवा Debian किंवा Ubuntu image वरील ufw वापरा.
जेव्हा बदलण्यासाठी boolean आणि label दोन्ही उपलब्ध नसतात
सामान्य सर्व्हरवर ही परिस्थिती क्वचितच येते. अशा वेळी लोकांकडून नुकसान होण्याची शक्यता असते. audit2allow लॉगमधील denials वरून policy module तयार करू शकते:
sudo ausearch -m AVC -ts recent -c nginx | audit2allow -M nginx_local
cat nginx_local.te
sudo semodule -i nginx_local.ppते install करण्यापूर्वी nginx_local.te वाचा. हे सुरक्षित ठेवण्यासाठी दोन सवयी उपयुक्त आहेत. -c वापरून input फक्त ज्या program मध्ये तुम्ही दुरुस्ती करत आहात त्यापुरता मर्यादित करा. कारण unrelated denials चा एक आठवड्याचा log audit2allow कडे pipe केल्यास ते सर्व denials एकाच वेळी मंजूर करते. तसेच, ज्या denial चे कारण तुम्ही स्पष्ट करू शकत नाही त्यावरून तयार केलेले module कधीही install करू नका. httpd_t ला संपूर्ण server वरील प्रत्येक file वाचण्याची परवानगी देणारा rule तयार करणे सोपे आहे, पण तो काही महिन्यांनंतर शोधणे कठीण असते. sudo semodule -r nginx_local वापरून module काढा.
Permissive हा निदानासाठीचा मोड आहे, उपाय नाही
sudo setenforce 0
# reproduce the problem once, all the way through
sudo ausearch -m AVC -ts recent
sudo setenforce 1Permissive मोड प्रवेशास अनुमती देतो आणि त्याची नोंद करतो. त्याचे खरे मूल्य सर्वसमावेशकतेत आहे. enforcing मोडमध्ये सेवा पहिल्या नकारावर थांबते. त्यामुळे तुम्ही तो नकार दुरुस्त करता, सेवा पुन्हा सुरू करता आणि दुसऱ्या नकाराला सामोरे जाता. Permissive मोडमध्ये प्रक्रिया सुरू राहते आणि एका फेरीत प्रत्येक नकाराची नोंद log मध्ये होते. त्यानंतर तुम्ही पुन्हा enforcing मोडवर जाऊन सर्व नकार एकत्र दुरुस्त करू शकता.
setenforce मुळे /etc/selinux/config वर कोणताही परिणाम होत नाही. त्यामुळे reboot केल्यानंतर सिस्टम पुन्हा enforcing मोडमध्ये येते. ही एक सुरक्षा व्यवस्था आहे. तसेच, setenforce 0 वर आधारित केलेला "उपाय" सर्वात अयोग्य वेळी पुन्हा दिसण्याचे हेच कारण आहे. एखाद्या सेवेवर काम करताना तिला तात्पुरती मुभा द्यायची असल्यास संपूर्ण मशीनऐवजी त्या domain ला mark करा: sudo semanage permissive -a httpd_t इतर सर्व गोष्टी enforcing मोडमध्ये ठेवते, आणि sudo semanage permissive -d httpd_t हा बदल पूर्ववत करते.
SELinux बंद करण्याची किंमत label दुरुस्त करण्यापेक्षा जास्त का आहे
SELINUX=disabled in /etc/selinux/config सेट केल्याने एका ओळीतील label दुरुस्तीऐवजी सर्व्हरची सुरक्षा कायमची कमकुवत होते. Web application वर हल्ला झालेल्या दिवशी हा फरक स्पष्ट दिसतो. Enforcing mode मध्ये हल्लेखोराचा code httpd_t मध्ये चालतो. त्यामुळे तो web content वाचू शकतो. मात्र Unix user ला परवानगी असली तरी policy नुसार /etc/shadow वाचणे किंवा systemd unit लिहिणे नाकारले जाते. कोणतीही policy load केलेली नसल्यास, त्याच code ला service account कडे असलेले सर्व अधिकार मिळतात.
SELinux बंद केल्याची किंमत नंतर मोजावी लागते. Policy load केलेली नसताना नवीन files कोणत्याही label शिवाय तयार होतात. त्यामुळे filesystem policy पासून हळूहळू विसंगत होते. नंतर SELinux पुन्हा सुरू करण्यासाठी संपूर्ण relabel करावे लागते. अन्यथा अनेक services एकाच वेळी fail होतात:
sudo fixfiles -F onboot
sudo rebootयामुळे /.autorelabel लिहिले जाते आणि पुढील boot वेळी प्रत्येक filesystem relabel केला जातो. मोठ्या disk वर यासाठी बराच वेळ लागतो आणि console अडकलेली दिसू शकते. त्यामुळे प्रतीक्षा करता येईल अशा वेळी ही प्रक्रिया सुरू करा. Rocky Linux आणि AlmaLinux 9 मध्ये config file आता kernel भाग स्वतंत्रपणे बंद करत नाही. SELinux पूर्णपणे बंद करण्याची documented पद्धत म्हणजे kernel argument (sudo grubby --update-kernel ALL --args selinux=0) वापरणे. दुसऱ्याच्या सर्व्हरची जबाबदारी घेताना हा command माहीत असणे उपयुक्त ठरते. मात्र 403 error साठी ही दुरुस्ती नाही.
कंटेनरमध्ये आणखी एक लेबल जोडा
Red Hat कुटुंबातील होस्टवर कंटेनर प्रक्रिया container_t मध्ये चालतात आणि त्या फक्त container_file_t असे लेबल असलेल्या फाइल्स वाचू शकतात. होस्टवरील bind mount कंटेनरमध्ये Permission denied सह अपयशी ठरतो, जरी होस्टवरील ls -l पूर्णपणे सामान्य दिसत असले तरी. :Z हा suffix runtime ला mount चे relabel करण्यास सांगतो:
docker run -d -v /data/appdata:/var/lib/app:Z myimage:Z ही directory फक्त या कंटेनरसाठी लेबल करते. :z ही directory कंटेनरमध्ये सामायिक करण्यासाठी लेबल करते. :Z कडे इतर सेवा वापरत असलेली directory निर्देशित केल्यास ती directory पुनरावृत्तीने relabel केली जाते आणि त्यामुळे त्या सेवा बिघडतात. म्हणून कंटेनरसाठी स्वतंत्र paths वापरा. या सेटअपमधील इतर सर्व बाबी VPS वर Docker चालवणे याप्रमाणेच आहेत.
Ubuntu आणि Debian मध्ये AppArmor उपलब्ध आहे
तेच कार्य, वेगळी रचना. AppArmor डिस्कवरील फाइल्सना लेबल लावण्याऐवजी /etc/apparmor.d/ अंतर्गत असलेल्या profile च्या साहाय्याने executable च्या path नुसार प्रोग्रामला मर्यादित करते. पुन्हा label लावण्याची गरज नसते आणि restorecon देखील नसते. सुरुवात येथे करा:
sudo aa-status
sudo journalctl -k | grep -i apparmorनकार apparmor="DENIED" operation="open" profile="/usr/sbin/nginx" name="/data/www/index.html" requested_mask="r" म्हणून दिसतो. कार्यपद्धतीची रूपरेषा तीच असते: denial वाचा, profile शोधा आणि rule बदला. sudo apt install apparmor-utils तुम्हाला aa-complain (एका profile साठी permissive mode) देते आणि पूर्वस्थितीत आणण्यासाठी aa-enforce देते. Ubuntu निवडक packaged services वर मर्यादा लागू करते आणि उर्वरित services unconfined ठेवते. त्यामुळे अंदाज न बांधता प्रत्यक्षात काय सक्रिय आहे हे पाहण्यासाठी aa-status वाचा.
दोन्ही systems मध्ये एक सवय समान लागू होते. एखादी service योग्य दिसणाऱ्या गोष्टीवर Permission denied नोंदवत असेल, तर permissions बदलण्यापूर्वी security log वाचा. एकदाच चुकीची असलेली permissions पुन्हा पुन्हा समस्या निर्माण करण्याचे कारण क्वचितच असते.
FAQ
nginx फाइल परवानग्या योग्य असतानाही 403 का परत करतो?
कारण SELinux ने वाचन नाकारले आहे; परवानगी बिट्सने नाही. वेब सर्व्हर httpd_t डोमेनमध्ये चालतो आणि तो फक्त वेब सामग्रीसाठी लेबल केलेल्या फाइल्स वाचू शकतो. त्यामुळे default_t किंवा admin_home_t असे लेबल असलेली फाइल नाकारली जाते आणि nginx कडे देण्यासाठी काहीही उरत नाही. sudo ausearch -m AVC -ts recent वापरून याची खात्री करा. त्यामध्ये scontext हे httpd_t वर संपते आणि tcontext मध्ये चुकीचा प्रकार असल्याचे दिसते. त्यानंतर योग्य लेबल नोंदवून ते लागू करा: sudo semanage fcontext -a -t httpd_sys_content_t "/data/www(/.*)?" आणि त्यानंतर sudo restorecon -Rv /data/www.
सेवा सुरू करण्यासाठी setenforce 0 चालवणे सुरक्षित आहे का?
setenforce 0 ही निदानासाठीची पायरी आहे; हा उपाय नाही. समस्येची एकदा पुनरुत्पत्ती करण्यासाठी ते वापरा, जेणेकरून log मध्ये एकाच प्रक्रियेत सर्व नकार नोंदवले जातील. ते sudo ausearch -m AVC -ts recent वापरून वाचा. त्यानंतर sudo setenforce 1 चालवून कारणे दुरुस्त करा. permissive स्थितीत ठेवलेल्या सर्व्हरमध्ये प्रत्येक नकाराची नोंद होते, परंतु कोणताही नकार अडवला जात नाही. त्यामुळे अनावश्यक नोंदी राहतात आणि संरक्षण नाहीसे होते. काम करताना एखाद्या सेवेला तात्पुरती मुभा देणे आवश्यक असल्यास sudo semanage permissive -a httpd_t चालवा, त्यामुळे उर्वरित मशीन enforcing स्थितीत राहते.
SELinux enforcing असताना non-standard पोर्टवर सेवा कशी चालवायची?
त्या सेवेला bind करण्याची परवानगी असलेल्या type मध्ये पोर्ट जोडा. 8081 वर web server साठी: sudo semanage port -a -t http_port_t -p tcp 8081. 2222 वर SSH साठी: sudo semanage port -a -t ssh_port_t -p tcp 2222. प्रथम sudo semanage port -l | grep -w http_port_t वापरून सध्याची यादी तपासा, कारण आधीच सूचीबद्ध असलेल्या पोर्टसाठी ValueError: Port tcp/8081 already defined अपयशी ठरते. ही पायरी न केल्यास इतर कोणतीही प्रक्रिया पोर्ट वापरत नसतानाही daemon सुरू होताना bind() ... Permission denied मुळे बंद होतो.
Ubuntu मध्ये SELinux आहे का?
नाही. Ubuntu आणि Debian मध्ये AppArmor दिले जाते. ते फाइल्सवरील labels ऐवजी executable च्या path शी जोडलेले profile लागू करते. sudo aa-status वापरून ते तपासा आणि sudo journalctl -k मध्ये apparmor="DENIED" ओळी शोधा. Ubuntu निवडक packaged सेवांवर मर्यादा लागू करते. त्यामुळे अनेक प्रोग्राम्स default ने unconfined चालतात. Rocky Linux आणि AlmaLinux मध्ये SELinux enforcing out of the box आढळते. Fedora आणि RHEL मध्येही तेच असते.