Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,6 @@ GATEWAY_CERT=${CERBOT_WORKDIR}/live/cert.pem
GATEWAY_KEY=${CERBOT_WORKDIR}/live/key.pem

# For certbot
CF_ZONE_ID=cc0a40...
CF_API_TOKEN=g-DwMH...
# ACME_URL=https://acme-v02.api.letsencrypt.org/directory
ACME_URL=https://acme-staging-v02.api.letsencrypt.org/directory
Expand Down
4 changes: 0 additions & 4 deletions certbot/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ struct Config {
acme_url: String,
/// Cloudflare API token
cf_api_token: String,
/// Cloudflare zone ID
cf_zone_id: String,
/// Auto set CAA record
auto_set_caa: bool,
/// List of domains to issue certificates for
Expand All @@ -87,7 +85,6 @@ impl Default for Config {
workdir: ".".into(),
acme_url: "https://acme-staging-v02.api.letsencrypt.org/directory".into(),
cf_api_token: "".into(),
cf_zone_id: "".into(),
auto_set_caa: true,
domains: vec!["example.com".into()],
renew_interval: 3600,
Expand Down Expand Up @@ -136,7 +133,6 @@ fn load_config(config: &PathBuf) -> Result<CertBotConfig> {
.key_file(workdir.key_path())
.auto_create_account(true)
.cert_subject_alt_names(config.domains)
.cf_zone_id(config.cf_zone_id)
.cf_api_token(config.cf_api_token)
.renew_interval(renew_interval)
.renew_timeout(renew_timeout)
Expand Down
6 changes: 3 additions & 3 deletions certbot/src/acme_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,14 +321,14 @@ impl AcmeClient {
let Identifier::Dns(identifier) = &authz.identifier;

let dns_value = order.key_authorization(challenge).dns_value();
debug!("creating dns record for {}", identifier);
debug!("creating dns record for {identifier}");
let acme_domain = format!("_acme-challenge.{identifier}");
debug!("removing existing dns record for {}", acme_domain);
debug!("removing existing TXT record for {acme_domain}");
self.dns01_client
.remove_txt_records(&acme_domain)
.await
.context("failed to remove existing dns record")?;
debug!("creating dns record for {}", acme_domain);
debug!("creating TXT record for {acme_domain}");
let id = self
.dns01_client
.add_txt_record(&acme_domain, &dns_value)
Expand Down
11 changes: 9 additions & 2 deletions certbot/src/bot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ pub struct CertBotConfig {
auto_set_caa: bool,
credentials_file: PathBuf,
auto_create_account: bool,
cf_zone_id: String,
cf_api_token: String,
cert_file: PathBuf,
key_file: PathBuf,
Expand Down Expand Up @@ -78,8 +77,16 @@ async fn create_new_account(
impl CertBot {
/// Build a new `CertBot` from a `CertBotConfig`.
pub async fn build(config: CertBotConfig) -> Result<Self> {
let base_domain = config
.cert_subject_alt_names
.first()
.context("cert_subject_alt_names is empty")?
.trim()
.trim_start_matches("*.")
.trim_end_matches('.')
.to_string();
let dns01_client =
Dns01Client::new_cloudflare(config.cf_zone_id.clone(), config.cf_api_token.clone());
Dns01Client::new_cloudflare(config.cf_api_token.clone(), base_domain).await?;
let acme_client = match fs::read_to_string(&config.credentials_file) {
Ok(credentials) => {
if acme_matches(&credentials, &config.acme_url) {
Expand Down
2 changes: 0 additions & 2 deletions certbot/src/bot/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@ use instant_acme::LetsEncrypt;
use super::*;

async fn new_certbot() -> Result<CertBot> {
let cf_zone_id = std::env::var("CLOUDFLARE_ZONE_ID").expect("CLOUDFLARE_ZONE_ID not set");
let cf_api_token = std::env::var("CLOUDFLARE_API_TOKEN").expect("CLOUDFLARE_API_TOKEN not set");
let domains = vec![std::env::var("TEST_DOMAIN").expect("TEST_DOMAIN not set")];
let config = CertBotConfig::builder()
.acme_url(LetsEncrypt::Staging.url())
.auto_create_account(true)
.credentials_file("./test-workdir/credentials.json")
.cf_zone_id(cf_zone_id)
.cf_api_token(cf_api_token)
.cert_dir("./test-workdir/backup")
.cert_file("./test-workdir/live/cert.pem")
Expand Down
13 changes: 9 additions & 4 deletions certbot/src/dns01_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use anyhow::Result;
use cloudflare::CloudflareClient;
use enum_dispatch::enum_dispatch;
use serde::{Deserialize, Serialize};
use tracing::debug;

mod cloudflare;

Expand Down Expand Up @@ -51,9 +52,11 @@ pub(crate) trait Dns01Api {
/// Deletes all TXT DNS records matching the given domain.
async fn remove_txt_records(&self, domain: &str) -> Result<()> {
for record in self.get_records(domain).await? {
if record.r#type == "TXT" {
self.remove_record(&record.id).await?;
if record.r#type != "TXT" {
continue;
}
debug!(domain = %domain, id = %record.id, "removing txt record");
self.remove_record(&record.id).await?;
}
Ok(())
}
Expand All @@ -68,7 +71,9 @@ pub enum Dns01Client {
}

impl Dns01Client {
pub fn new_cloudflare(zone_id: String, api_token: String) -> Self {
Self::Cloudflare(CloudflareClient::new(zone_id, api_token))
pub async fn new_cloudflare(api_token: String, base_domain: String) -> Result<Self> {
Ok(Self::Cloudflare(
CloudflareClient::new(api_token, base_domain).await?,
))
}
}
Loading