Skip to content

AlmaLinux 10 Web 控制面板配置教程

本教程详细介绍如何在 AlmaLinux 10 上安装和配置多种 Web 控制面板,包括 Cockpit、Webmin、Ajenti 等,提供图形化服务器管理界面。

控制面板对比

主流控制面板特性对比

控制面板开源性资源占用功能完整性中文支持适用场景
Cockpit开源极低中等系统监控、基础管理
Webmin开源全功能服务器管理
Ajenti开源中等部分现代化 Web 主机管理
cPanel商业极高专业 Web 主机
DirectAdmin商业轻量级 Web 主机

第一部分:Cockpit 系统管理

1.1 Cockpit 安装和配置

基础安装

bash
# 安装 Cockpit 主包
dnf install -y cockpit

# 安装额外模块
dnf install -y cockpit-machines cockpit-podman cockpit-storaged \
               cockpit-networkmanager cockpit-selinux cockpit-kdump

# 启用 Cockpit 服务
systemctl enable --now cockpit.socket

# 配置防火墙
firewall-cmd --permanent --add-service=cockpit
firewall-cmd --reload

# 验证安装
systemctl status cockpit.socket
ss -tulpn | grep :9090

高级配置和定制

bash
# 创建 Cockpit 配置目录
mkdir -p /etc/cockpit

# 配置 HTTPS 证书
cat > /etc/cockpit/cockpit.conf << 'EOF'
[WebService]
# 使用自定义证书
# ServerCert = /etc/ssl/certs/cockpit.crt
# ServerKey = /etc/ssl/private/cockpit.key

# 修改监听端口 (默认 9090)
# ListenStream = 9090

# 允许的主机名
Origins = https://your-domain.com:9090 wss://your-domain.com:9090

# 会话超时 (分钟)
IdleTimeout = 15

# 允许密码认证
AllowUnencrypted = false
EOF

# 生成自签名证书 (生产环境建议使用正式证书)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
    -keyout /etc/ssl/private/cockpit.key \
    -out /etc/ssl/certs/cockpit.crt \
    -subj "/C=CN/ST=Beijing/L=Beijing/O=Company/CN=your-domain.com"

# 设置证书权限
chmod 600 /etc/ssl/private/cockpit.key
chmod 644 /etc/ssl/certs/cockpit.crt

# 重启 Cockpit
systemctl restart cockpit.socket

Cockpit 插件开发

bash
# 创建自定义插件目录
mkdir -p /usr/local/share/cockpit/custom-monitor

# 创建插件清单
cat > /usr/local/share/cockpit/custom-monitor/manifest.json << 'EOF'
{
    "version": 0,
    "tools": {
        "custom-monitor": {
            "label": "自定义监控",
            "path": "/custom-monitor/index.html"
        }
    },
    "content-security-policy": "default-src 'self' 'unsafe-inline' 'unsafe-eval'"
}
EOF

# 创建插件主页
cat > /usr/local/share/cockpit/custom-monitor/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
    <title>自定义监控</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="../base1/cockpit.css">
    <script src="../base1/cockpit.js"></script>
</head>
<body>
    <div class="container-fluid">
        <h1>自定义系统监控</h1>
        <div class="row">
            <div class="col-md-6">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        <h3 class="panel-title">系统负载</h3>
                    </div>
                    <div class="panel-body" id="system-load">
                        <p>加载中...</p>
                    </div>
                </div>
            </div>
            <div class="col-md-6">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        <h3 class="panel-title">磁盘使用</h3>
                    </div>
                    <div class="panel-body" id="disk-usage">
                        <p>加载中...</p>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        // 获取系统负载
        function updateSystemLoad() {
            cockpit.spawn(["uptime"])
                .then(function(data) {
                    document.getElementById('system-load').innerHTML = 
                        '<pre>' + data + '</pre>';
                })
                .catch(function(ex) {
                    document.getElementById('system-load').innerHTML = 
                        '<p class="text-danger">加载失败: ' + ex + '</p>';
                });
        }

        // 获取磁盘使用
        function updateDiskUsage() {
            cockpit.spawn(["df", "-h"])
                .then(function(data) {
                    document.getElementById('disk-usage').innerHTML = 
                        '<pre>' + data + '</pre>';
                })
                .catch(function(ex) {
                    document.getElementById('disk-usage').innerHTML = 
                        '<p class="text-danger">加载失败: ' + ex + '</p>';
                });
        }

        // 页面加载时更新数据
        document.addEventListener('DOMContentLoaded', function() {
            updateSystemLoad();
            updateDiskUsage();
            
            // 每30秒更新一次
            setInterval(function() {
                updateSystemLoad();
                updateDiskUsage();
            }, 30000);
        });
    </script>
</body>
</html>
EOF

# 重启 Cockpit 以加载插件
systemctl restart cockpit.socket

1.2 Cockpit 企业级集成

集成 LDAP 认证

bash
# 安装 SSSD 和相关包
dnf install -y sssd sssd-ldap sssd-tools

# 配置 SSSD for LDAP
cat > /etc/sssd/sssd.conf << 'EOF'
[sssd]
config_file_version = 2
services = nss, pam
domains = LDAP

[domain/LDAP]
id_provider = ldap
auth_provider = ldap
ldap_uri = ldap://ldap.company.com
ldap_search_base = dc=company,dc=com
ldap_user_search_base = ou=users,dc=company,dc=com
ldap_group_search_base = ou=groups,dc=company,dc=com
ldap_default_bind_dn = cn=admin,dc=company,dc=com
ldap_default_authtok = your_ldap_password
enumerate = true
EOF

chmod 600 /etc/sssd/sssd.conf
systemctl enable --now sssd

# 配置 PAM 认证
authconfig --enablesssd --enablesssdauth --enablemkhomedir --update

# 测试 LDAP 用户登录
id ldap_user@LDAP

第二部分:Webmin 全功能管理

2.1 Webmin 安装和配置

标准安装流程

bash
# 添加 Webmin 官方仓库
cat > /etc/yum.repos.d/webmin.repo << 'EOF'
[Webmin]
name=Webmin Distribution Neutral
#baseurl=https://download.webmin.com/download/yum
mirrorlist=https://download.webmin.com/download/yum/mirrorlist
enabled=1
gpgcheck=1
gpgkey=https://www.webmin.com/jcameron-key.asc
EOF

# 安装 Webmin
dnf install -y webmin

# 配置防火墙
firewall-cmd --permanent --add-port=10000/tcp
firewall-cmd --reload

# 启动 Webmin
systemctl enable --now webmin

# 检查状态
systemctl status webmin
netstat -tulpn | grep :10000

Webmin 安全配置

bash
# 配置 SSL 证书
cat > /etc/webmin/miniserv.conf << 'EOF'
# SSL 配置
ssl=1
keyfile=/etc/webmin/miniserv.pem
certfile=/etc/webmin/miniserv.pem

# 安全设置
session=1
preroot=
logout=/etc/webmin/logout-flag
listen=10000
denyfile=\.pl$
allow=192.168.0.0/16 10.0.0.0/8
deny=
alwaysresolve=0
logfile=/var/webmin/miniserv.log
errorlog=/var/webmin/miniserv.error

# 性能优化
maxconns=50
pam_conv=1
blockhost_failures=5
blockhost_time=60
syslog=1
EOF

# 重新生成 SSL 证书
/usr/share/webmin/miniserv.pl /etc/webmin/miniserv.conf &
sleep 2
pkill -f miniserv.pl

# 重启 Webmin
systemctl restart webmin

Webmin 模块管理

bash
# 下载额外模块
cd /tmp
wget http://www.webmin.com/download/modules/virtualmin-gpl-latest.wbm

# 通过命令行安装模块
/usr/share/webmin/install-module.pl virtualmin-gpl-latest.wbm

# 或者创建自定义模块
mkdir -p /usr/share/webmin/custom-stats

cat > /usr/share/webmin/custom-stats/module.info << 'EOF'
desc=Custom Statistics
category=system
depends=proc
version=1.0
os_support=*-linux
EOF

# 创建模块主脚本
cat > /usr/share/webmin/custom-stats/index.cgi << 'EOF'
#!/usr/bin/perl

use strict;
use warnings;

require './custom-stats-lib.pl';

&ReadParse();
&ui_print_header(undef, "Custom Statistics", "");

print "<h2>System Statistics</h2>\n";

