TLS/SSL协议负责在传输层建立加密通道,但安全性高度依赖服务端的具体配置。一个常见误区是认为只要申请并安装了证书,HTTPS就足够安全。事实上,如果服务器仍然启用TLS 1.0或SSL 3.0,攻击者可以通过降级攻击迫使客户端使用弱协议;如果密码套件中包含NULL或EXPORT算法,流量可能被解密。因此,安全配置需要从协议版本、密码套件、证书和扩展机制多个维度同时收紧。

一、只保留TLS 1.2与TLS 1.3,关闭过时协议版本
TLS协议版本是安全性的第一道门槛。SSL 2.0与SSL 3.0早已被证实存在设计缺陷,TLS 1.0与TLS 1.1则依赖过时的密码学构造,容易受到BEAST、POODLE等攻击。现代浏览器和操作系统已经默认优先使用TLS 1.2和TLS 1.3,因此服务器不应再为极少数旧客户端保留弱协议。关闭旧版本不仅能消除大量降级攻击面,还能满足PCI DSS等合规要求。Nginx中可以通过 ssl_protocols 指令明确指定协议版本,只保留 TLSv1.2 与 TLSv1.3。
值得注意的是,TLS 1.3在握手机制上做了大幅简化,去除静态RSA密钥交换,只保留前向安全的ECDHE与DHE,并且密码套件不再包含对称加密与MAC算法,而是统一使用AEAD模式。这意味着启用TLS 1.3后,即使长期私钥泄露,历史会话也无法被解密。但客户端兼容性仍需评估。对于仍在使用旧版Android或Windows 7系统自带IE的访问占比,可以通过访问日志中的User-Agent与协议版本字段统计。如果占比很低,应当果断关闭TLS 1.0和TLS 1.1;如果暂时无法关闭,至少将TLS 1.2设为最高优先级,并强制服务器优先选择高版本。
下面是一个Nginx的协议版本配置示例,只开放TLS 1.2和TLS 1.3,并启用服务器端优先顺序。
ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on;
Apache中可以使用以下指令达到类似效果:
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLHonorCipherOrder on
通过命令行可以验证旧协议是否已关闭。执行如下命令连接TLS 1.1端口,如果握手失败说明配置生效:
openssl s_client -connect ipipp.com:443 -tls1_1
如果返回错误信息如 handshake failure,则说明服务器已正确拒绝弱协议。
二、筛选高强度密码套件,禁用弱算法与CBC模式
密码套件决定了密钥交换、身份认证、对称加密与消息认证的具体算法组合。选错密码套件会让整条加密通道形同虚设。必须禁用的类别包括:NULL加密、EXPORT导出级加密、RC4流加密、3DES、匿名Diffie-Hellman以及使用CBC分组模式的SHA-1套件。CBC模式在TLS记录层中使用MAC-then-Encrypt结构,容易遭受Padding Oracle类攻击,如POODLE、Lucky13等。攻击者可以反复探测密文中的填充字节,逐步还原明文。现代配置应当只允许AEAD模式,例如AES-GCM或CHACHA20-POLY1305,这类模式自带完整性校验,能够有效规避Padding Oracle风险。
密钥交换算法同样重要。优先使用ECDHE,也就是椭圆曲线临时Diffie-Hellman,保证每次会话都有独立的临时密钥,实现前向安全。RSA密钥交换虽然仍然可用,但不具备前向安全性,应尽量避免作为首选。推荐的Nginx密码套件列表如下,按服务器优先级排序:
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305'; ssl_ecdh_curve X25519:secp384r1:secp256r1; ssl_dhparam /etc/nginx/dhparam.pem;
Apache对应配置如下:
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305 SSLOpenSSLConfCmd Curves X25519:secp384r1:secp256r1
对于TLS 1.3,密码套件已经被大幅简化,不再需要像TLS 1.2那样手动拼接长列表。TLS 1.3只支持 TLS_AES_128_GCM_SHA256、TLS_AES_256_GCM_SHA384 和 TLS_CHACHA20_POLY1305_SHA256 三种套件,全部基于AEAD。因此只要正确启用TLS 1.3,即可避免大部分传统密码套件风险。如果使用Nginx 1.17.1以上版本或Apache 2.4.36以上版本,可以直接使用默认TLS 1.3套件,无需额外配置。
三、证书、私钥与关键扩展机制的安全管理
证书配置的核心是证书链完整、私钥权限严格、签名算法足够强。使用Let’s Encrypt、DigiCert、GlobalSign等机构签发的证书时,需要确保服务器返回完整的中间证书链,否则部分客户端无法完成证书路径验证。私钥文件应设置为仅root可读,例如权限400。签名算法应选择SHA-256,禁止使用SHA-1。RSA证书建议至少2048位,有条件的可以切换为ECDSA P-256证书以减少握手开销。
HSTS(HTTP严格传输安全)是防止SSL剥离攻击的关键扩展。它通过响应头告诉浏览器在指定时间内只能通过HTTPS访问该站点,即使用户手动输入HTTP地址,浏览器也会自动升级为HTTPS。这一机制极大地缩小了中间人攻击的窗口。Nginx配置示例如下:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Apache使用:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
OCSP装订(OCSP Stapling)可以减少客户端对CA服务器的证书吊销状态查询,提升握手速度并保护用户隐私。启用后,服务器定期获取OCSP响应并将其随证书一起发送给客户端,客户端无需单独连接CA。配置时需要指定完整的证书链文件,以便服务器正确验证OCSP响应。Nginx开启方式为 ssl_stapling on、ssl_stapling_verify on 和 ssl_trusted_certificate 指向完整证书链。同时建议关闭会话票证或定期轮换会话票证密钥,因为固定的会话票证密钥一旦泄露,攻击者可以解密已捕获的会话。
四、常见攻击与配置核查方法
理解常见TLS/SSL攻击有助于理解为什么某些配置必须关闭。BEAST攻击利用TLS 1.0中CBC模式的IV可预测性;POODLE利用SSL 3.0填充校验的缺陷;FREAK和Logjam分别针对导出级RSA与弱Diffie-Hellman参数;ROBOT针对RSA PKCS#1 v1.5填充缺陷。这些攻击的共同点是都依赖过时协议、弱密码套件或弱密钥交换参数。只要按照前文配置禁用TLS 1.0/1.1、只用AEAD套件并生成足够强度的DH参数,就能有效阻断这些攻击向量。
生成自定义DH参数有助于避免Logjam类攻击。推荐使用2048位或更高的安全素数,例如命令:
openssl dhparam -out /etc/nginx/dhparam.pem 2048
然后在Nginx中通过 ssl_dhparam 引用该文件。完成配置后,应当进行核查。命令行工具 openssl s_client 可以查看协议与证书信息,nmap --script ssl-enum-ciphers 可以枚举服务器支持的密码套件并标注强度。更直观的方式是使用testssl.sh或Qualys SSL Labs提供的在线扫描服务,这类工具会给出协议、密码套件、证书链、HSTS和OCSP装订的详细评分。
最终的安全基线可以总结为:仅启用TLS 1.2与TLS 1.3,仅使用AEAD密码套件,优先选择ECDHE前向安全,证书链完整且私钥权限最小化,开启HSTS与OCSP装订,并定期重新扫描验证。安全配置不是一次性工作,随着新攻击方法和OpenSSL漏洞的出现,需要持续关注更新并调整参数。仅有这样,HTTPS才能真正提供端到端的机密性与完整性保护,而不是一张无法兑现的安全凭证。