我的运维笔记

一台 Rocky 9 服务器的从零搭建记录 · huangweibo.icu

第 1 讲:服务器初始化与安全加固

拿到一台全新的阿里云 ECS(Rocky Linux 9),第一件事不是部署网站,而是把门关好。

密钥登录,禁用密码

密码可以被暴力穷举,SSH 密钥不会。本地生成密钥对后,把公钥交给服务器,再在 sshd 配置里关掉密码登录:

ssh-keygen -t ed25519                      # 本地生成 ed25519 密钥对
ssh-copy-id study@服务器IP                  # 把公钥装到服务器
sudo vi /etc/ssh/sshd_config               # PasswordAuthentication no
sudo systemctl restart sshd

fail2ban 自动封禁爆破 IP

即使换了密钥,仍每天有成千上万次爆破尝试。fail2ban 监控 sshd 日志,失败超限自动封 IP。它位于 EPEL 扩展源,要先装 EPEL:

sudo dnf install -y epel-release           # 安装 EPEL 扩展源
sudo dnf install -y fail2ban               # 安装 fail2ban
sudo systemctl enable --now fail2ban       # 启动并设置开机自启
sudo fail2ban-client status sshd           # 查看封禁统计

防火墙:只开需要的门

两层门都要开:阿里云安全组(外层)和 firewalld(内层)。原则是"服务上线时才开门"。

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reload
sudo firewall-cmd --list-services          # 核对已放行的服务
遇到的问题:一开始漏了安全组这层门,firewalld 放行了也连不上 —— 外层门没开,内层开多少都没用。两层门要分开检查。

第 2 讲:Nginx 与个人主页上线

这一讲把个人主页真正放到互联网上。

安装 Nginx 并认识它

sudo dnf install -y nginx                  # 安装 Nginx
sudo systemctl enable --now nginx          # 启动并设开机自启
ps -ef | grep [n]ginx                      # 1 个 master + 与 CPU 核数相同的 worker

一站一文件

站点配置放在 /etc/nginx/conf.d/ 下,每个网站一个 .conf 文件,主配置通过 include 加载它们。我的主站配置是 mysite.conf:

server {
    listen       80;
    server_name  huangweibo.icu www.huangweibo.icu;
    root         /var/www/mysite;
    index        index.html;
    location / {
        try_files $uri $uri/ =404;
    }
}

域名解析

在阿里云云解析添加两条 A 记录:@ 和 www 都指向服务器公网 IP。浏览器请求头里的 Host 就是 Nginx 分发请求的依据。

遇到的问题:403 Forbidden。原因是网页文件权限不足 —— Nginx 工作进程以 nginx 用户身份读文件,目录需要 755、文件需要 644,且整个路径上的目录都要"可进入"。

第 3 讲:HTTPS 与证书自动续期

HTTP 是明文传输,用 tcpdump 抓 80 端口能直接看到 GET、Host、User-Agent 甚至密码。HTTPS = HTTP + TLS,既加密内容又验证服务器身份。

申请证书(Let's Encrypt)

先放行 443(安全组 + firewalld),再用 certbot 以 webroot 方式申请。先 --dry-run 演练再正式申请,避免触发失败次数限制:

sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

sudo certbot certonly --webroot -w /var/www/mysite \
  -d huangweibo.icu -d www.huangweibo.icu \
  -m 邮箱 --agree-tos --no-eff-email --dry-run   # 先演练
sudo certbot certonly --webroot -w /var/www/mysite \
  -d huangweibo.icu -d www.huangweibo.icu \
  -m 邮箱 --agree-tos --no-eff-email             # 再正式申请

Nginx 双端口分工

80 端口只做两件事:给证书续期发验证文件、其余请求 301 跳转;443 端口才真正提供内容:

server {
    listen       443 ssl;
    server_name  huangweibo.icu www.huangweibo.icu;
    ssl_certificate      /etc/letsencrypt/live/huangweibo.icu/fullchain.pem;
    ssl_certificate_key  /etc/letsencrypt/live/huangweibo.icu/privkey.pem;
    ssl_protocols        TLSv1.2 TLSv1.3;
    root /var/www/mysite;
}

自动续期

证书 90 天有效,靠人记必然忘。启用 systemd 定时器,再放一个 deploy 钩子让 Nginx 在续期后自动重载:

sudo systemctl enable --now certbot-renew.timer
sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
# 内容:#!/bin/bash
#       systemctl reload nginx
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
sudo certbot renew --dry-run               # 演练续期全流程
遇到的问题:certbot 非交互执行时会随机延迟几分钟才开始,看起来像卡死 —— 其实是防止请求风暴的正常设计,等就行。另外抓包发现 HTTPS 下域名仍然可见(SNI 明文),它隐藏的是内容,不是"你访问了哪个网站"。