一、背景小故事

笔者手里有个朋友交给我去日常运维项目是PHP+微信小程序,部署在Linux系统上。

这个项目是用宝塔面板去进行日常的可视化运维管理,用起来蛮香的。

如不清楚宝塔的同学,可以自行了解,这里就不详细说明。

宝塔是一款简单好用的服务器运维面板,并且永久免费。

我们都知道, 小程序请求的后端接口,要求是https协议的。所以后端服务器得配置上SSL证书。

我接手之前,这个项目的SSL证书是直接购买的,而且也要到期了。当时,我对宝塔面板也是第一次接触,不是特熟悉。经过一番摸索,看到宝塔面板提供Let's Encrypt这样免费的证书。这个证书有个缺点就是只有3个月的免费期限,到期后需要再去续期。

经过一番折腾,就给网站安排上了这个免费的证书。而且宝塔面板在这里也有明确提示:将在距离到期时间一个月内尝试自动续签

看到那个提示后,发现这个证书可以一直免费使用,那倒是省钱又省心了。

隔了3个月后,老板发来一条消息说:网站不正常了,给我看看呗

经过我一顿熟悉操作分析,排查服务器,排查应用,并利用fiddler抓包工具去进行抓包分析后,确定是Https协议到期导致的问题。

然后我在SSL配置界面上,手动去点续签,等了一会儿,续签成功。网站又可以正常访问,告诉老板完美解决。

又经过一段时间后,老板又发来一条消息说,网站又不正常,再给我看看什么问题。

我一看到消息,知道又翻车了。不过这次我是轻车熟路,直接去手动点了一下续签,解决。

......

就这样,重复了很多次。

这样长久下去,也不是办法。

二、萌动想法

我得想出一个法子来解决这个问题。毕竟我们都是一枚程序员,专门去解决生活中出现的重复劳动力。

既然点一下续签,就可以解决证书到期问题。那我们能不能在程序里用定时任务+模拟请求来自动续签?

我就开始构想一下实现思路:

第一步:我们需要拿到续签按钮触发的后端服务接口及请求参数,后续能模拟请求。

第二步:验证接口是否可以直接请求成功,是否需要权限验证?经过验证,需要先登陆,才能请求成功。

第三步:还需要一个定时任务功能。经过确认 宝塔面板自带有任务计划功能。

带着这样的想法,开始去尝试实现,过程中有遇到很多问题,就不详细说明,主要都是在写Shell脚本构造请求参数传递。

我就直接上解决方案供同学们参考。

三、方案实践

3.1 找到续签请求接口

接口地址:http://IP:8888/ssl?action=Renew_SSL

如果我们直接请求该接口,会发现需要登陆,不能直接请求成功。

3.2 设置宝塔 API接口

经过查阅资料,宝塔面板提供了API接口,用密钥key生成token后,再发起请求就可以,而不需要用户名和密码。我们能方便直接使用宝塔里面的任何API接口。

面板设置 =》打开 API接口,拿到密钥key,并配置IP白名单。IP可以直接添加服务器IP。

而且宝塔也提供了多个版本的API接口 Demo样例,可以很方便的集成。

样例地址:https://www.bt.cn/bbs/thread-20376-1-1.html

我比较熟悉Java,也就下载的JavaDemo研究的。

package com.raysonfang.bt.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest; /**
* 宝塔API测试
*
* @author fanglei
* @date 2021/02/21 10:44
**/
public class BTTest {
public static void main(String[] args)
{
try {
String btSign = "宝塔API密钥";
String url = "http://IP:8888/ssl?action=Renew_SSL";
String timestamp = System.currentTimeMillis() + "";
String md5Sign = getMd5(btSign);
String temp = timestamp+md5Sign;
String token = getMd5(temp);
String json = "request_time="+timestamp+"&request_token="+token;
String responseText = sendPost(url,json);
System.out.println(responseText);
} catch (Exception e) {
e.printStackTrace();
}
} public static String getMd5(String str) throws Exception
{
try {
// 生成一个MD5加密计算摘要
MessageDigest md = MessageDigest.getInstance("MD5");
// 计算md5函数
md.update(str.getBytes());
// digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
// BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
return new BigInteger(1, md.digest()).toString(16);
} catch (Exception e) {
throw new Exception("MD5加密出现错误,"+e.toString());
}
} public static String sendPost(String url, String param) {
PrintWriter out = null;
BufferedReader in = null;
StringBuffer result = new StringBuffer();
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "text/xml,text/javascript,text/html,application/json");
conn.setRequestProperty("connection", "Keep-Alive");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
} catch (Exception e) {
System.out.println("发送 POST 请求出现异常!"+e);
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
ex.printStackTrace();
}
}
return result.toString();
}
}

