SSD Nodes Learn Hosting plans →
নির্দেশিকা Matt Connorদ্বারা Matt Connor · আপডেট করা হয়েছে 2026-08-26

unprivileged user হিসেবে service চালানোর নিয়ম

root হিসেবে service চালালে একটি bug-ই পুরো server-এর access দিতে পারে। প্রতিটি service-এর আলাদা unprivileged account ব্যবহার করুন, অথবা systemd-তে DynamicUser চালু করুন।

root হিসেবে সবকিছু চালাবেন না কেন

root মেশিনের যেকোনো কাজ করতে পারে: প্রতিটি ফাইল পড়তে, যেকোনো সেটিং পরিবর্তন করতে এবং পুরো সিস্টেম মুছে ফেলতে পারে। কোনো service root হিসেবে চালালে সেই service-কে এই সব ক্ষমতা দেওয়া হয়। service-এ এমন কোনো bug থাকলে যা attacker কাজে লাগাতে পারে, তারা শুধু service-এর নিয়ন্ত্রণ পায় না; root-এর নিয়ন্ত্রণও পায়। আর root-এর অর্থ হলো পুরো server-এর নিয়ন্ত্রণ। unprivileged user হিসেবে service চালালে ক্ষতির পরিমাণ সীমিত থাকে। সীমিত account হিসেবে চলা service-এ bug থাকলেও attacker কেবল ওই account যে resource-গুলোতে access করতে পারে, সেগুলোতেই access পায়। সাধারণত এই resource-এর পরিমাণ প্রায় কিছুই হওয়া উচিত নয়।

এটাই least privilege-এর নীতি: সিস্টেমের প্রতিটি অংশকে কাজ সম্পন্ন করার জন্য যতটুকু access প্রয়োজন, ঠিক ততটুকুই দিন; এর বেশি নয়। compromise-এর ক্ষতির পরিধি সীমিত করার জন্য এটি সবচেয়ে কার্যকর অভ্যাস। আধুনিক server-এ এটি প্রয়োগ করতে প্রায় কোনো অতিরিক্ত খরচও হয় না।

প্রতিটি service-এর জন্য পৃথক account

প্রচলিত পদ্ধতিতে প্রতিটি service-এর জন্য আলাদা system user তৈরি করা হয়। সেই user শুধু সংশ্লিষ্ট service-এর file-এর মালিক হয় এবং login করতে পারে না। একটি web app-এর জন্য system account এভাবে তৈরি করা যেতে পারে:

sudo useradd --system --no-create-home --shell /usr/sbin/nologin appsvc

প্রতিটি flag-এর নির্দিষ্ট কাজ আছে। --system এটিকে মানব ব্যবহারকারীর login account-এর পরিবর্তে service account হিসেবে তৈরি করে। --no-create-home প্রয়োজন না থাকা home directory তৈরি করা বাদ দেয়। --shell /usr/sbin/nologin নির্ধারণ করে যে কোনো attacker কোনোভাবে account-টির নিয়ন্ত্রণ পেলেও সেটি ব্যবহার করে shell খুলতে পারবে না। এই account-এর একমাত্র কাজ হলো একটি process এবং তার file-এর মালিক হওয়া।

এরপর user-টিকে শুধু প্রয়োজনীয় file-এর access দিন, এর বেশি নয়:

sudo chown -R appsvc:appsvc /opt/myapp

এখন service-টি নিজের directory পড়তে ও লিখতে পারবে এবং disk-এর অন্য কোথাও তার কোনো access থাকবে না। service-টি কখনও exploited হলে attacker যে file পরিবর্তন করতে পারবে, তা /opt/myapp-এর মধ্যে সীমাবদ্ধ থাকবে। account-টি world-readable যেকোনো file পড়তে পারবে, কিন্তু system-এর বাকি অংশ পরিবর্তন করতে পারবে না।

systemd-কে সেই account হিসেবে চালাতে দিন

account তৈরি হয়ে গেলে service-টি সেই account হিসেবে চালানোর জন্য systemd-কে নির্দেশ দিন। unit file-এ একটি line-ই যথেষ্ট:

