跳到主要内容

HTTP/HTTPS 协议

HTTP 协议基础

请求方法

方法语义幂等安全常见场景
GET获取资源查询数据
POST创建资源提交表单
PUT替换资源全量更新
PATCH部分更新增量更新
DELETE删除资源删除数据
HEAD获取响应头检查资源是否存在
OPTIONS预检请求CORS 跨域

HTTP 状态码

范围分类常见状态码
1xx信息100 Continue、101 Switching Protocols
2xx成功200 OK、201 Created、204 No Content
3xx重定向301 永久重定向、302 临时重定向、304 Not Modified
4xx客户端错误400 Bad Request、401 Unauthorized、403 Forbidden、404 Not Found、429 Too Many Requests
5xx服务端错误500 Internal Error、502 Bad Gateway、503 Service Unavailable、504 Gateway Timeout
运维必记状态码
  • 502 Bad Gateway:Nginx/LB 无法连接后端。检查后端服务是否存活。
  • 503 Service Unavailable:服务过载或维护中。检查后端容量、限流配置。
  • 504 Gateway Timeout:后端响应超时。检查 proxy_read_timeout 配置和后端处理时间。
  • 301 vs 302:301 浏览器会缓存重定向,302 不缓存。域名迁移用 301。

HTTP 版本对比

特性HTTP/1.0HTTP/1.1HTTP/2HTTP/3
连接方式短连接Keep-Alive多路复用多路复用
队头阻塞应用层解决完全解决
头部压缩HPACKQPACK
服务端推送
传输层TCPTCPTCPQUIC (UDP)
加密可选可选事实上必须 TLS强制 TLS 1.3

HTTPS 与 TLS

TLS 握手流程(TLS 1.2)

TLS 1.3 优化

TLS 1.3 优势
  • 更快:1-RTT 握手(TLS 1.2 需要 2-RTT),支持 0-RTT 恢复
  • 更安全:移除了不安全的密码套件(RC4、3DES、SHA-1 等)
  • 推荐所有新服务使用 TLS 1.3

证书管理

# 查看证书信息
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -text -noout

# 检查证书过期时间
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates

# 验证证书链
openssl verify -CAfile ca-bundle.crt server.crt

# 生成自签名证书(测试用)
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes \
-subj "/CN=example.com"

Let's Encrypt 免费证书

# 安装 certbot
apt install certbot python3-certbot-nginx # Debian/Ubuntu
yum install certbot python3-certbot-nginx # CentOS

# 申请证书(自动配置 Nginx)
certbot --nginx -d example.com -d www.example.com

# 申请证书(手动模式,不修改 Nginx 配置)
certbot certonly --webroot -w /var/www/html -d example.com

# 证书续期(建议加入 crontab)
certbot renew --dry-run # 测试续期
certbot renew # 正式续期

# 自动续期 crontab
0 3 * * * certbot renew --quiet --post-hook "systemctl reload nginx"
证书过期是常见事故

建议设置证书过期监控:

#!/bin/bash
# 证书过期检查脚本
DOMAIN="example.com"
DAYS_WARN=30

EXPIRY=$(echo | openssl s_client -connect ${DOMAIN}:443 -servername ${DOMAIN} 2>/dev/null | \
openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))

if [ $DAYS_LEFT -lt $DAYS_WARN ]; then
echo "WARNING: ${DOMAIN} 证书将在 ${DAYS_LEFT} 天后过期!"
# 发送告警通知
fi

HTTP 运维实践

curl 常用技巧

# 基础请求
curl -v https://example.com # 显示详细信息(含 TLS 握手)
curl -I https://example.com # 只获取响应头
curl -o /dev/null -s -w "HTTP %{http_code} | %{time_total}s\n" URL # 状态码+耗时

# 指定请求方法和数据
curl -X POST -d '{"key":"value"}' -H "Content-Type: application/json" URL

# 跟踪重定向
curl -L URL # 自动跟随重定向
curl -L -w "重定向次数: %{num_redirects}\n" URL

# 下载文件
curl -O URL # 保存原文件名
curl -o output.file URL # 指定文件名
curl -C - URL # 断点续传

