查询 25 次,耗时 0.3211 秒

从域名解析到 HTTPS 上线:一套可审计、可回滚的 Linux 网站服务器部署与安全加固实践

180647004

New member

180647004 Rep
0
0
0
Rep
0
180647004 Vouches
Vouches
0
1 MONTH
1 1 MONTH OF SERVICE
180647004 获得
0
0
0
获得
0
180647004 凭证
0
0
0
凭证
0
主题
3
点赞
0
HakB
1 月
在社区成长 1 月
LEVEL 1 1 XP
 
一、背景与目标

很多站点上线失败,并不是应用本身有问题,而是域名解析、服务器网络、反向代理、证书、权限和监控没有形成完整链路。本篇以“将一个静态站点或普通 Web 应用部署到一台 Ubuntu 22.04 LTS 云服务器”为例,域名使用 example.com,服务器公网地址使用 203.0.113.10。文中的 IP 和域名均为文档保留示例,实际操作时必须替换为自己拥有或获得明确授权的资源。

目标包括:正确配置 DNS 记录;让 Nginx 监听 80/443 端口;使用可信 CA 签发并自动续期的 TLS 证书;通过最小权限、主机防火墙、日志和备份降低风险;在变更前后进行可验证、可回滚的检查。涉及安全测试时,仅建议在本地虚拟机、授权测试环境或自有服务器上进行。

二、原理与前置条件

访问 https://www.example.com 时,浏览器首先通过递归 DNS 服务器查询域名。递归服务器再向权威 DNS 查询 A 或 AAAA 记录,返回服务器地址。浏览器连接 443 端口后,Nginx 根据 TLS 的 SNI 和 HTTP Host 选择站点,最后将请求交给静态文件或后端应用。

前置条件如下:一是已经注册域名,并能管理 DNS;二是拥有一台 Ubuntu 22.04 LTS 服务器及 sudo 权限;三是云厂商安全组允许 22、80、443 端口,且本机防火墙策略与安全组一致;四是服务器具备固定公网 IPv4,若配置 IPv6,则必须确认 IPv6 路由、防火墙和服务监听均正常;五是准备好站点目录、部署包和备份位置。

三、先做资产与变更准备

建议先建立一份简单的变更记录,包括域名、DNS 服务商、服务器 IP、SSH 端口、系统版本、证书邮箱、回滚方式和责任人。不要直接在生产机上反复试错,可以先用快照或虚拟机复制出实验环境。上线前确认域名没有被其他站点使用,服务器中也没有遗留的测试虚拟主机。

登录服务器后先更新系统并安装基础工具:

sudo apt update
sudo apt full-upgrade -y
sudo apt install -y nginx curl dnsutils ufw unattended-upgrades

如果服务器上已有业务,执行升级前应查看运行中的服务,并安排维护窗口。不要在不了解依赖关系的情况下批量删除软件包。

四、配置 DNS 解析

在 DNS 服务商控制台添加以下记录:

A @ 203.0.113.10 TTL 300
A www 203.0.113.10 TTL 300

如果确实启用了 IPv6,再添加 AAAA 记录;如果服务器没有可用 IPv6,不要为了“看起来完整”而添加错误的 AAAA,否则部分用户会优先走 IPv6 并访问失败。常用的解析检查命令如下:

dig A example.com +short
dig A www.example.com +short
dig NS example.com
dig +trace example.com

切换 DNS、修改 NS 记录或迁移 DNS 服务商时,先降低 TTL 并等待原 TTL 过期,再进行变更。TTL 只能影响缓存时间,不能保证所有运营商立即刷新。生产环境建议保留旧服务器一段时间,在确认访问量和日志已经切换后再下线。

如果域名用于邮件,还要单独配置 SPF、DKIM 和 DMARC。不要随意照抄网上的 SPF 内容,多个 SPF TXT 记录会导致校验失败。DMARC 可以先使用 p=none 收集报告,确认合法发信源后再逐步提高策略,避免误伤正常邮件。

五、服务器基础加固

首先创建普通运维用户,日常不直接使用 root:

sudo adduser deploy
sudo usermod -aG sudo deploy

在本地生成或使用已有 SSH 密钥,并将公钥写入 deploy 用户的 authorized_keys。确认新会话可以登录后,再编辑 SSH 配置:

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudoedit /etc/ssh/sshd_config

建议确认以下配置存在且符合实际情况:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes

修改后先检查语法,再重载服务:

sudo sshd -t
sudo systemctl reload ssh

不要在没有验证备用登录会话的情况下关闭密码登录,也不要忘记云厂商控制台、带外管理和应急账号的可用性。若使用非标准 SSH 端口,也只能减少自动扫描噪声,不能替代密钥认证、限流和日志审计。

配置 UFW 时先放行 SSH,再启用防火墙,避免把自己锁在服务器外:

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enable
sudo ufw status verbose

实际环境应把 22 端口限制为办公出口 IP 或 VPN 网段。应用后端端口,例如 127.0.0.1:3000,不应直接暴露到公网。

六、部署 Nginx 与站点

创建站点目录并设置权限:

