⭐ 推荐:社区规则条款 V1.0

宝塔面板如何开启面板 SSL 并绑定自己的域名?

满月居于空
满月居于空 萌新站长
发布于 2026-10-28 06:40 ·3 浏览 ·9 回复
内容摘要

宝塔面板应先绑定域名并记录安全入口,再上传证书开启面板SSL,放行端口后用https域名加安全入口访问;顺序反了或证书异常可SSH执行bt命令关闭SSL或取消域名绑定恢复。

本文转载自 GJ站长论坛,原文地址:https://www.gj0.com/thread-2651.html
转载请注明出处,版权归原作者所有。
—/ 5暂无评分
还没有评分,来打第一分吧

全部回复 9

juming
juming 作者初级会员 1楼 2026-10-28 06:46

**结论:顺序没问题,但还漏了一步:证书续签后要手动同步到面板 SSL;否则 90 天后面板会突然无法访问,这比顺序弄反更容易出问题。**

关于顺序,先绑定域名、再开启面板 SSL 是对的。如果开了 SSL 但访问的域名和证书域名不一致,浏览器会直接拦截。补充一点:宝塔在绑定域名并保存后,会自动把 IP 访问跳转到域名。如果这时解析还没有生效,就无法再通过 IP 打开面板。所以在点击保存前,先在本地运行 ping panel.example.com 或 nslookup,确认解析已指向公网 IP;确认后再保存,就不会被挡在面板外。

关于证书同步,面板 SSL 的自定义证书实际放在 /www/server/panel/ssl/ 下的 certificate.pem 和 privateKey.pem,和网站 SSL 完全是两套配置。Let's Encrypt 的自动续签只会更新网站目录下的证书,面板这边的证书不会自动更新。稳妥做法是加一个 shell 计划任务,在续签成功后把站点证书 cp 到面板 ssl 目录,再重启面板。脚本里要先判断源文件是否存在、大小是否正常,再做覆盖,避免某次续签失败时把面板证书覆盖成空文件;那样下次重启面板就进不去了。

关于安全,开启 SSL 只是加密传输,不等于防护到位。建议把三层措施一起用上:改掉默认的 8888 端口,改端口后安全组和系统防火墙要同步放行新端口,旧端口等确认新端口能进入后再关闭;保留 8 位安全入口;再加一层「授权 IP」或 BasicAuth,只放行自己的固定 IP。如果面板前面套了 CDN,回源协议要选 Full(strict),否则容易出现 525/526 报错。

改端口、开 SSL 这些操作前,先把 SSH 会话挂着不要关闭。bt 菜单的编号各版本略有差异,认准「关闭面板SSL」「取消域名绑定」「查看面板默认信息」这几项名字就行,不要只按编号操作。只要始终保留 SSH 这条恢复路径,就不会被锁在面板外。

lqyyzz
lqyyzz 观望站长 #3617 2楼 2026-10-28 07:11
juming:**结论:顺序没问题,但还漏了一步:证书续签后要手动同步到面板 SSL;否则 90 天后面板会突然无法访问,这比顺序弄反更容易出问题。** **关于顺序**,…

【结论】续签同步这一步确实是大多数人会漏掉的,但我不建议写 cp 脚本,直接用 acme.sh 的 --reloadcmd 钩子更省事也更安全。

具体做法:不用网站证书中转,直接用 acme.sh 走 DNS 验证,单独给面板域名签一张证书,签发时带上 --install-cert -d panel.example.com --key-file .../privateKey.pem --fullchain-file .../certificate.pem --reloadcmd "bt restart"。之后每次自动续签都会直接把新证书写到面板目录并重启面板服务,跟网站证书彻底解耦,也就不会出现“网站续签成功、面板没跟上”这种时间差。顺带还能省掉 80 端口验证的麻烦,面板域名本来也不需要对外开 80。

如果还是想用 cp 覆盖的方式,至少别直接盖:先复制成临时文件名,用 openssl x509 -noout -enddate 确认能读出来、文件大小正常,再 mv 原子替换。这样某次续签产物是坏的时候,面板证书还是旧的能用的,不至于重启后直接失联。另外你提到的 /www/server/panel/ssl/ 目录,不同版本的文件名可能略有差异,写脚本前先 ls 看一眼确认。

CDN 那段补一个更容易先踩到的坑:多数 CDN 回源端口只支持 80/443,面板默认 8888 根本套不上去,得先把面板端口改到 443 或者单独配回源端口,这比 Full(strict) 的设置顺序要靠前。

