]> git.proxmox.com Git - proxmox-backup.git/blob - src/bin/proxmox-backup-proxy.rs
ccf7c88a3d01bc1b2ac2a1e0c06550ffd5d1862f
[proxmox-backup.git] / src / bin / proxmox-backup-proxy.rs
1 use std::sync::Arc;
2
3 use failure::*;
4 use futures::*;
5 use hyper;
6 use openssl::ssl::{SslMethod, SslAcceptor, SslFiletype};
7
8 use proxmox::tools::try_block;
9 use proxmox::api::RpcEnvironmentType;
10
11 use proxmox_backup::configdir;
12 use proxmox_backup::buildcfg;
13 use proxmox_backup::server;
14 use proxmox_backup::tools::daemon;
15 use proxmox_backup::server::{ApiConfig, rest::*};
16 use proxmox_backup::auth_helpers::*;
17
18 #[tokio::main]
19 async fn main() {
20 if let Err(err) = run().await {
21 eprintln!("Error: {}", err);
22 std::process::exit(-1);
23 }
24 }
25
26 async fn run() -> Result<(), Error> {
27 if let Err(err) = syslog::init(
28 syslog::Facility::LOG_DAEMON,
29 log::LevelFilter::Info,
30 Some("proxmox-backup-proxy")) {
31 bail!("unable to inititialize syslog - {}", err);
32 }
33
34 let _ = public_auth_key(); // load with lazy_static
35 let _ = csrf_secret(); // load with lazy_static
36
37 let mut config = ApiConfig::new(
38 buildcfg::JS_DIR, &proxmox_backup::api2::ROUTER, RpcEnvironmentType::PUBLIC);
39
40 // add default dirs which includes jquery and bootstrap
41 // my $base = '/usr/share/libpve-http-server-perl';
42 // add_dirs($self->{dirs}, '/css/' => "$base/css/");
43 // add_dirs($self->{dirs}, '/js/' => "$base/js/");
44 // add_dirs($self->{dirs}, '/fonts/' => "$base/fonts/");
45 config.add_alias("novnc", "/usr/share/novnc-pve");
46 config.add_alias("extjs", "/usr/share/javascript/extjs");
47 config.add_alias("fontawesome", "/usr/share/fonts-font-awesome");
48 config.add_alias("xtermjs", "/usr/share/pve-xtermjs");
49 config.add_alias("widgettoolkit", "/usr/share/javascript/proxmox-widget-toolkit");
50 config.add_alias("css", "/usr/share/javascript/proxmox-backup/css");
51 config.add_alias("docs", "/usr/share/doc/proxmox-backup/html");
52
53 let rest_server = RestServer::new(config);
54
55 //openssl req -x509 -newkey rsa:4096 -keyout /etc/proxmox-backup/proxy.key -out /etc/proxmox-backup/proxy.pem -nodes
56 let key_path = configdir!("/proxy.key");
57 let cert_path = configdir!("/proxy.pem");
58
59 let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
60 acceptor.set_private_key_file(key_path, SslFiletype::PEM)
61 .map_err(|err| format_err!("unable to read proxy key {} - {}", key_path, err))?;
62 acceptor.set_certificate_chain_file(cert_path)
63 .map_err(|err| format_err!("unable to read proxy cert {} - {}", cert_path, err))?;
64 acceptor.check_private_key().unwrap();
65
66 let acceptor = Arc::new(acceptor.build());
67
68 let server = daemon::create_daemon(
69 ([0,0,0,0,0,0,0,0], 8007).into(),
70 |listener, ready| {
71 let connections = proxmox_backup::tools::async_io::StaticIncoming::from(listener)
72 .map_err(Error::from)
73 .try_filter_map(move |(sock, _addr)| {
74 let acceptor = Arc::clone(&acceptor);
75 async move {
76 sock.set_nodelay(true).unwrap();
77 sock.set_send_buffer_size(1024*1024).unwrap();
78 sock.set_recv_buffer_size(1024*1024).unwrap();
79 Ok(tokio_openssl::accept(&acceptor, sock)
80 .await
81 .ok() // handshake errors aren't be fatal, so return None to filter
82 )
83 }
84 });
85 let connections = proxmox_backup::tools::async_io::HyperAccept(connections);
86
87 Ok(ready
88 .and_then(|_| hyper::Server::builder(connections)
89 .serve(rest_server)
90 .with_graceful_shutdown(server::shutdown_future())
91 .map_err(Error::from)
92 )
93 .map_err(|err| eprintln!("server error: {}", err))
94 .map(|_| ())
95 )
96 },
97 );
98
99 daemon::systemd_notify(daemon::SystemdNotify::Ready)?;
100
101 let init_result: Result<(), Error> = try_block!({
102 server::create_task_control_socket()?;
103 server::server_state_init()?;
104 Ok(())
105 });
106
107 if let Err(err) = init_result {
108 bail!("unable to start daemon - {}", err);
109 }
110
111 server.await?;
112 log::info!("server shutting down, waiting for active workers to complete");
113 proxmox_backup::server::last_worker_future().await?;
114 log::info!("done - exit server");
115
116 Ok(())
117 }