সার্ভার একবার সাজিয়ে দেওয়া হয়, তারপর সে নিজেই চলতে থাকে। এক মাস পরে কিছু প্যাকেজ হালনাগাদের অপেক্ষায় থাকে, সার্টিফিকেট মেয়াদ শেষের তিন সপ্তাহের মধ্যে চলে আসে, সম্পর্কহীন কিছু ইনস্টল করার পরে SSH-এর কনফিগারেশনে একটি বাড়তি লাইন জুটে যায়, আর যে jail লগইনের উপর নজর রাখার কথা, সেটি থেমে যায় এবং কেউ টেরও পায় না। এর কোনোটিই চিৎকার করে না। সবকিছু কেবল নিঃশব্দে সত্য হওয়া বন্ধ করে দেয়।

নিচে বারোটি জিনিস, যেগুলো নিয়মিত পরীক্ষা করা সার্থক, কমান্ডসহ। চক্করটি মিনিট পনেরো নেয়। ক্রম চলে যেটা দিয়ে ভেতরে ঢোকা হয় তা থেকে যেটা নিজে থেকে নষ্ট হয় তার দিকে।

SSH: পাঁচটি লাইন

দেখার জিনিস ফাইল নয়, বরং কার্যকর কনফিগারেশন: সেটি তৈরি হয় /etc/ssh/sshd_config, পুরো sshd_config.d ডিরেক্টরি এবং কম্পাইলের ডিফল্ট মান মিলিয়ে।

sudo sshd -T | grep -iE 'permitrootlogin|passwordauthentication|permitemptypasswords|maxauthtries|x11forwarding'

আমরা যা দেখতে চাই: permitrootlogin no, passwordauthentication no, permitemptypasswords no, maxauthtries 3–4-এর মধ্যে এবং x11forwarding no। প্রথম তিনটি দরজা, শেষ দুটি তার কব্জা — প্রতি সংযোগে চেষ্টার সীমা, আর গ্রাফিক্স ফরোয়ার্ডিং যার সার্ভারে কোনো দরকার নেই।

দুটি সতর্কতা, দুটোই নিজেকে বাইরে আটকে ফেলার সহজ উপায়। প্রথমটি: পাসওয়ার্ড দিয়ে লগইন ও root লগইন বন্ধ করবেন না যতক্ষণ না নিশ্চিত হন যে আপনার কী কাজ করে — আলাদা একটি সেশনে, চলতি সেশন বন্ধ না করে। আপনি যদি এটি root হিসেবে পাসওয়ার্ড দিয়ে যুক্ত থেকে পড়েন, তবে ওই দুটি লাইন ঠিক আপনাকেই বাইরে আটকে দেবে।

দ্বিতীয়টি: ফাইলের ক্রম। OpenSSH কোনো প্যারামিটারের সেই মানটি নেয় যেটি প্রথমে পায়, আর sshd_config.d-এর ফাইলগুলো বর্ণানুক্রমে পড়া হয়। ক্লাউড ইমেজ সেখানে সাধারণত 50-cloud-init.conf রেখে যায়, আর আপনার ফাইলের নাম 90-hardening.conf ধরনের হলে সেটিই জিতে যাবে। নিজের সেটিংস ছোট নম্বরের নিচে রাখুন — 00- বা 10-। আর ফল যাচাই হয় sshd -T দিয়ে, ফাইল পড়ে নয়।

ফায়ারওয়াল: একটি পরীক্ষা

sudo ufw status verbose

এখানে মনে রাখা দরকার যে এই আউটপুট অভিপ্রায় দেখায়, ফল নয়। একটি নিয়ম তালিকায় থেকেও কিছুই বন্ধ না করতে পারে: UFW নিজেই বন্ধ, পোর্টটি সামলাচ্ছে Docker-এর প্রকাশ করা কিছু (সে নিজের নিয়ম UFW-এর নিচে iptables-এ লেখে), কিংবা ট্রাফিক সার্ভারে অন্য পথে পৌঁছাচ্ছে। তাই নিয়মের তালিকাকে বাইরের দিকে সত্যিই যা শুনছে তার সঙ্গে মিলিয়ে নেওয়া কাজে দেয়:

sudo ss -tulpn | grep -v '127.0.0.1\|::1'

fail2ban: দুটি পরীক্ষা

সেবা চালু থাকাই যথেষ্ট নয় — SSH-এর জন্য কার্যকর একটি jail-ও লাগে।

sudo fail2ban-client status
sudo fail2ban-client status sshd

এখানে সবচেয়ে সাধারণ ঝামেলা নীরব jail। Debian 12 ও নতুন Ubuntu-তে /var/log/auth.log আদৌ না-ও থাকতে পারে: rsyslog ইনস্টল করা নেই আর রেকর্ড বাস করে কেবল journald-এ। কারখানার logpath নিয়ে চলা jail তখন চালু হয়, নিজেকে সক্রিয় বলে জানায় এবং কখনো কাউকে ব্লক করে না। সারানো যায় একে systemd-এর জার্নালের দিকে ফিরিয়ে:

printf '[sshd]\nenabled = true\nbackend = systemd\n' | sudo tee /etc/fail2ban/jail.d/sshd-systemd.local
sudo systemctl restart fail2ban