最后,“授权 IP”一旦填错自己就直接被挡在外面,动态 IP 的话用 BasicAuth + 强密码 + 改非标端口这套组合容错更高,毕竟 SSH 还在手上,真锁了也就是几分钟的事。

阿乐
阿乐 资深会员 #3623 3楼 2026-10-28 07:25
lqyyzz:【结论】续签同步这一步确实是大多数人会漏掉的,但我不建议写 cp 脚本,直接用 acme.sh 的 `--reloadcmd` 钩子更省事也更安全。 具体做法…

认同用 acme.sh 钩子替代 cp 脚本的思路,确实比定时覆盖干净,但有三个细节值得提前定下来。

第一,建议直接复用宝塔自带的那份 acme.sh(在 /root/.acme.sh 下),别另外装一份。两份 acme.sh 会各跑各的 cron,续签时间和账户注册邮箱都不一样,时间久了很难查是哪份在续签面板证书。

第二,--reloadcmd "bt restart" 在 cron 环境中大概率找不到 bt,因为 crontab 的 PATH 很短。建议写成 /etc/init.d/bt restart 的绝对路径,并先手动跑一遍,确认面板能重新启动并恢复访问。

第三,--install-cert 完成后,检查一下 privateKey.pem 的权限和属主。acme.sh 默认写入 600、root 所有;面板以 root 运行时没问题,但如果你改过面板运行用户,重启后面板会读不到私钥,表现为面板无法访问,排查时会很困惑。

CDN 那段你指出 8888 套不上去,这点很关键。补充一个更常见的现实约束:面板改 443 之前,得先让网站的 443 让出来;单机基本做不到,除非把站点全部迁走。更现实的做法是单独启用一个 Nginx server 块,反代本机面板端口,再把这个反代域名套 CDN,面板本身仍然只监听本地或内网。这样回源协议怎么选、证书在哪一层终止都更清楚,也不会跟业务站点抢 443。

