feat: add domain check
This commit is contained in:
36
src/main.rs
36
src/main.rs
@@ -5,6 +5,7 @@ extern crate rust_util;
|
||||
|
||||
mod config;
|
||||
mod x509;
|
||||
mod network;
|
||||
// mod simple_thread_pool;
|
||||
|
||||
use std::env;
|
||||
@@ -27,6 +28,7 @@ use config::AcmeMode;
|
||||
use crate::config::{CertConfig, CERT_NAME, KEY_NAME};
|
||||
use crate::x509::{X509PublicKeyAlgo, X509EcPublicKeyAlgo};
|
||||
use std::path::PathBuf;
|
||||
use crate::network::{get_local_public_ip, get_resolver, resolve_first_ipv4};
|
||||
|
||||
const NAME: &str = env!("CARGO_PKG_NAME");
|
||||
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
@@ -46,6 +48,7 @@ struct AcmeRequest<'a> {
|
||||
mode: AcmeMode,
|
||||
account_dir: &'a str,
|
||||
timeout: u64,
|
||||
local_public_ip: Option<&'a str>,
|
||||
key_file: Option<String>,
|
||||
cert_file: Option<String>,
|
||||
}
|
||||
@@ -69,6 +72,7 @@ async fn main() -> tide::Result<()> {
|
||||
.arg(Arg::with_name("config").short("c").long("config").takes_value(true).help("Cert config"))
|
||||
.arg(Arg::with_name("check").long("check").help("Check cert config"))
|
||||
.arg(Arg::with_name("hide-logo").long("hide-logo").help("Hide logo"))
|
||||
.arg(Arg::with_name("skip-verify-ip").long("skip-verify-ip").help("Verify public ip"))
|
||||
.get_matches();
|
||||
|
||||
if matches.is_present("verbose") {
|
||||
@@ -85,6 +89,16 @@ async fn main() -> tide::Result<()> {
|
||||
println!("{}", include_str!("logo.txt"));
|
||||
}
|
||||
|
||||
let skip_verify_ip = matches.is_present("skip-verify-ip");
|
||||
let local_public_ip = if skip_verify_ip {
|
||||
None
|
||||
} else {
|
||||
Some(get_local_public_ip().unwrap_or_else(|e| {
|
||||
failure!("Get local public ip failed: {}", e);
|
||||
exit(1);
|
||||
}))
|
||||
};
|
||||
|
||||
debugging!("Clap matches: {:?}", matches);
|
||||
|
||||
let account_dir = matches.value_of("dir").unwrap_or("acme_dir");
|
||||
@@ -197,6 +211,7 @@ async fn main() -> tide::Result<()> {
|
||||
mode,
|
||||
account_dir,
|
||||
timeout,
|
||||
local_public_ip: local_public_ip.as_ref().map(|ip| ip.as_str()),
|
||||
..Default::default()
|
||||
};
|
||||
if let Err(e) = request_acme_certificate(acme_request) {
|
||||
@@ -233,6 +248,7 @@ async fn main() -> tide::Result<()> {
|
||||
mode,
|
||||
account_dir,
|
||||
timeout,
|
||||
local_public_ip: local_public_ip.as_ref().map(|ip| ip.as_str()),
|
||||
cert_file: Some(format!("{}/{}", item.path, CERT_NAME)),
|
||||
key_file: Some(format!("{}/{}", item.path, KEY_NAME)),
|
||||
};
|
||||
@@ -277,6 +293,26 @@ fn check_cert_config(cert_config: &CertConfig) {
|
||||
}
|
||||
|
||||
fn request_acme_certificate(acme_request: AcmeRequest) -> XResult<()> {
|
||||
if let Some(local_public_ip) = acme_request.local_public_ip {
|
||||
let mut all_domains = vec![acme_request.primary_name.to_string()];
|
||||
for alt_name in acme_request.alt_names {
|
||||
all_domains.push(alt_name.to_string());
|
||||
}
|
||||
information!("Checking domain dns records, domains: {:?}", all_domains);
|
||||
let resolver = opt_result!(get_resolver(), "Get resolver failed: {}");
|
||||
|
||||
for domain in &all_domains {
|
||||
debugging!("Checking domain: {}", domain);
|
||||
let ipv4 = opt_result!(resolve_first_ipv4(&resolver, domain), "{}");
|
||||
match ipv4 {
|
||||
None => return simple_error!("Resolve domain ip failed: {}", domain),
|
||||
Some(ipv4) => if local_public_ip != &ipv4 {
|
||||
return simple_error!("Check domain ip: {}, mis-match, local: {} vs domain: {}", domain, local_public_ip, ipv4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
information!("Acme mode: {:?}", acme_request.mode);
|
||||
let url = acme_request.mode.directory_url();
|
||||
information!("Acme dir: {}", acme_request.account_dir);
|
||||
|
||||
Reference in New Issue
Block a user