手动安装

完全手动安装:从刚购买的 VPS 到可用的面板,逐步完成。 服务器准备、创建站点、数据库、config.php 与 SSL 均在此说明。 各安全工具及 cron 的相关命令,请见 FAQ 参考手册,文中随处附有链接。

首要原则:更改 SSH 或防火墙时,在另一个窗口验证新连接可用之前,请勿关闭当前连接。若仍不慎失去访问权限——几乎所有主机商都会在控制面板中提供应急控制台(VNC/Recovery)。

01. 购买了装有 Ubuntu/Debian 的 VPS——从何入手

购买后,主机商会发送:IP 地址、用户名(通常为 root)和密码(或 SSH 密钥)。凭这些即可登录。操作步骤(每一步对应下方一节):

  1. 通过 SSH 连接到服务器;
  2. 更新系统,设置主机名和时区;
  3. 创建具有 sudo 权限的普通用户(不要以 root 身份操作);
  4. 配置 SSH 密钥登录并禁用密码登录
  5. 启用防火墙和自动防护;
  6. (可选)安装 HestiaCP 控制面板——开箱即用的 Web 服务器、数据库和邮件服务。

02. 首次通过 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. 系统更新与基础配置

首要任务:更新所有软件包,并设置主机名和时区。

# 更新系统: apt update && apt upgrade -y # 基础工具: apt install -y curl wget ufw fail2ban unattended-upgrades # 时区(示例)和主机名: timedatectl set-timezone Asia/Shanghai hostnamectl set-hostname myserver # 自动安全更新: dpkg-reconfigure -plow unattended-upgrades
时区列表见 timedatectl list-timezones。如果更新结束时出现蓝色的“Daemons using outdated libraries”窗口,请选中所有服务(空格键)并按 OK,此操作是安全的。

04. 创建具有 sudo 权限的用户

长期使用 root 运行并不安全。请创建一个普通用户并授予其 sudo 权限(需要时以管理员身份运行命令)。请将 deploy 替换为任意名称。

# 创建用户(会设置密码并询问相关信息——可直接回车跳过): 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)

第 2 步。公钥复制到服务器:

# macOS / Linux: ssh-copy-id deploy@203.0.113.10 # Windows (PowerShell): type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh deploy@203.0.113.10 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

第 3 步。窗口中测试密钥登录——应当无需密码即可登入:

ssh deploy@203.0.113.10
在密钥登录未经验证并确实可用之前(第 1–3 步),请勿执行方案 B,也不要关闭当前工作会话。它会为所有用户(包括 root)关闭密码登录。没有可用的密钥,您将彻底失去对服务器的访问权限——届时只能通过主机商的控制台恢复。没有密钥就选方案 A。

第 4 步。加固 SSH 访问。设置放入单独的配置文件,不改动主配置。请按情况选择方案:

方案 A — 仅关闭 root,保留密码。无需密钥,也不会失去访问权限:

echo 'PermitRootLogin no' | sudo tee /etc/ssh/sshd_config.d/00-hardening.conf >/dev/null sudo systemctl restart ssh

方案 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 是一款免费的主机管理面板:负责安装并配置 Web 服务器(nginx + apache)、PHP、数据库(MariaDB)、邮件、DNS 和 SSL 证书,并为网站提供 Web 界面。如果您不想手动配置一切,且计划托管网站(包括 Arcivéo Monitor 面板本身),它会非常方便。

请将 HestiaCP 安装在全新的服务器上(受支持的全新 Ubuntu/Debian,至少约 1–2 GB RAM),并在安装其他 Web 服务器和数据库之前进行——否则会产生冲突。安装耗时 10–20 分钟,且会重启服务器。
# 下载安装脚本并运行: wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh sudo bash hst-install.sh

安装脚本会询问邮箱和主机名,然后安装整套环境。重启后,可通过 https://YOUR_IP:8083 访问面板(安装脚本会在最后显示用户名和密码)。

HestiaCP 会自行管理 UFW 和 fail2ban——无需单独配置,它会自动接管。但 SSH 密钥和禁用密码登录(见上一节)仍需您自行完成。

08. 系统要求与 ionCube

该面板是运行在典型 LAMP/LEMP 环境上的 PHP 应用:

  • 操作系统:Linux(推荐 Ubuntu/Debian);
  • Web 服务器:Nginx 或搭配 PHP-FPM 的 Apache;
  • PHP 8.0+,并启用扩展:pdo_mysqlopensslcurljsonmbstring
  • ionCube Loader —— 面板运行所需的 PHP 扩展;
  • 数据库:MySQL 5.7+ 或 MariaDB 10.3+;
  • HTTPS —— 必须(登录和 WebAuthn 仅在 https 下可用);
  • 为 Web 服务器用户配置 sudo(仅限少量命令 —— 见步骤 13)。
# 检查 PHP 版本与扩展: php -v php -m | grep -iE 'pdo_mysql|openssl|curl|mbstring|ioncube'