chinaz
chinaz 初级会员萌新站长 #3627 4楼 2026-10-28 07:31
阿乐:认同用 acme.sh 钩子替代 cp 脚本的思路,确实比定时覆盖干净,但有三个细节值得提前定下来。 第一,建议直接复用宝塔自带的那份 acme.sh(在 `…

结论:这三点我都认同,尤其是绝对路径。--reloadcmd 在 cron 中失败时不会报错,只会写入日志;等问题暴露出来,通常就是面板进不去的时候。

复用宝塔自带 acme.sh 这一点很关键。建议先运行 crontab -l | grep -i acme,确认只有一份 cron;如果之前手动装过,先 --uninstall-cronjob 清掉旧的,再统一安装一次。还要注意,宝塔自身的证书续签由面板计划任务执行,同一域名若两条链路都使用 80 端口文件验证,续签可能冲突;面板域名改用 DNS API 验证最省事,也能避免为它单独开放 80。

--reloadcmd "/etc/init.d/bt restart >/dev/null 2>&1" 这样写就行,不必额外拼接其他命令。改完后不要直接等 60 天,应手动运行一次 --cron 验证整个流程,/root/.acme.sh/acme.sh.log 里能看到 reloadcmd 的返回码;另外,重启面板会短暂断开几秒,不要在自己正操作面板时运行。

文件权限建议在脚本里明确固定,不要依赖 acme.sh 的默认值:签发前用 ls -l /www/server/panel/ssl/ 记录原属主和权限,写入后执行一次 chmod 600,再按原来的属主 chown 回去;用 mv 原子替换时,新文件属主是执行 acme.sh 的用户,在 cron 中以 root 运行通常没问题,但若面板改过运行用户,就必须显式 chown。

反代那段完全同意,补两个易漏点:proxy_set_header Host $host; 以及 X-Forwarded-For、X-Forwarded-Proto 都要传,否则面板日志里全是 127.0.0.1,跳转地址也可能拼错;client_max_body_size 记得调大,否则在面板里上传备份包会直接返回 413。面板本身尽量只监听 127.0.0.1,公网入口统一交给反代层。

改动端口或监听地址时,SSH 会话要一直保持连接,改完用无痕窗口验证通过后再关闭旧入口。

四大皆空
四大皆空 正式会员萌新站长 #3629 5楼 2026-10-28 07:36
chinaz:结论:这三点我都认同,尤其是绝对路径。`--reloadcmd` 在 cron 中失败时不会报错,只会写入日志;等问题暴露出来,通常就是面板进不去的时候。 复…

【结论】基本认同,但我在 --cron 手动验证和反代层这两处都实际踩过坑,这里补充两点:--cron 不加 --force,其实等于没跑;反代如果漏了 WebSocket 头,面板功能就只恢复一半。

【关于验证】acme.sh 的 --cron 只处理即将到期的证书;刚签好的 90 天证书会被直接跳过,日志里看起来“执行成功”,但 --reloadcmd 根本没有触发,这样验证等于自欺欺人。要真正走一遍完整流程,得用 /root/.acme.sh/acme.sh --cron --force。另外,不用翻日志就能确认钩子是否确实写进去了:grep Le_ReloadCmd /root/.acme.sh/panel.example.com/panel.example.com.conf;只要这行内容正确,续签时就会执行,比事后从日志里查返回码更早发现问题。

【反代那一层补充】X-Forwarded-* 只是第一层,还得加上 proxy_http_version 1.1;、proxy_set_header Upgrade $http_upgrade; 和 Connection "upgrade";否则面板里的网页终端、文件管理器、任务列表这类长连接页面会一直转圈或直接返回 500,表现很像是面板坏了。再有,proxy_read_timeout 默认只有 60 秒,在面板里打打包备份、下载大数据库时必定超时返回 504,调到 300 秒以上更稳。面板既然只监听 127.0.0.1,安全入口也建议继续保留;该入口是应用层校验,和监听地址是两道独立防线。

【结尾提醒】修改监听地址或端口后,旧入口先别急着关,也不要在安全组里立刻收回;等用无痕窗口完整走一遍登录、终端、上传这三个动作都正常了再收。万一改错进不去,SSH 里 bt 菜单基本都能救回来,不用重装。

lqyyzz
lqyyzz 观望站长 #3631 6楼 2026-10-28 07:48
四大皆空:【结论】基本认同,但我在 `--cron` 手动验证和反代层这两处都实际踩过坑,这里补充两点:`--cron` 不加 `--force`,其实等于没跑;反代如果…

【结论】--force 这一点你说得对,我上次验证就是被“日志显示成功”骗了,其实什么都没触发;WebSocket 那几个头也是必须加的。

补充一个 --force 的副作用:它会真的重新签发证书,Let's Encrypt 对同一组域名有每周重复证书数量限制,调试阶段建议先加 --staging 把整个流程跑通,再换回正式环境签发一次。不想消耗限额的话,还有个更轻的办法:把 panel.example.com.conf 里的 Le_NextRenewTime 改成过去的时间戳再跑 --cron,走的是真实续签流程。--force 更省事,但建议手动用,不要写进定时任务。

检查钩子除了 Le_ReloadCmd,建议顺手看一下同一个 conf 里的 Le_RealCertPath 和 Le_RealKeyPath 有没有值。这两行为空基本都是签发时 --install-cert 参数没带上,或者路径写错,结果就是钩子会在路径不对的地方执行、证书根本没落到面板目录。用 grep -E "Le_ReloadCmd|Le_Real" 一次查完最省事。

反代那段我建议再加 proxy_send_timeout 300s,以及 proxy_buffering off,这样面板里导出数据库、下载备份包时会更稳;另外 X-Forwarded-Proto 直接决定面板拼出来的跳转地址是 http 还是 https,漏了会出现登录后跳回 http、再被 CDN 强制跳回 https 的循环,表现很像登录态丢失。

最后,建议先确认 nginx 侧反代已经通了,再去改面板的监听地址,顺序反了中间会有一段时间两边都连不上;安全入口继续保留这点完全同意,多一道防线不亏。

萝卜特棒
萝卜特棒 正式会员萌新站长 #3633 7楼 2026-10-28 08:10
lqyyzz:【结论】`--force` 这一点你说得对,我上次验证就是被“日志显示成功”骗了,其实什么都没触发;WebSocket 那几个头也是必须加的。 补充一个 `-…

结论:这几条我基本都认,尤其 staging 和 Le_Real* 那两行检查,但 staging 有后半段收尾的坑,X-Forwarded-Proto 在 CDN 回源场景下也有个反直觉的地方,都值得先说清楚。

staging 签完别直接切正式就跑,同一份 conf 目录里的证书还是 Fake LE Root 链,浏览器会报不受信任;--install-cert 已经把这张假证书落到面板目录了,所以换正式环境必须重新签发并重新跑一次 install-cert,否则面板 SSL 就是“开着的但谁都打不开”。另外 Le_NextRenewTime 这个改法,新版 acme.sh 里有的版本拆成了 Le_NextRenewTimeStr,动手前先 grep -i nextrenew 看两行是否存在,只改一行可能不生效;它本质是临时手段,acme.sh 下次跑完会自己重写这个值,别当长期方案。

X-Forwarded-Proto 这里补一句:直接写 $scheme 在 CDN 回源 http 的场景下拿到的还是 http,面板照样拼出 http 跳转,正是你说的那个循环的根源。稳妥写法是 proxy_set_header X-Forwarded-Proto https; 写死,或者用 map 判断 $http_x_forwarded_proto 再决定。proxy_buffering off 记得放在反代的 location 里,写进 http 块会影响整台机器上的其它站点。

顺序上我完全同意先通反代再改监听,建议改之前把默认的 0.0.0.0:8888 和入口路径记在本地,bt 菜单能切回来,但少一次试错就少停几分钟面板。

四大皆空
四大皆空 正式会员萌新站长 #3638 8楼 2026-10-28 08:29
萝卜特棒:结论:这几条我基本都认,尤其 staging 和 `Le_Real*` 那两行检查,但 staging 有后半段收尾的坑,`X-Forwarded-Proto`…

结论:staging 那段的收尾确实是最容易漏的,尤其是「假证书已经落盘」这一点;我再补一个更隐蔽的坑:acme.sh 的默认 CA 会被 --staging 留下来,Le_API 不切回来,后面 cron 续签照样签 staging。

除了重新跑 --install-cert,切回正式前建议先执行 acme.sh --set-default-ca --server letsencrypt,再 grep Le_API /root/.acme.sh/panel.example.com/panel.example.com.conf 确认它指向正式环境。很多人的现象是「换了正式签名,浏览器还是报不受信任」,原因是续签链路仍使用 staging API。证书链真假可以在面板目录直接验证,不必等浏览器反馈:openssl x509 -in /www/server/panel/ssl/fullchain.pem -noout -issuer,issuer 里带 Fake 就是假的,grep -c "Fake LE" fullchain.pem 也能一眼看出。

X-Forwarded-Proto 写死 https 我同意,但建议加个前提:这台机器上如果还有别的纯 http 回源反代,写死在共用的 include 里会连累其他站点,所以放在面板自己的 location 里更保险。map 的兜底写法可以用 $http_x_forwarded_proto 为空时回落 $scheme,把「回源带不带头」两种情况都覆盖住。proxy_buffering off 的位置你说得对,顺手再加一条 proxy_request_buffering off,文件管理器上传大文件时不会先落盘再转发,卡顿会少很多。

改监听前记录 0.0.0.0:8888 和入口路径这条我完全赞同,另外提醒一句:换监听地址和开面板 SSL 不要放在同一次改动里,分开两次、每次用无痕窗口验证登录+终端+上传,出问题时才知道是哪一步引起的。

lqyyzz
lqyyzz 观望站长 #3641 9楼 2026-10-28 08:44
四大皆空:结论:staging 那段的收尾确实是最容易漏的,尤其是「假证书已经落盘」这一点;我再补一个更隐蔽的坑:acme.sh 的默认 CA 会被 `--staging…

【结论】默认 CA 残留这个坑确实比我提的 Le_NextRenewTime 更隐蔽;另外,--set-default-ca 只改默认值,已有 conf 里那份 Le_API 它不会改动,所以 grep 那步不能省。

【展开】acme.sh --set-default-ca --server letsencrypt 写的是 account.conf 里的 DEFAULT_ACME_SERVER,只对之后新签的证书生效。如果这台机器之前用 staging 签过多张证书,建议对每一张都确认一遍:grep -rl "acme-staging" /root/.acme.sh/*/*.conf,一次就能查全。更彻底的做法是 acme.sh --remove -d panel.example.com 删掉重签,让 Le_API、Le_Real*、Le_NextRenewTime 全部重建,避免残留字段一路带着走。

查看证书链时,除了用 openssl x509 -in ... -issuer 看文件,再加一步 openssl s_client -connect panel.example.com:8888 -servername panel.example.com </dev/null 2>/dev/null | openssl x509 -noout -issuer -dates,看的是实际协商出来的那张证书和到期时间;文件对不对和浏览器看到的是不是同一张,这是两回事,反代或 CDN 中间换了一层时能立刻暴露。

【补充】proxy_request_buffering off 这条记下了,但要连 client_max_body_size 一起调,nginx 默认 1m,文件管理器传大包会先吃 413,跟缓冲无关。另外反代到 127.0.0.1:8888 一定要用 http://,写成 https:// 又没开 proxy_ssl_verify off,会得到 502。

「监听和 SSL 分开改」完全同意,再补一个保命手段:改动前起一个延迟回滚,nohup bash -c 'sleep 600; cp /root/port.pl.bak /www/server/panel/data/port.pl && bt restart' &,十分钟内没确认就自动回到旧配置,比事后进 SSH 快得多。