Server Ops Notes

我的运维笔记

《服务器运维》前三讲的动手记录:做了什么、用了哪些命令、踩过哪些坑。

项科铭 · 25网络A1 Rocky Linux 9.8 一台 ECS,多个站点
1

从云服务器到远程登录目标:拿到一台能用、能连、能装东西的 Linux 机器

这一讲做了什么

  • 在阿里云买一台 ECS,系统选 Rocky Linux 9,nproc 显示 2 核。
  • 记下公网 IP:47.111.128.189,这就是我这台机器的"门牌号"。
  • 在 安全组里放行 22、80、443 三个端口。这一步不做,后面 Nginx 装好了外面也访问不到。
  • 生成 SSH 密钥对,把公钥交给服务器,之后登录不再输密码。
  • 新建普通用户 study,日常操作都用它,需要管理员权限时临时借 sudo。

关键命令

本机生成密钥,把公钥推到服务器:

# 生成一对 ed25519 密钥(一路回车即可)
ssh-keygen -t ed25519

# 把公钥装到服务器的 study 用户下,实现免密登录
ssh-copy-id study@47.111.128.189

# 登录
ssh study@47.111.128.189

登录后在服务器上确认环境、创建用户:

# 看系统版本和 CPU 核数
cat /etc/redhat-release
nproc

# 新建用户 study,并加入 wheel 组(wheel 组才有 sudo 权限)
sudo useradd -m -G wheel study
sudo passwd study

# 把本机公钥写进 study 的 authorized_keys
sudo mkdir -p /home/study/.ssh
sudo cp ~/.ssh/authorized_keys /home/study/.ssh/
sudo chown -R study:study /home/study/.ssh
sudo chmod 700 /home/study/.ssh
sudo chmod 600 /home/study/.ssh/authorized_keys

为什么要建普通用户?直接用 root 登录,一条手滑的命令就可能把系统弄坏;而且 root 的一切操作都没有"确认"环节。日常用 study,危险操作用 sudo,等于给自己加了一道刹车。

踩过的坑

现象原因与解决
本机 ping 通,但 80 端口连不上 安全组没放行。云服务器的端口是"安全组 + 本机防火墙"两道门,先在控制台放行,再谈 firewalld。
ssh 提示 Permission denied (publickey) /home/study/.ssh 的属主或权限不对。必须是 study:study、目录 700、文件 600,权限放开 ssh 反而拒绝。
sudo 提示 study 不在 sudoers 中 建用户时漏了 -G wheel。补上:sudo usermod -aG wheel study,重新登录生效。
ssh 突然连不上:只超时、不报密码错 连续几次登录失败后,云安全中心判定为暴力破解,用 firewalld 富规则把来源 IP 拒了。sudo firewall-cmd --list-rich-rules 能看到 reject type="icmp-port-unreachable";用 --remove-rich-rule 删掉,且 --permanent 那份也要删,否则重启又回来。
2

装上 Nginx,第一次看到自己的网页目标:让浏览器访问到一个属于我的页面

这一讲做了什么

  • 用 dnf 安装 Nginx,交给 systemd 管理,设置开机自启。
  • 用 IP 访问,看到的是 Nginx 自带的欢迎页;用域名访问,看到的才是我的主页 —— 第一次直观感受到"请求里的域名"是有用的。
  • 做 403 实验:把网页文件的属主改成 root、权限改成 700,访问立刻变成 403,理解了 user nginx; 这一行的含义。
  • 写第一个站点配置 /etc/nginx/conf.d/mysite.conf,实现"一站一文件"。

关键命令

# 安装并立即启动,同时设为开机自启
sudo dnf install -y nginx
sudo systemctl enable --now nginx

# 看服务状态,q 退出
sudo systemctl status nginx

# 放行防火墙端口(--permanent 才是永久生效,必须 reload)
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

# 建网站目录,把属主交给 study,以后上传网页不用 sudo
sudo mkdir -p /var/www/mysite
sudo chown -R study:study /var/www/mysite
sudo chmod 755 /var/www/mysite

# 改完配置先测语法,再重载(不是 restart)
sudo nginx -t
sudo systemctl reload nginx

403 实验:Nginx 到底以谁的身份读文件

# 故意把权限改成"只有 root 能进"
sudo chown -R root:root /var/www/mysite
sudo chmod 700 /var/www/mysite

# 浏览器访问 → 403 Forbidden
# 看错误日志,能直接读到原因
sudo tail -n 20 /var/log/nginx/error.log

# 恢复
sudo chown -R study:study /var/www/mysite
sudo chmod 755 /var/www/mysite

