feat: v1.3.9, kms encrypts dns credential

This commit is contained in:
2025-04-05 00:58:16 +08:00
parent b5c142838f
commit a1c7bcba30
5 changed files with 42 additions and 6 deletions

2
Cargo.lock generated
View File

@@ -4,7 +4,7 @@ version = 4
[[package]]
name = "acme-client"
version = "1.3.8"
version = "1.3.9"
dependencies = [
"acme-lib",
"aliyun-openapi-core-rust-sdk",

View File

@@ -1,6 +1,6 @@
[package]
name = "acme-client"
version = "1.3.8"
version = "1.3.9"
authors = ["Hatter Jiang <jht5945@gmail.com>"]
edition = "2018"
description = "Acme auto challenge client, acme-client can issue certificates from Let's encrypt"

View File

@@ -19,7 +19,7 @@ lazy_static! {
pub struct AcmeRequest<'a> {
pub challenge: AcmeChallenge,
// issue, single acme request can only process one supplier
pub credential_supplier: Option<&'a str>,
pub credential_supplier: Option<String>,
pub allow_interact: bool,
pub contract_email: &'a str,
pub primary_name: &'a str,
@@ -69,7 +69,7 @@ pub fn request_acme_certificate(acme_request: AcmeRequest, dns_cleaned_domains:
let dir = opt_result!(Directory::from_url(persist, url), "Create directory from url failed: {}");
let acc = opt_result!(dir.account(acme_request.contract_email), "Directory set account failed: {}");
let mut ord_new = opt_result!( acc.new_order(acme_request.primary_name, acme_request.alt_names), "Create order failed: {}");
let mut dns_client: Option<Box<dyn DnsClient>> = match acme_request.credential_supplier {
let mut dns_client: Option<Box<dyn DnsClient>> = match &acme_request.credential_supplier {
Some(credential_supplier) => Some(
opt_result!(DnsClientFactory::build(credential_supplier), "Build dns client failed: {}")),
None => None,

29
src/kms.rs Normal file
View File

@@ -0,0 +1,29 @@
use reqwest::blocking::{Body, Client, Request};
use reqwest::{Method, Url};
use rust_util::XResult;
use serde::Deserialize;
use serde_json::json;
#[derive(Debug, Deserialize)]
struct DecryptResponse {
value: String,
}
pub fn try_kms_decrypt(ciphertext: &str) -> XResult<String> {
if !ciphertext.starts_with("LKMS:") {
return Ok(ciphertext.to_string());
}
debugging!("Try decrypt: {}", ciphertext);
let body = json!({ "encrypted_value": ciphertext });
let body = serde_json::to_string(&body)?;
let client = Client::new();
let uri = format!("http://{}/{}", "127.0.0.1:5567", "decrypt");
let mut request = Request::new(Method::POST, Url::parse(&uri)?);
let _ = request.body_mut().insert(Body::from(body));
let response = client.execute(request)?;
let response_text = response.text()?;
debugging!("KMS response text: {}", &response_text);
let decrypt_response: DecryptResponse = serde_json::from_str(&response_text)?;
debugging!("Decrypt value: {}", &decrypt_response.value);
Ok(decrypt_response.value)
}

View File

@@ -10,6 +10,7 @@ mod x509;
mod network;
mod statistics;
mod notification;
mod kms;
mod dns;
mod ali_dns;
// mod simple_thread_pool;
@@ -216,7 +217,7 @@ async fn main() -> tide::Result<()> {
let acme_request = AcmeRequest {
challenge: AcmeChallenge::from_str(matches.value_of("challenge-type")),
credential_supplier: matches.value_of("dns-supplier"),
credential_supplier: matches.value_of("dns-supplier").map(ToString::to_string),
allow_interact: matches.is_present("allow-interact"),
contract_email: &email,
primary_name,
@@ -268,7 +269,13 @@ async fn main() -> tide::Result<()> {
warning!("DNS challenge no credential supplier found");
None
}
Some(credential_supplier) => Some(credential_supplier.as_str()),
Some(credential_supplier) => match kms::try_kms_decrypt(credential_supplier) {
Ok(credential_supplier) => Some(credential_supplier),
Err(e) => {
failure!("Decrypt DNS challenge credential supplier failed: {}", e);
None
}
},
}
}
}