mirror of
https://forgejo.altau.su/lego/lego-monitoring.git
synced 2026-03-10 04:41:10 +00:00
login alerts
This commit is contained in:
parent
3eb358d618
commit
0e177210f6
10 changed files with 85 additions and 5 deletions
11
README.md
11
README.md
|
|
@ -13,8 +13,17 @@ DISCLAIMER: This repository does not have anything to do with the LEGO Group. "l
|
||||||
* Copy `config.example.json` to `config.json`, edit as necessary
|
* Copy `config.example.json` to `config.json`, edit as necessary
|
||||||
* Run `alerting/login.py` once to login into Matrix
|
* Run `alerting/login.py` once to login into Matrix
|
||||||
|
|
||||||
|
### Setting up login alerts
|
||||||
|
|
||||||
|
* Copy `lego-login-alert` to your `/etc/sudoers.d`
|
||||||
|
* Add this to your `/etc/ssh/sshd_config`:
|
||||||
|
```
|
||||||
|
# login alerts
|
||||||
|
ForceCommand /opt/lego-monitoring/wrappers/login_wrapper.sh
|
||||||
|
```
|
||||||
|
|
||||||
## Running
|
## Running
|
||||||
|
|
||||||
* `prettyprint.py` -- check and print all sensors
|
* `prettyprint.py` -- check and print all sensors
|
||||||
* `service.py` -- launch service
|
* `service.py` -- launch service
|
||||||
* `lego-monitoring.service` is a systemd unit that starts `service.py`
|
* `assets/lego-monitoring.service` is a systemd unit that starts `service.py`
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,10 @@
|
||||||
import json
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import aiofiles
|
|
||||||
import nio
|
import nio
|
||||||
|
|
||||||
from alerting.enum import AlertType, Severity
|
from alerting.enum import AlertType, Severity
|
||||||
from misc import cvars
|
from misc import cvars
|
||||||
from misc.common import CONFIG_FILE
|
|
||||||
from misc.config import get_config
|
from misc.config import get_config
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ class AlertType(StrEnum):
|
||||||
CPU = "CPU"
|
CPU = "CPU"
|
||||||
TEMP = "TEMP"
|
TEMP = "TEMP"
|
||||||
VULN = "VULN"
|
VULN = "VULN"
|
||||||
LOGIN = "LOGIN" # TODO
|
LOGIN = "LOGIN"
|
||||||
SMART = "SMART" # TODO
|
SMART = "SMART" # TODO
|
||||||
RAID = "RAID"
|
RAID = "RAID"
|
||||||
DISKS = "DISKS"
|
DISKS = "DISKS"
|
||||||
|
|
|
||||||
2
assets/lego-login-alert
Normal file
2
assets/lego-login-alert
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
Defaults env_keep += "SSH_CLIENT"
|
||||||
|
ALL ALL=(ALL:ALL) NOPASSWD: /opt/lego-monitoring/wrappers/send_login_alert.sh
|
||||||
|
|
@ -22,6 +22,9 @@
|
||||||
"severity": "CRITICAL"
|
"severity": "CRITICAL"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
"hostname": "example.com"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,11 +38,17 @@ class CheckWearoutConfig(NestedDeserializableDataclass):
|
||||||
disks: list[CheckWearoutDiskConfig]
|
disks: list[CheckWearoutDiskConfig]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class CheckLoginConfig:
|
||||||
|
hostname: str
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ChecksConfig(NestedDeserializableDataclass):
|
class ChecksConfig(NestedDeserializableDataclass):
|
||||||
docker_registry: CheckDockerRegistryConfig
|
docker_registry: CheckDockerRegistryConfig
|
||||||
raid: CheckRaidConfig
|
raid: CheckRaidConfig
|
||||||
wearout: CheckWearoutConfig
|
wearout: CheckWearoutConfig
|
||||||
|
login: CheckLoginConfig
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|
|
||||||
47
send_login_alert.py
Normal file
47
send_login_alert.py
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
import asyncio
|
||||||
|
import os
|
||||||
|
import socket
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from alerting import alerts
|
||||||
|
from alerting.enum import AlertType, Severity
|
||||||
|
from misc.config import get_config
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
check_config = get_config().checks.login
|
||||||
|
|
||||||
|
try:
|
||||||
|
from_where = os.environ["SSH_CLIENT"].split()[0]
|
||||||
|
except:
|
||||||
|
from_where = os.ttyname(sys.stdout.fileno())
|
||||||
|
is_local = True
|
||||||
|
else:
|
||||||
|
is_local = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
actual_user = os.environ["SUDO_USER"]
|
||||||
|
except Exception as exc:
|
||||||
|
await alerts.send_alert(
|
||||||
|
alerts.Alert(
|
||||||
|
alert_type=AlertType.ERROR,
|
||||||
|
message=f"Failed to determine username for login from {from_where}, see logs",
|
||||||
|
severity=Severity.CRITICAL,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
if not is_local:
|
||||||
|
rdns_result = socket.getnameinfo((from_where, 0), 0)[0]
|
||||||
|
message = f"Login from {from_where} as {actual_user} on `{check_config.hostname}`"
|
||||||
|
html_message = f"Login from <code>{from_where}</code> ({rdns_result}) as {actual_user} on <code>{check_config.hostname}</code>"
|
||||||
|
else:
|
||||||
|
message = f"Login from {from_where} as {actual_user} on {check_config.hostname}"
|
||||||
|
html_message = f"Login from {from_where} as {actual_user} on <code>{check_config.hostname}</code>"
|
||||||
|
|
||||||
|
alert = alerts.Alert(alert_type=AlertType.LOGIN, message=message, severity=Severity.INFO, html_message=html_message)
|
||||||
|
await alerts.send_alert(alert)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
||||||
12
wrappers/login_wrapper.sh
Executable file
12
wrappers/login_wrapper.sh
Executable file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
mydir=$(dirname "$0")
|
||||||
|
sudo "$mydir/send_login_alert.sh"
|
||||||
|
|
||||||
|
shell=$(getent passwd $LOGNAME | cut -d: -f7)
|
||||||
|
if [[ -n $SSH_ORIGINAL_COMMAND ]] # command given, so run it
|
||||||
|
then
|
||||||
|
exec "$shell" -c "$SSH_ORIGINAL_COMMAND"
|
||||||
|
else # no command, so interactive login shell
|
||||||
|
exec "$shell" -il
|
||||||
|
fi
|
||||||
4
wrappers/send_login_alert.sh
Executable file
4
wrappers/send_login_alert.sh
Executable file
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
mydir=$(dirname "$0")
|
||||||
|
"$mydir/../.venv/bin/python" "$mydir/../send_login_alert.py"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue