v1.0.1
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -4,7 +4,7 @@ version = 3
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "acme-client"
|
name = "acme-client"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"acme-lib",
|
"acme-lib",
|
||||||
"async-std",
|
"async-std",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "acme-client"
|
name = "acme-client"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "Acme auto challenge client, acme-client can issue certificates from Let's encrypt"
|
description = "Acme auto challenge client, acme-client can issue certificates from Let's encrypt"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ ACME Client in Rust
|
|||||||
Acme client help:
|
Acme client help:
|
||||||
```shell
|
```shell
|
||||||
$ acme-client --help
|
$ acme-client --help
|
||||||
acme-client 0.5.0
|
acme-client 1.0.1
|
||||||
Hatter Jiang <jht5945@gmail.com>
|
Hatter Jiang <jht5945@gmail.com>
|
||||||
Acme auto challenge client, acme-client can issue certificates from Let's encrypt
|
Acme auto challenge client, acme-client can issue certificates from Let's encrypt
|
||||||
|
|
||||||
@@ -16,12 +16,14 @@ FLAGS:
|
|||||||
--check Check cert config
|
--check Check cert config
|
||||||
-h, --help Prints help information
|
-h, --help Prints help information
|
||||||
--hide-logo Hide logo
|
--hide-logo Hide logo
|
||||||
--skip-verify-ip Skip verify public ip
|
-K, --skip-verify-certificate Skip verify certificate
|
||||||
|
-k, --skip-verify-ip Skip verify public ip
|
||||||
-v, --verbose Verbose
|
-v, --verbose Verbose
|
||||||
-V, --version Print version
|
-V, --version Print version
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
-a, --algo <algo> Pki algo [default: ec384]
|
-a, --algo <algo> Pki algo [default: ec384]
|
||||||
|
--cert-dir <cert-dir> Certificate dir
|
||||||
-c, --config <config> Cert config
|
-c, --config <config> Cert config
|
||||||
--dir <dir> Account key dir [default: acme_dir]
|
--dir <dir> Account key dir [default: acme_dir]
|
||||||
-d, --domain <domain>... Domains
|
-d, --domain <domain>... Domains
|
||||||
@@ -39,6 +41,9 @@ OPTIONS:
|
|||||||
使用参数 `--config` 时的配置文件示例:
|
使用参数 `--config` 时的配置文件示例:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
"port": 18342,
|
||||||
|
"triggerAfterUpdate": ["/usr/local/nginx/nginx", "-s", "reload"],
|
||||||
|
"notifyToken": "dingtalk:access_token?sec_token",
|
||||||
"certItems": [{
|
"certItems": [{
|
||||||
"path": "dir_cryptofan_org",
|
"path": "dir_cryptofan_org",
|
||||||
"dnsNames": ["cryptofan.org", "www.cryptofan.org"]
|
"dnsNames": ["cryptofan.org", "www.cryptofan.org"]
|
||||||
|
|||||||
12
src/main.rs
12
src/main.rs
@@ -79,6 +79,7 @@ async fn main() -> tide::Result<()> {
|
|||||||
.arg(Arg::with_name("check").long("check").help("Check 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("hide-logo").long("hide-logo").help("Hide logo"))
|
||||||
.arg(Arg::with_name("skip-verify-ip").short("k").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"))
|
||||||
|
.arg(Arg::with_name("skip-verify-certificate").short("K").long("skip-verify-certificate").help("Skip verify certificate"))
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
if matches.is_present("verbose") {
|
if matches.is_present("verbose") {
|
||||||
@@ -99,7 +100,8 @@ async fn main() -> tide::Result<()> {
|
|||||||
let local_public_ip = if skip_verify_ip {
|
let local_public_ip = if skip_verify_ip {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(get_local_public_ip().unwrap_or_else(|e| {
|
let skip_verify_certificate = matches.is_present("skip-verify-certificate");
|
||||||
|
Some(get_local_public_ip(skip_verify_certificate).unwrap_or_else(|e| {
|
||||||
failure!("Get local public ip failed: {}", e);
|
failure!("Get local public ip failed: {}", e);
|
||||||
exit(1);
|
exit(1);
|
||||||
}))
|
}))
|
||||||
@@ -309,18 +311,18 @@ async fn main() -> tide::Result<()> {
|
|||||||
match run_command_and_wait(&mut cmd) {
|
match run_command_and_wait(&mut cmd) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
success!("Restart nginx success");
|
success!("Restart nginx success");
|
||||||
dingtalk_message.push_str("\n\nrestart nginx success");
|
dingtalk_message.push_str(&format!("\n\ntrigger after update success: {:?}", cmd));
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
failure!("Restart nginx failed: {:?}", err);
|
failure!("Restart nginx failed: {:?}", err);
|
||||||
dingtalk_message.push_str(&format!("\n\nrestart nginx failed: {:?}", err));
|
dingtalk_message.push_str(&format!("\n\ntrigger after update failed: {:?}, message: {:?}", cmd, err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warning!("No trigger after update is configed but is empty");
|
warning!("No trigger after update is configured but is empty");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warning!("No trigger after update configed");
|
warning!("No trigger after update configured");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,51 @@ pub struct PublicIpResponse {
|
|||||||
pub user_agent: Option<String>,
|
pub user_agent: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_local_public_ip() -> XResult<String> {
|
pub fn get_local_public_ip(skip_verify_certificate: bool) -> XResult<String> {
|
||||||
let response = opt_result!(reqwest::blocking::get("https://hatter.ink/ip/ip.jsonp"), "Get local public ip failed: {}");
|
let mut client_builder = reqwest::blocking::Client::builder();
|
||||||
|
if skip_verify_certificate {
|
||||||
|
warning!("Skip verify certificate is turned on");
|
||||||
|
client_builder = client_builder.danger_accept_invalid_certs(true);
|
||||||
|
}
|
||||||
|
let root_certificate_isrg_x_pem = r#"-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
|
||||||
|
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
|
||||||
|
DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow
|
||||||
|
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
|
||||||
|
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwggIiMA0GCSqGSIb3DQEB
|
||||||
|
AQUAA4ICDwAwggIKAoICAQCt6CRz9BQ385ueK1coHIe+3LffOJCMbjzmV6B493XC
|
||||||
|
ov71am72AE8o295ohmxEk7axY/0UEmu/H9LqMZshftEzPLpI9d1537O4/xLxIZpL
|
||||||
|
wYqGcWlKZmZsj348cL+tKSIG8+TA5oCu4kuPt5l+lAOf00eXfJlII1PoOK5PCm+D
|
||||||
|
LtFJV4yAdLbaL9A4jXsDcCEbdfIwPPqPrt3aY6vrFk/CjhFLfs8L6P+1dy70sntK
|
||||||
|
4EwSJQxwjQMpoOFTJOwT2e4ZvxCzSow/iaNhUd6shweU9GNx7C7ib1uYgeGJXDR5
|
||||||
|
bHbvO5BieebbpJovJsXQEOEO3tkQjhb7t/eo98flAgeYjzYIlefiN5YNNnWe+w5y
|
||||||
|
sR2bvAP5SQXYgd0FtCrWQemsAXaVCg/Y39W9Eh81LygXbNKYwagJZHduRze6zqxZ
|
||||||
|
Xmidf3LWicUGQSk+WT7dJvUkyRGnWqNMQB9GoZm1pzpRboY7nn1ypxIFeFntPlF4
|
||||||
|
FQsDj43QLwWyPntKHEtzBRL8xurgUBN8Q5N0s8p0544fAQjQMNRbcTa0B7rBMDBc
|
||||||
|
SLeCO5imfWCKoqMpgsy6vYMEG6KDA0Gh1gXxG8K28Kh8hjtGqEgqiNx2mna/H2ql
|
||||||
|
PRmP6zjzZN7IKw0KKP/32+IVQtQi0Cdd4Xn+GOdwiK1O5tmLOsbdJ1Fu/7xk9TND
|
||||||
|
TwIDAQABo4IBRjCCAUIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
|
||||||
|
SwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5pZGVudHJ1
|
||||||
|
c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTEp7Gkeyxx
|
||||||
|
+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEB
|
||||||
|
ATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQu
|
||||||
|
b3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0LmNvbS9E
|
||||||
|
U1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFHm0WeZ7tuXkAXOACIjIGlj26Ztu
|
||||||
|
MA0GCSqGSIb3DQEBCwUAA4IBAQAKcwBslm7/DlLQrt2M51oGrS+o44+/yQoDFVDC
|
||||||
|
5WxCu2+b9LRPwkSICHXM6webFGJueN7sJ7o5XPWioW5WlHAQU7G75K/QosMrAdSW
|
||||||
|
9MUgNTP52GE24HGNtLi1qoJFlcDyqSMo59ahy2cI2qBDLKobkx/J3vWraV0T9VuG
|
||||||
|
WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O
|
||||||
|
he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC
|
||||||
|
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
|
||||||
|
-----END CERTIFICATE-----"#;
|
||||||
|
match reqwest::Certificate::from_pem(root_certificate_isrg_x_pem.as_bytes()) {
|
||||||
|
Err(err) => { warning!("Add ISRG X1 root failed: {}", err); },
|
||||||
|
Ok(certificate) => {
|
||||||
|
client_builder = client_builder.add_root_certificate(certificate);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
let client = opt_result!(client_builder.build(), "Build http client failed: {}");
|
||||||
|
let response = opt_result!(client.get("https://hatter.ink/ip/ip.jsonp").send(), "Get local public ip failed: {}");
|
||||||
let response_text = opt_result!(response.text(), "Get local public ip failed: {}");
|
let response_text = opt_result!(response.text(), "Get local public ip failed: {}");
|
||||||
debugging!("Get local public ip response: {}", response_text);
|
debugging!("Get local public ip response: {}", response_text);
|
||||||
let response_json: PublicIpResponse = opt_result!(deser_hjson::from_str(&response_text), "Parse get public ip response failed: {}");
|
let response_json: PublicIpResponse = opt_result!(deser_hjson::from_str(&response_text), "Parse get public ip response failed: {}");
|
||||||
@@ -33,5 +76,5 @@ pub fn resolve_first_ipv4(resolver: &Resolver, domain: &str) -> XResult<Option<S
|
|||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
println!("{:?}", resolve_first_ipv4(&get_resolver().unwrap(), "hatter.ink"));
|
println!("{:?}", resolve_first_ipv4(&get_resolver().unwrap(), "hatter.ink"));
|
||||||
println!("{:?}", get_local_public_ip());
|
println!("{:?}", get_local_public_ip(false));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user