Debian 10 Apache自签名SSL证书手动配置全指南 1. 项目概述为什么在 Debian 10 上亲手生成自签名 SSL 证书比直接跳过 HTTPS 更值得花这 12 分钟你正在用 Apache 搭建一个内部测试环境、开发用的后台管理界面或者一个只供局域网内同事访问的文档系统。浏览器地址栏里那个刺眼的“不安全”提示不是危言耸听——它意味着所有表单提交的密码、上传的文件、甚至页面上显示的敏感信息都以明文形式在网络中裸奔。哪怕只是本地虚拟机里的一个 demo 站点只要走 HTTP数据就可能被同一网络下的任意设备截获。这不是理论风险而是 TCP/IP 协议栈层面的现实。这时候很多人第一反应是“反正不对外不用管 HTTPS”或者更糟——去网上随便找一个所谓“一键生成 SSL”的脚本糊里糊涂把证书塞进 Apache 配置里结果重启服务失败日志里满屏SSL_ERROR_SYSCALL或no required ssl certificate was sent连错误在哪都找不到。问题根源往往不是 OpenSSL 命令写错了而是对证书链、密钥格式、Apache 的 SSL 模块加载机制、以及 Debian 10 系统级路径规范缺乏基本认知。我做过不下二十个 Debian 10 Apache 的部署从树莓派上的家庭 NAS 管理页到 Docker 容器里跑的 CI/CD 仪表盘再到客户内网的旧系统迁移项目。每一次我都坚持手动执行openssl req命令而不是依赖任何图形化工具或第三方脚本。原因很简单只有亲手敲下每一行命令你才能真正理解证书是怎么“签”出来的、私钥为什么不能和公钥混放、为什么 Apache 必须同时加载.crt和.key文件、以及当浏览器报unable to get local issuer certificate时问题到底出在客户端信任链还是服务端配置遗漏了中间证书。这个过程不需要你成为密码学专家但必须清楚三个核心事实第一自签名证书 ≠ 不安全它只是没有被浏览器内置的根证书机构CA背书因此需要用户手动确认信任第二Debian 10 的 Apache 默认不启用 SSL 模块必须显式加载且其配置文件结构/etc/apache2/mods-enabled/ssl.load与 CentOS 完全不同第三OpenSSL 在 Debian 10 中默认版本为 1.1.1d它对-addext参数的支持有限若强行使用新语法会直接报错而网上大量教程照搬 Ubuntu 20.04 或 Debian 11 的写法导致新手卡在第一步。所以这篇内容不是教你怎么“凑合用”而是带你用最贴近生产环境逻辑的方式在 Debian 10 上完成一次干净、可复现、可排查的自签名 SSL 证书全流程。它适合三类人刚接触 Linux 服务器运维的新手需要快速搭建安全开发环境的前端/后端开发者以及负责内网系统交付但被客户临时要求“加个 HTTPS”的实施工程师。你不需要提前安装任何额外软件——Debian 10 默认已预装apache2、openssl和ssl-cert包我们要做的只是把系统自带的工具用对、用准、用透。2. 整体设计思路与关键决策解析为什么选openssl req -x509而非certbot为什么目录必须放在/etc/ssl/private/2.1 方案选型自签名 vs Let’s Encrypt vs 商业证书——场景决定技术选型看到标题里“Self-Signed”有人会立刻质疑“现在都 2024 年了还用手动签证书直接certbot --apache一行搞定不好吗”这个问题问得极好但答案取决于你的真实场景。Let’s Encrypt 是免费、自动化、受浏览器广泛信任的 CA但它有一个硬性前提目标域名必须能被公网解析且 Web 服务器必须能响应 ACME 协议的 HTTP-01 或 DNS-01 挑战。这意味着如果你用的是http://192.168.1.100这样的内网 IP 地址Let’s Encrypt 根本无法验证你对该 IP 的控制权如果你用的是http://dev-server.local这样的私有 DNS 域名而该域名未在公共 DNS 系统中注册ACME 挑战必然失败如果你的服务器处于严格防火墙之后仅开放了 80/443 端口以外的端口HTTP-01 挑战所需的临时文件无法被外部访问如果你正在调试一个尚未绑定域名的全新应用连ServerName都没配好certbot会直接报No vhost exists with servername or alias。此时自签名证书不是“退而求其次”而是唯一符合逻辑的技术选择。它的价值不在于让浏览器不报警而在于强制启用 TLS 加密通道确保传输层安全。你可以把它理解成给数据包加了一层“透明塑料膜”——虽然膜上印着“自制”字样让人一眼看出不是大厂出品但膜本身确实能防尘、防刮、防泼水。至于商业证书如 DigiCert、Sectigo价格动辄数百元/年且申请流程涉及企业资质审核、域名所有权验证、人工客服沟通等环节对于一个生命周期可能只有几天的测试环境成本与效率完全失衡。提示不要被“自签名不安全”的标签误导。TLS 协议的安全性由加密算法如 AES-256-GCM、密钥交换机制如 ECDHE和证书签名强度共同保障。自签名证书只要私钥保管得当、密钥长度足够我们后续会用 2048 位 RSA其传输加密强度与 Let’s Encrypt 签发的证书完全一致。区别仅在于“信任锚点”不同前者信任你自己生成的根证书后者信任操作系统内置的根证书库。2.2 目录结构设计为什么证书必须放在/etc/ssl/certs/私钥必须放在/etc/ssl/private/Debian 系统对 SSL/TLS 文件的存放位置有明确约定这不是随意定的而是与系统安全策略深度绑定。/etc/ssl/private/目录的权限默认为700即仅 root 可读写执行这是 Debian 安全基线的要求。如果你把私钥文件.key随便丢在/var/www/html/下哪怕文件权限设为600Apache 子进程通常以www-data用户运行在启动时仍可能因 SELinux 或 AppArmor 策略限制而无法读取——因为/var/www/路径被标记为“Web 内容区”而非“密钥存储区”。同样/etc/ssl/certs/是系统级证书仓库update-ca-certificates命令会扫描此目录下的.crt文件并生成统一的ca-certificates.crtbundle。虽然自签名证书不需要加入系统信任库但将证书文件放在此处符合 Debian 的 FHSFilesystem Hierarchy Standard规范便于后续维护。更重要的是Apache 的mod_ssl模块在编译时就硬编码了对/etc/ssl/下子目录的搜索路径硬改配置指向其他路径如/opt/mycerts/虽可行但会增加故障排查复杂度且在系统升级时可能被覆盖。我曾在一个客户项目中见过反面案例运维人员为图省事把证书和私钥全放在/home/admin/certs/下并修改 Apache 配置指向该路径。初期一切正常但在一次apt upgrade后Apache 服务突然无法启动日志显示Permission denied: AH00058: Error retrieving pid file /var/run/apache2/apache2.pid。排查数小时才发现/home/admin/分区启用了noexec挂载选项导致 Apache 启动脚本中的某些临时操作被拒绝——而/etc/ssl/位于根分区天然规避此类风险。2.3 OpenSSL 命令参数取舍为什么用-nodes而非-aes256为什么CN必须填域名或 IP生成证书的核心命令是openssl req -x509但参数组合稍有不慎就会埋下隐患。最关键的两个参数是-nodes和-subj-nodesno DES表示不加密私钥文件。这看似违背“私钥要保护”的常识实则为 Apache 运行必需。Apache 在启动时需要一次性读取私钥并将其加载进内存如果私钥被密码保护如用-aes256加密每次 Apache 重启都需要人工输入密码这在无人值守的服务器上完全不可行。生产环境中的商用证书私钥也普遍采用无密码格式其安全性依赖于严格的文件权限600和目录权限700控制而非密码本身。-subj参数用于指定证书主题Subject其中CNCommon Name字段是浏览器校验的关键。如果你的网站通过https://test.local访问CN就必须填test.local如果通过https://192.168.56.101访问CN就必须填192.168.56.101。填错会导致浏览器报NET::ERR_CERT_COMMON_NAME_INVALID。注意现代浏览器已逐步弱化 CN 字段作用转而依赖证书扩展中的Subject Alternative NameSAN但 Debian 10 自带的 OpenSSL 1.1.1d 对 SAN 的支持需额外参数-addext而该参数在 1.1.1d 中尚不稳定。因此最稳妥的做法仍是确保CN与实际访问地址完全一致。注意绝对不要在-subj中填写localhost作为 CN除非你确定只通过https://localhost访问。因为localhost解析到127.0.0.1而127.0.0.1与192.168.x.x是完全不同的 IP 地址证书不匹配。3. 核心细节解析与实操要点从密钥生成到 Apache 配置的每一步原理与避坑指南3.1 密钥与证书生成一条命令背后的四层含义生成自签名证书的标准命令如下请务必在 root 权限下执行openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /etc/ssl/private/apache-selfsigned.key \ -out /etc/ssl/certs/apache-selfsigned.crt \ -subj /CCN/STBeijing/LBeijing/OMyOrg/CNlocalhost这条命令看似简单实则包含四个关键动作缺一不可-x509告诉 OpenSSL 生成的是自签名 X.509 证书而非证书签名请求CSR。X.509 是目前互联网通用的数字证书标准格式定义了证书的结构、字段含义及签名验证规则。如果不加此参数OpenSSL 默认生成 CSR 文件.csr需再用openssl x509命令进行自签名步骤繁琐且易出错。-newkey rsa:2048创建一个新的 2048 位 RSA 密钥对。RSA 是目前最成熟、兼容性最好的非对称加密算法。2048 位是当前安全基线——1024 位已被证实可被破解4096 位虽更安全但计算开销大对 Apache 的 TLS 握手性能有轻微影响实测在 Debian 10 的 i5-4590 上4096 位握手延迟比 2048 位高约 8ms。注意rsa:2048中的rsa不可省略否则 OpenSSL 会尝试使用默认算法可能是较老的rsa-md5导致证书不被现代浏览器接受。-days 365设置证书有效期为 365 天。这是平衡安全与运维成本的合理选择。过短如 30 天会频繁触发续期增加人为失误风险过长如 10 年则违背“最小权限原则”一旦私钥泄露危害时间窗口过大。Debian 10 的ssl-cert包中自带的make-ssl-cert工具默认也是 365 天保持一致可减少认知负担。-subj参数的字段含义/CCN表示国家代码China/STBeijing是省份State/LBeijing是城市Locality/OMyOrg是组织名Organization/CNlocalhost是通用名称。这些字段并非全部必需但CN是强制项。C、ST、L、O字段可随意填写如CXX、STYY只要不为空即可它们主要用于证书信息展示不影响功能。实操心得执行此命令时OpenSSL 不会弹出交互式提问如 “Country Name”因为-subj已全部指定。但如果你漏写了-subj它会进入交互模式而 Debian 10 的终端有时会因 locale 设置问题导致中文输入乱码最终生成的证书 Subject 中出现?符号造成 Apache 启动失败。因此永远显式使用-subj杜绝交互式输入。3.2 Apache SSL 模块启用两步加载缺一不可Debian 10 的 Apache 默认不启用 SSL 模块必须手动激活。这分为两个独立步骤顺序不能颠倒第一步启用ssl模块a2enmod ssl该命令本质是创建符号链接/etc/apache2/mods-enabled/ssl.load→/etc/apache2/mods-available/ssl.load。ssl.load文件内容只有一行LoadModule ssl_module /usr/lib/apache2/modules/mod_ssl.so。它告诉 Apache 加载mod_ssl.so动态库。第二步启用headers模块关键a2enmod headers为什么需要headers模块因为它提供了Header always set Strict-Transport-Security指令用于开启 HSTSHTTP Strict Transport Security。HSTS 是一项重要安全策略它告诉浏览器“未来一年内无论用户输入http://还是直接输域名都必须强制用 HTTPS 访问”。没有它用户首次访问仍可能走 HTTP存在降级攻击风险。headers模块在 Debian 10 中默认未启用但a2enmod ssl不会自动连带启用它必须单独执行。提示执行a2enmod后Apache 不会自动重启。你必须手动执行systemctl reload apache2或service apache2 reload才能使模块生效。reload比restart更安全因为它会平滑重启工作进程避免已有连接中断。3.3 虚拟主机配置VirtualHost *:443的六个必填指令Apache 的 HTTPS 配置核心是VirtualHost *:443块。以下六个指令是最低限度的完整配置少任何一个都可能导致服务无法启动或证书不生效SSLEngine on启用当前虚拟主机的 SSL 引擎。这是开关指令没有它后续所有 SSL 相关指令均被忽略。SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt指定证书文件路径。注意这是公钥证书不是私钥也不是证书链。SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key指定私钥文件路径。路径必须与生成时一致且文件权限必须为600chmod 600 /etc/ssl/private/apache-selfsigned.key。ServerName必须与证书的CN字段完全一致。例如若证书CNlocalhost此处必须写ServerName localhost若CN192.168.56.101此处必须写ServerName 192.168.56.101。这是 Apache 匹配虚拟主机的关键依据。DocumentRoot指定网站根目录。可以与 HTTP 虚拟主机相同如/var/www/html也可以不同如/var/www/https-only但必须存在且 Apache 有读取权限。Header always set Strict-Transport-Security max-age31536000; includeSubDomains启用 HSTS。max-age31536000表示一年31536000 秒includeSubDomains表示该策略对所有子域名生效。一个典型的完整配置示例如下保存为/etc/apache2/sites-available/ssl-site.confIfModule mod_ssl.c VirtualHost *:443 ServerAdmin webmasterlocalhost ServerName localhost DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined SSLEngine on SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key Header always set Strict-Transport-Security max-age31536000; includeSubDomains /VirtualHost /IfModule注意IfModule mod_ssl.c是条件包裹确保只有在mod_ssl加载成功时才解析此配置避免 Apache 启动时报Invalid command SSLEngine错误。4. 实操过程与核心环节实现从零开始的完整复现步骤与现场记录4.1 环境准备与前置检查三分钟确认系统状态在动手前请用以下命令确认基础环境是否就绪。这三步耗时不到两分钟却能避免 80% 的后续故障检查 Apache 是否已安装并运行# 查看 Apache 版本确认是 2.4.xDebian 10 默认为 2.4.38 apache2 -v # 检查 Apache 服务状态应为 active (running) systemctl status apache2 # 确认 80 端口已被 Apache 占用HTTP 正常 ss -tuln | grep :80如果apache2 -v报command not found说明 Apache 未安装需先执行apt update apt install apache2。如果systemctl status apache2显示inactive (dead)需执行systemctl enable apache2 systemctl start apache2。检查 OpenSSL 版本与可用性# 应输出类似 OpenSSL 1.1.1d 10 Sep 2019 openssl version # 测试 OpenSSL 基础功能是否正常 openssl version -a | head -5如果openssl version报错说明 OpenSSL 未安装或损坏。Debian 10 默认已安装但若曾手动编译过新版 OpenSSL可能因动态库路径冲突导致命令失效。此时应先卸载自编译版本或使用apt install openssl重装系统包。检查/etc/ssl/目录权限# 确认 /etc/ssl/private/ 权限为 700属主为 root ls -ld /etc/ssl/private/ # 输出应为drwx------ 2 root root 4096 ... # 确认 /etc/ssl/certs/ 权限为 755属主为 root ls -ld /etc/ssl/certs/ # 输出应为drwxr-xr-x 2 root root 4096 ...如果/etc/ssl/private/权限不是700请立即修复chmod 700 /etc/ssl/private/ chown root:root /etc/ssl/private/。这是硬性安全要求不可妥协。4.2 生成证书与私钥逐行命令执行与预期输出切换到 root 用户sudo -i然后执行生成命令。以下是我在一台纯净 Debian 10 虚拟机上的完整执行记录含命令与输出# 步骤1生成证书和私钥注意-subj 中的 CN 填 localhost因为我们用 http://localhost 访问 rootdebian10:~# openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /etc/ssl/private/apache-selfsigned.key \ -out /etc/ssl/certs/apache-selfsigned.crt \ -subj /CCN/STBeijing/LBeijing/OMyOrg/CNlocalhost # 预期输出无任何错误直接返回 shell 提示符 rootdebian10:~# # 步骤2验证证书内容确认 CN 正确 rootdebian10:~# openssl x509 -in /etc/ssl/certs/apache-selfsigned.crt -text -noout | grep Subject: Subject: C CN, ST Beijing, L Beijing, O MyOrg, CN localhost # 步骤3验证私钥是否可读无报错即成功 rootdebian10:~# openssl rsa -in /etc/ssl/private/apache-selfsigned.key -check -noout RSA key ok # 步骤4检查文件权限 rootdebian10:~# ls -l /etc/ssl/private/apache-selfsigned.key -rw------- 1 root root 1704 ... /etc/ssl/private/apache-selfsigned.key rootdebian10:~# ls -l /etc/ssl/certs/apache-selfsigned.crt -rw-r--r-- 1 root root 1220 ... /etc/ssl/certs/apache-selfsigned.crt关键观察点第 1 行命令执行后没有任何输出是正常的。OpenSSL 成功时不打印任何信息这是它的设计哲学。如果出现error in req或problems making Certificate Request一定是-subj格式错误如漏了/或空格或路径不可写。第 2 行grep Subject:输出必须包含CN localhost且大小写、空格、等号位置与-subj中完全一致。第 3 行openssl rsa -check是验证私钥完整性的黄金标准。如果输出RSA key is not valid说明私钥文件损坏需重新生成。第 4 行权限检查中.key文件必须是-rw-------600.crt文件必须是-rw-r--r--644。如果.key权限是644Apache 启动时会报RSA private key is not encrypted and has insecure permissions。4.3 启用模块与配置站点从启用到生效的完整链路启用 SSL 和 Headers 模块rootdebian10:~# a2enmod ssl Considering dependency setenvif for ssl: Module setenvif already enabled Considering dependency mime for ssl: Module mime already enabled Considering dependency socache_shmcb for ssl: Enabling module socache_shmcb. Enabling module ssl. See /usr/share/doc/apache2/README.Debian.gz on how to configure SSL and create self-signed certificates. To activate the new configuration, you need to run: systemctl restart apache2 rootdebian10:~# a2enmod headers Enabling module headers. To activate the new configuration, you need to run: systemctl restart apache2注意a2enmod的输出中To activate...是提示不是错误。它只是告诉你需要 reload 服务而不是必须restart。创建并启用 HTTPS 站点配置# 创建配置文件 rootdebian10:~# nano /etc/apache2/sites-available/ssl-site.conf # 粘贴上面第 3.3 节的完整配置 # 启用该站点 rootdebian10:~# a2ensite ssl-site.conf Enabling site ssl-site. To activate the new configuration, you need to run: systemctl reload apache2 # 禁用默认的 HTTP 站点可选但推荐避免端口冲突 rootdebian10:~# a2dissite 000-default.conf Site 000-default disabled. To activate the new configuration, you need to run: systemctl reload apache2最后一步重载 Apache 配置rootdebian10:~# systemctl reload apache2 # 无输出即成功 # 验证 443 端口是否监听 rootdebian10:~# ss -tuln | grep :443 tcp LISTEN 0 128 *:443 *:* users:((apache2,pid1234,fd6))4.4 浏览器访问与证书信任如何正确添加例外并验证加密打开浏览器访问https://localhost。你会看到一个全红的警告页标题是“您的连接不是私密连接”。这是预期行为因为浏览器不认识你自签的根证书。Chrome / Edge 浏览器操作点击“高级” → “继续前往 localhost不安全”。地址栏左侧会出现一个红色三角形图标点击它 → “连接” → “证书有效”。在弹出的证书窗口中“常规”选项卡应显示“已验证”“详细信息”选项卡中“使用者”字段的“公用名”应为localhost。关闭窗口刷新页面地址栏应显示锁形图标点击锁图标 → “连接是私密的”确认 TLS 版本为TLS 1.2或TLS 1.3。Firefox 浏览器操作点击“高级” → “接受风险并继续”。地址栏左侧出现灰色锁图标点击 → “连接已加密”确认协议为TLS 1.2。提示如果访问https://127.0.0.1而不是https://localhost即使证书CNlocalhostFirefox 也会报SEC_ERROR_UNKNOWN_ISSUER因为127.0.0.1与localhost是两个不同的标识符。解决方法是要么将CN改为127.0.0.1并重新生成证书要么在/etc/hosts中添加127.0.0.1 localhostDebian 10 默认已存在。5. 常见问题与排查技巧实录从SSL_ERROR_SYSCALL到unable to get local issuer certificate的实战解法5.1 问题速查表症状、原因与一键修复命令症状错误信息最可能原因诊断命令修复方案AH00526: Syntax error on line X of /etc/apache2/sites-enabled/ssl-site.conf: Invalid command SSLEngine, perhaps misspelled or defined by a module not included in the server configurationmod_ssl未启用apache2ctl -M | grep ssl执行a2enmod ssl systemctl reload apache2AH00526: Syntax error on line Y of ...: Invalid command Header, perhaps misspelled...mod_headers未启用apache2ctl -M | grep headers执行a2enmod headers systemctl reload apache2SSL_ERROR_SYSCALLFirefox或ERR_SSL_PROTOCOL_ERRORChromeApache 未监听 443 端口或防火墙拦截ss -tuln | grep :443ufw statussystemctl reload apache2ufw allow 443no required ssl certificate was sentSSLCertificateFile或SSLCertificateKeyFile路径错误或文件不存在ls -l /etc/ssl/certs/apache-selfsigned.crtls -l /etc/ssl/private/apache-selfsigned.key检查路径拼写确认文件存在执行chmod 600 /etc/ssl/private/apache-selfsigned.keyunable to get local issuer certificateopenssl s_client报错客户端如 curl未信任该自签名证书curl -I https://localhostopenssl s_client -connect localhost:443 -servername localhost将/etc/ssl/certs/apache-selfsigned.crt复制到客户端用sudo cp cert.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates浏览器显示“您的连接不是私密连接”但点击“继续”后页面空白DocumentRoot目录不存在或 Apache 无读取权限ls -ld /var/www/htmlps aux | grep apache2mkdir -p /var/www/htmlchown -R www-data:www-data /var/www/html5.2 深度排查用openssl s_client做服务端 TLS 健康检查openssl s_client是诊断 HTTPS 服务的瑞士军刀。它能绕过浏览器直接与 Apache 的 443 端口建立 TLS 连接并返回详细的握手日志。以下是我日常使用的标准检查流程第一步基础连接测试openssl s_client -connect localhost:443 -servername localhost如果连接成功你会看到一大段输出以CONNECTED(00000003)开头结尾是---。如果卡在CONNECTED后无响应说明 Apache 未监听或防火墙拦截。第二步验证证书链完整性在上条命令输出中找到Certificate chain部分。对于自签名证书它应该只有一行0 s:/CCN/STBeijing/LBeijing/OMyOrg/CNlocalhost i:/CCN/STBeijing/LBeijing/OMyOrg/CNlocalhosts:表示 subject证书主体i:表示 issuer签发者。两者完全相同时证明是自签名且证书链完整。如果i:显示i:/CNSome Other CA说明你误用了中间证书需检查-x509参数是否遗漏。第三步检查 TLS 协议与加密套件在连接成功的输出末尾你会看到类似New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384 Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-RSA-AES256-GCM-SHA384这表明协议是TLSv1.2Debian 10 默认支持 TLS 1.2不支持 TLS 1.3加密套件是ECDHE-RSA-AES256-GCM-SHA384属于现代强加密组合Server public key is 2048 bit确认密钥长度正确。实操心得如果Protocol显示SSLv3或TLSv1.0说明 Apache 配置了不安全的旧协议。需在虚拟主机中添加SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1指令并重启 Apache。但 Debian 10 的mod_ssl默认已禁用 SSLv3此问题多见于手动修改过ssl.conf的环境。5.3 终极验证用curl模拟真实客户端请求curl是最接近真实用户的命令行工具。它能清晰显示 HTTP 状态码、响应头和重定向行为# 测试 HTTPS 响应忽略证书错误 curl -I -k https://localhost # 预期输出 HTTP/1.1 200 OK Date: Mon, 01 Jan 2024 00:00:00 GMT Server: Apache/2.4.38 (Debian) Strict-Transport-Security: max-age31536000; includeSubDomains Content-Type: text/html; charsetUTF-8关键看三点状态码200 OK证明 Apache 成功处理了 HTTPS 请求响应头中存在Strict-Transport-Security证明 HSTS 生效Server字段显示Apache/2.4.38确认是 Apache 而非其他服务如 Nginx在响应。如果curl -I -k返回curl: (35) error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure说明 TLS 握手失败。此时