# 系统负载
my $uptime = `uptime`;
chomp $uptime;
print "<p><b>System Load:</b> $uptime</p>\n";

# 内存使用
my $free = `free -h`;
print "<pre>$free</pre>\n";

# 磁盘使用
my $df = `df -h`;
print "<pre>$df</pre>\n";

&ui_print_footer("", "Module Index");
EOF

chmod 755 /usr/share/webmin/custom-stats/index.cgi

# 重启 Webmin 以加载新模块
systemctl restart webmin

2.2 Webmin 高级功能

配置文件管理

bash
# 创建配置文件管理模板
mkdir -p /etc/webmin/custom-config/templates

cat > /etc/webmin/custom-config/templates/httpd.conf << 'EOF'
# Apache HTTP Server Configuration Template
ServerRoot "/etc/httpd"
Listen 80

# 基础模块
LoadModule dir_module modules/mod_dir.so
LoadModule mime_module modules/mod_mime.so
LoadModule rewrite_module modules/mod_rewrite.so

# 服务器配置
ServerName {SERVER_NAME}
ServerAdmin {ADMIN_EMAIL}

# 文档根目录
DocumentRoot "/var/www/html"

# 目录配置
<Directory "/var/www/html">
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

# 日志配置
ErrorLog logs/error_log
CustomLog logs/access_log combined

