当前位置:首页>Linux>阿里云 Linux 3 部署 HTTPS 踩坑全记录:从「一头雾水」到「万字真香」

阿里云 Linux 3 部署 HTTPS 踩坑全记录:从「一头雾水」到「万字真香」

  • 2026-10-11 08:10:57
阿里云 Linux 3 部署 HTTPS 踩坑全记录:从「一头雾水」到「万字真香」
最近帮朋友在阿里云 ECS 上部署了一个 PHP + MySQL + Apache 的网站,最后一步自然是给它上一把「安全锁」——申请 Let's Encrypt 免费 SSL 证书。本以为用 Certbot 三两下就能搞定,结果硬是被各种奇奇怪怪的报错魔了一整天。趁热打铁,我把整个过程记录成了这篇保姆级教程,希望能帮到有同样遭遇的兄弟。

服务器环境:Alibaba Cloud Linux 3.2104 LTS 64 位Web 环境:Apache 2.4 + PHP 7.x/8.x + MySQL域名:***.fun、zhao.***.fun(及各自 www 前缀),共 4 个子域名目标:申请一张通配符证书覆盖上面四个域名(当然这里是多域名证书),并实现自动续期。


一、工欲善其事,必先利其器——准备工作

在动手敲命令之前,一定要先确认下面这两件事,不然上来就撞墙的概率极高。

  1. 域名解析已生效把 ***.fun 和 zhao.***.fun(及它们的 www)都指向 ECS 的公网 IP,用 ping 或 dig 确认一下解析结果。

  2. 安全组放行 80 和 443 端口登录阿里云控制台 → 安全组规则,入方向放行 TCP 80 和 443,授权对象一般填 0.0.0.0/0(如果只是临时测试可以限定 IP)。同时,如果你的服务器在国内机房,域名必须先完成 ICP 备案,否则 80 端口的请求会被拦截,Certbot 验证会直接挂掉。

  3. Apache 已安装并正常运行没装的话先装一下:

    sudo dnf install httpd -y
    然后启动并设置开机自启
sudo systemctl enable --now httpd

二、安装 Certbot 及 Apache 插件

Alibaba Cloud Linux 3 源自 RHEL,所以包管理器是 dnf,需要先启用 EPEL 仓库。

sudo dnf install epel-release -ysudo dnf install certbot python3-certbot-apache -y

这里我们装了两个包:certbot 本体和 python3-certbot-apache 插件,后者可以帮我们自动修改 Apache 配置,实现一键 HTTPS。但就是这一步,为后面的连环坑埋下了伏笔。


三、第一次尝试「自动配置」就给我来了个下马威

我想着官方推荐用法嘛,走起:

sudo certbot --apache -d ***.fun -d www.***.fun

报错:

NoInstallationError('Cannot find Apache executable apache2ctl',)

查了一下,原来 Certbot 的 Apache 插件内部会查找 apache2ctl 这个可执行文件,但 RHEL 系(包括阿拉云 Linux)的 Apache 服务名叫 httpd,控制脚本是 /usr/sbin/apachectl。解决方法很简单:创建一个软链接。

sudo ln -s /usr/sbin/apachectl /usr/sbin/apache2ctl

再试一次,又报错:

“Could not find configuration root”

我又按照文档尝试了:

sudo certbot --apache --apache-server-root /etc/httpd -d ***.fun -d www.***.fun

依然不行,还是提示找不到 apache2ctl,哪怕我软链接都做了、根目录也指定了,这个插件就是跟我杠上了。

多次折腾后,我决定放弃自动配置,改用更稳的 webroot 模式 手动申请证书。


四、webroot 模式申请证书——这才是正确的打开方式

webroot 的原理很简单:Certbot 往你指定的网站根目录里放一个临时验证文件,然后通过 HTTP 访问这个文件来证明域名是你的。全程不碰 Apache 配置,非常安全。

因为我四个域名分布在两个不同的目录中(主站 ***.fun 根目录是 /var/www,招生子站 zhao.***.fun 根目录是 /var/www/xxx),所以命令要分别指定 webroot:

sudo certbot certonly --webroot \  -w /var/www -d ***.fun -d www.***.fun \  -w /var/www/xxx -d zhao.***.fun -d www.zhao.***.fun \  --email 你的邮箱@qq.com --agree-tos --no-eff-email

结果又红了,全部 404,只有招生站的子域名能过?这就很诡异了。

排查:到底是谁在背后捣鬼?

通过

 sudo apachectl -S

查看虚拟主机配置,我发现了端倪:

port 80 namevhost zhao.***.fun (/etc/httpd/conf.d/sir.conf:1)    alias www.zhao.***.fun    alias ***.fun        ← 这里居然把主站域名当了别名!

