SSD Nodes Learn 🎉 VPS $5.50/মাস থেকে
নির্দেশিকা Matt Connorদ্বারা Matt Connor · আপডেট করা হয়েছে 2026-08-13

nginx 403: permission ঠিক থাকলেও SELinux কী ভাঙে

nginx 403 ফেরালেও permission ঠিক থাকলে audit log-এর SELinux denial পড়ুন। semanage দিয়ে label ঠিক করে restorecon চালান, enforcing মোড চালু রাখুন।

যে ফাইলের permission সঠিক, nginx সেটিতে 403 কেন ফেরত দেয়

ফাইলের permission bit সঠিক হলেও nginx 403 ফেরত দিলে প্রায় সব ক্ষেত্রেই কারণ থাকে SELinux (security-enhanced Linux) ফাইলটি পড়তে দিচ্ছে না। সাধারণ permission পরীক্ষা পাস হওয়ার পর SELinux আরও একটি নিয়মের সেট পরীক্ষা করে। Web server শুধু সেই ফাইল পড়তে পারে, যেগুলোতে web content label আছে। আপনার ফাইলে অন্য label থাকায় ফাইল খোলা ব্যর্থ হয় এবং nginx-এর পাঠানোর মতো কোনো content থাকে না।

শুধু mode নয়, label-ও দেখুন:

ls -ldZ /data/www /data/www/index.html
drwxr-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.html

drwxr-xr-x-এর পরে মুদ্রিত dot-এর অর্থ হলো ফাইলটিতে SELinux label আছে। Policy আগে কখনও কোনো path সম্পর্কে না জানলে সেই path যে label পায়, তা হলো default_t। Web server-এর কোনো নিয়মেই এই type পড়ার অনুমতি নেই। Error log-এ সাধারণ Unix error দেখা যায়, তাই এটি permission সমস্যার মতো মনে হয়:

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"

সাধারণ permission প্রত্যাখ্যান এবং SELinux-এর প্রত্যাখ্যান—উভয় ক্ষেত্রেই kernel 13: Permission denied ফেরত দেয়। তাই প্রথমে কোন স্তর প্রত্যাখ্যান করেছে, তা নির্ধারণ করতে হবে। setenforce 0 দিয়ে শুরু করবেন না।

মডেলের প্রয়োজনীয় অংশ

SELinux হলো mandatory access control, সাধারণত MAC নামে লেখা হয়। প্রতিটি process একটি domain-এ চলে, যেমন web server-এর জন্য httpd_t। প্রতিটি file এবং network port-এর একটি type থাকে, যেমন httpd_sys_content_t। Policy-তে domain, type এবং action-এর অনুমোদিত সমন্বয়গুলোর তালিকা থাকে। সেই তালিকায় নেই এমন যেকোনো কিছু অস্বীকৃত হয়। এটি প্রচলিত Unix check-এর পরে কার্যকর হয়। তাই drwxr-xr-x-এ থাকা permission bits-কেও প্রথমে access অনুমোদন করতে হবে। উভয় layer-কেই অনুমতি দিতে হবে।

একটি পূর্ণ context-এ colon দিয়ে পৃথক করা চারটি field থাকে, যেমন system_u:system_r:httpd_t:s0: SELinux user, role, type এবং level। Server-এ আপনি প্রায় সব সময় তৃতীয় field, অর্থাৎ type, নিয়েই কাজ করবেন। দুটি command বর্তমান মান দেখায়:

ps -eZ | grep nginx
id -Z

nginx worker-গুলোর context httpd_t দিয়ে শেষ হয়। আপনার login shell-এ unconfined_u:unconfined_r:unconfined_t:s0 দেখা যায়, কারণ default targeted policy service-গুলোকে সীমাবদ্ধ রাখে এবং interactive user-দের সাধারণত সীমাবদ্ধ করে না। এটি জানা গুরুত্বপূর্ণ, কারণ SELinux সর্বনিম্ন privilege-এর user হিসেবে service চালানোর বিকল্প নয়। কেউ service-এ অনুপ্রবেশ করার পরে service কোন resource-এ পৌঁছাতে পারবে, SELinux তা সীমিত করে।

তিনটি মোড এবং কোন image-এ SELinux থাকে

