Skip to content

Commit c8fc789

Browse files
authored
Merge pull request #418 from Dstack-TEE/certbot-auto-zone
certbot: Auto-detect zone
2 parents fbd26a6 + 7aac04a commit c8fc789

File tree

14 files changed

+240
-86
lines changed

14 files changed

+240
-86
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,6 @@ GATEWAY_CERT=${CERBOT_WORKDIR}/live/cert.pem
314314
GATEWAY_KEY=${CERBOT_WORKDIR}/live/key.pem
315315

316316
# For certbot
317-
CF_ZONE_ID=cc0a40...
318317
CF_API_TOKEN=g-DwMH...
319318
# ACME_URL=https://acme-v02.api.letsencrypt.org/directory
320319
ACME_URL=https://acme-staging-v02.api.letsencrypt.org/directory

certbot/cli/src/main.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ struct Config {
6262
acme_url: String,
6363
/// Cloudflare API token
6464
cf_api_token: String,
65-
/// Cloudflare zone ID
66-
cf_zone_id: String,
6765
/// Auto set CAA record
6866
auto_set_caa: bool,
6967
/// List of domains to issue certificates for
@@ -87,7 +85,6 @@ impl Default for Config {
8785
workdir: ".".into(),
8886
acme_url: "https://acme-staging-v02.api.letsencrypt.org/directory".into(),
8987
cf_api_token: "".into(),
90-
cf_zone_id: "".into(),
9188
auto_set_caa: true,
9289
domains: vec!["example.com".into()],
9390
renew_interval: 3600,
@@ -136,7 +133,6 @@ fn load_config(config: &PathBuf) -> Result<CertBotConfig> {
136133
.key_file(workdir.key_path())
137134
.auto_create_account(true)
138135
.cert_subject_alt_names(config.domains)
139-
.cf_zone_id(config.cf_zone_id)
140136
.cf_api_token(config.cf_api_token)
141137
.renew_interval(renew_interval)
142138
.renew_timeout(renew_timeout)

certbot/src/acme_client.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -321,14 +321,14 @@ impl AcmeClient {
321321
let Identifier::Dns(identifier) = &authz.identifier;
322322

323323
let dns_value = order.key_authorization(challenge).dns_value();
324-
debug!("creating dns record for {}", identifier);
324+
debug!("creating dns record for {identifier}");
325325
let acme_domain = format!("_acme-challenge.{identifier}");
326-
debug!("removing existing dns record for {}", acme_domain);
326+
debug!("removing existing TXT record for {acme_domain}");
327327
self.dns01_client
328328
.remove_txt_records(&acme_domain)
329329
.await
330330
.context("failed to remove existing dns record")?;
331-
debug!("creating dns record for {}", acme_domain);
331+
debug!("creating TXT record for {acme_domain}");
332332
let id = self
333333
.dns01_client
334334
.add_txt_record(&acme_domain, &dns_value)

certbot/src/bot.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ pub struct CertBotConfig {
2727
auto_set_caa: bool,
2828
credentials_file: PathBuf,
2929
auto_create_account: bool,
30-
cf_zone_id: String,
3130
cf_api_token: String,
3231
cert_file: PathBuf,
3332
key_file: PathBuf,
@@ -78,8 +77,16 @@ async fn create_new_account(
7877
impl CertBot {
7978
/// Build a new `CertBot` from a `CertBotConfig`.
8079
pub async fn build(config: CertBotConfig) -> Result<Self> {
80+
let base_domain = config
81+
.cert_subject_alt_names
82+
.first()
83+
.context("cert_subject_alt_names is empty")?
84+
.trim()
85+
.trim_start_matches("*.")
86+
.trim_end_matches('.')
87+
.to_string();
8188
let dns01_client =
82-
Dns01Client::new_cloudflare(config.cf_zone_id.clone(), config.cf_api_token.clone());
89+
Dns01Client::new_cloudflare(config.cf_api_token.clone(), base_domain).await?;
8390
let acme_client = match fs::read_to_string(&config.credentials_file) {
8491
Ok(credentials) => {
8592
if acme_matches(&credentials, &config.acme_url) {

certbot/src/bot/tests.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,12 @@ use instant_acme::LetsEncrypt;
99
use super::*;
1010

1111
async fn new_certbot() -> Result<CertBot> {
12-
let cf_zone_id = std::env::var("CLOUDFLARE_ZONE_ID").expect("CLOUDFLARE_ZONE_ID not set");
1312
let cf_api_token = std::env::var("CLOUDFLARE_API_TOKEN").expect("CLOUDFLARE_API_TOKEN not set");
1413
let domains = vec![std::env::var("TEST_DOMAIN").expect("TEST_DOMAIN not set")];
1514
let config = CertBotConfig::builder()
1615
.acme_url(LetsEncrypt::Staging.url())
1716
.auto_create_account(true)
1817
.credentials_file("./test-workdir/credentials.json")
19-
.cf_zone_id(cf_zone_id)
2018
.cf_api_token(cf_api_token)
2119
.cert_dir("./test-workdir/backup")
2220
.cert_file("./test-workdir/live/cert.pem")

certbot/src/dns01_client.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use anyhow::Result;
66
use cloudflare::CloudflareClient;
77
use enum_dispatch::enum_dispatch;
88
use serde::{Deserialize, Serialize};
9+
use tracing::debug;
910

1011
mod cloudflare;
1112

@@ -51,9 +52,11 @@ pub(crate) trait Dns01Api {
5152
/// Deletes all TXT DNS records matching the given domain.
5253
async fn remove_txt_records(&self, domain: &str) -> Result<()> {
5354
for record in self.get_records(domain).await? {
54-
if record.r#type == "TXT" {
55-
self.remove_record(&record.id).await?;
55+
if record.r#type != "TXT" {
56+
continue;
5657
}
58+
debug!(domain = %domain, id = %record.id, "removing txt record");
59+
self.remove_record(&record.id).await?;
5760
}
5861
Ok(())
5962
}
@@ -68,7 +71,9 @@ pub enum Dns01Client {
6871
}
6972

7073
impl Dns01Client {
71-
pub fn new_cloudflare(zone_id: String, api_token: String) -> Self {
72-
Self::Cloudflare(CloudflareClient::new(zone_id, api_token))
74+
pub async fn new_cloudflare(api_token: String, base_domain: String) -> Result<Self> {
75+
Ok(Self::Cloudflare(
76+
CloudflareClient::new(api_token, base_domain).await?,
77+
))
7378
}
7479
}

0 commit comments

Comments
 (0)