[Service]
ExecStart=/opt/myapp/bin/server
User=appsvc
Group=appsvc

User=appsvc নির্ধারণ করে যে process-টি root-এর privileges দিয়ে নয়, ওই account-এর সীমিত privileges দিয়ে শুরু হবে। systemd-এর অধীনে application চালানোর জন্য এটি প্রচলিত এবং সঠিক পদ্ধতি। আপনি যে প্রতিটি service-এর জন্য unit লিখবেন, সেখানেই এটি ব্যবহার করা উচিত। তবে systemd যদি ভুল process monitor করে, তাহলে privileges কমালেও সমস্যার সমাধান হবে না। daemon নীরবে exit করার পরও unit active দেখালে, process-টি যেভাবে শুরু হয় তার জন্য সঠিক Type= নির্বাচন করেছেন কি না পরীক্ষা করুন।

অথবা DynamicUser ব্যবহার করে account সম্পূর্ণ এড়িয়ে যান

systemd আরও এক ধাপ এগিয়ে আপনার জন্য একটি অস্থায়ী user তৈরি করতে পারে। এই user শুধু service চলার সময়ই থাকে। DynamicUser=yes সেট করলে আপনাকে কোনো account পরিচালনা করতে হবে না:

[Service]
ExecStart=/opt/myapp/bin/server
DynamicUser=yes
StateDirectory=myapp

শুরু হওয়ার সময় systemd একটি অব্যবহৃত user ID বরাদ্দ করে। বন্ধ হওয়ার সময় সেটি ছেড়ে দেয়। Service-টি একটি ব্যক্তিগত /tmp, অধিকাংশ filesystem-এর read-only view এবং /var/lib/myapp-এর অধীনে একটি writable state directory-ও পায়। StateDirectory= এই directory প্রস্তুত করে service-এর কাছে হস্তান্তর করে। SysV init-এ এমন ব্যবস্থা সম্ভব ছিল না। সেখানে privilege কমানোর কাজটি প্রতিটি service-এর start script কীভাবে লেখা হয়েছে, তার ওপর নির্ভর করত। এই সীমাবদ্ধতাই distributions কেন প্রথমে systemd-এ পরিবর্তিত হয়েছিল তার একটি বড় কারণ। কোনো self-contained service-এর শুধু নিজস্ব state directory প্রয়োজন হলে DynamicUser=yes শক্তিশালী isolation পাওয়ার সবচেয়ে কম পরিশ্রমের উপায়। কারণ attacker লক্ষ্য করতে পারে এমন কোনো দীর্ঘস্থায়ী account একেবারেই থাকে না।

Unit হাতে লিখলে কাজটি ঝামেলাপূর্ণ হয়। Hardening directive সঠিকভাবে সেট করাই এই প্রক্রিয়ার সবচেয়ে গুরুত্বপূর্ণ অংশ। systemd service এবং timer guide-এর generator আপনার হয়ে এই option-গুলো পূরণ করতে পারে। এতে unit প্রথমবারেই সঠিকভাবে তৈরি হবে।

বাকি ব্যবস্থাগুলোর সঙ্গে এটি কীভাবে কাজ করে

Least privilege একটি স্তর। এটি অন্য স্তরগুলোর বিকল্প নয়; বরং সেগুলোর সঙ্গে কাজ করে। একটি default-deny firewall service-এ কী পৌঁছাতে পারবে তা নিয়ন্ত্রণ করে। unprivileged user হিসেবে service চালালে service-টি breached হলে কী করতে পারবে তা সীমিত থাকে। আর hardened SSH শুরুতেই attacker-দের server-এ প্রবেশ ঠেকায়। এগুলোর কোনো একটিই একা যথেষ্ট নয়। একসঙ্গে ব্যবহার করলে একটি service-এর bug পুরো server-এ compromise ঘটাতে পারে না। গোপন তথ্য সুরক্ষিত রাখে এমন কিছু host করলে এই layer-গুলোর সীমা স্পষ্ট হয়। একটি restricted account breached process কোন resource ব্যবহার করতে পারবে তা সীমিত করে। কিন্তু Vaultwarden-এর মতো self-hosted password manager-এর নিরাপত্তা শেষ পর্যন্ত নির্ভর করে তার admin token এবং backup file কীভাবে সুরক্ষিত রাখছেন তার ওপর। user isolation এই দুটির কোনোটি সুরক্ষিত করে না।