sestatus
getenforce

Enforcing নীতি লঙ্ঘনকারী কাজ আটকে দেয় এবং লগ করে। Permissive সবকিছু অনুমোদন করে, তবে কোন কাজ আটকে দেওয়া হতো তা লগ করে। Disabled কোনো policy-ই load করে না। getenforce বর্তমান mode দেখায়। sestatus /etc/selinux/config থেকে mode-ও দেখায়; reboot-এর পরে এই mode-ই আবার চালু হয়।

Rocky Linux, AlmaLinux, Fedora এবং RHEL targeted policy সহ SELinux-এর Enforcing mode চালু রেখে release হয়। Ubuntu এবং Debian-এর পরিবর্তে AppArmor থাকে। AppArmor ভিন্ন পদ্ধতিতে একই কাজ করে; শেষ section-এ এটি ব্যাখ্যা করা হয়েছে। তাই একই application আপনার একটি server-এ ঠিকভাবে install হতে পারে, কিন্তু অন্য server-এ 403 return করতে পারে।

প্রয়োজন হওয়ার আগেই টুলগুলো ইনস্টল করুন

sudo dnf install -y policycoreutils-python-utils setroubleshoot-server

ন্যূনতম image-এ semanage: command not found ব্যর্থ হলে এর অর্থ হলো policycoreutils-python-utils অনুপস্থিত। ওই package-এ semanage এবং audit2allow থাকে। setroubleshoot-server, sealert যোগ করে এবং প্রতিটি denial-এর সহজ ইংরেজি সারাংশ journal-এ লেখে। নতুন server-এ দুটিই আগে ইনস্টল করুন, কারণ এগুলো সাধারণত তখনই প্রয়োজন হয়, যখন কোনো কিছু ইতিমধ্যে নষ্ট হয়ে গেছে।

audit log-এ SELinux denial কীভাবে পড়বেন

প্রতিটি প্রত্যাখ্যান audit daemon একটি AVC (access vector cache) বার্তা হিসেবে রেকর্ড করে:

sudo ausearch -m AVC,USER_AVC,SELINUX_ERR -ts recent
type=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

চারটি field-এই পুরো বিষয়টি বোঝা যায়। comm হলো যে program-টিকে block করা হয়েছে। scontext হলো source context, অর্থাৎ যে domain-এ process-টি চলছিল। tcontext হলো target context, অর্থাৎ process-টি যে বস্তুতে access করার চেষ্টা করেছিল তার label। tclass হলো object-এর ধরন; এখানে এটি একটি file। একসঙ্গে পড়লে অর্থ দাঁড়ায়: httpd_t-এ চলা process default_t label-যুক্ত একটি file পড়ার চেষ্টা করেছিল, এবং permissive=0 দেখায় যে অনুরোধটি শুধু log করা হয়নি, সত্যিই block করা হয়েছে।

ausearch কিছু print না করলে audit daemon চালু নাও থাকতে পারে। সে ক্ষেত্রে denial kernel ring buffer-এ লেখা হয়:

sudo journalctl -k | grep -i avc

এখন record-টিকে একটি ইংরেজি বাক্যে রূপান্তর করুন:

sudo ausearch -m AVC -ts recent | audit2why
sudo journalctl -t setroubleshoot --since today
sudo sealert -a /var/log/audit/audit.log

audit2why একই record পড়ে এবং যে কারণটি শনাক্ত করতে পারে তা উল্লেখ করে: একটি বন্ধ boolean, policy-এর সঙ্গে না-মেলা label, অথবা কোনো rule না থাকা। sealert পুরো log পরীক্ষা করে প্রতিটি denial-এর জন্য একটি প্রস্তাবিত command print করে। প্রস্তাবটিকে নির্দেশনা নয়, সহায়ক ইঙ্গিত হিসেবে বিবেচনা করুন। বিভিন্ন release-এ এর wording বদলে যায়, এবং sealert কখনও এমন একটি custom policy module প্রস্তাব করে, যেখানে সঠিক সমাধান হলো একটি line-এর label ঠিক করা।

