diff --git a/app/lib/DeployHelper.php b/app/lib/DeployHelper.php index 569eb37..851f765 100644 --- a/app/lib/DeployHelper.php +++ b/app/lib/DeployHelper.php @@ -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, ], ], diff --git a/app/lib/deploy/aws.php b/app/lib/deploy/aws.php index 73b0ccc..1909668 100644 --- a/app/lib/deploy/aws.php +++ b/app/lib/deploy/aws.php @@ -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);