# 测试性能
curl -o /dev/null -s -w \
"DNS: %{time_namelookup}s\n\
TCP: %{time_connect}s\n\
TLS: %{time_appconnect}s\n\
首字节: %{time_starttransfer}s\n\
总时间: %{time_total}s\n\
HTTP状态: %{http_code}\n" \
https://example.com

# 指定 Host 头(不经过 DNS 解析)
curl -H "Host: example.com" http://10.0.0.1/

# 忽略证书验证(仅调试用)
curl -k https://self-signed.example.com

HTTP 缓存头

# 强缓存
Cache-Control: max-age=31536000 # 缓存 1 年
Cache-Control: no-cache # 每次需要验证
Cache-Control: no-store # 不缓存

# 协商缓存
ETag: "abc123" # 内容哈希
Last-Modified: Wed, 01 Jan 2024 # 最后修改时间

# CDN 相关
Cache-Control: s-maxage=3600 # CDN 缓存时间(覆盖 max-age)
Vary: Accept-Encoding # 区分 gzip/br 缓存

HTTP 安全头

nginx.conf - 安全头配置
# 防止点击劫持
add_header X-Frame-Options "SAMEORIGIN" always;

# 防止 MIME 嗅探
add_header X-Content-Type-Options "nosniff" always;

# XSS 保护
add_header X-XSS-Protection "1; mode=block" always;

# HSTS(强制 HTTPS)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

# 内容安全策略
add_header Content-Security-Policy "default-src 'self'" always;

# Referrer 控制
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

抓包分析

tcpdump 抓 HTTP 流量

# 抓取 80 端口 HTTP 明文流量
tcpdump -i eth0 port 80 -A | grep -E "^(GET|POST|HTTP/)"

# 抓取并保存为 pcap 文件(用 Wireshark 分析)
tcpdump -i eth0 port 443 -w https_traffic.pcap -c 1000

# 抓取特定主机的流量
tcpdump -i any host 10.0.0.1 and port 80

# 只抓 SYN 包(分析连接建立)
tcpdump -i eth0 "tcp[tcpflags] & (tcp-syn) != 0"

常见面试问题

Q1: HTTP 和 HTTPS 的区别?

答案

维度HTTPHTTPS
端口80443
加密明文传输TLS/SSL 加密
证书不需要需要 CA 证书
性能无额外开销TLS 握手增加延迟
SEO无优势Google 优先收录

HTTPS = HTTP + TLS,在 TCP 连接建立后、HTTP 请求前,增加了 TLS 握手,协商对称密钥后加密通信。

Q2: 502 Bad Gateway 如何排查?

答案

502 表示反向代理(Nginx/LB)无法连接到后端服务。排查步骤:

  1. 后端服务是否存活ss -tlnp | grep PORTsystemctl status 服务
  2. 后端日志:查看应用日志是否有 OOM、崩溃
  3. Nginx 日志/var/log/nginx/error.log,关注 upstream 错误
  4. 连接被拒:防火墙、安全组、SELinux
  5. 超时配置proxy_connect_timeoutproxy_read_timeout
  6. 资源耗尽:后端端口、文件描述符、内存

Q3: 如何用 curl 排查 HTTPS 证书问题?

答案

# 查看完整 TLS 握手信息
curl -v https://example.com 2>&1 | grep -A 10 "SSL connection"

# 查看证书详情
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | \
openssl x509 -text -noout | head -20

# 常见证书错误:
# - SSL certificate problem: certificate has expired → 证书过期
# - SSL certificate problem: unable to get local issuer certificate → 缺少中间证书
# - SSL: no alternative certificate subject name matches → 域名不匹配

Q4: HTTP/2 相比 HTTP/1.1 的优势?

答案

  1. 多路复用:单连接上并行传输多个请求/响应,解决了 HTTP/1.1 的队头阻塞
  2. 头部压缩(HPACK):减少重复头部传输,降低带宽消耗
  3. 二进制分帧:更高效的协议解析
  4. Server Push:服务端主动推送资源
  5. 流优先级:可以设置请求优先级

Nginx 开启 HTTP/2

listen 443 ssl http2;

相关链接