日志里写的是 Permission denied。原因在于主配置里的 user nginx;:真正处理请求的是 worker 进程,它以 nginx 用户身份运行,进不去 700 的目录。所以网页目录的规矩是:目录 755、文件 644。

坑:改完配置直接 systemctl restart nginx,一旦语法错就整个站点挂掉。正确顺序永远是 nginx -t 通过后再 reload。reload 是平滑加载,旧连接不断。

坑:在 conf.d/ 里备份配置时,文件名写成了 mysite.conf.bak —— 没问题;但写成 mysite.bak.conf 就会被 include conf.d/*.conf; 一起加载,导致"域名重复定义"报错。

3

域名备案与 HTTPS 证书目标:https:// 打开有安全锁,并且能自动续期

这一讲做了什么

  • 在阿里云云解析里给主域名加了 A 记录,指向服务器公网 IP。
  • 完成 ICP 备案,拿到备案号 浙ICP备2026083051号,放在页面底部。
  • 用 certbot 的 webroot 方式申请 Let's Encrypt 证书,先 --dry-run 演练,成功后再正式申请。
  • 把站点配置拆成两段:80 端口只负责证书验证和跳转,443 端口才提供内容。
  • 启用 certbot-renew.timer,让证书到期前自动续。

关键命令

# 安装 certbot(Rocky 9 需要 EPEL)
sudo dnf install -y epel-release
sudo dnf install -y certbot

# 先演练:-w 是网站根目录,-d 是域名
sudo certbot certonly --webroot -w /var/www/mysite -d xkmlbb666.cyou -d www.xkmlbb666.cyou --dry-run

# 演练出现 The dry run was successful. 后,去掉 --dry-run 正式申请
sudo certbot certonly --webroot -w /var/www/mysite -d xkmlbb666.cyou -d www.xkmlbb666.cyou

# 看本机有哪些证书、什么时候到期
sudo certbot certificates

# 模拟一次续期,确认定时任务配好了
sudo certbot renew --dry-run

# 看续期定时器
systemctl list-timers | grep certbot

主站配置(/etc/nginx/conf.d/mysite.conf)的骨架:

# 80 端口:只为证书申请/续期提供验证文件,其余全部跳到 HTTPS
server {
    listen 80;
    server_name xkmlbb666.cyou www.xkmlbb666.cyou;

    location /.well-known/acme-challenge/ {
        root /var/www/mysite;
    }
    location / {
        return 301 https://$host$request_uri;
    }
}

# 443 端口:真正提供内容
server {
    listen 443 ssl;
    server_name xkmlbb666.cyou www.xkmlbb666.cyou;

    ssl_certificate     /etc/letsencrypt/live/xkmlbb666.cyou/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/xkmlbb666.cyou/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    root  /var/www/mysite;
    index index.html;

    access_log /var/log/nginx/mysite_access.log;
    error_log  /var/log/nginx/mysite_error.log;

    location / {
        try_files $uri $uri/ =404;
    }
}

为什么 80 端口必须留着 acme-challenge 这一段?certbot 验证域名归属的方式,是让 Let's Encrypt 的服务器来下载一个随机文件。如果 80 端口把所有请求都 301 走了,验证请求就取不到文件,续期会失败。所以这一段是给"续期"留的门。

踩过的坑

现象原因与解决
certbot 报 unauthorized / 404 -w 的目录和 nginx 里 acme 路径的 root 不一致。两处必须指向同一个目录。
证书申请成功,但浏览器还是报警告 443 端口的 server 块没写或者没 reload。用 sudo nginx -T | grep server_name 核对。
nginx -t 报 cannot load certificate 证书还没申请就把 443 部分写进去了。顺序必须是:先 80 → 申请证书 → 再补 443。
http 打不开,https 正常 安全组只放了 443。80 也要放行,否则续期会断。
附

常用命令速查背不下来没关系,知道去哪查就行

我想……命令
看 Nginx 有没有在跑systemctl status nginx
检查配置语法sudo nginx -t
改完配置让它生效sudo systemctl reload nginx
看完整生效的配置sudo nginx -T | less
盘点所有站点的域名sudo nginx -T 2>/dev/null | grep -E "server_name"
实时看访问日志sudo tail -f /var/log/nginx/mysite_access.log
看最近 20 条错误sudo tail -n 20 /var/log/nginx/error.log
确认证书还在有效期内sudo certbot certificates
核对文件权限ls -l / ls -ld 目录

一份配置、一条命令,背后都是一个具体的问题。笔记的价值不在于记下命令,而在于记住"当时为什么这么写"。