تثبيت يدوي بالكامل: من VPS تم شراؤه للتو إلى لوحة تحكم عاملة، خطوة بخطوة.
تهيئة السيرفر وإنشاء الموقع وقاعدة البيانات وconfig.php وSSL مشروحة هنا.
أوامر كل أداة أمان وأوامر cron موجودة في
مرجع FAQ، والروابط مبثوثة أثناء الشرح.
القاعدة الأهم: عند تغيير SSH أو الجدار الناري، لا تُغلق الاتصال الحالي قبل التحقق من الاتصال الجديد في نافذة منفصلة. وإن فُقد الوصول رغم ذلك — يوفّر أغلب مزوّدي الاستضافة وحدة تحكم طوارئ (VNC/Recovery) في لوحة التحكم.
01. اشتريت VPS بنظام Ubuntu/Debian — من أين تبدأ
بعد الشراء يرسل لك مزوّد الاستضافة: عنوان IP واسم المستخدم (عادةً root) وكلمة المرور (أو مفتاح SSH). هذا يكفي لتسجيل الدخول. تسلسل الخطوات (كل خطوة قسم أدناه):
الاتصال بالسيرفر عبر SSH؛
تحديث النظام وضبط اسم المضيف والمنطقة الزمنية؛
إنشاء مستخدم عادي بصلاحيات sudo (لا تعمل بحساب root)؛
إعداد الدخول بمفتاح SSH وتعطيل الدخول بكلمة المرور؛
تفعيل الجدار الناري والحماية التلقائية؛
(اختياري) تثبيت لوحة التحكم HestiaCP — سيرفر الويب وقاعدة البيانات والبريد جاهزة مباشرةً.
02. الاتصال الأول عبر SSH
SSH هو طرفية آمنة للاتصال بالسيرفر. ضع عنوان IP الخاص بك بدلاً من 203.0.113.10.
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 وتعطيل الدخول بكلمة المرور
الدخول بالمفتاح أكثر أماناً من كلمة المرور: كلمة المرور يمكن تخمينها، أما المفتاح فلا عملياً. أولاً ننشئ المفتاح على جهازك، ننسخه إلى السيرفر، نتحقق من الدخول — وبعد ذلك فقط نعطّل كلمة المرور.
الخطوة 1. إنشاء مفتاح على جهازك (Windows PowerShell / macOS / Linux):
ssh-keygen -t ed25519 -C "my-laptop"
# اضغط Enter على كل الأسئلة (سيُحفظ المفتاح في ~/.ssh/id_ed25519)
الخطوة 3. التحقق من الدخول بالمفتاح في نافذة جديدة — يجب أن يسمح بالدخول دون كلمة مرور:
ssh deploy@203.0.113.10
لا تُنفّذ الخيار B قبل التأكد من أن الدخول بالمفتاح تم اختباره ويعمل (الخطوات 1–3)، ولا تُغلق الجلسة الحالية. فهو يعطّل الدخول بكلمة المرور لـجميع المستخدمين، بمن فيهم root. بدون مفتاح يعمل ستفقد الوصول إلى السيرفر بالكامل — ولن تستعيده إلا عبر كونسول الاستضافة. لا تملك مفتاحاً — اختر الخيار A.
الخطوة 4. تشديد الوصول عبر 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 حديثة مدعومة، بحد أدنى ~1–2 غيغابايت RAM)، قبل تثبيت سيرفرات ويب وقواعد بيانات أخرى — وإلا ستحدث تعارضات. يستغرق التثبيت 10–20 دقيقة ويعيد تشغيل السيرفر.
سيطلب المثبّت البريد الإلكتروني واسم المضيف، ثم يثبّت الحزمة كاملة. بعد إعادة التشغيل تكون اللوحة متاحة على العنوان https://YOUR_IP:8083 (يعرض المثبّت اسم المستخدم وكلمة المرور في النهاية).
يدير HestiaCP بنفسه UFW وfail2ban — لا حاجة لإعدادهما بشكل منفصل، فسيتولى ذلك. أما مفاتيح SSH وتعطيل كلمة المرور (القسم السابق) فأنجزها على أي حال.
08. متطلبات النظام وionCube
لوحة التحكم تطبيق PHP يعمل على حزمة LAMP/LEMP نموذجية:
نظام التشغيل: Linux (يُنصح بـ Ubuntu/Debian)؛
سيرفر الويب: nginx أو Apache مع PHP-FPM؛
PHP 8.0+ مع الإضافات: pdo_mysql، openssl، curl، json، mbstring؛
ionCube Loader — إضافة PHP لازمة لتشغيل لوحة التحكم؛
قاعدة البيانات: MySQL 5.7+ أو MariaDB 10.3+؛
HTTPS — إلزامي (تسجيل الدخول وWebAuthn يعملان عبر https فقط)؛
# التحقق من إصدار PHP والإضافات:
php -v
php -m | grep -iE 'pdo_mysql|openssl|curl|mbstring|ioncube'
تثبيت ionCube Loader (إذا لم يكن مثبتًا بعد). على الاستضافة المزوّدة بلوحة تحكم (HestiaCP، cPanel) يُفعَّل ionCube بخيار في إعدادات PHP. يدويًا على 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 (مثلًا ioncube_loader_lin_8.1.so لـ PHP 8.1). إذا كنت تستخدم عدة إصدارات من 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
يُصدَر شهادة SSL من Let's Encrypt للنطاق فقط — يجب أن يشير DNS إلى السيرفر قبل إصدار الشهادة.
10. إنشاء موقع ورفع ملفات اللوحة
Apache: اجعل DocumentRoot على جذر اللوحة، وليس على public/. ملفات التنسيق (CSS/JS) وsw.js وmanifest.json موجودة في assets/ بجوار public/ ويُطلَب الوصول إليها من جذر الموقع. ملف .htaccess الجذري هو المتحكم الأمامي. إذا وضعت DocumentRoot على public/ ضمن Apache، فستُفتح اللوحة بدون تنسيقات. أما مع nginx الصِرف فالعكس: يُؤخذ public/ جذرًا، ويُقدَّم assets/ بقاعدة منفصلة (انظر مقطع nginx أدناه).
تُنزَّل ملفات اللوحة (أرشيف التوزيعة) بعد الشراء من الحساب الشخصي my.arciveo.com ← «التنزيلات». فُكّ ضغط الأرشيف قبل الرفع.
1) أنشئ مجلد اللوحة وارفع إليه محتوى التوزيعة (بحيث يكون بداخله public/ وassets/ وconfig.php وغيرها):
sudo mkdir -p /var/www/monitor
# ثم ارفع ملفات التوزيعة إلى /var/www/monitor (FileZilla / WinSCP / scp)
2) اضبط سيرفر الويب.Apache: اجعل DocumentRoot على جذر اللوحة (وليس على /public)؛ AllowOverride All إلزامي. يُحدَّد مسار مقبس PHP-FPM تلقائيًا. يُلصَق المقطع في الطرفية كاملًا:
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، وحرف s بدل x يعني أن setgid مفعَّل.
11. قاعدة البيانات
أنشئ قاعدة بيانات ومستخدمًا، ثم استورد المخطط. تُلصق الكتلة في الطرفية بالكامل. monitor_db وmonitor_user اسمان للمثال، ويمكنك اختيار أي اسمين؛ احفظ اسم قاعدة البيانات والمستخدم وكلمة المرور — ستُدخلها في config.php في الخطوة التالية:
# 1. قاعدة البيانات. تُحدَّد كلمة المرور مرة واحدة في DBPASS وتُدرَج في كل الأسطر.
# تُلصق الكتلة في الطرفية بالكامل؛ sudo mysql يدخل بحساب root عبر مقبس unix
# (لا حاجة لكلمة مرور 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
ضع قيمك مكان المواضع المميّزة؛ واترك الباقي كما هو:
// --- قاعدة البيانات (من الخطوة 11) ---
define('DB_HOST', 'localhost'); // اتركه
define('DB_NAME', 'db_name'); // ما أنشأته في الخطوة 11
define('DB_USER', 'user'); // ما أنشأته في الخطوة 11
define('DB_PASS', 'db_password'); // ما حددته في الخطوة 11
define('DB_CHARSET', 'utf8mb4'); // اتركه
// --- التطبيق ---
define('APP_URL', 'https://monitor.example.com'); // عنوان اللوحة، دون شرطة مائلة في النهاية
define('TIMEZONE', 'Asia/Riyadh'); // منطقتك الزمنية
// --- مدة الجلسة ---
define('SESSION_LIFETIME', 28800); // مدة الخمول قبل إعادة الدخول، بالثواني (28800 = 8 س)
ما الذي يجب تغييره:
DB_NAME، DB_USER، DB_PASS — بالضبط نفس اسم القاعدة والمستخدم وكلمة المرور التي حددتها عند إنشاء قاعدة البيانات في الخطوة 11 (إذا تركت الأمثلة — monitor_db / monitor_user). لا تلمس DB_HOST وDB_CHARSET.
APP_URL — العنوان الكامل للوحة مع https://، دون شرطة مائلة في النهاية ودون www. يجب أن يطابق النطاق الذي تفعّل عليه الترخيص (الخطوة 16)، وإلا سيُرفض المفتاح.
TIMEZONE — منطقتك الزمنية (القائمة — timedatectl list-timezones). تؤثر فقط على طريقة عرض اللوحة للتواريخ؛ ولا تؤثر على وقت تشغيل مهام cron إطلاقًا (هناك تُعتمد منطقة النظام).
SESSION_LIFETIME — بعد كم ثانية من الخمول تطلب اللوحة تسجيل الدخول من جديد (افتراضيًا 8 ساعات). مثلاً 3600 = ساعة واحدة، 86400 = يوم كامل.
كتلة تسجيل الأخطاء (display_errors، log_errors، error_log) — اتركها كما هي افتراضيًا.
احفظ الملف (Ctrl+O، Enter، ثم Ctrl+X) وأعد تشغيل PHP-FPM — وإلا فلن تُطبّق التغييرات بسبب OPcache:
sudo systemctl restart php*-fpm
config.php ملف سرّي (يحتوي على كلمة مرور قاعدة البيانات). يقع في جذر اللوحة، وهو نفسه جذر الويب، لكنه محمي: بصلاحيات 640 (المضبوطة في الخطوة 10) ومنع صريح في .htaccess الجذري. لا تنشره في مستودعات عامة ولا ترسله للدعم بكلمة مرور حقيقية.
يعمل PHP بصلاحيات مستخدم سيرفر الويب الذي لا يملك صلاحيات تنفيذ أوامر النظام. تُمنح الصلاحيات بشكل ضيّق: sudo محدّد النطاق لأدوات معيّنة وقراءة السجلّات عبر المجموعات (دون sudo). اختراق طبقة الويب لا يمنح صلاحيات root.
في الأمثلة www-data هو المستخدم القياسي لـ Apache. إذا كان لديك مستخدم آخر (في بعض اللوحات يعمل PHP بمستخدم منفصل) فاستبدله في كل موضع. لمعرفته: ps -o user= -C php-fpm | sort -u.
1. أنشئ /etc/sudoers.d/monitor عبر sudo visudo -f /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 — الحالة والحظر ورفع الحظر (banned يعرض حظر كل الـ jail بأمر واحد؛
# 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 المؤقتة (~70 ميغابايت) متاحة لـ root فقط، وغير root يعيد بناءها في كل استدعاء
# (4.2 ثانية CPU مقابل 0.01 ثانية). دون 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، انظر البند 2؛ منح sudo لـ journalctl غير ضروري وغير آمن)
www-data ALL=(ALL) NOPASSWD: /usr/bin/ss -tuln, /usr/sbin/ss -tuln, /bin/ss -tuln
# PostgreSQL (فقط إذا كنت تستخدمه) — سكربت ثابت للقراءة فقط،
# يُنشأ حسب FAQ «PostgreSQL لا يظهر»؛ دونه احذف السطر
www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-pgstat
sudo chmod 440 /etc/sudoers.d/monitor
sudo visudo -c # يجب أن يظهر "parsed OK"
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) مملوك لـ root بصلاحيات 640، ولا يستطيع مستخدم الويب قراءته مباشرةً. تأخذ صفحة ModSecurity وضع المحرّك والأحداث وقائمة القواعد النشطة عبر سكربت ثابت للقراءة فقط — وهو المسموح في 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. إذا كان Nginx أمام Apache (HestiaCP وISPmanager ولوحات أخرى — يوكّل Nginx فيها PHP إلى Apache ويقدّم الملفات الثابتة بنفسه). المجلّدات الخدمية مغلقة بملفات .htaccess، لكن Nginx لا يقرأها: أي ملف ثابت (.json، .txt، .log، .dat) سيقدّمه مباشرةً متجاوزاً Apache. سيتسرّب إلى الخارج كاش اللوحة وبياناتها — مثلاً tmp/modsec_cache.json الذي يحوي أحداث WAF وعناوين IP المهاجمين. أضف المنع إلى إعداد موقع Nginx:
البادئة ^~ إلزامية: تُختار قبل القاعدة النظامية للملفات الثابتة داخل location /، وإلا فلن يعمل المنع.
في HestiaCP ضع هذا في ملف منفصل /home/<user>/conf/web/<domain>/nginx.ssl.conf_deny (وnginx.conf_deny لـ HTTP) — يستدعي إعداد الموقع 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 مُعدًّا بالفعل حسب الخطوة 10، فلا تُضِفlocation / ثانيًا — بل أدرِج سطري allow/deny في الكتلة الموجودة أصلًا. وجود كتلتي location / متطابقتين داخل نفس server { } خطأ في الإعداد، ولن يُعيد nginx التشغيل.
# في إعداد nginx (داخل server { }):
# نُبقي مسار ACME الخاص بـ Let's Encrypt مفتوحًا متجاوزًا تقييد IP —
# حتى لا يعتمد إصدار SSL وتجديده التلقائي (الخطوة 15) على فلتر 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: البريد الإلكتروني ← الموافقة على Terms (Y) ← إرسال البريد إلى EFF (حسب رغبتك). بعدها يصدر الشهادة تلقائيًا، ويضيف <VirtualHost *:443>، ويضبط إعادة التوجيه http→https والتجديد التلقائي.
يجب أن يشير DNS إلى السيرفر قبل تشغيل certbot (التحقق من الملكية عبر المنفذ 80). التحقق: dig +short monitor.example.com ← IP السيرفر. المنفذان 80/443 مفتوحان: sudo ufw allow 80,443/tcp.
بعد الإصدار: https://monitor.example.com يفتح مع رمز القفل، وhttp:// يعيد التوجيه إلى https:// (APP_URL في config.php مضبوط مسبقًا في الخطوة 12).
16. تسجيل الدخول والإعداد الأولي
افتح https://monitor.example.com، وسجّل الدخول admin / useradmin واتبع قائمة التحقق:
غيّر كلمة مرور admin — قسم «المستخدمون» في القائمة.
فعّل WebAuthn (2FA) — «مفاتيح WebAuthn» ← سجّل مفتاحًا/passkey (يتطلب HTTPS). سجّل مفتاحين دفعةً واحدة: عند فقدان المفتاح الوحيد يتعذّر الدخول به. التفاصيل.
قيّد الوصول حسب IP — «الإعدادات» ← «تقييد الوصول حسب IP» (أدخل عنوان IP الخاص بك قبل التفعيل، وإلا ستحجب وصولك).
أدخل الترخيص — فعّل الرمز ARCIVEO-… من الحساب على نطاقك وألصق المفتاح في «الإعدادات» ← «الترخيص». التفاصيل.
اضبط الإشعارات — Telegram و/أو البريد الإلكتروني في «الإعدادات». التفاصيل.
احذف أداة التثبيتpublic/start_db.php إن بقيت (الخطوة 11).
17. أدوات الأمان (اختياري)
لوحة التحكم تعمل بالفعل. تُثبَّت الأدوات حسب الرغبة — تُثبِّت ما تحتاجه فقط، وستعرض اللوحة الحالة فورًا. أوامر تثبيت كل أداة موجودة في الدليل (أقسام منفصلة لكل أداة):