前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[php实现]通过腾讯云Api上传SSL证书

[php实现]通过腾讯云Api上传SSL证书

原创
作者头像
TDP-苏苏
发布2022-03-01 16:27:10
9.1K0
发布2022-03-01 16:27:10
举报
文章被收录于专栏:上云实践笔记

背景

笔者使用的轻量应用服务器安装的Windows系统(集成环境没有更新证书功能),SSL证书是acme.sh生成的多域名证书,有效期90天。因为使用了腾讯云的CDN,每次生成新证书需要手动上传到腾讯云,太麻烦了。既然官方提供了上传证书的Api(UploadCertificate),服务器是php环境,就想用php撸个小工具,实现自动上传SSL证书到腾讯云。

主要思路

acme.sh(计划任务)更新证书 -> 证书更新成功hook工具网址实现上传

核心代码

执行acme.sh时,额外增加如下参数:(5秒延时可取消,网址换成自己脚本存放位置)

代码语言:javascript
复制
--renew-hook "sleep 5s && curl http://127.0.0.1/Qcloud/ssl_update.php"

简版腾讯云SDK文件:Qcloud.php

代码语言:javascript
复制
<?php
//腾讯云SDK

class Qcloud {
	private $SecretId;
	private $SecretKey;
	private $endpoint = "scf.tencentcloudapi.com"; //接口请求域名
	private $service = "scf"; //服务名称
	private $version = "2018-04-16"; //API版本号
	private $region = "ap-shanghai"; //地域参数

	/**
	 * SecretId 腾讯云SecretId
	 * SecretKey 腾讯云SecretKey
	*/
	function __construct($SecretId, $SecretKey){
        $this->SecretId = $SecretId;
        $this->SecretKey = $SecretKey;
    }
    
    /**
     * $api 接口请求域名
    */
    public function SetApi($api){
        $this->endpoint = $api;
        $ex = explode('.', $api);
        $this->service = $ex[0];
        //print_r($ex);
    }
    
    /**
     * $api 服务名称
    */
    public function SetService($ser){
        $this->service = $ser;
    }
    
    /**
     * $api API版本号
    */
    public function SetVersion($ver){
        $this->version = $ver;
    }
    
    /**
     * $api 地域参数
    */
    public function SetRegion($reg=null){
        $this->region = $reg;
    }
	
	public function send_reuqest($action, $param){
		$payload = json_encode($param);
		$time = time();
		$authorization = $this->generateSign($payload, $time);
		$header = [
			'Authorization: '.$authorization,
			'Content-Type: application/json; charset=utf-8',
			'X-TC-Action: '.$action,
			'X-TC-Timestamp: '.$time,
			'X-TC-Version: '.$this->version,
			'X-TC-Region: '.$this->region,
		];
		return $this->curl_post($payload, $header);
	}

	private function generateSign($payload, $time){
		$algorithm = "TC3-HMAC-SHA256";

		// step 1: build canonical request string
		$httpRequestMethod = "POST";
		$canonicalUri = "/";
		$canonicalQueryString = "";
		$canonicalHeaders = "content-type:application/json; charset=utf-8\n"."host:".$this->endpoint."\n";
		$signedHeaders = "content-type;host";
		$hashedRequestPayload = hash("SHA256", $payload);
		$canonicalRequest = $httpRequestMethod."\n"
			.$canonicalUri."\n"
			.$canonicalQueryString."\n"
			.$canonicalHeaders."\n"
			.$signedHeaders."\n"
			.$hashedRequestPayload;
		
		// step 2: build string to sign
		$date = gmdate("Y-m-d", $time);
		$credentialScope = $date."/".$this->service."/tc3_request";
		$hashedCanonicalRequest = hash("SHA256", $canonicalRequest);
		$stringToSign = $algorithm."\n"
			.$time."\n"
			.$credentialScope."\n"
			.$hashedCanonicalRequest;
		
		// step 3: sign string
		$secretDate = hash_hmac("SHA256", $date, "TC3".$this->SecretKey, true);
		$secretService = hash_hmac("SHA256", $this->service, $secretDate, true);
		$secretSigning = hash_hmac("SHA256", "tc3_request", $secretService, true);
		$signature = hash_hmac("SHA256", $stringToSign, $secretSigning);

		// step 4: build authorization
		$authorization = $algorithm
			." Credential=".$this->SecretId."/".$credentialScope
			.", SignedHeaders=content-type;host, Signature=".$signature;

		return $authorization;
	}