sudo mkdir -p /var/www/example.com/public
sudo chown -R deploy:deploy /var/www/example.com
printf '<!doctype html><html><meta charset="utf-8"><title>example.com</title><h1>It works</h1></html>' > /var/www/example.com/public/index.html

创建 Nginx 配置文件 /etc/nginx/sites-available/example.com:

server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/public;
index index.html;

access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log warn;

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

location ~ /\. {
deny all;
}
}

启用配置并检查:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
sudo nginx -t
sudo systemctl reload nginx
curl -I -H 'Host: example.com' http://127.0.0.1/

如果部署的是后端应用,建议让应用只监听 127.0.0.1:3000,再由 Nginx 反向代理:

location / {
proxy_pass http://127.0.0.1:3000
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

后端应用需要使用 systemd、容器编排或其他可靠进程管理方式运行,并限制环境变量、日志和数据目录权限。不要把数据库端口直接暴露在公网。

七、申请 HTTPS 并设置跳转

确认 A/AAAA 记录已经指向正确服务器,且 80 端口可以从公网访问后,再申请证书。以 Certbot 为例:

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com --email [email protected] --agree-tos --no-eff-email

Certbot 通常会自动修改 Nginx 配置。完成后检查:

sudo nginx -t
curl -I http://example.com
curl -I https://example.com
sudo certbot renew --dry-run

确认 HTTPS 正常后,将 HTTP 请求永久跳转到 HTTPS。可以使用 Nginx 中的 return 301 https://$host$request_uri;,但不要在证书尚未签发、站点尚未验证前提前开启强制跳转,否则会增加排查难度。HSTS 也不要一开始就设置很长的 max-age,先观察所有子域名和旧资源是否都支持 HTTPS,再逐步启用。

八、性能与可观测性

小型站点的性能优化应从缓存、压缩、连接和资源体积入手,而不是盲目增加配置。静态资源可以设置 Cache-Control,例如对带版本号的 CSS、JS、图片使用较长缓存;HTML 则保持较短缓存,方便发布回滚。启用 gzip 前应确认不会压缩已经压缩的图片、视频和压缩包。

每日检查磁盘、内存、负载和日志增长:

df -h
free -h
uptime
sudo journalctl -u nginx --since today --no-pager
sudo tail -n 100 /var/log/nginx/example.com.error.log

可以用 curl 测试响应头和基础延迟:

curl -sS -o /dev/null -w 'code=%{http_code} connect=%{time_connect} total=%{time_total}\n' https://example.com/

生产环境应设置日志轮转,避免访问日志占满磁盘。对于后端服务,还应记录请求耗时、错误率、进程重启次数和数据库连接数,但不要把密码、Cookie、Authorization 头或用户隐私写入日志。

九、备份、更新与回滚

备份至少应覆盖网站文件、Nginx 配置、应用配置模板、数据库以及 DNS 变更记录。备份不能只放在同一台服务器上,建议采用异地、加密、定期验证恢复的策略。可以先打包配置和站点文件:

sudo tar -czf /tmp/example-backup-$(date +%F).tar.gz /etc/nginx /var/www/example.com

此命令仅用于示例,正式环境应将备份传送到权限隔离的备份存储,并设置保留周期。每次发布遵循“备份—小范围变更—健康检查—观察—确认”的顺序。若 Nginx 配置错误,使用 nginx -t 失败时不要 reload;若发布后异常,可恢复上一个配置、应用包或服务器快照,并保留故障日志供分析。

十、常见问题

1. DNS 已修改但仍访问旧服务器:检查 dig 结果、NS 记录和本地缓存;确认是否存在 AAAA 记录导致 IPv6 走向错误地址。

2. Certbot 提示验证失败:检查 80 端口、安全组、UFW、Nginx server_name 和 DNS 是否一致;不要用代理或重写规则阻断 ACME 验证路径。

3. 浏览器显示 502:通常是后端进程未启动、监听地址错误、权限不足或 Nginx proxy_pass 配置错误。用 ss -lntp 和 journalctl 检查实际监听情况。

4. 修改 SSH 后无法登录:保留一个已验证的 SSH 会话,修改前执行 sshd -t,并准备云厂商控制台或带外恢复方式。

5. 页面偶尔打不开:分别从 DNS、TCP 连接、TLS 握手、Nginx 状态码和后端日志定位,不要只看浏览器提示。必要时从不同网络执行 dig、curl 和 mtr,对比 IPv4 与 IPv6 路径。

十一、总结

可靠的域名与服务器部署不是“装好 Nginx 就结束”,而是 DNS、网络、TLS、权限、日志、备份和回滚共同构成的交付链路。实践中应坚持最小暴露面:只开放必要端口,后端仅监听本机或内网;坚持可验证:每次修改前后都用 dig、nginx -t、curl、systemctl 和日志检查;坚持可恢复:保留配置备份、快照和经过验证的异地备份。完成这些基础工作后,再根据真实访问量优化缓存、连接数和数据库,通常比直接套用所谓“高性能参数”更稳定,也更容易审计和维护。
 
顶部