কনফিগারেশন না ঘেঁটেই এটি ধরার চিহ্ন: fail2ban-client status sshd-তে «Currently failed» এবং «Total failed» শূন্যে দাঁড়িয়ে থাকে, যদিও জার্নালে ব্যর্থ লগইন স্পষ্টভাবেই আছে।

হালনাগাদ: তিনটি পরীক্ষা

আলাদাভাবে: মোট কতগুলো প্যাকেজ অপেক্ষায়, তার কতগুলো নিরাপত্তাসংক্রান্ত, আর কার্নেল হালনাগাদের পরে সিস্টেম রিস্টার্ট চাইছে কি না।

sudo apt update
apt list --upgradable 2>/dev/null | grep -c -- '-security'
ls /var/run/reboot-required 2>/dev/null && echo 'রিস্টার্ট দরকার'

তৃতীয় পরীক্ষা হলো স্বয়ংক্রিয় নিরাপত্তা হালনাগাদ চালু আছে কি না, যাতে প্রথম দুটি মাসিক আচারে পরিণত না হয়:

systemctl status unattended-upgrades --no-pager
cat /etc/apt/apt.conf.d/20auto-upgrades

সেই ফাইলের দুই লাইনেই 1 থাকা উচিত। প্যাকেজ না থাকলে: sudo apt install unattended-upgrades && sudo dpkg-reconfigure -plow unattended-upgrades।

সার্টিফিকেট: একটি পরীক্ষা

Let's Encrypt-এর সার্টিফিকেট নব্বই দিন বাঁচে, আর নবায়ন সাধারণত নিজে থেকেই চলে — ঠিক সেই দিন পর্যন্ত যেদিন সেটি থেমে যায়। দেখার জিনিস রেজিস্ট্রারের প্যানেল নয়, বরং সার্ভার সত্যিই যা পরিবেশন করছে তা:

echo | openssl s_client -connect localhost:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate
sudo certbot renew --dry-run

প্রথম কমান্ড ওই নামের জন্য পরিবেশিত সার্টিফিকেটের মেয়াদ শেষের তারিখ দেয়; দ্বিতীয়টি আসল সময়সীমার অপেক্ষা না করেই নিশ্চিত করে যে নবায়ন উতরে যাবে। সার্ভার যত নাম সামলায় সবগুলোতেই চোখ বোলানো উচিত, কেবল মূল ডোমেইনে নয়: ভুলে যাওয়া হয় সাধারণত পরে যোগ করা সাবডোমেইনটিই।

ডিস্ক: একটি পরীক্ষা

df -h
df -i

দুটি কমান্ড, কারণ জায়গা আর ফাইলের নথি একে অপরের থেকে স্বাধীনভাবে ফুরোয়। বেশির ভাগ সার্ভারে দ্বিতীয়টি আগে ছাদে ঠেকে — PHP সেশনে বা অ্যাপ্লিকেশনের ক্যাশে লক্ষ লক্ষ ছোট ফাইল IUse%-কে 100-এ তুলে দেয় যখন গিগাবাইট খালি পড়ে থাকে। দুটি ক্ষেত্রেই আমাদের আলাদা লেখা আছে।

এই তালিকার সমস্যা কোথায়

তালিকাটি ঠিক, কিন্তু তার একটি ধর্ম আছে: কাউকে সেটি মনে রাখতে হয়। সপ্তাহে পনেরো মিনিট বেশি নয়, যতক্ষণ সার্ভার একটি আর যতক্ষণ কারণ আছে। দুটি শান্ত মাসের পরে চক্কর বাদ পড়ে, আর jail থেমে গেছে সেটা জানা যায় অন্য কারও লগ থেকে।

তাই আমরা ঠিক এই বারোটি পরীক্ষাকে একটি আলাদা বিনামূল্যের প্যানেলে জড়ো করেছি — Arcivéo FREE। এটি এক কমান্ডে ইনস্টল হয়, আপনার নিজের সার্ভারে চলে, আমাদের কিছুই পাঠায় না এবং নিবন্ধন চায় না। একটি সংগ্রাহক cron থেকে প্রতি পাঁচ মিনিটে চলে এবং একই জিনিস স্থানীয় ডেটাবেসে লেখে: SSH লগইন ও প্রত্যাখ্যাত সংযোগ, UFW ও fail2ban-এর অবস্থা, অপেক্ষমাণ নিরাপত্তা হালনাগাদ, সার্টিফিকেটের মেয়াদ, ডিস্কের জায়গা। ইতিহাস সাত দিনের, ইন্টারফেস 34টি ভাষায়। দাম শূন্য, কাজের সার্ভারেও: লাইসেন্স প্যানেলটি নিজের মেশিনে, কোম্পানির মেশিনসহ, ইনস্টল করার অনুমতি দেয়, আর সেটি পুনর্বিক্রয় করা বা অন্যের সার্ভারের জন্য সেবা হিসেবে চালানোর অনুমতি দেয় না।

বিনামূল্যের সংস্করণের স্ট্যাক বিনয়ী: এটি UFW আর fail2ban ইনস্টল ও চালু করে, তারপর অবস্থা দেখায়। ModSecurity, Suricata, AIDE আর বাকি মডিউল এতে নেই, সেগুলো সবেতন সংস্করণের। তবে সাপ্তাহিক চক্কর মাথায় বয়ে বেড়ানো বন্ধ করতে এটুকুই যথেষ্ট। একই তথ্য পূর্ণ প্যানেলে কেমন দেখায় — নিচের ডেমো পাতাগুলোয়।