Line data Source code
1 : use std::process::Command;
2 : use std::{fs::OpenOptions, io::Write};
3 :
4 : use anyhow::{Context, Result};
5 : use tracing::info;
6 :
7 0 : fn get_rsyslog_pid() -> Option<String> {
8 0 : let output = Command::new("pgrep")
9 0 : .arg("rsyslogd")
10 0 : .output()
11 0 : .expect("Failed to execute pgrep");
12 0 :
13 0 : if !output.stdout.is_empty() {
14 0 : let pid = std::str::from_utf8(&output.stdout)
15 0 : .expect("Invalid UTF-8 in process output")
16 0 : .trim()
17 0 : .to_string();
18 0 : Some(pid)
19 : } else {
20 0 : None
21 : }
22 0 : }
23 :
24 : // Restart rsyslogd to apply the new configuration.
25 : // This is necessary, because there is no other way to reload the rsyslog configuration.
26 : //
27 : // Rsyslogd shouldn't lose any messages, because of the restart,
28 : // because it tracks the last read position in the log files
29 : // and will continue reading from that position.
30 : // TODO: test it properly
31 : //
32 0 : fn restart_rsyslog() -> Result<()> {
33 0 : let old_pid = get_rsyslog_pid().context("rsyslogd is not running")?;
34 0 : info!("rsyslogd is running with pid: {}, restart it", old_pid);
35 :
36 : // kill it to restart
37 0 : let _ = Command::new("pkill")
38 0 : .arg("rsyslogd")
39 0 : .output()
40 0 : .context("Failed to stop rsyslogd")?;
41 :
42 0 : Ok(())
43 0 : }
44 :
45 0 : pub fn configure_audit_rsyslog(
46 0 : log_directory: &str,
47 0 : tag: &str,
48 0 : remote_endpoint: &str,
49 0 : ) -> Result<()> {
50 0 : let config_content: String = format!(
51 0 : include_str!("config_template/compute_audit_rsyslog_template.conf"),
52 0 : log_directory = log_directory,
53 0 : tag = tag,
54 0 : remote_endpoint = remote_endpoint
55 0 : );
56 0 :
57 0 : info!("rsyslog config_content: {}", config_content);
58 :
59 0 : let rsyslog_conf_path = "/etc/rsyslog.d/compute_audit_rsyslog.conf";
60 0 : let mut file = OpenOptions::new()
61 0 : .create(true)
62 0 : .write(true)
63 0 : .truncate(true)
64 0 : .open(rsyslog_conf_path)?;
65 :
66 0 : file.write_all(config_content.as_bytes())?;
67 :
68 0 : info!(
69 0 : "rsyslog configuration file {} added successfully. Starting rsyslogd",
70 : rsyslog_conf_path
71 : );
72 :
73 : // start the service, using the configuration
74 0 : restart_rsyslog()?;
75 :
76 0 : Ok(())
77 0 : }
|