	private function curl_post($payload, $header){
		$url = 'https://'.$this->endpoint.'/';
		$ch=curl_init($url);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
		curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_TIMEOUT, 10);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
		$json=curl_exec($ch);
		$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		curl_close($ch);
		if($httpCode==200){
			$arr=json_decode($json,true);
			return $arr['Response'];
		}else{
			return false;
		}
	}
}

受访文件:ssl_upload.php

代码语言:javascript
复制
<?php
include 'Qcloud.php';
$SecretId = 'xxxx';
$SecretKey='xxxxxx';

$param['pbk'] = file_get_contents('证书路径');
$param['pak'] = file_get_contents('私钥路径');

new ssl_upload($param, $SecretId, $SecretKey);

//输出json信息
function msg($msg='ok', $code=200){
	$arr = array(
		'code'=>$code,
		'msg'=>$msg,
	);
	exit(json_encode($arr, JSON_UNESCAPED_UNICODE));
}

//上传ssl证书
class ssl_upload{
	function __construct($opt, $SecretId, $SecretKey){
		$QC = new Qcloud($SecretId, $SecretKey);
		//公共参数
		$api = 'ssl.tencentcloudapi.com';
		$ver = '2019-12-05';
		
		$pbk = $opt['pbk'];
		$pak = isset($opt['pak']) ? $opt['pak']: null;
		$type = isset($opt['type']) ? $opt['type']:'SVR';
		$alias = isset($opt['alias']) ? $opt['alias']:'upload_'.date('Ymd');


		//功能参数
		$action = 'UploadCertificate';          //公共参数 功能
		$param['CertificatePublicKey']=$pbk;    //证书内容
		$param['CertificatePrivateKey']=$pak;   //私钥内容,证书类型为 SVR 时必填,为 CA 时可不填。
		$param['CertificateType']=$type;        //证书类型,默认 SVR。CA = 客户端证书,SVR = 服务器证书。
		$param['Alias']=$alias;                 //备注名称

		$QC->SetApi($api);      //接口请求域名
		$QC->SetVersion($ver);  //API版本号
		$rsp = $QC->send_reuqest($action, $param);

		if(isset($rsp['CertificateId'])){
			//上传成功
			$result = $rsp['CertificateId'];
			msg($result);
		}else if(isset($rsp['Error'])){
			//上传失败
			$code = $rsp['Error']['Code'];
			$msg = $rsp['Error']['Message'];
			msg($msg, $code);
		}else{
			//未知错误
			$msg = $rsp;
			$code = 500;
			msg($msg, $code);
		}
	}
}

后记

其实更新成功后,还可以做一些事情,比如通过Email/短信发送更新成功的信息,甚至可以再写代码,遍历CDN加速的域名,实现自动更换所有网站的ssl证书(主要用到的接口有DescribeDomainsConfigUpdateDomainConfig),可以自行拓展。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 主要思路
  • 核心代码
  • 后记
相关产品与服务
轻量应用服务器
轻量应用服务器(TencentCloud Lighthouse)是新一代开箱即用、面向轻量应用场景的云服务器产品,助力中小企业和开发者便捷高效的在云端构建网站、Web应用、小程序/小游戏、游戏服、电商应用、云盘/图床和开发测试环境,相比普通云服务器更加简单易用且更贴近应用,以套餐形式整体售卖云资源并提供高带宽流量包,将热门软件打包实现一键构建应用,提供极简上云体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档