আরেকটি বিষয় জানা দরকার। Policy-তে dontaudit rule থাকে, যেগুলোকে harmless বিবেচনা করা denial আড়াল করে। তাই log খালি থাকলেও কোনো program সঠিকভাবে কাজ নাও করতে পারে। একটি test চালানোর সময়ের জন্য সেগুলো দৃশ্যমান করুন:

sudo semodule -DB
# reproduce the problem, then read the log again
sudo semodule -B

semanage fcontext এবং restorecon দিয়ে ভুল label-যুক্ত path ঠিক করা

দুটি command ব্যবহার করতে হবে এবং ক্রমটি গুরুত্বপূর্ণ। semanage fcontext -a কোনো path-এর label কী হওয়া উচিত, তা record করে। restorecon disk-এ থাকা file-গুলোর ওপর সেই recorded default প্রয়োগ করে।

sudo semanage fcontext -a -t httpd_sys_content_t "/data/www(/.*)?"
sudo restorecon -Rv /data/www
ls -ldZ /data/www/index.html

Path-টি একটি regular expression। (/.*)? directory নিজে এবং তার অধীন সবকিছুকে অন্তর্ভুক্ত করে, যা document root-এর জন্য প্রয়োজন। পরিবর্তন করার আগে কী বদলাবে তা দেখুন: sudo restorecon -Rvn /data/www পরিকল্পিত relabel দেখায়, কারণ -n কোনো action না নেওয়ার অর্থ। প্রকৃত restorecon-এর পরে label httpd_sys_content_t দেখায় এবং service restart ছাড়াই 403 চলে যায়।

chcon শুধু test হিসেবে ব্যবহার করুন। chcon -t httpd_sys_content_t index.html সরাসরি label সেট করে, কিন্তু পরের restorecon, package update বা full relabel-এর সময় এটি reset হয়, কারণ policy এখনও বলে path-টির অন্য label হওয়া উচিত। semanage fcontext হলো টিকে থাকা version। sudo semanage fcontext -l | grep '^/data' দিয়ে record করা setting-গুলোর তালিকা দেখুন।

Service-কে যে content-এ write করতে হবে, তার জন্য আলাদা type প্রয়োজন। Upload directory বা cache-এর জন্য httpd_sys_rw_content_t ব্যবহার করুন এবং এটি শুধু ওই path-গুলোতেই সীমাবদ্ধ রাখুন: writable type-এর অধীনে একটি read-only site রাখলে application-এর প্রয়োজনের চেয়ে বেশি access দেওয়া হয়।

Label ভুল হলো কেন? প্রায় সবসময় কারণ file কীভাবে এসেছে। mv file-এর বিদ্যমান label অপরিবর্তিত রাখে। তাই /root থেকে সরানো site admin_home_t label নিয়ে আসে এবং সেভাবেই থাকে। সাধারণ cp নতুন file-কে destination directory-এর default label দেয়, যা সাধারণত আপনি চান। অন্যদিকে cp -a এবং rsync -X file-এর সঙ্গে source label-ও copy করে। নতুন top-level directory-তে একটি git clone করলে default_t তৈরি হয়। /usr/share/nginx/html থেকে page ঠিকমতো load হলেও নিজের directory থেকে ব্যর্থ হলে, এটাই কারণ।

বুলিয়ান দিয়ে একটি আচরণ নিয়ন্ত্রণ করুন

কিছু ব্যর্থতা 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-কে ডিফল্টভাবে outbound network connection খোলার অনুমতি দেওয়া হয় না। তাই connect() call loopback interface-এ পৌঁছানোর আগেই প্রত্যাখ্যাত হয়। একটি switch পুরো আচরণটি নিয়ন্ত্রণ করে:

getsebool -a | grep httpd_can_network
sudo setsebool -P httpd_can_network_connect on

-P হলো গুরুত্বপূর্ণ flag। এটি মানটি disk-এ লিখে রাখে। -P ছাড়া পরবর্তী reboot-এ পরিবর্তনটি হারিয়ে যায়। ফলে machine restart না হওয়া পর্যন্ত service কাজ করে। semanage boolean -l | grep httpd_can_network_connect দিয়ে নিশ্চিত করুন। এটি running value-এর পাশে stored value দেখায়।