下载demo 研究请求参数构成,并调试成功。

3.3 设置定时任务,模拟请求

宝塔 直接提供有计划任务功能,我们先看看能不能实现我们想要的功能,如果不能,我们再想其他办法解决。

我看了任务类型有:Shell脚本, 备份网站,备份数据库,日志切割,释放内存,访问URL。

其中 Shell脚本访问URL这两种任务类型跟我们想要的很接近,其他的都不怎么适合。

访问URL这种类型也可以排除,是因为这里采用直接配置URL,适合无动态参数,无权限验证的URL。

那剩下的就只有Shell脚本来实现。

我们知道Shell脚本也是一种编程语言脚本,那我们就用它来模拟请求了。

经过几个小时的研究,把shell脚本写出来。还是很费劲,对于Shell脚本里的参数传递语法不怎么熟悉,也反复去尝试,才摸索清楚。

#!/bin/bash

# 获取时间戳
cur_timestamp=$((`date '+%s'`*1000+`date '+%N'`/1000000))
# 宝塔密钥
api_sk='uSth3rmADQ9Np5Zyhxxxxxxxxxxxxxxx'
# 密钥MD5加密
key=`echo -n $api_sk|md5sum|cut -d" " -f1`
# 生成token
request_token=`echo -n $cur_timestamp$key|md5sum|cut -d" " -f1`
# 构造请求参数,并通过curl发送请求
curl -i -X POST -d "request_token=$request_token&request_time=$cur_timestamp" http://ip:8888/ssl?action=Renew_SSL

把Shell脚本的密钥和IP进行替换,就可以直接去任务计划添加上,然后手动执行一下看看 是否可以运行成功

注意:第一次添加任务后,需要手动点执行,并在日志去查看是否执行成功

至此,以后可以放心交给程序自动续签。

四、总结

也许官方已经解决了自动续签的问题,而我这个也许是个偏方,但这里面包含抓包,定时任务,接口鉴权,Shell脚本等知识运用

宝塔面板配置Let's Encrypt证书自动续签失效及解决方案的更多相关文章

  1. 宝塔面板配置阿里云SSL证书流程

    阿里云SSL证书申请过程就不在这里说了 1 先下载阿里云成功申请的SSL证书 解压后 有3个文件 2  找到宝塔面板的 站点设置  找到SSL设置 3 找到其他证书 用文本打开.key文件  复制里面 ...

  2. 宝塔面板如何有效的清除SSL证书以及缓存

    一:关闭SSL 我们先关闭SSL证书,这个大家都会的吧.如图: 二:证书夹 网站配置的证书夹,我们删除掉,如图: 三:寻找SSL证书路径 网站配置里有一路径我们看下:如下 ssl_certificat ...

  3. 使用宝塔面板 配置nginx 访问ftp服务器下面的图片

    如果 你在服务器上 运行war项目 可以在tomcat 配置访问的: tomcat 也贴出来吧! 一.tomca配置访问,需要更改配置文件server.xml ,如果找不到,自己好好找一下  一般在 ...

  4. Nginx 通过certbot 配置let's encrypt 证书 【转载,整理】

    重要目录:/usr/local/certbot,/var/log/letencrypt,/etc/letencrypt

  5. oneinstack如何安装ssl证书和配置Let's Encrypt免费SSL证书教程汇总(转)

    OneinStack包含以下组合:lnmp(Linux + Nginx+ MySQL+ PHP) LNMP安装SSL安全证书 部署HTTPS:https://www.gworg.com/ssl/309 ...

  6. WordPress安装篇(2):用宝塔面板在Windows上安装WordPress

    上一篇文章介绍了如何使用PHPStudy工具在Windows Server环境安装WordPress,接下来介绍一款更加强大的部署WordPress的集成工具--宝塔面板.宝塔面板不仅提供免费版本,还 ...

  7. [转]部署Let’s Encrypt免费SSL证书&&自动续期

    最近公司网站要用https,从自己摸索到找到国内的免费证书到选购正式的收费证书,最后老板说:太贵!不要.一脸懵逼的听老板提到Let's Encrypt证书,没办法,用呗.之前是有一些了解,国外发布的一 ...

  8. 宝塔面板设置腾迅COS自动备份网站

    之前写了如何配置腾迅云COS并挂载到服务器中,今天看到宝塔面板中有腾迅云COS的插件,不过研究了下,只是将COS绑定在宝塔面板中,不能自动备份,需要用到宝塔的计划任务功能 1.下载腾迅云COS插件 2 ...

  9. 宝塔面板安装SSL证书

    2016年阿里云与国内证书颁发机构天威诚信推出了基于Symantec(赛门铁克)的免费SSL证书,有需要免费SSL证书产品的可以前往阿里云进行申请. 申请地址:阿里云云盾证书服务—Symantec免费 ...