安装 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 位): 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.jsmanifest.jsonpublic/ 同级,位于 assets/ 中,从站点根目录请求。根目录下的 .htaccess 是前端控制器。如果在 Apache 下把 DocumentRoot 指向 public/,面板打开后将没有样式纯 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) 配置 Web 服务器。 Apache:DocumentRoot 指向面板根目录(不是 /public);必须启用 AllowOverride All。PHP-FPM 套接字路径会自动检测。请将整个代码块完整粘贴到终端中:

PHPSOCK=$(ls -1 /run/php/php*-fpm.sock 2>/dev/null | head -1) # 自动检测 PHP-FPM 套接字 sudo tee /etc/apache2/sites-available/monitor.conf > /dev/null <<'EOF' <VirtualHost *:80> ServerName monitor.example.com DocumentRoot /var/www/monitor <Directory /var/www/monitor> AllowOverride All Require all granted </Directory> <FilesMatch \.php$> SetHandler "proxy:unix:__PHPSOCK__|fcgi://localhost" </FilesMatch> </VirtualHost> EOF sudo sed -i "s#__PHPSOCK__#${PHPSOCK}#" /etc/apache2/sites-available/monitor.conf sudo a2dissite 000-default.conf sudo a2ensite monitor.conf sudo apache2ctl configtest sudo systemctl reload apache2

nginx:nginx 没有 .htaccess,因此以 public/ 为根目录,而 assets/sw.jsmanifest.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,Web 服务器(www-data)将无法读取——面板打开后会空白或报 403 错误(日志中:.htaccess unreadable / directory not executable)。下面的命令可以修复此问题:
# 规范整个 Web 根目录的权限:由 root 创建的目录 # Web 服务器(www-data)无法访问——不处理面板会返回空白页面或 403。 # Apache 以 www-data 运行;如果您使用其他 Web 用户,请替换。 cd /var/www/monitor # 工作目录要在 chown 之前创建——否则新目录会保持 root:root, # 在 chmod 750 后 Web 服务器(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

3) 为自己开通 SFTP 上传权限。执行上面的命令后,所有文件都归 www-data 所有,而 FileZilla / WinSCP 是以您自己的用户连接的——上传时会报 SSH_FX_PERMISSION_DENIEDPermission denied)。也不能用 root 登录来上传:root 登录已在第 05 步关闭。请从以下两种方案中选择一种。

方案 A——仅为您的用户设置 ACL(推荐)。只有您获得写入权限,Web 服务器仍然无法覆盖面板代码:

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 组。更简单,但 Web 服务器同样获得对面板文件的写入权限:一旦 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-datals -ld /var/www/monitor,权限为 drwxrwsr-x,用 s 代替 x 表示 setgid 已设置。

11. 数据库

创建数据库和用户,然后导入架构。请将整段代码完整粘贴到终端。monitor_dbmonitor_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

高亮处填入您自己的值;其余保持原样:

// --- 数据库(来自第 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/Shanghai'); // 您的时区 // --- 会话时长 --- define('SESSION_LIFETIME', 28800); // 空闲多久后需重新登录,单位秒(28800 = 8 小时)

需要修改的项:

  • DB_NAMEDB_USERDB_PASS — 与您在第 11 步创建数据库时设置的库名、用户和密码完全一致(若沿用示例则为 monitor_db / monitor_user)。DB_HOSTDB_CHARSET 请勿改动。
  • APP_URL — 面板的完整地址,含 https://,结尾不带斜杠,也不带 www。必须与您激活许可证所用的域名(第 16 步)一致,否则密钥将被拒绝。
  • TIMEZONE — 您的时区(列表见 timedatectl list-timezones)。仅影响面板显示日期的方式;对 cron 任务的执行时间没有影响(那里使用系统时区)。
  • SESSION_LIFETIME — 空闲多少秒后面板要求重新登录(默认 8 小时)。例如 3600 = 1 小时,86400 = 一天。
  • 错误日志相关配置(display_errorslog_errorserror_log)— 保持默认即可。

保存文件(Ctrl+OEnter,然后 Ctrl+X)并重启 PHP-FPM,否则因 OPcache 缓存改动不会生效:

sudo systemctl restart php*-fpm
config.php 是机密文件(其中含有数据库密码)。它位于面板根目录,也就是网站根目录,但已受保护:权限为 640(在第 10 步设置)并在根目录 .htaccess 中明确禁止访问。请勿将其上传到公开仓库,也不要带着真实密码发给技术支持。
所有参数的详细说明见 FAQ:“config.php 文件 — 面板的全部设置”

13. 为 Web 服务器配置 sudo

PHP 以 Web 服务器用户身份运行,该用户没有执行系统命令的权限。授权范围要收窄:对特定工具使用精确的 sudo,通过用户组读取日志(无需 sudo)。即便 Web 层被攻破也拿不到 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 — 状态、封禁与解封(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 MB)只有 root 可访问,非 root 每次调用都要重建 # (4.2 秒 CPU 对比 0.01 秒)。不用通配符——就这一条命令,不会安装任何东西。 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 点;给 journalctl 加 sudo 既没必要也不安全) 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.logauth.logufw.logapache2/*aide(在 Debian/Ubuntu 上这些日志属于 adm 组)。内核、SSH 和 Falco 事件通过 journalctl 命令无需 sudo 从 journald 获取,走 systemd-journal 组。请将 Web 用户加入这两个组并重启 PHP-FPM