原来之前有人在 sir.conf 文件里把 ***.fun 写成了招生站的别名,导致所有访问 ***.fun 的请求全部落到了招生站的根目录 /var/www/xxx,而 Certbot 放在 /var/www/.well-known/ 下的验证文件根本访问不到,所以主站的两个域名一直 404。

修复:

编辑 /etc/httpd/conf.d/sir.conf,找到类似 ServerAlias 那行,把 ***.fun 删掉,只保留 www.zhao.***.fun。同时确保主站自己的配置文件 /etc/httpd/conf.d/high.conf 中只包含这两个别名:

<VirtualHost *:80>    ServerName ***.fun    ServerAlias www.***.fun    DocumentRoot /var/www    <Directory /var/www>        Options Indexes FollowSymLinks        AllowOverride All        Require all granted    </Directory></VirtualHost>

重载 Apache 后,本地测试了一下验证文件,一切正常。再次执行上面的 certbot certonly 命令,成功!

Successfully received certificate.Certificate is saved at: /etc/letsencrypt/live/***.fun/fullchain.pemKey is saved at:         /etc/letsencrypt/live/***.fun/privkey.pemThis certificate expires on 2026-08-05.

看到这个提示的时候,眼泪都快下来了。


五、手动配置 Apache SSL 虚拟主机

证书是拿到了,但 Apache 还不知道怎么用。接下来我们要手动配置 HTTPS 站点了。

首先备份一下系统自带的 SSL 默认配置(避免端口冲突):

sudo mv /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.bak

然后创建主站的 SSL 配置文件

/etc/httpd/conf.d/high-ssl.conf:

<VirtualHost *:443>    ServerName ***.fun    ServerAlias www.***.fun    SSLEngine on    SSLCertificateFile /etc/letsencrypt/live/***.fun/fullchain.pem    SSLCertificateKeyFile /etc/letsencrypt/live/***.fun/privkey.pem    DocumentRoot /var/www    <Directory /var/www>        Options Indexes FollowSymLinks        AllowOverride All        Require all granted    </Directory>    # 如果你的站点需要 PHP,这里根据实际 PHP-FPM 监听方式填写    # <FilesMatch \.php$>    #     SetHandler "proxy:fcgi://127.0.0.1:9000"    # </FilesMatch></VirtualHost>

同样道理,创建招生子站的 SSL 配置

/etc/httpd/conf.d/zhao-ssl.conf把 ServerName 和 DocumentRoot 换成对应的即可。

检查配置时报了个语法错误:SetHandler takes one argument。原来 SetHandler 后面的值要作为一个整体,用引号包起来且中间不能有空格,比如 "proxy:fcgi://127.0.0.1:9000"。改好后再 apachectl configtest 就 OK 了。

重载 Apache:

sudo systemctl reload httpd

打开浏览器访问 https://***.fun,终于看到了绿色小锁!


六、自动续期——免维护的最后一步

Certbot 在安装时理论上会自动配置一个 systemd timer,但我机器上的状态是 inactive (dead)。手动启用一下:

sudo systemctl enable certbot-renew.timer --nowsudo systemctl status certbot-renew.timer

确保状态为 active (waiting) 并且有下一次触发时间。不放心的话还可以再加一条 cron 兜底:

sudo crontab -e# 每周日凌晨 3 点续期并重载 apache0 3 * * 7 /usr/bin/certbot renew --quiet --post-hook "systemctl reload httpd"

最后用 

sudo certbot renew --dry-run

测试一遍,输出 

“Congratulations, all simulated renewals succeeded”

 就说明万事大吉。


七、总结:我踩过的坑,你们绕着走

  1. Certbot 的 Apache 插件在 RHEL 系(含 Alibaba Cloud Linux)上经常水土不服
    遇到报错别硬刚,直接切 webroot 模式手动配置反而更可控。
  2. 虚拟主机别名(ServerAlias)不要乱写
    一个域名的别名配到了其他站点下,就会导致 404 或证书申请卡死。
  3. SetHandler 的语法
    全部参数用英文双引号括起来作为一个整体,中间不能有空格。
  4. 自动续期依赖 systemd timer
    如果发现没起来要手动 enable --now,或者用 crontab 做个兜底。

整个流程走下来,从跌跌撞撞到最终成功,不仅把 HTTPS 搞定了,对 Apache 虚拟主机的运作机制也理解得更深了一层。希望这篇分享能帮你在部署 SSL 的路上少走几段弯路。

如果你也遇到了奇怪的问题,欢迎留言交流,我们一起把坑填平!

最新文章

随机文章