随机推荐

  1. nginx教程<一>

    2020最新Nginx教程全面讲解教程,感觉讲的很不错但是需要有docker基础,因为是基于docker快速搭建的nginx. 1.为什么要学习Nginx 肯定是工作和业务需求催生的学习需要哈哈,不过 ...

  2. SignalR入坑笔记

    什么是SignalR ASP.NET Core SignalR 是一个开源库,它简化了向应用程序添加实时 web 功能的功能. 实时 Web 功能使服务器端代码能够即时将内容推送到客户端. ASP.N ...

  3. C++typename的由来和用法

  4. A - A Gifts Fixing

    t组询问,每次给出数列长度n 以及两个长度为n的数列{ai​}和{bi​}. 有三种操作:ai​−1, bi​−1以及ai​,bi​同时− 1 -1−1. 问最少多少步以后可以让两个数列变成常数数列. ...

  5. 宝塔Linux面板FTP无法连接的解决办法

    我使用的是阿里云服务器,需要在安全组设置中,对22.21端口放行,并且被动端口(39000 - 40000)也需要处于放行状态(即是指在阿里云安全组的添加端口范围为 39000/40000 的设置) ...

  6. 最大子阵 DP or 前缀和orb暴力 能过

    在一个给定的n*m二维矩阵中求一个子矩阵元素和的最大值. 思路: 1:一个二维矩阵由两个点可以确定,枚举两个点,取子矩阵最大值. 2:在一维矩阵中,求一个序列的最大子段,利用 f[i]=max(f[i ...

  7. 2020牛客暑期多校训练营(第二场) F.Fake Maxpooling (单调队列)

    题意:有一个\(n\)x\(m\)的矩阵,\(A_{i,j}=lcm(i,j)\),对于每个\(k\)x\(k\)的子矩阵,其最大元素贡献给答案,求答案的最大值. 题解:矩阵构成我们直接\(i*j/g ...

  8. Linux 查看系统日志 ,查看服务日志

    journalctl 查看系统日志参数 -f 表示日志跟中-u 指定的是 unit 指定要查看的服务日志,如果不指定的话会显示所有服务的日志 journalctl -f -u 要查看的服务日志 jou ...

  9. kubernetes进阶(六)k8s平滑升级

    当我们遇到K8S有漏洞的时候,或者为了满足需求,有时候可能会需要升级或者降级版本, 为了减少对业务的影响,尽量选择在业务低谷的时候来升级: 首先准备好文件:我这里选择的是内网文件服务器上下载的,请自行 ...

  10. 忘记Mysql的root用户密码处理方法(以mysql 5.5.33为例)

    1.修改mysql服务器的脚本 ~]#vi /etc/rc.d/init.d/mysqld #找到$bindir/mysqld_safe --datadir="$datadir" ...