CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
DevSecOps 入门/课时/网络安全基础
RawBlame
课时目录12 节

DevSecOps 入门

  1. 01DevSecOps 概览
  2. 02网络安全基础
  3. 03密码学
  4. 04身份与访问
  5. 05应用安全
  6. 06威胁建模
  7. 07云安全
  8. 08容器安全
  9. 09供应链安全
  10. 10检测与 SIEM
  11. 11Incident 响应
  12. 12合规与扫描

网络安全基础

TLS、分段与防火墙。

30 分钟

网络安全基础

这一课你将能做到

  1. 用 openssl s_client 和 curl -v 完整走一遍 TLS 握手过程,说出每一步在交换什么
  2. 在 Nginx 上配置一套合格的 HTTPS(TLS 1.2+、强加密套件、HTTP 强制跳转、HSTS),并用 SSL Labs 验证评分
  3. 解释 VLAN、安全组、防火墙在网络分段中的作用,画出本站(Nginx → Spring Boot → MySQL/Redis)的分段拓扑

为什么要学

你的 Java 应用不是活在真空里:浏览器到 Nginx、Nginx 到 Spring Boot、Spring Boot 到 MySQL/Redis,每一跳都是网络。不懂网络,就看不懂「为什么开了 HTTPS 还被劫持」「为什么数据库不能暴露公网」这些基本问题。

人话:网络是敌我分界线。TLS 保证「你和我说的话别人听不懂」;防火墙和分段保证「不该通的路一律不通」。本站的事故里,一半以上本质是网络配置问题——Redis 裸奔公网、MySQL 0.0.0.0 监听、TLS 版本太老被降级攻击。

先建立图像

一次 HTTPS 请求的完整旅程:

浏览器 ──① DNS 查询──→ DNS 服务器 (拿到 IP)
   │
   ├──② TCP 三次握手──→ Nginx (443 端口)
   │    SYN → SYN+ACK → ACK
   │
   ├──③ TLS 握手──→ Nginx
   │    ClientHello (支持的 TLS 版本/套件)
   │    ServerHello + 证书链
   │    密钥交换 → 会话密钥
   │
   ├──④ 加密 HTTP 请求──→ Nginx
   │
   └── Nginx ──⑤ 反向代理(明文HTTP)──→ Spring Boot :8080
                                          │
                                          ├──⑥ TCP──→ MySQL :3306
                                          └──⑦ TCP──→ Redis :6379

网络分段的正确姿势:

┌─ 公网 ────────────────────────────┐
│  只暴露 Nginx 的 80/443            │
└──────────┬────────────────────────┘
           │ (DMZ 区)
┌──────────▼────────────────────────┐
│  Spring Boot :8080                 │
│  安全组:只允许 Nginx 服务器 IP 访问 │
└──────────┬────────────────────────┘
           │ (内网数据区)
┌──────────▼────────────────────────┐
│  MySQL :3306 / Redis :6379         │
│  安全组:只允许应用服务器 IP 访问    │
│  bind 127.0.0.1 或内网网卡          │
└───────────────────────────────────┘

跟着做

步骤 1:观察 TLS 握手

# 看完整握手过程:协议版本、加密套件、证书链
openssl s_client -connect coderoadmap.cn:443 -servername coderoadmap.cn

# 重点看这几行输出:
# Protocol  : TLSv1.3
# Cipher    : TLS_AES_256_GCM_SHA384
# Verify return code: 0 (ok)

用 curl 看简化版:

curl -vI https://coderoadmap.cn 2>&1 | findstr /C:"SSL connection" /C:"subject:" /C:"issuer:"

-servername 参数是 SNI(Server Name Indication):一台 Nginx 托管多个域名证书时,靠它告诉服务器「我要访问哪个域名」。

步骤 2:Nginx 配置合格的 HTTPS

server {
    listen 443 ssl;
    server_name coderoadmap.cn;

    # 证书(用 Let's Encrypt 免费证书)
    ssl_certificate     /etc/letsencrypt/live/coderoadmap.cn/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/coderoadmap.cn/privkey.pem;

    # 只开 TLS 1.2 和 1.3,关掉有漏洞的 SSLv3/TLS1.0/1.1
    ssl_protocols TLSv1.2 TLSv1.3;

    # 强加密套件,禁用弱算法
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
    ssl_prefer_server_ciphers off;  # TLS1.3 下让客户端选

    # HSTS:告诉浏览器以后只走 HTTPS,防降级
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header X-Forwarded-Proto $scheme;  # 让后端知道原始协议
    }
}

# HTTP 强制跳转 HTTPS
server {
    listen 80;
    server_name coderoadmap.cn;
    return 301 https://$host$request_uri;
}

改完验证:

nginx -t && nginx -s reload
curl -I http://coderoadmap.cn   # 应返回 301

再去 ssllabs.com/ssltest 测一下,目标 A 或 A+。

步骤 3:验证 TLS 版本下限

# 这两条应该失败(握手被拒绝),说明老协议已关闭
openssl s_client -connect coderoadmap.cn:443 -tls1_1
openssl s_client -connect coderoadmap.cn:443 -ssl3

# 这条应该成功
openssl s_client -connect coderoadmap.cn:443 -tls1_3

步骤 4:收紧内网服务监听

MySQL 的 my.cnf:

[mysqld]
# 如果 MySQL 和 Spring Boot 同机,只监听回环
bind-address = 127.0.0.1

Redis 的 redis.conf:

bind 127.0.0.1
requirepass 一个足够长的随机密码
# 重命名危险命令,防被拿到后一键 FLUSHALL
rename-command FLUSHALL ""
rename-command CONFIG ""

验证端口暴露面:

# Windows
netstat -ano | findstr LISTENING
# 确认 3306、6379 只绑在 127.0.0.1,不是 0.0.0.0

步骤 5:用防火墙做分段

云服务器用安全组;裸机用防火墙。以 Windows/Linux 通用思路为例,规则分三层:

入站规则(按优先级):
1. 允许 任意来源 → 本机 80/443  (Nginx)
2. 允许 Nginx 服务器IP → 本机 8080 (Spring Boot)
3. 允许 办公网IP段 → 本机 22 (SSH 管理)
4. 拒绝 其余所有入站

原则一句话:默认拒绝,按需放行,而不是默认放行、出事再堵。

讲清楚要点

  1. TLS 握手的本质:用非对称加密(证书里的公钥)安全地协商出一个对称会话密钥,之后的数据用对称加密传输(快)。证书解决「你是谁」,密钥交换解决「话不被偷听」。

  2. HTTPS 不等于绝对安全:它能防传输窃听和篡改,但防不了「两端之一被攻破」「证书签发环节被骗(误签 CA)」「用户无视证书警告点继续」。

  3. 网络分段(Segmentation)是横向移动的克星:攻击者打进 Nginx 服务器,不代表能摸到 MySQL。每段之间默认不通,让一次入侵停在一段。

  4. bind 地址是第一道闸:bind 127.0.0.1 意味着这个端口物理上不可能被外网访问,比任何防火墙规则都可靠。Redis 未授权访问事件的根因几乎全是 bind 0.0.0.0 且无密码。

  5. HSTS 防降级攻击:没有 HSTS 时,攻击者可以把用户的 HTTPS 请求降级成 HTTP 再窃听(SSL Strip)。HSTS 让浏览器记住「这个站只走 HTTPS」。

你可能会懵的地方

  • Nginx 到 Spring Boot 之间要不要也上 HTTPS? 同一台机器或同一内网可信段,通常走明文 HTTP 即可(性能考虑);跨机房、跨 VPC、零信任架构下建议 mTLS(双向 TLS)。判断标准:这条链路上的流量会不会经过你不信任的网络设备。

  • TLS 1.3 和 1.2 差在哪? 1.3 握手从 2 个 RTT 减到 1 个(更快),删掉了所有已知不安全的算法(RSA 密钥交换、CBC 模式、SHA-1),强制前向保密。能开就开。

  • 证书免费和付费有区别吗? 加密强度一样。区别在:有效期(Let's Encrypt 90 天需自动续期 vs 付费 1 年)、是否支持通配符/多域名、赔付保险。技术上免费证书完全够用。

  • 防火墙和安全组是一回事吗? 作用相同,位置不同。安全组是云平台在 hypervisor 层做的(虚拟机外面),防火墙(iptables/Windows Firewall)跑在操作系统里。纵深防御:两层都配。

  • 为什么 HTTP 跳转用 301 而不是 302? 301 是永久跳转,浏览器会缓存,下次直接访问 HTTPS,减少一次可被劫持的 HTTP 请求。配合 HSTS 双保险。

错法对照

错法问题正解
ssl_protocols 包含 TLSv1.0POODLE 等降级攻击只留 TLSv1.2 TLSv1.3
Redis bind 0.0.0.0 无密码公网任何人可读写,勒索高发bind 127.0.0.1 + requirepass
数据库安全组对 0.0.0.0/0 开放全网可探测爆破只放行应用服务器 IP
只配 HTTPS 不配 HSTS 和跳转用户仍可能走 HTTP 被窃听301 跳转 + HSTS 头
Nginx 把 X-Forwarded-* 透传给不可信后端伪造来源 IP 绕过白名单内网可信才透传,或在后端校验

卡点急救

  1. 证书配好浏览器还报「不安全」:九成是证书链不完整——ssl_certificate 要用 fullchain.pem(服务器证书+中间证书),不是 cert.pem。用 openssl s_client 看 Verify return code,21 号错误就是缺链。

  2. Let's Encrypt 续期失败:certbot 续期需要 80 端口可访问做验证。检查:安全组 80 是否放行、Nginx 的 80 跳转规则是否把 /.well-known/acme-challenge/ 也跳走了(要单独放行)。设个 cron/systemd timer 自动续期,别手动。

  3. 开了 TLS1.3 only 后老客户端连不上:某些老旧 Java 客户端(JDK 8 早期版本)、安卓 4.x 不支持 TLS 1.3。生产建议 TLS1.2+1.3 并存,除非确定客户端全可控。

面试常问

  • 描述 TLS 握手过程? ① ClientHello:客户端发支持的 TLS 版本、加密套件列表、随机数。② ServerHello:服务器选定版本和套件,发证书链和随机数。③ 客户端验证证书(CA 签名、有效期、域名匹配),生成预主密钥,用服务器公钥加密发送(或走 ECDHE 交换)。④ 双方用三个随机数算出会话密钥,之后对称加密通信。TLS 1.3 把密钥交换合并进前两步,只需 1-RTT。

  • HTTPS 如何防中间人攻击? 靠 CA 体系:浏览器内置受信 CA 根证书,验证服务器证书链是否由可信 CA 签发、域名是否匹配、是否在有效期。中间人没有合法证书,伪造的证书验签不通过,浏览器报警。前提:用户不无视警告、CA 不被攻破或误签。

  • 什么是网络分段,为什么重要? 把网络按信任级别划分成多个区域(公网/DMZ/应用区/数据区),区域间默认隔离、按需放行。重要性:限制攻击者横向移动——单点被攻破不扩散为全局失守。落地手段:VLAN、安全组、防火墙、bind 地址、零信任微分段。

自测三问

  1. TLS 握手中,非对称加密和对称加密各承担什么角色?为什么不全程用非对称?
  2. 本站的 MySQL 为什么应该 bind 127.0.0.1?如果必须远程访问,正确做法是什么?
  3. HSTS 解决什么攻击?它和 301 跳转是什么关系?

小结一句话

网络安全的地基是三件事:TLS 保证传输机密完整、最小暴露面(bind+防火墙)保证不该通的不通、网络分段保证一次入侵不蔓延。

延伸

  • Mozilla SSL Configuration Generator — 生成各版本 Nginx 的安全配置
  • 下一课:密码学——对称/非对称、哈希、PKI,以及为什么密码必须用 bcrypt 而不是 SHA-256。
加载本节练习…
← 上一课DevSecOps 概览下一课 →密码学