যেখানে boolean আছে, সেখানে হাতে লেখা rule-এর পরিবর্তে boolean ব্যবহার করুন। Boolean distribution policy-এর সঙ্গে প্রকাশিত হয়। তাই এগুলো রক্ষণাবেক্ষণ করা হয়, নথিভুক্ত থাকে এবং পরবর্তী ব্যক্তি সহজে খুঁজে পান। getsebool -a সিস্টেমের সব boolean-এর তালিকা দেখায়।

একটি service-কে non-standard port-এ listen করান

Port-গুলোকেও label করা হয়। nginx-কে 8081-এ সরালে এটি start হতে অস্বীকার করে:

nginx: [emerg] bind() to 0.0.0.0:8081 failed (13: Permission denied)

httpd_t কেবল http_port_t label থাকা port 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 port ইতিমধ্যে অনুমোদিত, এবং একই port দ্বিতীয়বার যোগ করলে ValueError: Port tcp/8081 already defined ব্যর্থ হয়। Port-টি যদি ইতিমধ্যে অন্য কোনো type-এর অন্তর্ভুক্ত হয়, তাহলে এটি যোগ না করে semanage port -m -t http_port_t -p tcp 8081 দিয়ে পরিবর্তন করুন।

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 নিয়ে কোনো সাধারণ guide অনুসরণ করার সময় মানুষ সাধারণত এই ধাপটি বাদ দেয়। SELinux firewall নয়। তাই port-টিও open রাখতে হবে: এখানে sudo firewall-cmd --permanent --add-port=8081/tcp && sudo firewall-cmd --reload ব্যবহার করুন, অথবা Debian বা Ubuntu image-এ ufw ব্যবহার করুন।

যখন পরিবর্তন করার মতো কোনো boolean বা label থাকে না

স্বাভাবিক সার্ভারে এটি বিরল। এই অবস্থাতেই মানুষ ক্ষতি করে। লগে থাকা denial থেকে audit2allow একটি policy module তৈরি করতে পারে:

sudo ausearch -m AVC -ts recent -c nginx | audit2allow -M nginx_local
cat nginx_local.te
sudo semodule -i nginx_local.pp

ইনস্টল করার আগে nginx_local.te পড়ুন। দুটি অভ্যাস এই কাজকে নিরাপদ রাখে। -c দিয়ে input শুধু যে program-টি ঠিক করছেন সেটিতে সীমাবদ্ধ করুন, কারণ এক সপ্তাহের অসংলগ্ন denial audit2allow-এ pipe করলে সেগুলো সব একসঙ্গে অনুমোদিত হয়ে যায়। যে denial-এর কারণ আপনি ব্যাখ্যা করতে পারেন না, তা থেকে তৈরি module কখনোই install করবেন না। যেমন, httpd_t-কে সার্ভারের প্রতিটি file পড়ার অনুমতি দেওয়ার rule তৈরি করা সহজ, কিন্তু কয়েক মাস পরে সেটি শনাক্ত করা কঠিন। sudo semodule -r nginx_local দিয়ে module সরিয়ে ফেলুন।

Permissive একটি diagnostic mode, সমাধান নয়

sudo setenforce 0
# reproduce the problem once, all the way through
sudo ausearch -m AVC -ts recent
sudo setenforce 1

Permissive mode access অনুমোদন করে এবং তা লগ করে। এর প্রকৃত মূল্য হলো সম্পূর্ণতা। Enforcing mode-এ service প্রথম denial-এই থেমে যায়। তাই একটি সমস্যা ঠিক করে service restart করলে পরের denial-এর মুখোমুখি হতে হয়। Permissive mode-এ run চলতে থাকে এবং একবারেই প্রতিটি denial লগে সংগ্রহ হয়। এরপর আপনি আবার enforcing mode চালু করে সবগুলো একসঙ্গে ঠিক করতে পারেন।

setenforce, /etc/selinux/config-এ কোনো পরিবর্তন করে না। তাই reboot হলে সিস্টেম আবার enforcing mode-এ ফিরে যায়। এটি একটি safety net। একই কারণে setenforce 0 দিয়ে করা "fix" সবচেয়ে অনুপযুক্ত সময়ে আবার দেখা দিতে পারে। কাজ করার সময় কোনো একটি service-এর জন্য সাময়িকভাবে বেশি সুযোগের প্রয়োজন হলে পুরো মেশিনের পরিবর্তে সেই domain চিহ্নিত করুন: sudo semanage permissive -a httpd_t অন্য সবকিছুকে enforcing mode-এ রাখে, আর sudo semanage permissive -d httpd_t সেটি ফিরিয়ে দেয়।

