Compare commits

..

No commits in common. "08ff104659d36c8647b93f21b78dd71f976d627f" and "c3a572619f8f30a0f6bd079ab14b8f92d198f8d3" have entirely different histories.

5 changed files with 47 additions and 147 deletions

1
.gitignore vendored
View File

@ -9,4 +9,3 @@
# Build files # Build files
target target
Cargo.lock

13
Cargo.lock generated
View File

@ -34,12 +34,11 @@ checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]] [[package]]
name = "cai-watchdog" name = "cai-watchdog"
version = "0.3.0" version = "0.2.0"
dependencies = [ dependencies = [
"chrono", "chrono",
"exitcode", "exitcode",
"file-utils", "file-utils",
"hashmap",
"ini", "ini",
"reqwest", "reqwest",
"tokio", "tokio",
@ -217,12 +216,6 @@ version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
[[package]]
name = "hashmap"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58f4c5bfe5d332cdefc57bd31471448f8b6cb0398542f4aecc2620e577e6fd54"
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.1.19" version = "0.1.19"
@ -402,9 +395,9 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.5.0" version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]] [[package]]
name = "mime" name = "mime"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "cai-watchdog" name = "cai-watchdog"
version = "0.3.0" version = "0.2.0"
authors = ["Alexander I. Chebykin <alex.chebykin@gmail.com>"] authors = ["Alexander I. Chebykin <alex.chebykin@gmail.com>"]
edition = "2018" edition = "2018"
@ -16,4 +16,3 @@ reqwest = "0.11"
tokio = { version = "1", features = ["full"] } tokio = { version = "1", features = ["full"] }
ini = "1.3.0" ini = "1.3.0"
exitcode = "1.1.2" exitcode = "1.1.2"
hashmap = "0.0.1"

View File

@ -26,13 +26,13 @@ You can specify config file as parameter: ```cai-watchdog /path/to/config/config
``` ```
[main] [main]
check_interval = Interval between checks in seconds check_interval - Interval between checks in seconds
rules_count = Rules count to be loaded from config. Rules sections must be enumerated continuously [rule1], [rule2] ... etc rules_count - Rules count to be loaded from config. Rules sections must be enumerated continuously [rule1], [rule2] ... etc
[notifications] [notifications]
email = E-mail address for system notifications. Can be empty email - E-mail address for system notifications. Can be empty
command = Command to send notification command - Command to send notification
service_start = Send program start notification [true | false] service_start - Send program start notification [true | false]
[rule1] [rule1]
service = Service name service = Service name
@ -102,39 +102,3 @@ Next you need to find your Telegram Chat ID.
1. From the Telegram home screen, search for ```chatid_echo_bot```. Click Chat ID Echo to open a chat 1. From the Telegram home screen, search for ```chatid_echo_bot```. Click Chat ID Echo to open a chat
1. Enter ```/start``` to get the bot to send you your Telegram Chat ID 1. Enter ```/start``` to get the bot to send you your Telegram Chat ID
1. Take note of the Telegram Chat ID returned 1. Take note of the Telegram Chat ID returned
## User logins monitoring (*nix)
Watchdog can send notifications on user login. Just add to ```/etc/profile.d/sshinfo.sh``` next lines:
- For Telegram:
1. ```User=$(whoami)```
1. ```send-telegram "SSH: User ${Users} is logged in"```
- For e-mail:
1. ```User=$(whoami)```
1. ```send-mail your@mail.addr 'SSH: User ${Users} is logged in' 'SSH: User ${Users} is logged in'```
## User logouts monitoring (*nix)
1. Create file ```/etc/pam.d/pam_session.sh``` with next content:
For Telegram:
```
#!/bin/sh
if [ "$PAM_TYPE" = "close_session" ]; then
send-telegram "SSH: User is logged out"
fi
```
For e-mail:
```
#!/bin/sh
if [ "$PAM_TYPE" = "close_session" ]; then
send-mail your@mail.addr 'SSH: User is logged out' 'SSH: User is logged out'
fi
```
and set executable flag on it
1. Modify ```/etc/pam.d/sshd```, add line ```session optional pam_exec.so quiet /etc/pam.d/pam_session.sh```

View File

@ -154,8 +154,6 @@ fn main() {
print_help(args.clone()); print_help(args.clone());
let mut just_started = true;
let cfg_file = if args.len() > 1 { let cfg_file = if args.len() > 1 {
&args[1] &args[1]
} else if cfg!(windows) { } else if cfg!(windows) {
@ -173,44 +171,16 @@ fn main() {
let cfg = ini!(cfg_file); let cfg = ini!(cfg_file);
let check_interval = if cfg["main"].contains_key("check_interval") { let check_interval = cfg["main"]["check_interval"].clone().unwrap().parse::<u64>().unwrap() * 1000;
cfg["main"]["check_interval"].clone().unwrap().parse::<u64>().unwrap() * 1000 let rules_count = cfg["main"]["rules_count"].clone().unwrap().parse::<u8>().unwrap();
} else {
10000
};
let rules_count = if cfg["main"].contains_key("check_interval") {
cfg["main"]["rules_count"].clone().unwrap().parse::<u8>().unwrap()
} else {
0
};
let mut tasks = vec![]; let mut tasks = vec![];
for i in 1..rules_count + 1 { for i in 1..rules_count + 1 {
let service = if cfg[&format!("{}{}", "rule", i)].contains_key("service") { let service = cfg[&format!("{}{}", "rule", i)]["service"].clone().unwrap();
cfg[&format!("{}{}", "rule", i)]["service"].clone().unwrap() let uri = cfg[&format!("{}{}", "rule", i)]["uri"].clone().unwrap();
} else { let email = cfg[&format!("{}{}", "rule", i)]["email"].clone().unwrap();
format!("Service {}", i) let command = cfg[&format!("{}{}", "rule", i)]["command"].clone().unwrap();
};
let uri = if cfg[&format!("{}{}", "rule", i)].contains_key("uri") {
cfg[&format!("{}{}", "rule", i)]["uri"].clone().unwrap()
} else {
"".to_string()
};
let email = if cfg[&format!("{}{}", "rule", i)].contains_key("email") {
cfg[&format!("{}{}", "rule", i)]["email"].clone().unwrap()
} else {
"".to_string()
};
let command = if cfg[&format!("{}{}", "rule", i)].contains_key("command") {
cfg[&format!("{}{}", "rule", i)]["command"].clone().unwrap()
} else {
"".to_string()
};
debug_log(format!("rule {}", i)); debug_log(format!("rule {}", i));
debug_log(format!("service {}", service)); debug_log(format!("service {}", service));
@ -220,34 +190,20 @@ fn main() {
tasks.push( tasks.push(
Rule{ Rule{
service: service, service: cfg[&format!("{}{}", "rule", i)]["service"].clone().unwrap().to_string(),
uri: uri, uri: cfg[&format!("{}{}", "rule", i)]["uri"].clone().unwrap().to_string(),
email: email, email: cfg[&format!("{}{}", "rule", i)]["email"].clone().unwrap().to_string(),
command: command, command: cfg[&format!("{}{}", "rule", i)]["command"].clone().unwrap().to_string(),
last_state: false, last_state: false,
} }
); );
} }
let start_notification = if cfg["notifications"].contains_key("service_start") { let start_notification = cfg["notifications"]["service_start"].clone().unwrap().to_string() == "true".to_string();
cfg["notifications"]["service_start"].clone().unwrap().to_string() == "true".to_string() let notification_email = cfg["notifications"]["email"].clone().unwrap();
} else { let notification_command = cfg["notifications"]["command"].clone().unwrap();
true
};
let notification_email = if cfg["notifications"].contains_key("email") { if start_notification {
cfg["notifications"]["email"].clone().unwrap()
} else {
"".to_string()
};
let notification_command = if cfg["notifications"].contains_key("command") {
cfg["notifications"]["command"].clone().unwrap()
} else {
"".to_string()
};
if start_notification && notification_command.to_string() != "" {
debug_log(format!("Service started")); debug_log(format!("Service started"));
let shell_cmd = notification_command.to_string() let shell_cmd = notification_command.to_string()
@ -263,13 +219,9 @@ fn main() {
loop { loop {
for i in 0..tasks.len() { for i in 0..tasks.len() {
let rt = tokio::runtime::Runtime::new().unwrap(); let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async { rt.block_on(async {
if check(tasks[i].uri.clone()).await { if check(tasks[i].uri.clone()).await {
if tasks[i].last_state != true || just_started { if tasks[i].last_state != true {
if tasks[i].command.to_string() == "".to_string() {
println!("{} state changed to true", tasks[i].uri);
} else {
debug_log(format!("{} state changed to true", tasks[i].uri)); debug_log(format!("{} state changed to true", tasks[i].uri));
let shell_cmd = tasks[i].command.to_string() let shell_cmd = tasks[i].command.to_string()
@ -281,16 +233,12 @@ fn main() {
execute(shell_cmd); execute(shell_cmd);
} }
}
debug_log(format!("{} check is ok", tasks[i].uri)); debug_log(format!("{} check is ok", tasks[i].uri));
tasks[i].last_state = true; tasks[i].last_state = true
} else {
if tasks[i].last_state != false || just_started {
if tasks[i].command.to_string() == "".to_string() {
println!("{} state changed to false", tasks[i].uri);
} else { } else {
if tasks[i].last_state != false {
debug_log(format!("{} state changed to false", tasks[i].uri)); debug_log(format!("{} state changed to false", tasks[i].uri));
let shell_cmd = tasks[i].command.to_string() let shell_cmd = tasks[i].command.to_string()
@ -301,14 +249,11 @@ fn main() {
debug_log(format!("execute {}", shell_cmd)); debug_log(format!("execute {}", shell_cmd));
execute(shell_cmd); execute(shell_cmd);
} }
}
debug_log(format!("{} check failed", tasks[i].uri)); debug_log(format!("{} check failed", tasks[i].uri));
tasks[i].last_state = false; tasks[i].last_state = false
} }
just_started = false;
}); });
} }