এগিয়ে যাওয়ার আগে পুরো server-এর জন্য একটি hardening checklist অনুসরণ করুন এবং কাজের সুবিধার জন্য নিজের প্রয়োজন অনুযায়ী একটি কপি তৈরি করুন:

ToolVPS hardening checklist

FAQ

কেন service-কে root হিসেবে চালানো উচিত নয়?

root মেশিনে যেকোনো কাজ করতে পারে। তাই root হিসেবে চলা কোনো service exploit হলে attacker শুধু service নয়, পুরো server-এর নিয়ন্ত্রণ পেয়ে যায়। service-কে সীমিত privilege-সহ unprivileged account হিসেবে চালালে ক্ষতি সেই account যে resource-গুলোতে access করতে পারে, সেখানেই সীমাবদ্ধ থাকে। প্রশাসনিক কাজের জন্য root সংরক্ষণ করুন এবং প্রতিটি দীর্ঘসময় চলা service restricted user হিসেবে চালান।

কীভাবে এমন user তৈরি করব যে login করতে পারবে না?

sudo useradd --system --no-create-home --shell /usr/sbin/nologin NAME চালান। nologin shell থাকলে account-এর credential চুরি হলেও এটি interactive session খুলতে পারে না। --system এটিকে service account হিসেবে চিহ্নিত করে। --no-create-home account-এর প্রয়োজন নেই এমন home directory তৈরি করা এড়িয়ে যায়। chown ব্যবহার করে account-কে শুধু নিজের file-গুলোর ownership দিন।

systemd DynamicUser কী?

DynamicUser=yes systemd-কে service চলার সময়ের জন্য একটি temporary user তৈরি করতে বলে। service বন্ধ হলে user-টি আর থাকে না। ফলে দীর্ঘস্থায়ী account পরিচালনা করতে হয় না। এটি service-কে একটি private /tmp, প্রায় read-only filesystem view এবং managed state directory-ও দেয়। throwaway, low-privilege identity-এর অধীনে self-contained service চালানোর এটি সবচেয়ে কম পরিশ্রমের পদ্ধতি।

non-root user হিসেবে চালানো কি firewall-এর বিকল্প?

না। তারা ভিন্ন বিষয় সুরক্ষিত করে। unprivileged user হিসেবে চালালে service breach হলে সেটি কী করতে পারবে তা সীমিত হয়। অন্যদিকে firewall service-এ আদৌ কী পৌঁছাতে পারবে তা সীমিত করে। hardened SSH-এর পাশাপাশি দুটিই ব্যবহার করুন, যাতে প্রতিটি layer অন্য layer-এর সীমাবদ্ধতা পূরণ করে।

কোন file-এর ownership service user-এর থাকা উচিত?

শুধু service-এর প্রকৃতপক্ষে প্রয়োজনীয় file-গুলোর, এর বেশি নয়। account-কে তার নিজস্ব working directory এবং data-এর ownership দিন। বাকি সবকিছু root-এর ownership-এ রাখুন। একটি ভালো pattern হলো application directory-এর জন্য sudo chown -R svc-app:svc-app /opt/svc-app ব্যবহার করা। অন্যদিকে /etc-এর অধীন configuration root-এর ownership-এ থাকবে এবং service শুধু সেগুলো পড়তে পারবে। লক্ষ্য হলো process কখনো compromised হলে সেটি যে file পরিবর্তন করতে পারে, তা যেন নিজের data-তে সীমাবদ্ধ থাকে; system-এর অন্য অংশে নয়।

#security#least-privilege#systemd#users#hardening#linux