SELinux-Label ঠিক করার চেয়ে SELinux নিষ্ক্রিয় করার খরচ বেশি

/etc/selinux/config-এ SELINUX=disabled সেট করলে এক লাইনের label ঠিক করার বিনিময়ে সার্ভার স্থায়ীভাবে কম নিরাপদ হয়ে যায়। কোনো web application compromised হওয়ার দিন এই পার্থক্য স্পষ্ট হয়। Enforcing অবস্থায় আক্রমণকারীর code httpd_t-এ চলে। তাই এটি web content পড়তে পারলেও /etc/shadow পড়া বা systemd unit লেখার অনুমতি policy প্রত্যাখ্যান করে, Unix user যতটুকুই অনুমতি দিক না কেন। কোনো policy loaded না থাকলে একই code service account-এর সব অনুমতি পেয়ে যায়।

SELinux নিষ্ক্রিয় করার আরেকটি খরচ পরে দিতে হয়। কোনো policy loaded না থাকলে নতুন file কোনো label ছাড়াই তৈরি হয়। ফলে filesystem ধীরে ধীরে policy-এর সঙ্গে অসামঞ্জস্যপূর্ণ হয়ে যায়। পরে SELinux আবার চালু করলে সম্পূর্ণ relabel করতে হয়। নইলে একসঙ্গে অনেক service ব্যর্থ হতে পারে:

sudo fixfiles -F onboot
sudo reboot

এটি /.autorelabel লেখে এবং পরবর্তী boot-এর সময় প্রতিটি filesystem relabel করে। বড় disk-এ কাজটি দীর্ঘ সময় নেয় এবং console আটকে আছে বলে মনে হতে পারে। তাই অপেক্ষা করতে পারবেন এমন সময়ে এটি শুরু করুন। Rocky Linux এবং AlmaLinux 9-এ configuration file আর নিজে থেকে kernel অংশ নিষ্ক্রিয় করে না। SELinux সম্পূর্ণ নিষ্ক্রিয় করার নথিভুক্ত পদ্ধতি হলো kernel argument (sudo grubby --update-kernel ALL --args selinux=0) ব্যবহার করা। অন্য কারও server পরিচালনার দায়িত্ব নেওয়ার সময় এই command জানা কাজে লাগে। এটি 403 error ঠিক করার পদ্ধতি নয়।

Container আরও একটি label যোগ করে

Red Hat family host-এ container process-গুলো container_t-এ চলে এবং শুধু container_file_t label-যুক্ত file পড়তে পারে। Host থেকে করা bind mount container-এর ভিতরে Permission denied দেখায়, যদিও host-এ ls -l সম্পূর্ণ স্বাভাবিক মনে হয়। :Z suffix runtime-কে mount-টি relabel করতে নির্দেশ দেয়:

docker run -d -v /data/appdata:/var/lib/app:Z myimage

:Z শুধু এই container-এর জন্য directory-টি label করে। :z container-গুলোর মধ্যে ভাগ করে ব্যবহারের জন্য directory-টি label করে। :Z-কে অন্য service ব্যবহার করে এমন directory-তে নির্দেশ করলে সেটি directory-টি recursiveভাবে relabel করে, ফলে ওই service-গুলো নষ্ট হয়। তাই container-এর জন্য আলাদা path ব্যবহার করুন। সেটআপের বাকি সবকিছু অন্য যেকোনো image-এর মতোই, যা VPS-এ Docker চালানো অংশে বর্ণনা করা হয়েছে।

Ubuntu ও Debian-এ AppArmor রয়েছে

কাজ একই, নকশা ভিন্ন। AppArmor কোনো প্রোগ্রামকে তার executable-এর path অনুযায়ী সীমাবদ্ধ করে। এ জন্য এটি /etc/apparmor.d/-এর অধীনে থাকা একটি profile ব্যবহার করে, disk-এর file-এ label প্রয়োগ করে না। তাই relabel করার কিছু নেই এবং 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) এবং আবার enforcement চালু করতে aa-enforce ব্যবহার করা যায়। Ubuntu নির্বাচিত কিছু packaged service-এ confinement প্রয়োগ করে এবং বাকিগুলোকে unconfined রাখে। তাই কী সক্রিয় আছে তা দেখতে aa-status পড়ুন; অনুমান করবেন না।