# 虚拟主机配置
Include conf.d/*.conf
EOF

# 创建配置生成脚本
cat > /usr/local/bin/webmin-config-generator.sh << 'EOF'
#!/bin/bash

TEMPLATE_DIR="/etc/webmin/custom-config/templates"
OUTPUT_DIR="/tmp/webmin-configs"

mkdir -p $OUTPUT_DIR

# 生成 Apache 配置
sed -e "s/{SERVER_NAME}/$(hostname -f)/g" \
    -e "s/{ADMIN_EMAIL}/admin@$(hostname -d)/g" \
    $TEMPLATE_DIR/httpd.conf > $OUTPUT_DIR/httpd.conf

echo "配置文件生成完成: $OUTPUT_DIR"
EOF

chmod +x /usr/local/bin/webmin-config-generator.sh

第三部分:Ajenti 现代化面板

3.1 Ajenti 安装配置

Python 环境准备和安装

bash
# 安装 Python 3 和 pip
dnf install -y python3 python3-pip python3-devel

# 安装依赖包
dnf install -y gcc openssl-devel libffi-devel

# 安装 Ajenti
pip3 install ajenti

# 创建 Ajenti 用户
useradd -r -s /bin/false ajenti

# 创建配置目录
mkdir -p /etc/ajenti
chown ajenti:ajenti /etc/ajenti

# 生成初始配置
ajenti-panel --configure

# 创建 systemd 服务文件
cat > /etc/systemd/system/ajenti.service << 'EOF'
[Unit]
Description=Ajenti panel
After=network.target

[Service]
Type=forking
User=root
ExecStart=/usr/local/bin/ajenti-panel -d
Restart=always

[Install]
WantedBy=multi-user.target
EOF

# 启用服务
systemctl daemon-reload
systemctl enable --now ajenti

# 配置防火墙
firewall-cmd --permanent --add-port=8000/tcp
firewall-cmd --reload

Ajenti 插件配置

bash
# 安装常用插件
pip3 install ajenti.plugin.core ajenti.plugin.dashboard \
             ajenti.plugin.filesystem ajenti.plugin.services \
             ajenti.plugin.terminal ajenti.plugin.notepad

# 安装 Web 服务器插件
pip3 install ajenti.plugin.vh ajenti.plugin.vh-nginx \
             ajenti.plugin.vh-php-fpm ajenti.plugin.vh-mysql

# 创建自定义插件目录
mkdir -p /var/lib/ajenti/plugins/custom_monitor

# 创建插件描述文件
cat > /var/lib/ajenti/plugins/custom_monitor/plugin.yml << 'EOF'
name: custom_monitor
title: Custom Monitor
author: Admin
homepage: http://localhost
version: '1.0'

dependencies:
  - core

components:
  - type: python
    path: main.py
EOF

# 创建插件主文件
cat > /var/lib/ajenti/plugins/custom_monitor/main.py << 'EOF'
from ajenti.api import *
from ajenti.plugins import *
from ajenti.ui import *
from ajenti.ui.binder import Binder

@component(CorePlugin)
class CustomMonitor(BasePlugin):
    def init(self):
        self.title = 'Custom Monitor'
        self.icon = 'dashboard'
        self.category = 'System'
        
    def render(self):
        # 获取系统信息
        import subprocess
        
        uptime = subprocess.check_output(['uptime']).decode('utf-8').strip()
        free_output = subprocess.check_output(['free', '-h']).decode('utf-8')
        df_output = subprocess.check_output(['df', '-h']).decode('utf-8')
        
        return self.ui.inflate('layout'), {
            'uptime': uptime,
            'memory': free_output,
            'disk': df_output
        }
EOF

# 创建插件布局文件
cat > /var/lib/ajenti/plugins/custom_monitor/layout.xml << 'EOF'
<document>
    <box>
        <label text="System Information" size="3" />
        
        <pad>
            <box>
                <label text="Uptime:" style="bold" />
                <label bind="uptime" />
            </box>
        </pad>
        
        <pad>
            <box>
                <label text="Memory Usage:" style="bold" />
                <terminal bind="memory" readonly="True" />
            </box>
        </pad>
        
        <pad>
            <box>
                <label text="Disk Usage:" style="bold" />
                <terminal bind="disk" readonly="True" />
            </box>
        </pad>
    </box>
</document>
EOF

# 重启 Ajenti 加载插件
systemctl restart ajenti

第四部分:企业级部署方案

4.1 负载均衡和高可用

HAProxy 负载均衡配置

bash
# 安装 HAProxy
dnf install -y haproxy

# 配置 HAProxy
cat > /etc/haproxy/haproxy.cfg << 'EOF'
global
    log 127.0.0.1:514 local0
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

defaults
    mode http
    log global
    option httplog
    option dontlognull
    option redispatch
    retries 3
    timeout http-request 10s
    timeout queue 1m
    timeout connect 10s
    timeout client 1m
    timeout server 1m
    timeout http-keep-alive 10s
    timeout check 10s
    maxconn 3000

# 统计页面
stats enable
stats uri /haproxy-stats
stats realm HAProxy\ Statistics
stats auth admin:admin123

# Cockpit 负载均衡
frontend cockpit_frontend
    bind *:9090
    default_backend cockpit_servers

backend cockpit_servers
    balance roundrobin
    option httpchk GET /
    server cockpit1 192.168.100.10:9090 check
    server cockpit2 192.168.100.11:9090 check backup

# Webmin 负载均衡
frontend webmin_frontend
    bind *:10000
    default_backend webmin_servers

backend webmin_servers
    balance roundrobin
    option httpchk GET /
    server webmin1 192.168.100.10:10000 check ssl verify none
    server webmin2 192.168.100.11:10000 check ssl verify none backup
EOF

# 启用 HAProxy
systemctl enable --now haproxy

# 配置防火墙
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload

4.2 监控和告警集成

Prometheus 监控集成

bash
# 安装 Node Exporter
cd /tmp
wget https://github.com/prometheus/node_exporter/releases/download/v1.6.1/node_exporter-1.6.1.linux-amd64.tar.gz
tar xvfz node_exporter-1.6.1.linux-amd64.tar.gz
cp node_exporter-1.6.1.linux-amd64/node_exporter /usr/local/bin/

# 创建服务文件
cat > /etc/systemd/system/node_exporter.service << 'EOF'
[Unit]
Description=Node Exporter
After=network.target

[Service]
Type=simple
User=nobody
ExecStart=/usr/local/bin/node_exporter --web.listen-address=:9100
Restart=always

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now node_exporter

# 创建控制面板监控脚本
cat > /usr/local/bin/panel-monitor.sh << 'EOF'
#!/bin/bash

METRICS_FILE="/var/log/panel-metrics.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S')

# 检查 Cockpit
if systemctl is-active --quiet cockpit.socket; then
    COCKPIT_STATUS="UP"
else
    COCKPIT_STATUS="DOWN"
fi

# 检查 Webmin
if systemctl is-active --quiet webmin; then
    WEBMIN_STATUS="UP"
else
    WEBMIN_STATUS="DOWN"
fi

# 检查 Ajenti
if systemctl is-active --quiet ajenti; then
    AJENTI_STATUS="UP"
else
    AJENTI_STATUS="DOWN"
fi

# 记录指标
echo "[$DATE] Cockpit: $COCKPIT_STATUS, Webmin: $WEBMIN_STATUS, Ajenti: $AJENTI_STATUS" >> $METRICS_FILE

# 发送告警 (如果服务异常)
if [ "$COCKPIT_STATUS" = "DOWN" ] || [ "$WEBMIN_STATUS" = "DOWN" ] || [ "$AJENTI_STATUS" = "DOWN" ]; then
    echo "警告: 控制面板服务异常" | mail -s "Panel Alert" [email protected]
fi
EOF

chmod +x /usr/local/bin/panel-monitor.sh

# 配置定期检查
echo "*/5 * * * * /usr/local/bin/panel-monitor.sh" | crontab -

