Initial Commit
This commit is contained in:
30
LICENSE
30
LICENSE
@@ -1,7 +1,4 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
---
|
||||
MIT License
|
||||
|
||||
Copyright ©
|
||||
|
||||
@@ -12,15 +9,20 @@ Blog: https://www.cleveradmin.de
|
||||
|
||||
---
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
74
README.md
74
README.md
@@ -4,26 +4,86 @@
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h1 align="center">Name des Projekts</h1>
|
||||
<h1 align="center">SSH Login Notifier</h1>
|
||||
|
||||
<h4 align="center">
|
||||
Kurzbeschreibung des Projekts/Anwendung, um die es geht
|
||||
Benachrichtigungen bei SSH-Logins per E-Mail und/oder ntfy.
|
||||
</h4>
|
||||
|
||||
<h6 align="center">
|
||||
<a href="https://www.cleveradmin.de">🏰 Website</a>
|
||||
<a href="https://www.cleveradmin.de">Website</a>
|
||||
·
|
||||
<a href="https://techniverse.net">📰 Community</a>
|
||||
<a href="https://techniverse.net">Community</a>
|
||||
·
|
||||
<a href="https://social.techniverse.net/@donnerwolke">🐘 Mastodon</a>
|
||||
<a href="https://social.techniverse.net/@donnerwolke">Mastodon</a>
|
||||
·
|
||||
<a href="https://matrix.to/#/#support:techniverse.net">💬 Support</a>
|
||||
<a href="https://matrix.to/#/#support:techniverse.net">Support</a>
|
||||
</h6>
|
||||
<br><br>
|
||||
|
||||
## Funktionen
|
||||
|
||||
CONTENT BEREICH
|
||||
- Benachrichtigung bei jedem SSH-Login
|
||||
- **E-Mail** und/oder **ntfy** als Benachrichtigungskanal (einzeln oder kombiniert)
|
||||
- **Geo-Location** der Quell-IP (Land, Stadt, Provider)
|
||||
- Shell-unabhängig dank **PAM-Integration** (funktioniert mit Bash, Zsh, Fish, etc.)
|
||||
- Einfache Konfiguration über eine zentrale `config.conf`
|
||||
- Installations- und Deinstallationsscript
|
||||
|
||||
## Schnellstart
|
||||
|
||||
### 1. Voraussetzungen prüfen
|
||||
|
||||
Siehe [Voraussetzungen](docs/prerequisites.md) (curl wird automatisch installiert, Mail-Tool muss ggf. manuell eingerichtet werden).
|
||||
|
||||
### 2. Repository klonen
|
||||
|
||||
```bash
|
||||
git clone https://git.techniverse.net/scriptos/ssh-login-notifier.git
|
||||
cd ssh-login-notifier
|
||||
```
|
||||
|
||||
### 3. Installation
|
||||
|
||||
```bash
|
||||
sudo bash install.sh
|
||||
```
|
||||
|
||||
### 4. Konfiguration anpassen
|
||||
|
||||
```bash
|
||||
sudo nano /opt/ssh-login-notifier/config.conf
|
||||
```
|
||||
|
||||
Siehe [Konfigurationsreferenz](docs/configuration.md) für alle Optionen.
|
||||
|
||||
### 5. Testen
|
||||
|
||||
Einfach per SSH auf den Server einloggen — die Benachrichtigung sollte sofort eintreffen.
|
||||
|
||||
## Deinstallation
|
||||
|
||||
```bash
|
||||
sudo /opt/ssh-login-notifier/uninstall.sh
|
||||
```
|
||||
|
||||
## Enthaltene Informationen
|
||||
|
||||
Jede Benachrichtigung enthält:
|
||||
|
||||
| Information | Beispiel |
|
||||
|---|---|
|
||||
| Hostname | `srv-web-01.example.com` |
|
||||
| Datum | `26.04.2026` |
|
||||
| Uhrzeit | `14:32:08` |
|
||||
| Benutzername | `admin` |
|
||||
| Quell-IP | `203.0.113.42` |
|
||||
| Standort | `Berlin, Berlin, Germany (Telekom)` |
|
||||
|
||||
## Dokumentation
|
||||
|
||||
- [Voraussetzungen](docs/prerequisites.md)
|
||||
- [Konfigurationsreferenz](docs/configuration.md)
|
||||
|
||||
<br><br>
|
||||
<p align="center">
|
||||
|
||||
43
config.conf
Normal file
43
config.conf
Normal file
@@ -0,0 +1,43 @@
|
||||
# ============================================================
|
||||
# SSH Login Notifier - Konfiguration
|
||||
# ============================================================
|
||||
# Benachrichtigungsmethode(n)
|
||||
# Erlaubte Werte: email, ntfy, email,ntfy
|
||||
NOTIFICATION_METHODS=ntfy
|
||||
|
||||
# ============================================================
|
||||
# E-Mail Einstellungen
|
||||
# ============================================================
|
||||
# Empfaenger-Adresse
|
||||
EMAIL_RECIPIENT=admin@example.com
|
||||
|
||||
# Absender-Adresse (wird nur von manchen Mail-Tools unterstuetzt)
|
||||
EMAIL_FROM=noreply@example.com
|
||||
|
||||
# Betreff-Prefix (Hostname wird automatisch angehaengt)
|
||||
EMAIL_SUBJECT_PREFIX=SSH Login
|
||||
|
||||
# ============================================================
|
||||
# ntfy Einstellungen
|
||||
# ============================================================
|
||||
# ntfy Server-URL (ohne abschliessendes /)
|
||||
NTFY_SERVER=https://ntfy.example.com
|
||||
|
||||
# ntfy Topic
|
||||
NTFY_TOPIC=ssh-login
|
||||
|
||||
# ntfy Prioritaet (1=min, 2=niedrig, 3=standard, 4=hoch, 5=max)
|
||||
NTFY_PRIORITY=3
|
||||
|
||||
# ntfy Tags (kommasepariert, Emoji-Shortcodes)
|
||||
NTFY_TAGS=warning,computer
|
||||
|
||||
# ntfy Auth-Token (leer lassen fuer Server ohne Authentifizierung)
|
||||
NTFY_AUTH_TOKEN=
|
||||
|
||||
# ============================================================
|
||||
# Erweiterte Einstellungen
|
||||
# ============================================================
|
||||
# Geo-Location der Quell-IP abfragen (true/false)
|
||||
# Nutzt die kostenlose API von ip-api.com (kein API-Key noetig)
|
||||
GEO_LOOKUP=true
|
||||
96
docs/configuration.md
Normal file
96
docs/configuration.md
Normal file
@@ -0,0 +1,96 @@
|
||||
# Konfiguration
|
||||
|
||||
Die Konfigurationsdatei befindet sich unter:
|
||||
|
||||
```
|
||||
/opt/ssh-login-notifier/config.conf
|
||||
```
|
||||
|
||||
Nach der Installation kann sie jederzeit bearbeitet werden:
|
||||
|
||||
```bash
|
||||
sudo nano /opt/ssh-login-notifier/config.conf
|
||||
```
|
||||
|
||||
Änderungen werden **sofort** beim nächsten SSH-Login wirksam — kein Neustart nötig.
|
||||
|
||||
## Benachrichtigungsmethoden
|
||||
|
||||
| Schlüssel | Werte | Beschreibung |
|
||||
|---|---|---|
|
||||
| `NOTIFICATION_METHODS` | `email`, `ntfy`, `email,ntfy` | Kommasepariert für mehrere Methoden |
|
||||
|
||||
## E-Mail Einstellungen
|
||||
|
||||
| Schlüssel | Beschreibung | Beispiel |
|
||||
|---|---|---|
|
||||
| `EMAIL_RECIPIENT` | Empfänger-Adresse | `admin@example.com` |
|
||||
| `EMAIL_FROM` | Absender-Adresse | `noreply@example.com` |
|
||||
| `EMAIL_SUBJECT_PREFIX` | Betreff-Prefix (Hostname wird angehängt) | `SSH Login` |
|
||||
|
||||
> Voraussetzung: Ein funktionierender Mail-Versand auf dem System (siehe [Voraussetzungen](prerequisites.md)).
|
||||
|
||||
## ntfy Einstellungen
|
||||
|
||||
| Schlüssel | Beschreibung | Beispiel |
|
||||
|---|---|---|
|
||||
| `NTFY_SERVER` | Server-URL (ohne `/` am Ende) | `https://ntfy.example.com` |
|
||||
| `NTFY_TOPIC` | Topic-Name | `ssh-login` |
|
||||
| `NTFY_PRIORITY` | Priorität (1–5) | `3` |
|
||||
| `NTFY_TAGS` | Emoji-Tags, kommasepariert | `warning,computer` |
|
||||
| `NTFY_AUTH_TOKEN` | Bearer-Token (leer = keine Auth) | `tk_abc123` |
|
||||
|
||||
### ntfy Prioritäten
|
||||
|
||||
| Wert | Bedeutung |
|
||||
|---|---|
|
||||
| `1` | Minimum |
|
||||
| `2` | Niedrig |
|
||||
| `3` | Standard |
|
||||
| `4` | Hoch |
|
||||
| `5` | Maximum (dringend) |
|
||||
|
||||
## Erweiterte Einstellungen
|
||||
|
||||
| Schlüssel | Werte | Beschreibung |
|
||||
|---|---|---|
|
||||
| `GEO_LOOKUP` | `true` / `false` | IP-Standort über ip-api.com abfragen |
|
||||
|
||||
## Beispielkonfigurationen
|
||||
|
||||
### Nur ntfy (einfachste Variante)
|
||||
|
||||
```conf
|
||||
NOTIFICATION_METHODS=ntfy
|
||||
NTFY_SERVER=https://ntfy.example.com
|
||||
NTFY_TOPIC=ssh-alerts
|
||||
NTFY_PRIORITY=4
|
||||
NTFY_TAGS=warning,skull
|
||||
NTFY_AUTH_TOKEN=tk_dein_token
|
||||
GEO_LOOKUP=true
|
||||
```
|
||||
|
||||
### Nur E-Mail
|
||||
|
||||
```conf
|
||||
NOTIFICATION_METHODS=email
|
||||
EMAIL_RECIPIENT=admin@example.com
|
||||
EMAIL_FROM=server@example.com
|
||||
EMAIL_SUBJECT_PREFIX=SSH Login
|
||||
GEO_LOOKUP=true
|
||||
```
|
||||
|
||||
### Beides kombiniert
|
||||
|
||||
```conf
|
||||
NOTIFICATION_METHODS=email,ntfy
|
||||
EMAIL_RECIPIENT=admin@example.com
|
||||
EMAIL_FROM=server@example.com
|
||||
EMAIL_SUBJECT_PREFIX=SSH Login
|
||||
NTFY_SERVER=https://ntfy.example.com
|
||||
NTFY_TOPIC=ssh-alerts
|
||||
NTFY_PRIORITY=3
|
||||
NTFY_TAGS=warning,computer
|
||||
NTFY_AUTH_TOKEN=
|
||||
GEO_LOOKUP=false
|
||||
```
|
||||
69
docs/prerequisites.md
Normal file
69
docs/prerequisites.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# Voraussetzungen
|
||||
|
||||
## Betriebssystem
|
||||
|
||||
- Debian 11+ (Bullseye oder neuer)
|
||||
- Ubuntu 20.04+
|
||||
- Andere Debian-basierte Distributionen sollten ebenfalls funktionieren
|
||||
|
||||
Architektur: x64 (amd64) und ARM (arm64/armhf) werden unterstützt.
|
||||
|
||||
## Abhängigkeiten
|
||||
|
||||
### Pflicht
|
||||
|
||||
| Paket | Zweck | Prüfung |
|
||||
|---|---|---|
|
||||
| `curl` | ntfy-Benachrichtigungen und Geo-Lookup | `command -v curl` |
|
||||
|
||||
> Das Installationsscript installiert fehlende Pflicht-Abhängigkeiten automatisch.
|
||||
|
||||
### Optional (für E-Mail)
|
||||
|
||||
Mindestens **eines** der folgenden Mail-Tools muss installiert und konfiguriert sein:
|
||||
|
||||
| Tool | Paket | Anmerkung |
|
||||
|---|---|---|
|
||||
| `mail` | `mailutils` oder `bsd-mailx` | Am weitesten verbreitet |
|
||||
| `msmtp` | `msmtp` + `msmtp-mta` | Leichtgewichtig, gut für Relay |
|
||||
| `sendmail` | `postfix` oder `sendmail` | Vollständiger MTA |
|
||||
|
||||
Das Script erkennt automatisch welches Tool verfügbar ist (Reihenfolge: mail → sendmail → msmtp).
|
||||
|
||||
### Optional (für Geo-Location)
|
||||
|
||||
Die Geo-Location nutzt die kostenlose API von [ip-api.com](http://ip-api.com). Dafür ist keine Registrierung oder API-Key nötig.
|
||||
|
||||
**Einschränkungen:**
|
||||
- Maximal 45 Anfragen pro Minute
|
||||
- Nur für nicht-kommerzielle Nutzung
|
||||
- Funktioniert nur mit öffentlichen IPs (lokale IPs wie 192.168.x.x liefern kein Ergebnis)
|
||||
|
||||
Die Geo-Location kann in der `config.conf` deaktiviert werden (`GEO_LOOKUP=false`).
|
||||
|
||||
## Shell-Kompatibilität
|
||||
|
||||
Das Script wird über `/etc/profile.d/` eingebunden und bei jedem interaktiven Login ausgeführt.
|
||||
|
||||
| Shell | Unterstützt | Mechanismus |
|
||||
|---|---|---|
|
||||
| Bash | Ja | `/etc/profile.d/` wird nativ geladen |
|
||||
| Zsh (oh-my-zsh) | Ja | `/etc/zsh/zprofile` sourct `/etc/profile` auf Debian/Ubuntu |
|
||||
| Sh / Dash | Ja | `/etc/profile.d/` wird nativ geladen |
|
||||
| Fish | Nein | Fish sourct `/etc/profile` nicht |
|
||||
|
||||
> **Hinweis:** Nur SSH-Verbindungen lösen eine Benachrichtigung aus. Lokale Logins, `su`, `sudo` und nicht-interaktive Verbindungen (SCP, SFTP, Monitoring-Tools wie PRTG) werden ignoriert.
|
||||
|
||||
## Funktionsweise
|
||||
|
||||
Das Installationsscript legt eine kleine Datei in `/etc/profile.d/` ab:
|
||||
|
||||
```bash
|
||||
# /etc/profile.d/ssh-login-notify.sh
|
||||
[ -n "$SSH_CONNECTION" ] && [ -x /opt/ssh-login-notifier/ssh-login-notify.sh ] && . /opt/ssh-login-notifier/ssh-login-notify.sh
|
||||
```
|
||||
|
||||
Diese Zeile prüft:
|
||||
1. Ist `$SSH_CONNECTION` gesetzt? (Nur bei SSH-Logins der Fall)
|
||||
2. Ist das Hauptscript vorhanden und ausführbar?
|
||||
3. Wenn ja → Hauptscript im Hintergrund ausführen (Login wird nicht verzögert)
|
||||
170
install.sh
Normal file
170
install.sh
Normal file
@@ -0,0 +1,170 @@
|
||||
#!/bin/bash
|
||||
# SSH Login Notifier - Installationsscript
|
||||
# https://git.techniverse.net/scriptos/ssh-login-notifier
|
||||
|
||||
set -e
|
||||
|
||||
INSTALL_DIR="/opt/ssh-login-notifier"
|
||||
PROFILE_HOOK="/etc/profile.d/ssh-login-notify.sh"
|
||||
ZSH_HOOK_MARKER="# SSH Login Notifier"
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
# --- Hilfsfunktionen ---
|
||||
|
||||
info() { echo -e "\e[32m[INFO]\e[0m $1"; }
|
||||
warn() { echo -e "\e[33m[WARN]\e[0m $1"; }
|
||||
error() { echo -e "\e[31m[ERROR]\e[0m $1"; exit 1; }
|
||||
|
||||
check_root() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
error "Dieses Script muss als root ausgefuehrt werden (sudo)."
|
||||
fi
|
||||
}
|
||||
|
||||
check_os() {
|
||||
if [[ ! -f /etc/os-release ]]; then
|
||||
error "Betriebssystem nicht erkannt. Nur Debian/Ubuntu werden unterstuetzt."
|
||||
fi
|
||||
. /etc/os-release
|
||||
case "$ID" in
|
||||
debian|ubuntu) info "Erkanntes OS: ${PRETTY_NAME}" ;;
|
||||
*) warn "Ungetestetes OS: ${PRETTY_NAME} - Installation wird fortgesetzt." ;;
|
||||
esac
|
||||
}
|
||||
|
||||
check_arch() {
|
||||
local arch
|
||||
arch="$(uname -m)"
|
||||
case "$arch" in
|
||||
x86_64) info "Architektur: x64 (amd64)" ;;
|
||||
aarch64) info "Architektur: ARM64 (aarch64)" ;;
|
||||
armv7l) info "Architektur: ARMv7 (armhf)" ;;
|
||||
*) warn "Ungetestete Architektur: ${arch}" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
check_dependencies() {
|
||||
local missing=()
|
||||
|
||||
if ! command -v curl &>/dev/null; then
|
||||
missing+=("curl")
|
||||
fi
|
||||
|
||||
if ! command -v mail &>/dev/null && ! command -v sendmail &>/dev/null && ! command -v msmtp &>/dev/null; then
|
||||
warn "Kein Mail-Tool gefunden (mail, sendmail, msmtp)."
|
||||
warn "E-Mail-Benachrichtigungen funktionieren erst nach Installation eines Mail-Tools."
|
||||
fi
|
||||
|
||||
if [[ ${#missing[@]} -gt 0 ]]; then
|
||||
info "Installiere fehlende Abhaengigkeiten: ${missing[*]}"
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq "${missing[@]}"
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Installation ---
|
||||
|
||||
install_files() {
|
||||
info "Erstelle Installationsverzeichnis: ${INSTALL_DIR}"
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
|
||||
info "Kopiere Dateien..."
|
||||
cp "${SCRIPT_DIR}/ssh-login-notify.sh" "${INSTALL_DIR}/ssh-login-notify.sh"
|
||||
cp "${SCRIPT_DIR}/uninstall.sh" "${INSTALL_DIR}/uninstall.sh"
|
||||
|
||||
if [[ -f "${INSTALL_DIR}/config.conf" ]]; then
|
||||
warn "Bestehende config.conf gefunden - wird nicht ueberschrieben."
|
||||
info "Neue Konfiguration als config.conf.new abgelegt."
|
||||
cp "${SCRIPT_DIR}/config.conf" "${INSTALL_DIR}/config.conf.new"
|
||||
else
|
||||
cp "${SCRIPT_DIR}/config.conf" "${INSTALL_DIR}/config.conf"
|
||||
fi
|
||||
|
||||
chmod 755 "${INSTALL_DIR}/ssh-login-notify.sh"
|
||||
chmod 755 "${INSTALL_DIR}/uninstall.sh"
|
||||
chmod 644 "${INSTALL_DIR}/config.conf"
|
||||
chown root:root "${INSTALL_DIR}" -R
|
||||
|
||||
info "Dateien installiert nach ${INSTALL_DIR}"
|
||||
}
|
||||
|
||||
install_profile_hook() {
|
||||
if [[ -f "$PROFILE_HOOK" ]]; then
|
||||
info "Profile-Hook ist bereits vorhanden."
|
||||
return
|
||||
fi
|
||||
|
||||
info "Erstelle Profile-Hook: ${PROFILE_HOOK}"
|
||||
cat > "$PROFILE_HOOK" << 'HOOKEOF'
|
||||
# SSH Login Notifier - wird bei interaktivem Login ausgefuehrt
|
||||
# Installiert von: https://git.techniverse.net/scriptos/ssh-login-notifier
|
||||
[ -n "$SSH_CONNECTION" ] && [ -x /opt/ssh-login-notifier/ssh-login-notify.sh ] && /opt/ssh-login-notifier/ssh-login-notify.sh
|
||||
HOOKEOF
|
||||
|
||||
chmod 644 "$PROFILE_HOOK"
|
||||
info "Profile-Hook aktiviert (Bash, Sh)."
|
||||
}
|
||||
|
||||
install_zsh_hook() {
|
||||
local zshrc="/etc/zsh/zshrc"
|
||||
|
||||
if [[ ! -f "$zshrc" ]]; then
|
||||
info "Keine /etc/zsh/zshrc gefunden - Zsh-Hook wird uebersprungen."
|
||||
return
|
||||
fi
|
||||
|
||||
if grep -qF "$ZSH_HOOK_MARKER" "$zshrc" 2>/dev/null; then
|
||||
info "Zsh-Hook ist bereits in ${zshrc} vorhanden."
|
||||
return
|
||||
fi
|
||||
|
||||
info "Fuege Zsh-Hook in ${zshrc} ein..."
|
||||
cat >> "$zshrc" << 'HOOKEOF'
|
||||
|
||||
# SSH Login Notifier
|
||||
# Installiert von: https://git.techniverse.net/scriptos/ssh-login-notifier
|
||||
[ -n "$SSH_CONNECTION" ] && [ -x /opt/ssh-login-notifier/ssh-login-notify.sh ] && /opt/ssh-login-notifier/ssh-login-notify.sh
|
||||
HOOKEOF
|
||||
|
||||
info "Zsh-Hook aktiviert."
|
||||
}
|
||||
|
||||
print_summary() {
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo " SSH Login Notifier - Installation"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo " Status: Installiert und aktiv"
|
||||
echo " Version: 1.0.0"
|
||||
echo " Pfad: ${INSTALL_DIR}"
|
||||
echo " Konfig: ${INSTALL_DIR}/config.conf"
|
||||
echo " Hook: ${PROFILE_HOOK}"
|
||||
echo ""
|
||||
echo " Naechste Schritte:"
|
||||
echo " 1. Konfiguration anpassen:"
|
||||
echo " sudo nano ${INSTALL_DIR}/config.conf"
|
||||
echo ""
|
||||
echo " 2. Test durch SSH-Login auf diesen Server"
|
||||
echo ""
|
||||
echo " Deinstallation:"
|
||||
echo " sudo ${INSTALL_DIR}/uninstall.sh"
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
}
|
||||
|
||||
# --- Hauptprogramm ---
|
||||
|
||||
echo ""
|
||||
echo "SSH Login Notifier - Installation"
|
||||
echo "================================="
|
||||
echo ""
|
||||
|
||||
check_root
|
||||
check_os
|
||||
check_arch
|
||||
check_dependencies
|
||||
install_files
|
||||
install_profile_hook
|
||||
install_zsh_hook
|
||||
print_summary
|
||||
143
ssh-login-notify.sh
Normal file
143
ssh-login-notify.sh
Normal file
@@ -0,0 +1,143 @@
|
||||
#!/bin/bash
|
||||
# SSH Login Notifier - Hauptscript
|
||||
# Wird ueber /etc/profile.d/ bei interaktivem SSH-Login aufgerufen
|
||||
# https://git.techniverse.net/scriptos/ssh-login-notifier
|
||||
|
||||
# Nur bei SSH-Verbindungen ausfuehren
|
||||
[[ -z "$SSH_CONNECTION" ]] && return 0 2>/dev/null || [[ -z "$SSH_CONNECTION" ]] && exit 0
|
||||
|
||||
INSTALL_DIR="/opt/ssh-login-notifier"
|
||||
CONFIG_FILE="${INSTALL_DIR}/config.conf"
|
||||
VERSION="1.0.0"
|
||||
|
||||
# Im Hintergrund ausfuehren, damit der Login nicht verzoegert wird
|
||||
(
|
||||
|
||||
# --- Konfiguration laden ---
|
||||
|
||||
load_config() {
|
||||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||
logger -t ssh-login-notifier "FEHLER: Konfigurationsdatei nicht gefunden: ${CONFIG_FILE}"
|
||||
exit 0
|
||||
fi
|
||||
while IFS='=' read -r key value; do
|
||||
key=$(echo "$key" | xargs)
|
||||
value=$(echo "$value" | xargs)
|
||||
[[ -z "$key" || "$key" == \#* ]] && continue
|
||||
declare -g "$key=$value"
|
||||
done < "$CONFIG_FILE"
|
||||
}
|
||||
|
||||
# --- Login-Informationen sammeln ---
|
||||
|
||||
collect_login_info() {
|
||||
LOGIN_USER="$USER"
|
||||
LOGIN_HOST="$(hostname -f 2>/dev/null || hostname)"
|
||||
LOGIN_DATE="$(date +%d.%m.%Y)"
|
||||
LOGIN_TIME="$(date +%H:%M:%S)"
|
||||
LOGIN_IP="${SSH_CLIENT%% *}"
|
||||
LOGIN_IP="${LOGIN_IP:-unbekannt}"
|
||||
|
||||
GEO_INFO=""
|
||||
if [[ "$GEO_LOOKUP" == "true" && "$LOGIN_IP" != "unbekannt" ]]; then
|
||||
GEO_JSON=$(curl -s --max-time 5 "http://ip-api.com/json/${LOGIN_IP}?fields=status,country,regionName,city,isp" 2>/dev/null)
|
||||
if echo "$GEO_JSON" | grep -q '"status":"success"'; then
|
||||
GEO_COUNTRY=$(echo "$GEO_JSON" | grep -o '"country":"[^"]*"' | cut -d'"' -f4)
|
||||
GEO_REGION=$(echo "$GEO_JSON" | grep -o '"regionName":"[^"]*"' | cut -d'"' -f4)
|
||||
GEO_CITY=$(echo "$GEO_JSON" | grep -o '"city":"[^"]*"' | cut -d'"' -f4)
|
||||
GEO_ISP=$(echo "$GEO_JSON" | grep -o '"isp":"[^"]*"' | cut -d'"' -f4)
|
||||
GEO_INFO="${GEO_CITY}, ${GEO_REGION}, ${GEO_COUNTRY} (${GEO_ISP})"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# --- E-Mail senden ---
|
||||
|
||||
send_email() {
|
||||
local subject="${EMAIL_SUBJECT_PREFIX} auf ${LOGIN_HOST}"
|
||||
local body=""
|
||||
body+="SSH-Zugriff erkannt\n"
|
||||
body+="==============================\n\n"
|
||||
body+="Server: ${LOGIN_HOST}\n"
|
||||
body+="Datum: ${LOGIN_DATE}\n"
|
||||
body+="Uhrzeit: ${LOGIN_TIME}\n"
|
||||
body+="Benutzer: ${LOGIN_USER}\n"
|
||||
body+="Quell-IP: ${LOGIN_IP}\n"
|
||||
if [[ -n "$GEO_INFO" ]]; then
|
||||
body+="Standort: ${GEO_INFO}\n"
|
||||
fi
|
||||
|
||||
if command -v mail &>/dev/null; then
|
||||
echo -e "$body" | mail -s "$subject" "$EMAIL_RECIPIENT"
|
||||
elif command -v sendmail &>/dev/null; then
|
||||
{
|
||||
echo "Subject: ${subject}"
|
||||
echo "From: ${EMAIL_FROM}"
|
||||
echo "To: ${EMAIL_RECIPIENT}"
|
||||
echo "Content-Type: text/plain; charset=UTF-8"
|
||||
echo ""
|
||||
echo -e "$body"
|
||||
} | sendmail "$EMAIL_RECIPIENT"
|
||||
elif command -v msmtp &>/dev/null; then
|
||||
{
|
||||
echo "Subject: ${subject}"
|
||||
echo "From: ${EMAIL_FROM}"
|
||||
echo "To: ${EMAIL_RECIPIENT}"
|
||||
echo "Content-Type: text/plain; charset=UTF-8"
|
||||
echo ""
|
||||
echo -e "$body"
|
||||
} | msmtp "$EMAIL_RECIPIENT"
|
||||
else
|
||||
logger -t ssh-login-notifier "FEHLER: Kein Mail-Tool gefunden (mail, sendmail, msmtp)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# --- ntfy senden ---
|
||||
|
||||
send_ntfy() {
|
||||
local title="SSH Login registriert"
|
||||
local message=""
|
||||
message+="Es wurde ein SSH Login auf ${LOGIN_HOST} registriert.\n"
|
||||
message+="\n"
|
||||
message+="Datum: ${LOGIN_DATE}\n"
|
||||
message+="Uhrzeit: ${LOGIN_TIME}\n"
|
||||
message+="Benutzer: ${LOGIN_USER}\n"
|
||||
message+="IP-Adresse des Clients: ${LOGIN_IP}"
|
||||
if [[ -n "$GEO_INFO" ]]; then
|
||||
message+="\nStandort: ${GEO_INFO}"
|
||||
fi
|
||||
|
||||
local -a curl_args=(
|
||||
-s
|
||||
--max-time 10
|
||||
-H "Title: ${title}"
|
||||
-H "Priority: ${NTFY_PRIORITY:-3}"
|
||||
-H "Tags: ${NTFY_TAGS:-warning,computer}"
|
||||
-d "$(echo -e "$message")"
|
||||
)
|
||||
|
||||
if [[ -n "$NTFY_AUTH_TOKEN" ]]; then
|
||||
curl_args+=(-H "Authorization: Bearer ${NTFY_AUTH_TOKEN}")
|
||||
fi
|
||||
|
||||
curl "${curl_args[@]}" "${NTFY_SERVER}/${NTFY_TOPIC}" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# --- Hauptprogramm ---
|
||||
|
||||
load_config
|
||||
collect_login_info
|
||||
|
||||
IFS=',' read -ra METHODS <<< "$NOTIFICATION_METHODS"
|
||||
for method in "${METHODS[@]}"; do
|
||||
method=$(echo "$method" | xargs)
|
||||
case "$method" in
|
||||
email) send_email ;;
|
||||
ntfy) send_ntfy ;;
|
||||
*) logger -t ssh-login-notifier "Unbekannte Methode: ${method}" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
) &>/dev/null &
|
||||
disown
|
||||
78
uninstall.sh
Normal file
78
uninstall.sh
Normal file
@@ -0,0 +1,78 @@
|
||||
#!/bin/bash
|
||||
# SSH Login Notifier - Deinstallationsscript
|
||||
# https://git.techniverse.net/scriptos/ssh-login-notifier
|
||||
|
||||
set -e
|
||||
|
||||
INSTALL_DIR="/opt/ssh-login-notifier"
|
||||
PROFILE_HOOK="/etc/profile.d/ssh-login-notify.sh"
|
||||
ZSH_HOOK_MARKER="# SSH Login Notifier"
|
||||
|
||||
# --- Hilfsfunktionen ---
|
||||
|
||||
info() { echo -e "\e[32m[INFO]\e[0m $1"; }
|
||||
warn() { echo -e "\e[33m[WARN]\e[0m $1"; }
|
||||
error() { echo -e "\e[31m[ERROR]\e[0m $1"; exit 1; }
|
||||
|
||||
check_root() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
error "Dieses Script muss als root ausgefuehrt werden (sudo)."
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Deinstallation ---
|
||||
|
||||
remove_profile_hook() {
|
||||
if [[ -f "$PROFILE_HOOK" ]]; then
|
||||
info "Entferne Profile-Hook: ${PROFILE_HOOK}"
|
||||
rm -f "$PROFILE_HOOK"
|
||||
info "Profile-Hook entfernt."
|
||||
else
|
||||
info "Kein Profile-Hook gefunden - nichts zu entfernen."
|
||||
fi
|
||||
}
|
||||
|
||||
remove_zsh_hook() {
|
||||
local zshrc="/etc/zsh/zshrc"
|
||||
if [[ -f "$zshrc" ]] && grep -qF "$ZSH_HOOK_MARKER" "$zshrc" 2>/dev/null; then
|
||||
info "Entferne Zsh-Hook aus ${zshrc}"
|
||||
sed -i "/^${ZSH_HOOK_MARKER}/,+2d" "$zshrc"
|
||||
sed -i '/^$/N;/^\n$/d' "$zshrc"
|
||||
info "Zsh-Hook entfernt."
|
||||
else
|
||||
info "Kein Zsh-Hook gefunden - nichts zu entfernen."
|
||||
fi
|
||||
}
|
||||
|
||||
remove_files() {
|
||||
if [[ -d "$INSTALL_DIR" ]]; then
|
||||
info "Entferne Installationsverzeichnis: ${INSTALL_DIR}"
|
||||
rm -rf "$INSTALL_DIR"
|
||||
info "Dateien entfernt."
|
||||
else
|
||||
info "Installationsverzeichnis nicht gefunden - nichts zu entfernen."
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Hauptprogramm ---
|
||||
|
||||
echo ""
|
||||
echo "SSH Login Notifier - Deinstallation"
|
||||
echo "===================================="
|
||||
echo ""
|
||||
|
||||
check_root
|
||||
|
||||
read -p "SSH Login Notifier wirklich deinstallieren? (j/N) " confirm
|
||||
if [[ "$confirm" != "j" && "$confirm" != "J" ]]; then
|
||||
info "Abgebrochen."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
remove_profile_hook
|
||||
remove_zsh_hook
|
||||
remove_files
|
||||
|
||||
echo ""
|
||||
info "SSH Login Notifier wurde vollstaendig deinstalliert."
|
||||
echo ""
|
||||
Reference in New Issue
Block a user