উভয় সিস্টেমেই একটি অভ্যাস কার্যকর। কোনো service সঠিক মনে হওয়া কিছুর ক্ষেত্রে Permission denied জানালে permission পরিবর্তন করার আগে security log পড়ুন। একই সমস্যা বারবার permission-এর কারণে হয় না।

FAQ

nginx সঠিক file permission থাকা সত্ত্বেও 403 ফেরত দেয় কেন?

কারণ SELinux permission bit নয়, বরং read access অস্বীকার করেছে। web server httpd_t domain-এ চলে এবং শুধু web content হিসেবে label করা file পড়তে পারে। তাই default_t বা admin_home_t label-যুক্ত file প্রত্যাখ্যাত হয়, ফলে nginx পরিবেশন করার মতো কিছু পায় না। sudo ausearch -m AVC -ts recent দিয়ে বিষয়টি নিশ্চিত করুন। এতে scontext-এর শেষে httpd_t এবং tcontext-এ ভুল type দেখা যাবে। এরপর সঠিক label নথিবদ্ধ করে প্রয়োগ করুন: sudo semanage fcontext -a -t httpd_sys_content_t "/data/www(/.*)?", তারপর sudo restorecon -Rv /data/www

কোনো service সচল করতে setenforce 0 চালানো কি নিরাপদ?

setenforce 0 একটি diagnostic step, সমাধান নয়। সমস্যাটি একবার পুনরুৎপাদনের জন্য এটি ব্যবহার করুন, যাতে একবারের pass-এ log সব denial সংগ্রহ করে। sudo ausearch -m AVC -ts recent দিয়ে সেগুলো পড়ুন। এরপর sudo setenforce 1 চালিয়ে কারণগুলো ঠিক করুন। permissive অবস্থায় থাকা server প্রতিটি denial log করে, কিন্তু কোনো denial block করে না। ফলে অপ্রয়োজনীয় log থেকে যায় এবং protection নষ্ট হয়। কাজ করার সময় কোনো একটি service-কে সাময়িকভাবে অনুমতি দিতে হলে sudo semanage permissive -a httpd_t চালান, যাতে মেশিনের বাকি অংশ enforcing অবস্থায় থাকে।

SELinux enforcing অবস্থায় non-standard port-এ কোনো service কীভাবে চালাব?

service-টি যে type-এ bind করতে পারে, সেই type-এ port যোগ করুন। 8081 port-এ web server-এর জন্য: sudo semanage port -a -t http_port_t -p tcp 8081। 2222 port-এ SSH-এর জন্য: sudo semanage port -a -t ssh_port_t -p tcp 2222। প্রথমে sudo semanage port -l | grep -w http_port_t দিয়ে বর্তমান তালিকা দেখুন। কারণ তালিকায় আগে থেকেই থাকা port যোগ করতে গেলে ValueError: Port tcp/8081 already defined ব্যর্থ হয়। এই ধাপটি না করলে অন্য কোনো process port-টি ব্যবহার না করলেও daemon startup-এর সময় bind() ... Permission denied-সহ বন্ধ হয়ে যায়।

Ubuntu-তে কি SELinux আছে?

না। Ubuntu এবং Debian AppArmor সরবরাহ করে। এটি file-এর label-এর পরিবর্তে executable-এর path-এর সঙ্গে যুক্ত profile প্রয়োগ করে। sudo aa-status দিয়ে এর অবস্থা পরীক্ষা করুন এবং sudo journalctl -k-এ apparmor="DENIED" line খুঁজুন। Ubuntu নির্বাচিত packaged service-গুলোকে সীমাবদ্ধ করে। তাই অনেক program default অবস্থায় unconfined থাকে। Rocky Linux এবং AlmaLinux-এ Fedora ও RHEL-এর পাশাপাশি out of the box SELinux enforcing অবস্থায় পাওয়া যায়।