4.3 安全加固和审计

安全配置脚本

bash
# 创建安全加固脚本
cat > /usr/local/bin/panel-security-hardening.sh << 'EOF'
#!/bin/bash

echo "开始控制面板安全加固..."

# 1. 更新默认端口
# Cockpit
sed -i 's/ListenStream=9090/ListenStream=19090/' /usr/lib/systemd/system/cockpit.socket

# Webmin
sed -i 's/listen=10000/listen=20000/' /etc/webmin/miniserv.conf

# 2. 配置 IP 白名单
# Cockpit
echo 'Origins = https://trusted-ip:19090 wss://trusted-ip:19090' >> /etc/cockpit/cockpit.conf

# Webmin
echo 'allow=192.168.0.0/16 10.0.0.0/8' >> /etc/webmin/miniserv.conf

# 3. 启用日志记录
# 确保所有面板都启用详细日志
mkdir -p /var/log/panels
chmod 750 /var/log/panels

# 4. 配置 fail2ban
dnf install -y fail2ban

cat > /etc/fail2ban/jail.d/panels.conf << 'EOF_FAIL2BAN'
[cockpit]
enabled = true
filter = cockpit
logpath = /var/log/cockpit.log
maxretry = 3
bantime = 3600

[webmin]
enabled = true
filter = webmin
logpath = /var/webmin/miniserv.log
maxretry = 3
bantime = 3600
EOF_FAIL2BAN

# 创建过滤器
cat > /etc/fail2ban/filter.d/cockpit.conf << 'EOF_FILTER'
[Definition]
failregex = ^.*: Received unauthenticated request from <HOST>
ignoreregex =
EOF_FILTER

systemctl enable --now fail2ban

# 5. 重启服务应用配置
systemctl daemon-reload
systemctl restart cockpit.socket
systemctl restart webmin

echo "安全加固完成"
EOF

chmod +x /usr/local/bin/panel-security-hardening.sh

故障排查和维护

常见问题解决

控制面板诊断脚本

bash
cat > /usr/local/bin/panel-diagnostic.sh << 'EOF'
#!/bin/bash

echo "=== 控制面板诊断工具 ==="

# 检查端口占用
echo "1. 端口检查:"
ss -tulpn | grep -E ":(9090|10000|8000)"

# 检查服务状态
echo -e "\n2. 服务状态:"
systemctl status cockpit.socket --no-pager
systemctl status webmin --no-pager
systemctl status ajenti --no-pager

# 检查防火墙
echo -e "\n3. 防火墙状态:"
firewall-cmd --list-services
firewall-cmd --list-ports

# 检查日志错误
echo -e "\n4. 近期错误日志:"
journalctl -u cockpit.service --since "1 hour ago" --no-pager | tail -10
tail -10 /var/webmin/miniserv.error

# 检查资源使用
echo -e "\n5. 资源使用:"
ps aux | grep -E "(cockpit|webmin|ajenti)" | grep -v grep

echo -e "\n=== 诊断完成 ==="
EOF

chmod +x /usr/local/bin/panel-diagnostic.sh

总结: 本教程提供了在 AlmaLinux 10 上部署和配置多种 Web 控制面板的完整指南,包括 Cockpit、Webmin 和 Ajenti 的安装、配置、安全加固和高可用部署。通过这些控制面板,管理员可以方便地进行图形化服务器管理,提高运维效率。

相关文档:

基于 MIT 许可发布