login alerts

This commit is contained in:
Alex 2025-01-07 02:52:19 +03:00
parent 3eb358d618
commit 0e177210f6
10 changed files with 85 additions and 5 deletions

View file

@ -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`

View file

@ -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

View file

@ -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
View file

@ -0,0 +1,2 @@
Defaults env_keep += "SSH_CLIENT"
ALL ALL=(ALL:ALL) NOPASSWD: /opt/lego-monitoring/wrappers/send_login_alert.sh

View file

@ -22,6 +22,9 @@
"severity": "CRITICAL" "severity": "CRITICAL"
} }
] ]
},
"login": {
"hostname": "example.com"
} }
} }
} }

View file

@ -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
View 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
View 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
View file

@ -0,0 +1,4 @@
#!/bin/bash
mydir=$(dirname "$0")
"$mydir/../.venv/bin/python" "$mydir/../send_login_alert.py"