সম্পূর্ণ ম্যানুয়াল ইনস্টলেশন: সদ্য কেনা VPS থেকে চালু ড্যাশবোর্ড পর্যন্ত, ধাপে ধাপে।
সার্ভার প্রস্তুতি, সাইট তৈরি, ডেটাবেস, config.php এবং SSL এখানে বিস্তারিত দেওয়া আছে।
প্রতিটি নিরাপত্তা টুল ও cron সংক্রান্ত কমান্ড রয়েছে
FAQ-রেফারেন্সে, প্রয়োজন অনুযায়ী লিঙ্ক দেওয়া আছে।
প্রধান নিয়ম: SSH বা ফায়ারওয়াল পরিবর্তন করার সময়, নতুন সংযোগ আলাদা উইন্ডোতে যাচাই না করা পর্যন্ত বর্তমান সংযোগ বন্ধ করবেন না। যদি তবুও অ্যাক্সেস হারিয়ে যায় — প্রায় সব হোস্টিং প্রোভাইডার তাদের কন্ট্রোল প্যানেলে জরুরি কনসোল (VNC/Recovery) দিয়ে থাকে।
01. Ubuntu/Debian সহ VPS কিনেছেন — কোথা থেকে শুরু করবেন
কেনার পরে হোস্টিং প্রোভাইডার পাঠায়: IP অ্যাড্রেস, ব্যবহারকারীর নাম (সাধারণত root) এবং পাসওয়ার্ড (অথবা SSH কী)। প্রবেশ করতে এটুকুই যথেষ্ট। কাজের ধাপগুলো (প্রতিটি ধাপ — নিচে একটি বিভাগ):
SSH দিয়ে সার্ভারে সংযোগ করুন;
সিস্টেম আপডেট করুন, হোস্টনেম ও টাইমজোন নির্ধারণ করুন;
sudo অধিকারসহ একজন সাধারণ ব্যবহারকারী তৈরি করুন (root হিসেবে কাজ করবেন না);
SSH কী দিয়ে প্রবেশ কনফিগার করুন এবং পাসওয়ার্ড দিয়ে প্রবেশ বন্ধ করুন;
SSH হলো সার্ভারের সাথে একটি সুরক্ষিত টার্মিনাল সংযোগ। 203.0.113.10-এর জায়গায় আপনার নিজের IP বসান।
203.0.113.10 — এটি একটি উদাহরণ, বাস্তবে নেই এমন ঠিকানা (ডকুমেন্টেশনের জন্য সংরক্ষিত)। এটি হুবহু বসাবেন না — হোস্টারের ইমেল থেকে পাওয়া আপনার সার্ভারের আসল IP দিয়ে বদলে নিন। নাহলে সংযোগ হবে না।
Windows 10/11: PowerShell বা “টার্মিনাল” খুলে বিল্ট-ইন ssh ব্যবহার করুন (অথবা PuTTY / MobaXterm ক্লায়েন্ট)। macOS / Linux: “টার্মিনাল” খুলুন।
# root হিসেবে লগইন (পাসওয়ার্ড হোস্টার থেকে এসেছে):
ssh root@203.0.113.10
# হোস্টার পাসওয়ার্ডের বদলে ফাইল-কি দিলে:
ssh -i পথ/কি-এর root@203.0.113.10
প্রথম সংযোগের সময় SSH “authenticity of host” সম্পর্কে জিজ্ঞাসা করবে — yes লিখুন। পাসওয়ার্ড টাইপ করার সময় দেখা যায় না (এটি স্বাভাবিক)। হোস্টার অস্থায়ী পাসওয়ার্ড দিলে passwd কমান্ড দিয়ে সেটি বদলে নিন।
03. সিস্টেম আপডেট ও প্রাথমিক কনফিগারেশন
প্রথমেই সব প্যাকেজ আপডেট করুন এবং হোস্টনেম ও টাইমজোন নির্ধারণ করুন।
টাইমজোনের তালিকা — timedatectl list-timezones। আপডেট শেষে যদি নীল উইন্ডো “Daemons using outdated libraries” দেখা যায় — সব সার্ভিস চিহ্নিত করুন (স্পেস) এবং OK চাপুন, এটি নিরাপদ।
04. sudo সহ ব্যবহারকারী তৈরি
সবসময় root হিসেবে কাজ করা নিরাপদ নয়। একটি সাধারণ ব্যবহারকারী তৈরি করুন এবং তাকে sudo অধিকার দিন (প্রয়োজনে অ্যাডমিন হিসেবে কমান্ড চালানোর জন্য)। deploy-এর জায়গায় যেকোনো নাম বসান।
# ব্যবহারকারী তৈরি করুন (পাসওয়ার্ড সেট করবে ও তথ্য জিজ্ঞাসা করবে — Enter চাপা যায়):
adduser deploy
# sudo গ্রুপে যোগ করুন:
usermod -aG sudo deploy
# যাচাই করুন (root হিসেবে):
su - deploy
sudo whoami # আউটপুট হওয়া উচিত: root
exit
এরপর এই ব্যবহারকারী দিয়েই সার্ভারে লগ ইন করুন: ssh deploy@203.0.113.10, আর অ্যাডমিন কমান্ডগুলো sudo উপসর্গ দিয়ে চালান।
05. SSH কী এবং পাসওয়ার্ড দিয়ে লগইন বন্ধ করা
কী দিয়ে লগইন পাসওয়ার্ডের চেয়ে নিরাপদ: পাসওয়ার্ড অনুমান করা যায়, কী প্রায় অসম্ভব। প্রথমে নিজের কম্পিউটারে কী তৈরি করি, সেটি সার্ভারে কপি করি, লগইন যাচাই করি — এবং তারপরই পাসওয়ার্ড বন্ধ করি।
ধাপ ১. নিজের কম্পিউটারে কী তৈরি করুন (Windows PowerShell / macOS / Linux):
ssh-keygen -t ed25519 -C "my-laptop"
# সব প্রশ্নে Enter (কী ~/.ssh/id_ed25519-এ সংরক্ষিত হবে)
ধাপ ৩. একটি নতুন উইন্ডোতে কী দিয়ে লগইন যাচাই করুন — পাসওয়ার্ড ছাড়াই ঢুকতে দেওয়া উচিত:
ssh deploy@203.0.113.10
কী দিয়ে লগইন যাচাই ও কার্যকর প্রমাণিত না হওয়া পর্যন্ত (ধাপ ১–৩) বিকল্প B চালাবেন না, এবং চালু সেশনটি বন্ধ করবেন না। এটি root সহ সব ব্যবহারকারীর জন্য পাসওয়ার্ড দিয়ে লগইন বন্ধ করে দেয়। কার্যকর কী ছাড়া সার্ভারে অ্যাক্সেস সম্পূর্ণভাবে হারাবেন — যা কেবল হোস্টিং কনসোলের মাধ্যমেই ফিরে পাওয়া যাবে। কী না থাকলে বিকল্প A নিন।
ধাপ ৪. SSH অ্যাক্সেস কঠোর করুন। সেটিংস একটি আলাদা ফাইলে রাখি, মূল কনফিগ ছুঁই না। আপনার পরিস্থিতি অনুযায়ী বিকল্প বেছে নিন:
বিকল্প A — শুধু root বন্ধ করুন, পাসওয়ার্ড রেখে দিন। কী লাগবে না এবং অ্যাক্সেস হারাবেন না:
বিকল্প B — পূর্ণ হার্ডেনিং। পাসওয়ার্ড দিয়ে লগইন বন্ধ করুন এবং root কেবল কী দিয়ে রাখুন। এটি কেবল তখনই চালান যখন নিশ্চিত হবেন যে কী দিয়ে লগইন কাজ করছে:
sudo tee /etc/ssh/sshd_config.d/00-hardening.conf >/dev/null <<'EOF'
PubkeyAuthentication yes
PasswordAuthentication no
PermitRootLogin prohibit-password
KbdInteractiveAuthentication no
EOF
sudo systemctl restart ssh
দুই বিকল্পেই root-এর পাসওয়ার্ড দিয়ে লগইন বন্ধ হয়ে যায়। PermitRootLogin no root-কে সম্পূর্ণভাবে বন্ধ করে, আর prohibit-password কেবল কী দিয়ে লগইন রাখে (প্রশাসনের জন্য deploy দিয়ে ঢুকুন ও sudo ব্যবহার করুন)। SSH পোর্ট বদলাতে চাইলে Port 2222 লাইন যোগ করুন, তবে প্রথমে ফায়ারওয়ালে নতুন পোর্ট খুলুন (পরের বিভাগ) এবং লগইন যাচাই করুন, নইলে নিজের অ্যাক্সেস বন্ধ করে ফেলবেন।
06. বেসিক ফায়ারওয়াল এবং স্বয়ংক্রিয় সুরক্ষা
ফায়ারওয়াল দিয়ে সব অপ্রয়োজনীয় পোর্ট বন্ধ করুন এবং fail2ban চালু করুন (SSH-তে পাসওয়ার্ড ব্রুট-ফোর্স ব্যান করে)। প্রথমে SSH অনুমোদন করুন, নইলে UFW চালু করার পর অ্যাক্সেস হারাবেন।
# SSH (বা আপনার পোর্ট, যদি পরিবর্তন করে থাকেন) এবং ওয়েব অনুমোদন করুন:
sudo ufw allow OpenSSH
sudo ufw allow 80,443/tcp
# ফায়ারওয়াল চালু করুন:
sudo ufw enable
sudo ufw status verbose
# fail2ban — ব্রুট-ফোর্স থেকে SSH সুরক্ষা (বেসিক প্রোফাইল সঙ্গে সঙ্গে সক্রিয়):
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
এটি ন্যূনতম। fail2ban-এর কার্যকর সেটিংস, ipsum ব্লক-লিস্ট, বর্ধিত UFW এবং অন্যান্য টুল — রেফারেন্সের “নিরাপত্তা টুল” গ্রুপে। Arcivéo Monitor প্যানেল নিজেই এসব কিছুর স্ট্যাটাস স্পষ্টভাবে দেখাবে।
07. HestiaCP প্যানেল ইনস্টল করা (ঐচ্ছিক)
HestiaCP — একটি বিনামূল্যের হোস্টিং কন্ট্রোল প্যানেল: এটি ওয়েব সার্ভার (nginx + apache), PHP, ডেটাবেস (MariaDB), মেইল, DNS ও SSL সার্টিফিকেট ইনস্টল ও কনফিগার করে এবং সাইটের জন্য ওয়েব ইন্টারফেস দেয়। সবকিছু হাতে কনফিগার করতে না চাইলে এবং সাইট (Arcivéo Monitor প্যানেল সহ) রাখার পরিকল্পনা থাকলে এটি সুবিধাজনক।
HestiaCP একটি পরিষ্কার সার্ভারে ইনস্টল করুন (সদ্য ইনস্টল করা সমর্থিত Ubuntu/Debian, ন্যূনতম ~১–২ GB RAM), অন্য ওয়েব সার্ভার ও ডেটাবেস ইনস্টলের আগে — নয়তো বিরোধ দেখা দেবে। ইনস্টল করতে ১০–২০ মিনিট লাগে এবং সার্ভার রিবুট হবে।
# ইনস্টলার ডাউনলোড করে চালান:
wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh
sudo bash hst-install.sh
ইনস্টলার email ও হোস্টনেম জিজ্ঞাসা করবে, তারপর পুরো স্ট্যাকটি ইনস্টল করবে। রিবুটের পর প্যানেলটি https://YOUR_IP:8083 ঠিকানায় পাওয়া যাবে (লগইন ও পাসওয়ার্ড ইনস্টলার শেষে দেখাবে)।
HestiaCP নিজেই UFW ও fail2ban পরিচালনা করে — সেগুলি আলাদাভাবে কনফিগার করার দরকার নেই, এটি নিজে থেকেই সামলে নেবে। তবু SSH কী ও পাসওয়ার্ড নিষ্ক্রিয় করা (আগের অংশ) করে নিন।
08. সিস্টেম প্রয়োজনীয়তা এবং ionCube
ড্যাশবোর্ড হলো সাধারণ LAMP/LEMP স্ট্যাকের উপর তৈরি একটি PHP অ্যাপ্লিকেশন:
ionCube Loader ইনস্টল (যদি এখনও না থাকে)। প্যানেলযুক্ত হোস্টিংয়ে (HestiaCP, cPanel) PHP সেটিংসে একটি চেকবক্স দিয়ে ionCube চালু হয়। Ubuntu/Debian-এ ম্যানুয়ালি:
# PHP সংস্করণ ও এক্সটেনশন ডিরেক্টরি জানুন:
php -v
EXTDIR=$(php -r 'echo ini_get("extension_dir");'); PHPVER=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')
# লোডার ডাউনলোড ও আনপ্যাক করুন (64-bit):
cd /tmp
wget -q https://downloads.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz
tar xzf ioncube_loaders_lin_x86-64.tar.gz
# আপনার PHP সংস্করণের লোডার এক্সটেনশন ডিরেক্টরিতে কপি করুন:
sudo cp ioncube/ioncube_loader_lin_${PHPVER}.so "$EXTDIR"/
# সংযুক্ত করুন (CLI + PHP-FPM) এবং পুনরায় চালু করুন:
echo "zend_extension=ioncube_loader_lin_${PHPVER}.so" | sudo tee /etc/php/${PHPVER}/mods-available/ioncube.ini
sudo phpenmod ioncube
sudo systemctl restart php${PHPVER}-fpm
# যাচাই — আউটপুটে "with the ionCube PHP Loader" লাইনটি দেখা যাবে:
php -v
লোডারের সংস্করণ PHP সংস্করণের সাথে মিলতে হবে (যেমন PHP 8.1-এর জন্য ioncube_loader_lin_8.1.so)। যদি একাধিক PHP সংস্করণ ব্যবহার করেন — প্রতিটির জন্য লোডার সংযুক্ত করুন।
09. ডোমেইন এবং DNS
প্যানেলটি monitor.example.com এর মতো ঠিকানায় খুলতে এবং বিনামূল্যে SSL পেতে — আপনার সার্ভারের দিকে নির্দেশ করা একটি ডোমেইন প্রয়োজন। DNS নিয়ন্ত্রণ প্যানেলে একটি A-রেকর্ড তৈরি করুন:
টাইপ: A
নাম: monitor (সাবডোমেইন → monitor.example.com)
বা @ (ডোমেইনের মূল → example.com)
মান: 203.0.113.10 ← আপনার সার্ভারের IP
TTL: 3600
কয়েক মিনিট পর যাচাই করুন যে ডোমেইনটি সার্ভারের দিকে নির্দেশ করছে:
dig +short monitor.example.com # আপনার IP ফেরত দেওয়া উচিত
# অথবা, dig না থাকলে:
getent hosts monitor.example.com
Let's Encrypt SSL সার্টিফিকেট শুধুমাত্র ডোমেইনের জন্য ইস্যু করা হয় — সার্টিফিকেট ইস্যু করার আগে DNS অবশ্যই সার্ভারের দিকে নির্দেশ করতে হবে।
10. সাইট তৈরি করুন ও প্যানেলের ফাইল আপলোড করুন
Apache: DocumentRoot — প্যানেলের রুটে, public/-এ নয়। স্টাইল (CSS/JS), sw.js, manifest.json থাকে public/-এর পাশে assets/-এ এবং সাইটের রুট থেকে অনুরোধ করা হয়। রুটের .htaccess — ফ্রন্ট-কন্ট্রোলার। Apache-তে যদি DocumentRoot public/-এ দেওয়া হয় — প্যানেল স্টাইল ছাড়া খুলবে। বিশুদ্ধ nginx-এর জন্য উল্টো: রুট হিসেবে নেওয়া হয় public/, আর assets/ আলাদা নিয়মে দেওয়া হয় (নিচের nginx ব্লক দেখুন)।
প্যানেলের ফাইল (ডিস্ট্রিবিউশন আর্কাইভ) কেনার পর my.arciveo.com → “ডাউনলোড”-এ অ্যাকাউন্ট থেকে ডাউনলোড হয়। আপলোডের আগে আর্কাইভটি আনজিপ করুন।
1) প্যানেলের ডিরেক্টরি তৈরি করুন এবং তাতে ডিস্ট্রিবিউশনের কন্টেন্ট আপলোড করুন (যাতে ভেতরে public/, assets/, config.php ইত্যাদি থাকে):
nginx: nginx-এ .htaccess নেই, তাই রুট হিসেবে নেওয়া হয় public/, আর assets/, sw.js, manifest.json (এক স্তর উপরে) আলাদা নিয়মে দেওয়া হয়:
PHPSOCK=$(ls -1 /run/php/php*-fpm.sock 2>/dev/null | head -1) # PHP-FPM সকেট স্বয়ংক্রিয় শনাক্তকরণ
sudo tee /etc/nginx/sites-available/monitor.conf > /dev/null <<'EOF'
server {
listen 80;
server_name monitor.example.com;
root /var/www/monitor/public;
index index.php;
# assets, service worker ও manifest public/-এর এক স্তর উপরে থাকে
location ~ ^/(assets/|sw\.js|manifest\.json) { root /var/www/monitor; }
location / { try_files $uri $uri/ /index.php?$query_string; }
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:__PHPSOCK__;
}
}
EOF
sudo sed -i "s#__PHPSOCK__#${PHPSOCK}#" /etc/nginx/sites-available/monitor.conf
sudo ln -s /etc/nginx/sites-available/monitor.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
ফাইল আপলোড — SFTP/SCP (FileZilla, WinSCP) বা scp:
# লোকাল কম্পিউটার থেকে scp-এর উদাহরণ:
scp -r ./monitor/* deploy@203.0.113.10:/var/www/monitor/
ফাইলের অনুমতি সেট করুন — এটি বাধ্যতামূলক ধাপ। যদি root হিসেবে বা SFTP-তে আপলোড করে থাকেন, ফাইলগুলো root-এর মালিকানাধীন থাকে, আর ওয়েব-সার্ভার (www-data) সেগুলো পড়তে পারবে না — প্যানেল খালি বা 403 এরর দিয়ে খুলবে (লগে: .htaccess unreadable / directory not executable)। নিচের কমান্ড এটি ঠিক করে:
# পুরো ওয়েবরুটের অনুমতি স্বাভাবিক করি: root-এর তৈরি ডিরেক্টরি
# ওয়েব-সার্ভারের (www-data) কাছে অগম্য — এটি ছাড়া প্যানেল খালি পৃষ্ঠা বা 403 দেয়।
# Apache www-data হিসেবে চলে; আপনার ভিন্ন ওয়েব-ইউজার হলে — বদলে নিন।
cd /var/www/monitor
# কাজের ফোল্ডার chown-এর আগে তৈরি করি — নাহলে নতুন ডিরেক্টরি root:root থেকে যাবে
# এবং chmod 750-এ ওয়েব-সার্ভার (www-data) সেখানে লিখতে পারবে না।
sudo mkdir -p data/lynis data/logwatch tmp logs
sudo chown -R www-data:www-data /var/www/monitor
sudo find /var/www/monitor -type d -exec chmod 755 {} \;
sudo find /var/www/monitor -type f -exec chmod 644 {} \;
sudo chmod 640 /var/www/monitor/config.php
sudo chmod 750 data tmp logs
৩) নিজের জন্য SFTP-তে ফাইল আপলোড খুলে দিন। উপরের কমান্ডের পর সব ফাইল www-data-এর মালিকানাধীন হয়, অথচ FileZilla / WinSCP আপনার নিজের ব্যবহারকারী দিয়ে সংযোগ করে — তখন আপলোড SSH_FX_PERMISSION_DENIED (Permission denied) দিয়ে ব্যর্থ হবে। আপলোডের জন্য root দিয়ে লগইন করাও যাবে না — root লগইন ধাপ ০৫-এ বন্ধ করা হয়েছে। দুটি বিকল্পের একটি বেছে নিন।
বিকল্প A — শুধু আপনার ব্যবহারকারীর জন্য ACL (প্রস্তাবিত)। লেখার অনুমতি কেবল আপনিই পান; ওয়েব সার্ভার তখনও প্যানেলের কোড বদলাতে পারে না:
sudo apt install -y acl
# প্যানেলের পুরো ডিরেক্টরিতে আপনার ব্যবহারকারীর জন্য লেখার অনুমতি:
sudo setfacl -R -m u:deploy:rwX /var/www/monitor
# একই নিয়ম ডিফল্ট হিসেবে — পরে তৈরি হওয়া ফাইল ও ফোল্ডারের জন্য:
sudo setfacl -R -d -m u:deploy:rwX /var/www/monitor
বিকল্প B — www-data গ্রুপের মাধ্যমে। সহজ, তবে প্যানেলের ফাইলে লেখার অনুমতি ওয়েব সার্ভারও পেয়ে যায়: PHP-তে দুর্বলতা থাকলে কোড বদলে দেওয়া সম্ভব হবে। কমান্ডের ক্রম গুরুত্বপূর্ণ — config.php ও কাজের ফোল্ডারগুলো সবশেষে বন্ধ করা হয়:
sudo usermod -aG www-data deploy
# গ্রুপের জন্য লেখার অনুমতি + setgid (বিট 2): SFTP-তে আপলোড করা ফাইল
# www-data গ্রুপেই থাকে — নইলে প্যানেল সেগুলো পুনরায় লিখতে পারবে না।
sudo find /var/www/monitor -type d -exec chmod 2775 {} \;
sudo find /var/www/monitor -type f -exec chmod 664 {} \;
sudo chmod 640 /var/www/monitor/config.php
sudo chmod 2750 /var/www/monitor/data /var/www/monitor/tmp /var/www/monitor/logs
বিকল্প B-এর পরে FileZilla-তে আবার সংযোগ করুন (সার্ভার → সংযোগ বিচ্ছিন্ন করুন, তারপর নতুন করে লগইন) — নতুন গ্রুপ কেবল নতুন লগইনেই কার্যকর হয়, তার আগে অনুমতি তবুও থাকবে না। যাচাই: id deploy — গ্রুপের তালিকায় www-data দেখা যেতে হবে; ls -ld /var/www/monitor — অনুমতি drwxrwsr-x, x-এর জায়গায় s অক্ষরের মানে setgid সেট করা আছে।
11. ডেটাবেস
একটি ডেটাবেস ও ব্যবহারকারী তৈরি করুন, তারপর স্কিমা ইমপোর্ট করুন। ব্লকটি টার্মিনালে সম্পূর্ণভাবে পেস্ট করুন। monitor_db ও monitor_user — উদাহরণের নাম, আপনি নিজের যেকোনো নাম দিতে পারেন; ডেটাবেসের নাম, ব্যবহারকারী ও পাসওয়ার্ড মনে রাখুন — পরের ধাপে config.php-এ এগুলো লিখতে হবে:
# 1. ডেটাবেস। পাসওয়ার্ড DBPASS-এ একবারই দেওয়া হয় এবং সব লাইনে বসানো হয়।
# ব্লকটি টার্মিনালে সম্পূর্ণভাবে পেস্ট করুন; sudo mysql unix-সকেটে root হিসেবে ঢোকে
# (root পাসওয়ার্ড লাগে না)। কপিপেস্টসহ ইন্টারঅ্যাকটিভ `sudo mysql -u root -p`
# ব্যবহার করবেন না — পেস্টের সময় SQL লাইন পাসওয়ার্ড প্রম্পটে চলে গিয়ে হারিয়ে যাবে।
DBPASS='CHOOSE_A_PASSWORD' # ← শুধু এই লাইনটি বদলান
sudo mysql <<SQL
CREATE DATABASE IF NOT EXISTS monitor_db CHARACTER SET utf8mb4;
CREATE USER IF NOT EXISTS 'monitor_user'@'localhost' IDENTIFIED BY '$DBPASS';
GRANT ALL ON monitor_db.* TO 'monitor_user'@'localhost';
FLUSH PRIVILEGES;
SQL
# যাচাই (monitor_db দেখানো উচিত):
mysql -u monitor_user -p"$DBPASS" -e "SHOW DATABASES;"
# এই একই পাসওয়ার্ড config.php → DB_PASS-এ লিখুন।
স্কিমা ইমপোর্ট করার দরকার নেই — ডেটাবেস খালি থাকলে ব্রাউজারে প্রথম প্রবেশের সময় প্যানেল নিজেই টেবিল ও admin অ্যাকাউন্ট তৈরি করে (database/db.sql থেকে)। ম্যানুয়াল স্কিমা ইমপোর্ট কেবল তখনই দরকার, যদি অটো-ইনিশিয়ালাইজেশন কাজ না করে।
যদি ব্রাউজার ইনস্টলার public/start_db.php ব্যবহার করে থাকেন — ইনস্টলের পরপরই এটি মুছে ফেলুন: এটি অনুমোদন ছাড়াই ডেটাবেস পুনরায় তৈরি করার সুযোগ দেয়। ফাইলটি যতক্ষণ প্যানেলের রুটে বা public/-এ থাকে, প্যানেল লাল সতর্কতা দেখায়।
12. config.php কনফিগার করা
প্যানেলের রুটে থাকা config.php (/var/www/monitor/config.php) — একমাত্র ফাইল যেটি হাতে সম্পাদনা করতে হয়। প্যানেলের সব সেটিংস এতে define() কনস্ট্যান্ট দিয়ে নির্ধারিত। এটি এডিটরে খুলুন:
sudo nano /var/www/monitor/config.php
হাইলাইট করা জায়গায় নিজের মান বসান; বাকিটা যেমন আছে রেখে দিন:
// --- ডেটাবেস (ধাপ ১১ থেকে) ---
define('DB_HOST', 'localhost'); // রেখে দিন
define('DB_NAME', 'db_name'); // ধাপ ১১-এ যা তৈরি করেছেন
define('DB_USER', 'user'); // ধাপ ১১-এ যা তৈরি করেছেন
define('DB_PASS', 'db_password'); // ধাপ ১১-এ যা সেট করেছেন
define('DB_CHARSET', 'utf8mb4'); // রেখে দিন
// --- অ্যাপ্লিকেশন ---
define('APP_URL', 'https://monitor.example.com'); // প্যানেলের ঠিকানা, শেষে স্ল্যাশ ছাড়া
define('TIMEZONE', 'Asia/Dhaka'); // আপনার টাইম জোন
// --- সেশনের সময় ---
define('SESSION_LIFETIME', 28800); // নিষ্ক্রিয়তার পর পুনরায় লগইন, সেকেন্ড (28800 = 8 ঘণ্টা)
যা পরিবর্তন করবেন:
DB_NAME, DB_USER, DB_PASS — ধাপ ১১-এ ডেটাবেস তৈরির সময় আপনি যে ডেটাবেসের নাম, ব্যবহারকারী ও পাসওয়ার্ড দিয়েছিলেন ঠিক সেগুলোই (উদাহরণ রেখে দিলে — monitor_db / monitor_user)। DB_HOST ও DB_CHARSET ছোঁবেন না।
APP_URL — https:// সহ প্যানেলের পূর্ণ ঠিকানা, শেষে স্ল্যাশ ছাড়া এবং www ছাড়া। যে ডোমেইনে লাইসেন্স অ্যাক্টিভেট করবেন (ধাপ ১৬) তার সাথে মিলতে হবে, নয়তো কী প্রত্যাখ্যাত হবে।
TIMEZONE — আপনার টাইম জোন (তালিকা — timedatectl list-timezones)। এটি শুধু প্যানেল কীভাবে তারিখ দেখায় তা প্রভাবিত করে; cron-কাজ চালুর সময়ে প্রভাব ফেলে না (সেখানে সিস্টেমের জোন কার্যকর)।
SESSION_LIFETIME — কত সেকেন্ড নিষ্ক্রিয় থাকার পর প্যানেল পুনরায় লগইন চাইবে (ডিফল্ট ৮ ঘণ্টা)। যেমন 3600 = ১ ঘণ্টা, 86400 = এক দিন।
ত্রুটি লগিং ব্লক (display_errors, log_errors, error_log) — ডিফল্ট রেখে দিন।
ফাইলটি সংরক্ষণ করুন (Ctrl+O, Enter, তারপর Ctrl+X) এবং PHP-FPM পুনরায় চালু করুন — নয়তো OPcache-এর কারণে পরিবর্তন কার্যকর হবে না:
sudo systemctl restart php*-fpm
config.php — গোপন ফাইল (এতে ডেটাবেসের পাসওয়ার্ড আছে)। এটি প্যানেলের রুটে থাকে, যা-ই ওয়েব-রুট, তবে সুরক্ষিত: 640 অনুমতি (ধাপ ১০-এ সেট করা) এবং রুট .htaccess-এ স্পষ্ট নিষেধ। এটি পাবলিক রিপোজিটরিতে দেবেন না এবং আসল পাসওয়ার্ড সহ সাপোর্টে পাঠাবেন না।
PHP চলে ওয়েব সার্ভারের ব্যবহারকারী হিসেবে, যার সিস্টেম কমান্ড চালানোর অধিকার নেই। অ্যাক্সেস সীমিতভাবে দেওয়া হয়: নির্দিষ্ট ইউটিলিটির জন্য টার্গেটেড sudo এবং গ্রুপের মাধ্যমে লগ পড়া (sudo ছাড়া)। ওয়েব লেয়ার হ্যাক হলেও root পাওয়া যাবে না।
উদাহরণে www-data — Apache-এর স্ট্যান্ডার্ড ব্যবহারকারী। যদি আপনার অন্য হয় (কিছু প্যানেলে PHP আলাদা ব্যবহারকারীর অধীনে চলে) — সব জায়গায় বদলে নিন। জানতে: ps -o user= -C php-fpm | sort -u।
1.sudo visudo -f /etc/sudoers.d/monitor দিয়ে /etc/sudoers.d/monitor তৈরি করুন এবং নিচেরটি বসান (অব্যবহৃত মডিউলের লাইনগুলো মুছে দিন):
# UFW — স্ট্যাটাস ও নিয়ম (“ফায়ারওয়াল” পেজ)
www-data ALL=(ALL) NOPASSWD: /usr/sbin/ufw status, /usr/sbin/ufw status verbose, /usr/sbin/ufw status numbered
www-data ALL=(ALL) NOPASSWD: /usr/sbin/ufw allow [0-9]*, /usr/sbin/ufw deny [0-9]*, /usr/sbin/ufw --force delete [0-9]*
# Fail2ban — স্ট্যাটাস, ban ও unban (banned এক কমান্ডে সব jail-এর ban ফেরত দেয়;
# ban/unban প্যানেলের বোতামগুলোর জন্য দরকার)
www-data ALL=(ALL) NOPASSWD: /usr/bin/fail2ban-client status, /usr/bin/fail2ban-client status *, /usr/bin/fail2ban-client banned, /usr/bin/fail2ban-client set * banip *, /usr/bin/fail2ban-client set * unbanip *
# সিকিউরিটি আপডেট (“আপডেট” কার্ড)। শুধু পড়া, তবে root থেকেই দরকার:
# apt ক্যাশ (~৭০ MB) কেবল root-এর কাছে অ্যাক্সেসযোগ্য, non-root প্রতিবার তা পুনর্নির্মাণ করে
# (৪.২ সে CPU বনাম ০.০১ সে)। wildcard ছাড়া — ঠিক এই একটিই কমান্ড, কিছুই ইনস্টল করে না।
www-data ALL=(ALL) NOPASSWD: /usr/bin/apt list --upgradable
# IPset (আক্রমণের মানচিত্র, ড্যাশবোর্ড)
www-data ALL=(ALL) NOPASSWD: /usr/sbin/ipset list -t ipsum
# CrowdSec
www-data ALL=(ALL) NOPASSWD: /usr/bin/cscli decisions list *, /usr/bin/cscli alerts list *, /usr/bin/cscli bouncers list *, /usr/bin/cscli scenarios list *
# Auditd — ইভেন্ট অনুসন্ধান + জার্নালের শেষ কয়েক লাইন পড়া (নির্দিষ্ট পাথ)
www-data ALL=(ALL) NOPASSWD: /usr/sbin/ausearch -m *
www-data ALL=(ALL) NOPASSWD: /usr/bin/tail -n 300 /var/log/audit/audit.log
# Monit / ModSecurity / AppArmor / PSAD
www-data ALL=(ALL) NOPASSWD: /usr/bin/monit status
www-data ALL=(ALL) NOPASSWD: /usr/sbin/apache2ctl -M
www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-modsec
www-data ALL=(ALL) NOPASSWD: /usr/sbin/aa-status
www-data ALL=(ALL) NOPASSWD: /usr/sbin/psad --Status
# খোলা পোর্ট (কার্নেল/SSH/Falco লগ sudo ছাড়া পড়া হয় — systemd-journal
# গ্রুপের মাধ্যমে, দেখুন ২ নং; journalctl-এর জন্য sudo দেওয়া দরকার নেই এবং অনিরাপদ)
www-data ALL=(ALL) NOPASSWD: /usr/bin/ss -tuln, /usr/sbin/ss -tuln, /bin/ss -tuln
# PostgreSQL (শুধু ব্যবহার করলে) — ফিক্সড read-only স্ক্রিপ্ট,
# “PostgreSQL দেখা যাচ্ছে না” FAQ অনুযায়ী তৈরি করুন; না হলে লাইনটি মুছে দিন
www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-pgstat
2. লগ ও systemd জার্নালে অ্যাক্সেস। মডিউলগুলো /var/log/fail2ban.log, auth.log, ufw.log, apache2/*, aide সরাসরি পড়ে (Debian/Ubuntu-তে এই লগগুলো adm গ্রুপে থাকে)। কার্নেল, SSH ও Falco-এর ইভেন্ট journald থেকে journalctl কমান্ডে sudo ছাড়াই, systemd-journal গ্রুপের মাধ্যমে নেওয়া হয়। ওয়েব ব্যবহারকারীকে দুটি গ্রুপেই যোগ করুন এবং PHP-FPM পুনরায় চালু করুন:
sudo usermod -aG adm,systemd-journal www-data
sudo systemctl restart php*-fpm # আবশ্যক, না হলে গ্রুপগুলো প্রয়োগ হবে না
3. যদি ClamAV বা Suricata লগ adm গ্রুপে না লেখে (কখনও root:root হয়) — ACL দিয়ে অ্যাক্সেস দিন:
4. ModSecurity র্যাপার। WAF-এর অডিট লগ (/var/log/apache2/modsec_audit.log) 640 অধিকার নিয়ে root-এর মালিকানায় থাকে, ওয়েব ব্যবহারকারী তা সরাসরি পড়তে পারে না। ModSecurity পেজ ইঞ্জিনের মোড, ইভেন্ট ও সক্রিয় নিয়মের তালিকা একটি ফিক্সড read-only স্ক্রিপ্টের মাধ্যমে নেয় — উপরের লাইনে sudoers-এ সেটিই অনুমোদিত:
/etc/modsecurity/modsecurity.conf ফাইল ছাড়া WAF নিজেই চলে না: প্যাকেজ কেবল modsecurity.conf-recommended রাখে, আর নিয়ম ইঞ্জিন বন্ধ থেকে যায় — কীভাবে চালু করবেন, দেখুন FAQ → “ModSecurity ইনস্টলেশন”।
sudoers-এর সব লাইনের ব্যবহারকারী FPM-পুলের ব্যবহারকারীর সঙ্গে মিলতে হবে: সাধারণ Apache/Debian-এ এটি www-data, HestiaCP-তে সাইটের পুল সাইটের মালিকের অধীনে চলে (যেমন admin) — যাচাই করুন grep -E '^user' /etc/php/*/fpm/pool.d/monitor.example.com.conf।
5. যদি Apache-এর সামনে Nginx থাকে (HestiaCP, ISPmanager ও অন্যান্য প্যানেল — সেখানে Nginx PHP-কে Apache-এ প্রক্সি করে, আর স্ট্যাটিক নিজেই সরবরাহ করে)। সার্ভিস ডিরেক্টরিগুলো .htaccess ফাইল দিয়ে বন্ধ থাকে, কিন্তু Nginx সেগুলো পড়ে না: যেকোনো স্ট্যাটিক ফাইল (.json, .txt, .log, .dat) সে Apache বাদ দিয়ে সরাসরি সরবরাহ করবে। বাইরে ফাঁস হবে প্যানেলের ক্যাশ ও ডেটা — যেমন WAF ইভেন্ট ও আক্রমণকারীর IP সহ tmp/modsec_cache.json। Nginx সাইট কনফিগে নিষেধাজ্ঞা যোগ করুন:
^~ প্রিফিক্স আবশ্যক: location /-এর ভেতর স্ট্যাটিকের রেগুলার নিয়মের আগেই এটি নির্বাচিত হয়, না হলে নিষেধাজ্ঞা কাজ করবে না।
HestiaCP-তে এটি আলাদা ফাইল /home/<user>/conf/web/<domain>/nginx.ssl.conf_deny হিসেবে রাখুন (এবং HTTP-এর জন্য nginx.conf_deny) — সাইট কনফিগ nginx.ssl.conf_* যুক্ত করে এবং পুনর্নির্মাণের সময় এমন ফাইল মুছে না। প্রয়োগ করতে: sudo nginx -t && sudo systemctl reload nginx।
যাচাই: curl -s -o /dev/null -w '%{http_code}\n' https://monitor.example.com/tmp/modsec_cache.json — 403 হওয়া উচিত। যদি Apache Nginx ছাড়া চলে (নিজেই 80/443 শোনে), কিছু যোগ করার দরকার নেই — .htaccess-ই যথেষ্ট।
বাইনারির পাথ which দিয়ে যাচাই করুন (যেমন which ufw cscli ausearch ss)। sudoers কেবল visudo দিয়ে সম্পাদনা করুন। MySQL-এর সব ডেটাবেসের তালিকা আলাদা GRANT দিয়ে চালু হয় (FAQ → “শুধু একটি ডেটাবেস দেখা যাচ্ছে”)।
14. IP অনুযায়ী অ্যাক্সেস সীমিত করা
IP অ্যাড্রেস অনুযায়ী মনিটরে অ্যাক্সেস সীমিত করুন — URL জানা গেলেও লগইন পৃষ্ঠা খুলবে না। এটি ওয়েব সার্ভারের স্তরে (নিচে nginx-এর উদাহরণ) বা প্যানেলেই করা যায় (“সেটিংস” → “IP অনুযায়ী অ্যাক্সেস সীমিত করা”)। যদি আপনার Apache থাকে, প্যানেলের সীমাবদ্ধতা ব্যবহার করুন।
যদি nginx সাইট ধাপ ১০ অনুযায়ী ইতিমধ্যে কনফিগার করা থাকে, দ্বিতীয় একটি যোগ করবেন নাlocation / — বিদ্যমান ব্লকেই allow/deny লাইনগুলো লিখুন। একই server { }-এ দুটি একই রকম location / — কনফিগারেশন ভুল, nginx রিস্টার্ট হবে না।
# nginx কনফিগে (server { } এর ভিতরে):
# Let's Encrypt-এর ACME পাথ IP সীমাবদ্ধতা এড়িয়ে খোলা রাখুন —
# যাতে SSL ইস্যু ও অটো-রিনিউ (ধাপ ১৫) IP ফিল্টারের উপর নির্ভর না করে।
location ^~ /.well-known/acme-challenge/ { allow all; }
location / {
allow 203.0.113.10; # ← আপনার IP লিখুন
allow 10.0.0.0/8; # লোকাল নেটওয়ার্ক (প্রয়োজন হলে)
deny all;
try_files $uri $uri/ /index.php?$query_string;
}
# nginx রিলোড করুন:
sudo nginx -t && sudo systemctl reload nginx
15. SSL (HTTPS) ইস্যু করুন
ড্যাশবোর্ড শুধুমাত্র HTTPS-এ কাজ করে। লগইন সেশন একটি সুরক্ষিত কুকি ব্যবহার করে, এবং WebAuthn (2FA) কেবল HTTPS-এ কাজ করে। http:// দিয়ে লগইন করা যায় না।
সার্টিফিকেট বিনামূল্যে (Let's Encrypt)। ডোমেইনের DNS ইতিমধ্যে সার্ভারের দিকে নির্দেশ করতে হবে। কমান্ডটি ওয়েব সার্ভারের উপর নির্ভর করে:
# Apache:
sudo certbot --apache -d monitor.example.com
# nginx — শুধুমাত্র যদি আপনার ঠিক nginx থাকে। Apache-তে চালাবেন না:
# apt nginx টেনে আনবে এবং পোর্ট 80 দখল করবে, Apache-র সাথে দ্বন্দ্ব।
# sudo apt install python3-certbot-nginx
# sudo certbot --nginx -d monitor.example.com
# certbot নিজেই কনফিগে HTTPS লিখবে এবং স্বয়ংক্রিয় নবায়ন সেট করবে
certbot যা জিজ্ঞেস করবে: e-mail → Terms-এ সম্মতি (Y) → EFF-এ e-mail পাঠানো (আপনার ইচ্ছা)। এরপর নিজেই সার্টিফিকেট ইস্যু করবে, <VirtualHost *:443> লিখবে, http→https রিডাইরেক্ট ও স্বয়ংক্রিয় নবায়ন সেট করবে।
certbot চালানোর আগে DNS অবশ্যই সার্ভারের দিকে নির্দেশ করতে হবে (৮০ পোর্ট দিয়ে মালিকানা যাচাই)। যাচাই: dig +short monitor.example.com → সার্ভারের IP। পোর্ট 80/443 খোলা: sudo ufw allow 80,443/tcp।
ইস্যু করার পর: https://monitor.example.com তালা চিহ্ন সহ খোলে, http://https://-এ রিডাইরেক্ট করে (config.php-এ APP_URL ইতিমধ্যে ধাপ ১২-এ সেট করা আছে)।
16. লগইন এবং প্রাথমিক সেটআপ
https://monitor.example.com খুলুন, admin / useradmin দিয়ে লগইন করুন এবং চেকলিস্টটি সম্পন্ন করুন:
admin পাসওয়ার্ড পরিবর্তন করুন — মেনুতে “ব্যবহারকারী” বিভাগ।
WebAuthn (2FA) চালু করুন — “WebAuthn কী” → কী/passkey নিবন্ধন করুন (HTTPS প্রয়োজন)। একসঙ্গে দুটি নিবন্ধন করুন: একমাত্র কী হারালে সেটি দিয়ে লগইন করা সম্ভব হবে না। বিস্তারিত।
IP অনুযায়ী অ্যাক্সেস সীমিত করুন — “সেটিংস” → “IP অনুযায়ী অ্যাক্সেস সীমাবদ্ধকরণ” (চালু করার আগে নিজের IP লিখুন, নইলে নিজের অ্যাক্সেস বন্ধ হয়ে যাবে)।
লাইসেন্স প্রবেশ করান — অ্যাকাউন্ট থেকে ARCIVEO-… কোডটি আপনার ডোমেনে অ্যাক্টিভেট করুন এবং কী “সেটিংস” → “লাইসেন্স”-এ বসান। বিস্তারিত।
ইনস্টলার মুছে ফেলুনpublic/start_db.php, যদি এটি থেকে যায় (ধাপ ১১)।
17. নিরাপত্তা টুল (ঐচ্ছিক)
প্যানেল ইতিমধ্যেই চালু। টুলগুলো ইচ্ছেমতো বসানো যায় — যেটা দরকার সেটাই বসান, প্যানেল সঙ্গে সঙ্গে স্ট্যাটাস দেখাবে। প্রতিটির ইনস্টল কমান্ড রেফারেন্সে আছে (টুল অনুযায়ী আলাদা বিভাগে):