Compare commits
No commits in common. "08ff104659d36c8647b93f21b78dd71f976d627f" and "c3a572619f8f30a0f6bd079ab14b8f92d198f8d3" have entirely different histories.
08ff104659
...
c3a572619f
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,4 +9,3 @@
|
|||||||
|
|
||||||
# Build files
|
# Build files
|
||||||
target
|
target
|
||||||
Cargo.lock
|
|
||||||
|
|||||||
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -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"
|
||||||
|
|||||||
@ -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"
|
|
||||||
46
README.md
46
README.md
@ -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```
|
|
||||||
|
|||||||
127
src/main.rs
127
src/main.rs
@ -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,85 +171,43 @@ 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") {
|
debug_log(format!("rule {}", i));
|
||||||
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!("service {}", service));
|
debug_log(format!("service {}", service));
|
||||||
debug_log(format!("uri {}", uri));
|
debug_log(format!("uri {}", uri));
|
||||||
debug_log(format!("email {}", email));
|
debug_log(format!("email {}", email));
|
||||||
debug_log(format!("command {}", command));
|
debug_log(format!("command {}", command));
|
||||||
|
|
||||||
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()
|
||||||
.replace("<email>", ¬ification_email.to_string())
|
.replace("<email>", ¬ification_email.to_string())
|
||||||
.replace("<subject>", &format!("\"Watchdog service started\""))
|
.replace("<subject>", &format!("\"Watchdog service started\""))
|
||||||
.replace("<message>", &format!("\"Watchdog service started\""));
|
.replace("<message>", &format!("\"Watchdog service started\""));
|
||||||
|
|
||||||
@ -263,52 +219,41 @@ 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() {
|
debug_log(format!("{} state changed to true", tasks[i].uri));
|
||||||
println!("{} state changed to true", tasks[i].uri);
|
|
||||||
} else {
|
|
||||||
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()
|
||||||
.replace("<email>", &tasks[i].email)
|
.replace("<email>", &tasks[i].email)
|
||||||
.replace("<subject>", &format!("\"Service {} ({}) is online\"", tasks[i].service, tasks[i].uri))
|
.replace("<subject>", &format!("\"Service {} ({}) is online\"", tasks[i].service, tasks[i].uri))
|
||||||
.replace("<message>", &format!("\"Service {} ({}) is now online\"", tasks[i].service, tasks[i].uri));
|
.replace("<message>", &format!("\"Service {} ({}) is now online\"", tasks[i].service, tasks[i].uri));
|
||||||
|
|
||||||
debug_log(format!("execute {}", shell_cmd));
|
debug_log(format!("execute {}", shell_cmd));
|
||||||
|
|
||||||
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 {
|
} else {
|
||||||
if tasks[i].last_state != false || just_started {
|
if tasks[i].last_state != false {
|
||||||
if tasks[i].command.to_string() == "".to_string() {
|
debug_log(format!("{} state changed to false", tasks[i].uri));
|
||||||
println!("{} state changed to false", tasks[i].uri);
|
|
||||||
} else {
|
|
||||||
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()
|
||||||
.replace("<email>", &tasks[i].email)
|
.replace("<email>", &tasks[i].email)
|
||||||
.replace("<subject>", &format!("\"Service {} ({}) is offline\"", tasks[i].service, tasks[i].uri))
|
.replace("<subject>", &format!("\"Service {} ({}) is offline\"", tasks[i].service, tasks[i].uri))
|
||||||
.replace("<message>", &format!("\"Service {} ({}) is now offline\"", tasks[i].service, tasks[i].uri));
|
.replace("<message>", &format!("\"Service {} ({}) is now offline\"", tasks[i].service, tasks[i].uri));
|
||||||
|
|
||||||
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;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user