sudo usermod -aG adm,systemd-journal www-data sudo systemctl restart php*-fpm # 必须执行,否则组不会生效

3. 如果 ClamAV 或 Suricata 写日志时不属于 adm 组(有时是 root:root)——请通过 ACL 授权:

sudo apt install acl sudo setfacl -R -m u:www-data:rX /var/log/clamav /var/log/suricata 2>/dev/null sudo setfacl -d -m u:www-data:rX /var/log/clamav /var/log/suricata 2>/dev/null

4. ModSecurity 封装脚本。 WAF 审计日志(/var/log/apache2/modsec_audit.log)属于 root,权限为 640,Web 用户无法直接读取。ModSecurity 页面通过固定的只读脚本获取引擎模式、事件和已启用规则列表——上面的 sudoers 行已经允许了该脚本:

sudo tee /usr/local/bin/monitor-modsec >/dev/null <<'EOF' #!/bin/sh echo "ENGINE=$(grep -hE '^SecRuleEngine[[:space:]]+' /etc/modsecurity/*.conf 2>/dev/null | tail -1 | awk '{print $2}')" echo "---LOG---" tail -n 3000 /var/log/apache2/modsec_audit.log 2>/dev/null echo "---RULES---" for f in /etc/modsecurity/crs/rules/*.conf /usr/share/modsecurity-crs/rules/*.conf /etc/modsecurity/custom-rules.conf; do [ -f "$f" ] && { echo "===FILE:$(basename "$f")==="; cat "$f"; } done EOF sudo chown root:root /usr/local/bin/monitor-modsec sudo chmod 755 /usr/local/bin/monitor-modsec
没有 /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 直接返回。面板的缓存和数据会外泄——例如 tmp/modsec_cache.json,其中含有 WAF 事件和攻击者 IP。请在 Nginx 网站配置中加入禁止规则:

location ^~ /data/ { deny all; } location ^~ /tmp/ { deny all; } location ^~ /logs/ { deny all; } location ^~ /includes/ { deny all; } location ^~ /cron/ { deny all; } location ^~ /database/ { deny all; } location = /config.php { deny all; }
^~ 前缀必不可少:它会先于 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 泄露,登录页面也无法打开。既可在 Web 服务器层面设置(下方为 nginx 示例),也可在面板内设置(“设置”→“按 IP 限制访问”)。若您使用 Apache,请使用面板内的限制功能。

若 nginx 站点已按第 10 步配置完成,请勿再添加第二个 location /——请将 allow/deny 行写入已有的代码块中。同一 server { } 内出现两个相同的 location / 是配置错误,会导致 nginx 无法重启。
# 在 nginx 配置中(server { } 内部): # 保持 Let's Encrypt 的 ACME 路径开放,绕过 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 访问。登录会话使用受保护的 cookie,且 WebAuthn(2FA)仅在 HTTPS 下有效。无法通过 http:// 登录。

证书免费(Let's Encrypt)。域名的 DNS 必须已指向服务器。命令因 Web 服务器而异:

# 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 重定向及自动续期。
在运行 certbot 之前,DNS 必须已指向服务器(通过 80 端口验证所有权)。检查:dig +short monitor.example.com → 服务器 IP。开放 80/443 端口:sudo ufw allow 80,443/tcp

签发后:https://monitor.example.com 打开时显示锁标志,http:// 会重定向到 https://config.php 中的 APP_URL 已在第 12 步设置)。

16. 登录与初始设置

打开 https://monitor.example.com,使用 admin / useradmin 登录并完成以下检查清单:

  1. 修改 admin 密码 — 菜单中的“用户”板块。
  2. 启用 WebAuthn (2FA) — “WebAuthn 密钥”→ 注册密钥/passkey(需要 HTTPS)。请一次注册两个:若唯一的密钥丢失,将无法使用它登录。了解详情
  3. 按 IP 限制访问 — “设置”→“按 IP 限制访问”(启用前请先填入您自己的 IP,否则会把自己挡在门外)。
  4. 输入许可证 — 将个人中心中的 ARCIVEO-… 代码激活到您的域名,并把密钥填入“设置”→“许可证”。了解详情
  5. 配置通知 — 在“设置”中配置 Telegram 和/或 Email。了解详情
  6. 删除安装程序 public/start_db.php(若仍存在,见步骤 11)。

17. 安全工具(可选)

面板已经可以运行。工具按需安装——需要哪个就装哪个,面板会立即显示其状态。各工具的安装命令都在参考手册中(按工具分设的独立章节):

18. Cron 与维护

只需配置一次,同样为可选项,但建议进行配置。详细命令请参阅参考手册:

  1. Cron 任务(报告、更新列表、检查);
  2. 备份
  3. 面板更新与迁移
  4. 恢复访问 — 以防丢失密钥或密码。
有功能无法使用或显示"无数据"?请查看参考手册中的"诊断"分组。
Arcivéo - Security Monitor © 2026