From e25650099a3aa1248d8a9cf42127a5df728e5376 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 2 Jan 2022 10:35:28 +0800 Subject: [PATCH] feat dingtalk and restart nginx --- Cargo.lock | 168 ++++++++++++++++++++++++++++++++++++++++++-------- Cargo.toml | 7 ++- src/config.rs | 9 ++- src/main.rs | 69 ++++++++++++++++++++- 4 files changed, 224 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e6569d7..0615a73 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,19 +4,24 @@ version = 3 [[package]] name = "acme-client" -version = "0.6.1" +version = "1.0.0" dependencies = [ "acme-lib", "async-std", + "base64 0.11.0", "clap", "deser-hjson", + "hmac 0.7.1", "lazy_static", "reqwest", "rust_util", "serde", + "serde_json", + "sha2 0.8.2", "simpledateformat", "tide", "trust-dns-resolver", + "urlencoding", "x509-parser", ] @@ -42,7 +47,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331" dependencies = [ - "generic-array", + "generic-array 0.14.4", ] [[package]] @@ -67,7 +72,7 @@ dependencies = [ "cipher", "ctr", "ghash", - "subtle", + "subtle 2.4.1", ] [[package]] @@ -77,7 +82,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" dependencies = [ "cipher", - "opaque-debug", + "opaque-debug 0.3.0", ] [[package]] @@ -87,7 +92,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce" dependencies = [ "cipher", - "opaque-debug", + "opaque-debug 0.3.0", ] [[package]] @@ -268,7 +273,7 @@ dependencies = [ "rand 0.7.3", "serde", "serde_json", - "sha2", + "sha2 0.9.6", ] [[package]] @@ -360,6 +365,12 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" +[[package]] +name = "base64" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" + [[package]] name = "base64" version = "0.12.3" @@ -411,7 +422,19 @@ dependencies = [ "cfg-if 0.1.10", "constant_time_eq", "crypto-mac 0.8.0", - "digest", + "digest 0.9.0", +] + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array 0.12.4", ] [[package]] @@ -420,7 +443,16 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array", + "generic-array 0.14.4", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", ] [[package]] @@ -453,6 +485,18 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "bytes" version = "1.1.0" @@ -509,7 +553,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801" dependencies = [ - "generic-array", + "generic-array 0.14.4", ] [[package]] @@ -560,7 +604,7 @@ dependencies = [ "hmac 0.10.1", "percent-encoding", "rand 0.8.4", - "sha2", + "sha2 0.9.6", "time 0.2.27", "version_check", ] @@ -632,14 +676,24 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "crypto-mac" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +dependencies = [ + "generic-array 0.12.4", + "subtle 1.0.0", +] + [[package]] name = "crypto-mac" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ - "generic-array", - "subtle", + "generic-array 0.14.4", + "subtle 2.4.1", ] [[package]] @@ -648,8 +702,8 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bff07008ec701e8028e2ceb8f83f0e4274ee62bd2dbdc4fefff2e9a91824081a" dependencies = [ - "generic-array", - "subtle", + "generic-array 0.14.4", + "subtle 2.4.1", ] [[package]] @@ -721,13 +775,22 @@ dependencies = [ "serde", ] +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + [[package]] name = "digest" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array", + "generic-array 0.14.4", ] [[package]] @@ -784,6 +847,12 @@ version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + [[package]] name = "fastrand" version = "1.5.0" @@ -926,6 +995,15 @@ dependencies = [ "slab", ] +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + [[package]] name = "generic-array" version = "0.14.4" @@ -964,7 +1042,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97304e4cd182c3846f7575ced3890c53012ce534ad9114046b0a9e00bb30a375" dependencies = [ - "opaque-debug", + "opaque-debug 0.3.0", "polyval", ] @@ -1030,10 +1108,20 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51ab2f639c231793c5f6114bdb9bbe50a7dbbfcd7c7c6bd8475dec2d991e964f" dependencies = [ - "digest", + "digest 0.9.0", "hmac 0.10.1", ] +[[package]] +name = "hmac" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" +dependencies = [ + "crypto-mac 0.7.0", + "digest 0.8.1", +] + [[package]] name = "hmac" version = "0.8.1" @@ -1041,7 +1129,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" dependencies = [ "crypto-mac 0.8.0", - "digest", + "digest 0.9.0", ] [[package]] @@ -1051,7 +1139,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" dependencies = [ "crypto-mac 0.10.1", - "digest", + "digest 0.9.0", ] [[package]] @@ -1449,6 +1537,12 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + [[package]] name = "opaque-debug" version = "0.3.0" @@ -1589,7 +1683,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eebcc4aa140b9abd2bc40d9c3f7ccec842679cd79045ac3a7ac698c1a064b7cd" dependencies = [ "cpuid-bool", - "opaque-debug", + "opaque-debug 0.3.0", "universal-hash", ] @@ -2013,17 +2107,29 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" +[[package]] +name = "sha2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +dependencies = [ + "block-buffer 0.7.3", + "digest 0.8.1", + "fake-simd", + "opaque-debug 0.2.3", +] + [[package]] name = "sha2" version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9204c41a1597a8c5af23c82d1c921cb01ec0a4c59e07a9c7306062829a3903f3" dependencies = [ - "block-buffer", + "block-buffer 0.9.0", "cfg-if 1.0.0", "cpufeatures", - "digest", - "opaque-debug", + "digest 0.9.0", + "opaque-debug 0.3.0", ] [[package]] @@ -2179,6 +2285,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +[[package]] +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" + [[package]] name = "subtle" version = "2.4.1" @@ -2520,8 +2632,8 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" dependencies = [ - "generic-array", - "subtle", + "generic-array 0.14.4", + "subtle 2.4.1", ] [[package]] @@ -2562,6 +2674,12 @@ dependencies = [ "serde", ] +[[package]] +name = "urlencoding" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a1f0175e03a0973cf4afd476bef05c26e228520400eb1fd473ad417b1c00ffb" + [[package]] name = "value-bag" version = "1.0.0-alpha.7" diff --git a/Cargo.toml b/Cargo.toml index daab8fd..6010e26 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "acme-client" -version = "0.6.1" +version = "1.0.0" authors = ["Hatter Jiang "] edition = "2018" description = "Acme auto challenge client, acme-client can issue certificates from Let's encrypt" @@ -20,6 +20,11 @@ x509-parser = "0.9" reqwest = { version = "0.11", features = ["blocking"] } trust-dns-resolver = "0.20" simpledateformat = "0.1.3" +serde_json = "1.0" +urlencoding = "1.0.0" +base64 = "0.11.0" +hmac = "0.7.1" +sha2 = "0.8.1" [profile.release] codegen-units = 1 diff --git a/src/config.rs b/src/config.rs index b8eadc7..0387ba8 100644 --- a/src/config.rs +++ b/src/config.rs @@ -55,6 +55,8 @@ pub struct CertConfigItem { pub struct CertConfig { pub port: Option, pub cert_items: Vec, + pub trigger_after_update: Option>, + pub notify_token: Option, } impl CertConfig { @@ -98,7 +100,12 @@ impl CertConfig { } } - Self { port: self.port, cert_items: filtered_cert_items } + Self { + port: self.port, + cert_items: filtered_cert_items, + trigger_after_update: self.trigger_after_update, + notify_token: self.notify_token, + } } pub fn load(config_fn: &str) -> XResult { diff --git a/src/main.rs b/src/main.rs index 3b4c595..633a054 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ mod config; mod x509; mod network; mod statics; +mod dingtalk; // mod simple_thread_pool; use std::env; @@ -20,7 +21,7 @@ use std::str::FromStr; use std::sync::RwLock; use std::collections::BTreeMap; use tide::Request; -use std::process::exit; +use std::process::{Command, exit}; use std::time::{Duration, SystemTime}; use async_std::task; use async_std::channel; @@ -29,6 +30,8 @@ use config::AcmeMode; use crate::config::{CertConfig, CERT_NAME, KEY_NAME}; use crate::x509::{X509PublicKeyAlgo, X509EcPublicKeyAlgo}; use std::path::PathBuf; +use rust_util::util_cmd::run_command_and_wait; +use crate::dingtalk::send_dingtalk_message; use crate::network::{get_local_public_ip, get_resolver, resolve_first_ipv4}; use crate::statics::{AcmeStatics, AcmeStatus}; @@ -75,7 +78,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("Skip verify public ip")) + .arg(Arg::with_name("skip-verify-ip").short("k").long("skip-verify-ip").help("Skip verify public ip")) .get_matches(); if matches.is_present("verbose") { @@ -285,7 +288,69 @@ async fn main() -> tide::Result<()> { } } acme_statics.end(); + + let mut success_count = 0; + for acme_static in &acme_statics.items { + if let AcmeStatus::Success = acme_static.status { + success_count += 1; + } + } + success!("Statics: \n{}", acme_statics); + + let mut dingtalk_message = format!("Statics: \n{}", acme_statics); + if success_count > 0 { + if let Some(trigger_after_update) = &filtered_cert_config.trigger_after_update { + if trigger_after_update.len() > 0 { + let mut cmd = Command::new(&trigger_after_update[0]); + for i in 1..trigger_after_update.len() { + cmd.arg(&trigger_after_update[i]); + } + match run_command_and_wait(&mut cmd) { + Ok(_) => { + success!("Restart nginx success"); + dingtalk_message.push_str("\n\nrestart nginx success"); + } + Err(err) => { + failure!("Restart nginx failed: {:?}", err); + dingtalk_message.push_str(&format!("\n\nrestart nginx failed: {:?}", err)); + } + } + } else { + warning!("No trigger after update is configed but is empty"); + } + } else { + warning!("No trigger after update configed"); + } + } + + let mut success_domains = vec![]; + let mut failed_domains = vec![]; + for acme_static in &acme_statics.items { + if let AcmeStatus::Success = acme_static.status { + success_domains.push(format!("* {}", acme_static.domains.join(", "))); + } + if let AcmeStatus::Fail(_) = acme_static.status { + failed_domains.push(format!("* {}", &acme_static.domains.join(", "))); + } + } + + if !success_domains.is_empty() { + dingtalk_message.push_str("\nsuccess domains:\n"); + dingtalk_message.push_str(&success_domains.join("\n")); + } + if !failed_domains.is_empty() { + dingtalk_message.push_str("\nfailed domains:\n"); + dingtalk_message.push_str(&failed_domains.join("\n")); + } + + if !acme_statics.items.is_empty() && filtered_cert_config.notify_token.is_some() { + if let Err(err) = send_dingtalk_message(&filtered_cert_config, &dingtalk_message) { + failure!("Send notification message failed: {:?}", err); + } + } else { + information!("No notification message need to send, or not configed notification token"); + } } }