1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use warp::{path, Filter};
pub fn lets_encrypt<F>(service: F, domain: &str)
where
F: warp::Filter<Error = warp::Rejection> + Send + Sync + 'static,
F::Extract: warp::reply::Reply,
{
use acme_client::Directory;
let directory = Directory::lets_encrypt().expect("Trouble connecting to let's encrypt");
let account = directory
.account_registration()
.register()
.expect("Trouble registring for an account.");
let authorization = account
.authorization(domain)
.expect("Trouble creating authorization for the account for the domain.");
let http_challenge = authorization
.get_http_challenge()
.expect("Problem with the challenge");
let authorization = http_challenge.key_authorization().to_string();
let token_name = Box::leak(http_challenge.token().to_string().into_boxed_str());
std::thread::spawn(move || {
use std::str::FromStr;
let token = warp::path!(".well-known" / "acme-challenge")
.and(warp::path(token_name))
.map(move || authorization.clone());
let redirect = warp::path::tail()
.map(|path: warp::path::Tail| {
println!("redirecting to https://{}", path.as_str());
warp::redirect::redirect(warp::http::Uri::from_str(&format!("https://{}", path.as_str()))
.expect("problem with uri?"))
});
warp::serve(token.or(redirect))
.run(([0, 0, 0, 0], 80));
});
std::thread::sleep(std::time::Duration::from_millis(500));
http_challenge.validate().expect("Trouble validating.");
let cert = account
.certificate_signer(&[domain])
.sign_certificate()
.expect("Trouble signing?");
cert.save_signed_certificate("certificate.pem")
.expect("Touble saving pem");
cert.save_private_key("certificate.key")
.expect("Trouble saving key");
warp::serve(service)
.tls("certificate.pem", "certificate.key")
.run(([0, 0, 0, 0], 443));
}