支持直接部署证书到AWS ACM

This commit is contained in:
Hanada 2025-05-12 00:43:33 +08:00
parent dcc440c1f9
commit f8add88e3d
2 changed files with 42 additions and 9 deletions

View File

@ -1371,7 +1371,7 @@ class DeployHelper
'name' => 'AWS',
'class' => 2,
'icon' => 'aws.ico',
'note' => '支持部署到Amazon CloudFront',
'note' => '支持部署到Amazon CloudFront、AWS Certificate Manager',
'inputs' => [
'AccessKeyId' => [
'name' => 'AccessKeyId',
@ -1401,14 +1401,24 @@ class DeployHelper
'type' => 'select',
'options' => [
['value'=>'cloudfront', 'label'=>'CloudFront'],
['value'=>'acm', 'label'=>'AWS Certificate Manager'],
],
'value' => 'cloudfront',
'value' => 'acm',
'required' => true,
],
'distribution_id' => [
'name' => '分配ID',
'type' => 'input',
'placeholder' => 'distributions id',
'show' => 'product==\'cloudfront\'',
'required' => true,
],
'acm_arn' => [
'name' => 'ACM ARN',
'type' => 'input',
'placeholder' => '',
'show' => 'product==\'acm\'',
'note' => '在AWS Certificate Manager控制台查看证书的ARN',
'required' => true,
],
],

View File

@ -29,6 +29,16 @@ class aws implements DeployInterface
}
public function deploy($fullchain, $privatekey, $config, &$info)
{
if ($config['product'] == 'acm') {
if (empty($config['acm_arn'])) throw new Exception('ACM ARN不能为空');
$this->get_cert_id($fullchain, $privatekey, $config['acm_arn'], true);
} else {
$this->deploy_cloudfront($fullchain, $privatekey, $config, $info);
}
}
private function deploy_cloudfront($fullchain, $privatekey, $config, &$info)
{
if (empty($config['distribution_id'])) throw new Exception('分配ID不能为空');
$certInfo = openssl_x509_parse($fullchain, true);
@ -55,8 +65,15 @@ class aws implements DeployInterface
$this->log('分配ID: ' . $config['distribution_id'] . ' 证书部署成功!');
}
private function get_cert_id($fullchain, $privatekey, $cert_id = null)
private function get_cert_id($fullchain, $privatekey, $cert_id = null, $acm = false)
{
if ($acm === true && $cert_id == null) {
throw new Exception('ACM ARN不能为空');
}
$certificates = explode('-----END CERTIFICATE-----', $fullchain);
$cert = $certificates[0] . '-----END CERTIFICATE-----';
$client = new AWSClient($this->AccessKeyId, $this->SecretAccessKey, 'acm.us-east-1.amazonaws.com', 'acm', '', 'us-east-1', $this->proxy);
if (!empty($cert_id)) {
@ -65,19 +82,20 @@ class aws implements DeployInterface
'CertificateArn' => $cert_id
]);
// 如果成功获取证书信息说明证书存在直接返回cert_id
if (isset($data['Certificate'])) {
$this->log('证书已存在' . $cert_id);
if (isset($data['Certificate']) && trim($data['Certificate']) == trim($cert)) {
$this->log('证书已是最新ACM ARN' . $cert_id);
return $cert_id;
} else {
$this->log('证书已过期或被删除,准备更新或者重新上传');
}
} catch (Exception $e) {
if ($acm === true) {
throw new Exception('获取证书信息失败请检查ACM ARN是否正确' . $e->getMessage());
}
$this->log('证书已被删除:' . $cert_id. ',准备重新上传');
}
}
$this->log('证书尚未存在开始上传到AWS ACM');
$certificates = explode('-----END CERTIFICATE-----', $fullchain);
$cert = $certificates[0] . '-----END CERTIFICATE-----';
$certificateChain = '';
if (count($certificates) > 1) {
// 从第二个证书开始,重新拼接中间证书链
@ -98,6 +116,11 @@ class aws implements DeployInterface
$param['CertificateChain'] = base64_encode($certificateChain);
}
// 如果是ACM则添加ARN参数用于更新证书
if ($acm === true) {
$param['CertificateArn'] = $cert_id;
}
$client = new AWSClient($this->AccessKeyId, $this->SecretAccessKey, 'acm.us-east-1.amazonaws.com', 'acm', '', 'us-east-1', $this->proxy);
try {
$data = $client->request('POST', 'CertificateManager.ImportCertificate', $param);