more tools
This commit is contained in:
26
README.md
26
README.md
@@ -1,27 +1,5 @@
|
|||||||
# server-toolset
|
# server-toolset
|
||||||
|
|
||||||
## login-mailer.sh
|
A collection of self-contained programs and scripts to manage different scenarios surrounding homelab, development and production server management.
|
||||||
|
|
||||||
Get an email when someone logs in on your server. Depends on `rsyslog` and `/var/log/auth.log`.
|
Built upon my personal experience of self hosting.
|
||||||
|
|
||||||
Requires you to host/use an email proxy. See [git.fybx.dev/fyb/mail-proxy](https://git.fybx.dev/fyb/mail-proxy) for a simple Express.js and nodemailer powered alternative. Fork and deploy to Vercel, it's set!
|
|
||||||
|
|
||||||
Change `EMAIL` and `ENDPOINT` environment variables in `login-mailer.service.template` and copy to `login-mailer.service`. Run `install.sh`.
|
|
||||||
|
|
||||||
`install.sh` and `uninstall.sh` provided for ease-of-use, places systemctl service and timer, and enables it.
|
|
||||||
|
|
||||||
## credits
|
|
||||||
|
|
||||||
Feel free to contact me for collaboration on anything!
|
|
||||||
|
|
||||||
Yiğid BALABAN, <[fyb@fybx.dev][llmail]>
|
|
||||||
|
|
||||||
[My Website][llwebsite] • [My Bento][llbento] • [X][llx] • [LinkedIn][lllinkedin]
|
|
||||||
|
|
||||||
2024
|
|
||||||
|
|
||||||
[llmail]: mailto:fyb@fybx.dev
|
|
||||||
[llwebsite]: https://fybx.dev
|
|
||||||
[llbento]: https://bento.me/balaban
|
|
||||||
[llx]: https://x.com/fybalaban
|
|
||||||
[lllinkedin]: https://linkedin.com/in/fybx
|
|
||||||
|
|||||||
5
derpcheck-ssh/README.md
Normal file
5
derpcheck-ssh/README.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# server-toolset
|
||||||
|
|
||||||
|
## derpcheck-ssh
|
||||||
|
|
||||||
|
See connection details while SSH'ing to a remote with Tailscale.
|
||||||
12
derpcheck-ssh/ssh.fish
Normal file
12
derpcheck-ssh/ssh.fish
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
function ssh --wraps ssh
|
||||||
|
if test (count $argv) -eq 1
|
||||||
|
set -l target_host $argv[1]
|
||||||
|
set -l ts_status (tailscale status | grep -i -- "$target_host")
|
||||||
|
if test -n "$ts_status"
|
||||||
|
echo "$ts_status"
|
||||||
|
echo ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
command ssh $argv
|
||||||
|
end
|
||||||
30
login-mailer/README.md
Normal file
30
login-mailer/README.md
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# server-toolset
|
||||||
|
|
||||||
|
## login-mailer.sh \[ARCHIVED\]
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> Please do not use this.
|
||||||
|
> Use ssh-notify instead.
|
||||||
|
|
||||||
|
Get an email when someone logs in on your server. Depends on `rsyslog` and `/var/log/auth.log`.
|
||||||
|
|
||||||
|
Requires you to host/use an email proxy. See [git.fybx.dev/fyb/mail-proxy](https://git.fybx.dev/fyb/mail-proxy) for a simple Express.js and nodemailer powered alternative. Fork and deploy to Vercel, it's set!
|
||||||
|
|
||||||
|
Change `EMAIL` and `ENDPOINT` environment variables in `login-mailer.service.template` and copy to `login-mailer.service`. Run `install.sh`.
|
||||||
|
|
||||||
|
`install.sh` and `uninstall.sh` provided for ease-of-use, places systemctl service and timer, and enables it.
|
||||||
|
|
||||||
|
## credits
|
||||||
|
|
||||||
|
Feel free to contact me for collaboration on anything!
|
||||||
|
|
||||||
|
Yiğid BALABAN, <[fyb@fybx.dev][llmail]>
|
||||||
|
|
||||||
|
[My Website][llwebsite] • [X][llx] • [LinkedIn][lllinkedin]
|
||||||
|
|
||||||
|
2024
|
||||||
|
|
||||||
|
[llmail]: mailto:fyb@fybx.dev
|
||||||
|
[llwebsite]: https://fybx.dev
|
||||||
|
[llx]: https://x.com/fybalaban
|
||||||
|
[lllinkedin]: https://linkedin.com/in/fybx
|
||||||
0
login-mailer.sh → login-mailer/login-mailer.sh
Executable file → Normal file
0
login-mailer.sh → login-mailer/login-mailer.sh
Executable file → Normal file
66
ssh-notify/README.md
Normal file
66
ssh-notify/README.md
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
# server-toolset
|
||||||
|
|
||||||
|
## ssh-notify
|
||||||
|
|
||||||
|
Get notified through emails or Telegram messages when a user logs in to your server. Uses PAM modules, and a single Bash script!
|
||||||
|
|
||||||
|
### Why use this?
|
||||||
|
|
||||||
|
- It's plug-and-play: use emails with []() or Telegram, or both.
|
||||||
|
- Distro agnostic: uses PAM and Bash with the least amount of surface.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Run `install.sh` to automate the steps below.
|
||||||
|
|
||||||
|
### 1. The script
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cp ssh-notify.sh /usr/local/sbin/ssh-notify.sh
|
||||||
|
chmod 700 /usr/local/sbin/ssh-notify.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Configuration
|
||||||
|
|
||||||
|
```sh
|
||||||
|
mkdir /etc/ssh-notify
|
||||||
|
cp example.conf /etc/ssh-notify/config.conf
|
||||||
|
vim /etc/ssh-notify/config.conf # edit in place
|
||||||
|
chmod 600 /etc/ssh-notify/config.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. PAM configuration
|
||||||
|
|
||||||
|
```sh
|
||||||
|
vim /etc/pam.d/sshd # edit in place and add the following lines:
|
||||||
|
```
|
||||||
|
|
||||||
|
```conf
|
||||||
|
# Send notification upon successful login (added by ssh-notify install.sh)
|
||||||
|
session optional pam_exec.so seteuid /usr/local/sbin/ssh-notify.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Logging
|
||||||
|
|
||||||
|
Optional, but suggested:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cp ssh-notify.logrotate /etc/logrotate.d/ssh-notify
|
||||||
|
```
|
||||||
|
|
||||||
|
The `ssh-notify.logrotate` tells `logrotate` to rotate `/var/log/ssh‑notify.log` once a day, keep seven old copies, compress older archives (but delay compressing the newest one), skip rotation if the file is empty or missing, and after each rotation immediately create a fresh log with permissions `600` owned by `root:root`; the `sharedscripts` directive ensures any `postrotate` commands (none are defined here) would only run once even if multiple files were listed.
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
Feel free to contact me for collaboration on anything!
|
||||||
|
|
||||||
|
Yiğid BALABAN, <[fyb@fybx.dev][llmail]>
|
||||||
|
|
||||||
|
[My Website][llwebsite] • [X][llx] • [LinkedIn][lllinkedin]
|
||||||
|
|
||||||
|
2024
|
||||||
|
|
||||||
|
[llmail]: mailto:fyb@fybx.dev
|
||||||
|
[llwebsite]: https://fybx.dev
|
||||||
|
[llx]: https://x.com/fybalaban
|
||||||
|
[lllinkedin]: https://linkedin.com/in/fybx
|
||||||
10
ssh-notify/example.conf
Normal file
10
ssh-notify/example.conf
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Email Notification Settings
|
||||||
|
EMAIL_RECIPIENT=""
|
||||||
|
EMAIL_API_ENDPOINT="https://mail-proxy.example.org/api/mail"
|
||||||
|
|
||||||
|
# Telegram Notification Settings
|
||||||
|
TELEGRAM_BOT_TOKEN=""
|
||||||
|
TELEGRAM_CHAT_ID=""
|
||||||
|
|
||||||
|
# Log file for the notifier script
|
||||||
|
LOG_FILE="/var/log/ssh-notify.log"
|
||||||
97
ssh-notify/install.sh
Normal file
97
ssh-notify/install.sh
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# install.sh
|
||||||
|
# part of ssh-notify from server-toolset
|
||||||
|
# 2025 © Yigid BALABAN <fyb@fybx.dev>
|
||||||
|
|
||||||
|
# This script must be run as root. It installs the SSH login notification script,
|
||||||
|
# example config, updates PAM, and installs a logrotate config in a transactional manner.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Ensure running as root
|
||||||
|
if [[ "$(id -u)" -ne 0 ]]; then
|
||||||
|
echo "Error: This script must be run as root." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create temporary directory for backups
|
||||||
|
BACKUP_DIR="$(mktemp -d)"
|
||||||
|
|
||||||
|
# Rollback function on error
|
||||||
|
rollback() {
|
||||||
|
echo "Error encountered. Rolling back changes..." >&2
|
||||||
|
[[ -f "$BACKUP_DIR/sshd.bak" ]] && mv "$BACKUP_DIR/sshd.bak" /etc/pam.d/sshd
|
||||||
|
[[ -f "$BACKUP_DIR/ssh-notify.sh.bak" ]] && mv "$BACKUP_DIR/ssh-notify.sh.bak" /usr/local/sbin/ssh-notify.sh
|
||||||
|
[[ -f "$BACKUP_DIR/config.conf.bak" ]] && mv "$BACKUP_DIR/config.conf.bak" /etc/ssh-notify/config.conf
|
||||||
|
[[ -f "$BACKUP_DIR/ssh-notify.logrotate.bak" ]] && mv "$BACKUP_DIR/ssh-notify.logrotate.bak" /etc/logrotate.d/ssh-notify
|
||||||
|
rm -rf "$BACKUP_DIR"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
trap rollback ERR
|
||||||
|
trap 'rm -rf "$BACKUP_DIR"' EXIT
|
||||||
|
|
||||||
|
# Determine script and config sources (relative to this install.sh)
|
||||||
|
_project_root="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
SCRIPT_SRC="${_project_root}/ssh-notify.sh"
|
||||||
|
CONF_SRC="${_project_root}/example.conf"
|
||||||
|
LOGROTATE_SRC="${_project_root}/ssh-notify.logrotate"
|
||||||
|
|
||||||
|
# Destinations
|
||||||
|
SCRIPT_DEST="/usr/local/sbin/ssh-notify.sh"
|
||||||
|
CONF_DIR="/etc/ssh-notify"
|
||||||
|
CONF_DEST="${CONF_DIR}/config.conf"
|
||||||
|
PAM_FILE="/etc/pam.d/sshd"
|
||||||
|
LOGROTATE_FILE="/etc/logrotate.d/ssh-notify"
|
||||||
|
|
||||||
|
# Step 1: Install the main script
|
||||||
|
if [[ ! -f "$SCRIPT_SRC" ]]; then
|
||||||
|
echo "Error: Source script not found at $SCRIPT_SRC" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ -f "$SCRIPT_DEST" ]]; then
|
||||||
|
cp "$SCRIPT_DEST" "$BACKUP_DIR/ssh-notify.sh.bak"
|
||||||
|
fi
|
||||||
|
install -o root -g root -m 700 "$SCRIPT_SRC" "$SCRIPT_DEST"
|
||||||
|
echo "Installed script to $SCRIPT_DEST"
|
||||||
|
|
||||||
|
# Step 2: Install the example configuration
|
||||||
|
if [[ ! -f "$CONF_SRC" ]]; then
|
||||||
|
echo "Error: Example config not found at $CONF_SRC" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
mkdir -p "$CONF_DIR" && chmod 700 "$CONF_DIR"
|
||||||
|
if [[ -f "$CONF_DEST" ]]; then
|
||||||
|
cp "$CONF_DEST" "$BACKUP_DIR/config.conf.bak"
|
||||||
|
fi
|
||||||
|
install -o root -g root -m 600 "$CONF_SRC" "$CONF_DEST"
|
||||||
|
echo "Installed config to $CONF_DEST"
|
||||||
|
|
||||||
|
# Step 3: Update PAM configuration idempotently
|
||||||
|
if [[ ! -f "$PAM_FILE" ]]; then
|
||||||
|
echo "Error: PAM config file not found at $PAM_FILE" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
cp "$PAM_FILE" "$BACKUP_DIR/sshd.bak"
|
||||||
|
if ! grep -q "ssh-notify.sh" "$PAM_FILE"; then
|
||||||
|
cat << 'EOF' >> "$PAM_FILE"
|
||||||
|
|
||||||
|
# Send notification upon successful login (added by ssh-notify install.sh)
|
||||||
|
session optional pam_exec.so seteuid /usr/local/sbin/ssh-notify.sh
|
||||||
|
EOF
|
||||||
|
echo "Appended PAM exec to $PAM_FILE"
|
||||||
|
else
|
||||||
|
echo "PAM already configured for ssh-notify"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Step 4: Install logrotate configuration
|
||||||
|
if [[ -f $LOGROTATE_FILE ]]; then
|
||||||
|
cp $LOGROTATE_FILE $BACKUP_DIR/ssh-notify.logrotate.bak
|
||||||
|
fi
|
||||||
|
install -o root -g root -m 644 $LOGROTATE_SRC $LOGROTATE_FILE
|
||||||
|
echo Copied logrotate config to $LOGROTATE_FILE
|
||||||
|
|
||||||
|
# Success message
|
||||||
|
trap - ERR
|
||||||
|
echo "Installation completed successfully."
|
||||||
|
echo "Please edit the config file at $CONF_DEST and restart sshd service."
|
||||||
12
ssh-notify/ssh-notify.logrotate
Normal file
12
ssh-notify/ssh-notify.logrotate
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/var/log/ssh-notify.log {
|
||||||
|
daily
|
||||||
|
missingok
|
||||||
|
rotate 7
|
||||||
|
compress
|
||||||
|
delaycompress
|
||||||
|
notifempty
|
||||||
|
create 600 root root
|
||||||
|
sharedscripts
|
||||||
|
postrotate
|
||||||
|
endscript
|
||||||
|
}
|
||||||
177
ssh-notify/ssh-notify.sh
Normal file
177
ssh-notify/ssh-notify.sh
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# ssh-notify.sh
|
||||||
|
# part of ssh-notify from server-toolset
|
||||||
|
# 2025 © Yigid BALABAN <fyb@fybx.dev>
|
||||||
|
|
||||||
|
# --- Configuration ---
|
||||||
|
CONFIG_FILE="/etc/ssh-notify/config.conf"
|
||||||
|
HOSTNAME=$(hostname -f)
|
||||||
|
|
||||||
|
# --- Script Variables ---
|
||||||
|
LOGIN_USER=""
|
||||||
|
REMOTE_HOST=""
|
||||||
|
MODE="PAM"
|
||||||
|
TEST_TYPE="both"
|
||||||
|
|
||||||
|
# --- Helper Functions ---
|
||||||
|
usage() {
|
||||||
|
echo
|
||||||
|
echo "Usage:"
|
||||||
|
echo " (As PAM module): Called automatically by PAM on SSH session start"
|
||||||
|
echo " (For Testing): sudo $0 -t[=email|telegram] <test_user> <test_remote_host>"
|
||||||
|
echo " -t, --test : Test both email and Telegram"
|
||||||
|
echo " -t email, --test=email : Test email only"
|
||||||
|
echo " -t telegram, --test=telegram : Test Telegram only"
|
||||||
|
echo " Example: sudo $0 -t testuser 192.168.1.100"
|
||||||
|
echo " Example: sudo $0 -t email testuser 192.168.1.100"
|
||||||
|
echo " Example: sudo $0 --test=telegram testuser 192.168.1.100"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
log_message() {
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$1] $2" >> "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Argument Parsing & Mode Detection ---
|
||||||
|
case "$1" in
|
||||||
|
-t|--test)
|
||||||
|
MODE="TEST"
|
||||||
|
TEST_TYPE="both"
|
||||||
|
shift
|
||||||
|
if [[ "$1" == "email" ]]; then
|
||||||
|
TEST_TYPE="email"
|
||||||
|
shift
|
||||||
|
elif [[ "$1" == "telegram" ]]; then
|
||||||
|
TEST_TYPE="telegram"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
-t=email|--test=email)
|
||||||
|
MODE="TEST"
|
||||||
|
TEST_TYPE="email"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-t=telegram|--test=telegram)
|
||||||
|
MODE="TEST"
|
||||||
|
TEST_TYPE="telegram"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
MODE="PAM"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ "$MODE" == "TEST" ]]; then
|
||||||
|
if [[ $# -lt 2 ]]; then
|
||||||
|
echo "Error: Test mode requires <test_user> and <test_remote_host> arguments."
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
LOGIN_USER="$1"
|
||||||
|
REMOTE_HOST="$2"
|
||||||
|
echo "--- Running in TEST mode ($TEST_TYPE) ---"
|
||||||
|
echo "User: $LOGIN_USER"
|
||||||
|
echo "Host: $REMOTE_HOST"
|
||||||
|
else
|
||||||
|
# --- PAM Mode Logic ---
|
||||||
|
if [[ "$PAM_TYPE" != "open_session" || -z "$PAM_USER" || -z "$PAM_RHOST" ]]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
LOGIN_USER="$PAM_USER"
|
||||||
|
REMOTE_HOST="$PAM_RHOST"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Load Configuration (needed for both modes) ---
|
||||||
|
if [[ -f "$CONFIG_FILE" ]]; then
|
||||||
|
source "$CONFIG_FILE"
|
||||||
|
else
|
||||||
|
ERR_MSG="ssh-notify Error: Configuration file $CONFIG_FILE not found."
|
||||||
|
echo "$ERR_MSG" | systemd-cat -p err -t 'ssh-notify'
|
||||||
|
echo "$ERR_MSG" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ensure required config variables are set
|
||||||
|
if [[ -z "$EMAIL_RECIPIENT" || -z "$EMAIL_API_ENDPOINT" || -z "$TELEGRAM_BOT_TOKEN" || -z "$TELEGRAM_CHAT_ID" || -z "$LOG_FILE" ]]; then
|
||||||
|
ERR_MSG="ssh-notify Error: One or more required variables are missing in $CONFIG_FILE."
|
||||||
|
echo "$ERR_MSG" | systemd-cat -p err -t 'ssh-notify'
|
||||||
|
echo "$ERR_MSG" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prepare log directory and file
|
||||||
|
LOG_DIR=$(dirname "$LOG_FILE")
|
||||||
|
mkdir -p "$LOG_DIR"
|
||||||
|
if [[ ! -f "$LOG_FILE" ]]; then
|
||||||
|
touch "$LOG_FILE"
|
||||||
|
# Set permissions only if we create it
|
||||||
|
chown root:root "$LOG_FILE" # Or another appropriate user/group if needed
|
||||||
|
chmod 640 "$LOG_FILE" # Restrict write access
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Log the mode of operation
|
||||||
|
log_message INFO "Script triggered. Mode: $MODE. User: '$LOGIN_USER'. Host: '$REMOTE_HOST'."
|
||||||
|
|
||||||
|
# --- Prepare Notification Details ---
|
||||||
|
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S %Z')
|
||||||
|
SUBJECT="[${MODE}] SSH Login on $HOSTNAME: $LOGIN_USER" # Add mode to subject
|
||||||
|
MESSAGE_TEXT="[${MODE}] SSH login detected on $HOSTNAME: User '$LOGIN_USER' from '$REMOTE_HOST' at $TIMESTAMP"
|
||||||
|
MESSAGE_HTML="<b>[${MODE}] SSH Login Alert</b>%0AServer: $HOSTNAME%0AUser: $LOGIN_USER%0AFrom: $REMOTE_HOST%0ATime: $TIMESTAMP"
|
||||||
|
|
||||||
|
# --- Notification Functions ---
|
||||||
|
send_email() {
|
||||||
|
log_message INFO "Attempting to send email to $EMAIL_RECIPIENT for user $LOGIN_USER from $REMOTE_HOST"
|
||||||
|
JSON_PAYLOAD=$(jq -n \
|
||||||
|
--arg subject "$SUBJECT" \
|
||||||
|
--arg text "$MESSAGE_TEXT" \
|
||||||
|
--arg recipient "$EMAIL_RECIPIENT" \
|
||||||
|
'{subject: $subject, text: $text, recipient: $recipient}')
|
||||||
|
|
||||||
|
RESPONSE_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "$JSON_PAYLOAD" \
|
||||||
|
-L "$EMAIL_API_ENDPOINT")
|
||||||
|
|
||||||
|
if [[ "$RESPONSE_CODE" -eq 200 ]]; then
|
||||||
|
log_message INFO "Email alert sent successfully. Response code: $RESPONSE_CODE"
|
||||||
|
else
|
||||||
|
log_message ERROR "Failure sending email alert. Response code: $RESPONSE_CODE"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
send_telegram() {
|
||||||
|
log_message INFO "Attempting to send Telegram message to chat $TELEGRAM_CHAT_ID for user $LOGIN_USER from $REMOTE_HOST"
|
||||||
|
TELEGRAM_API_URL="https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage"
|
||||||
|
|
||||||
|
RESPONSE=$(curl -s -X POST "$TELEGRAM_API_URL" \
|
||||||
|
-d chat_id="$TELEGRAM_CHAT_ID" \
|
||||||
|
-d text="$MESSAGE_HTML" \
|
||||||
|
-d parse_mode="HTML")
|
||||||
|
|
||||||
|
if echo "$RESPONSE" | grep -q '"ok":true'; then
|
||||||
|
log_message INFO "Telegram alert sent successfully."
|
||||||
|
else
|
||||||
|
ERROR_DESC=$(echo "$RESPONSE" | jq -r .description)
|
||||||
|
log_message ERROR "Failure sending Telegram alert. Response: $ERROR_DESC"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Execute Notifications in Background ---
|
||||||
|
(
|
||||||
|
if [[ "$MODE" == "TEST" ]]; then
|
||||||
|
[[ "$TEST_TYPE" == "both" || "$TEST_TYPE" == "email" ]] && send_email
|
||||||
|
[[ "$TEST_TYPE" == "both" || "$TEST_TYPE" == "telegram" ]] && send_telegram
|
||||||
|
else
|
||||||
|
send_email
|
||||||
|
send_telegram
|
||||||
|
fi
|
||||||
|
) &
|
||||||
|
|
||||||
|
log_message INFO "Notification process forked for user $LOGIN_USER from $REMOTE_HOST"
|
||||||
|
|
||||||
|
if [[ "$MODE" == "TEST" ]]; then
|
||||||
|
echo "--- Test notifications triggered in background ---"
|
||||||
|
echo "Check $LOG_FILE for details."
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
102
ssh-notify/uninstall.sh
Normal file
102
ssh-notify/uninstall.sh
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# uninstall.sh
|
||||||
|
# part of ssh-notify from server-toolset
|
||||||
|
# 2025 © Yigid BALABAN <fyb@fybx.dev>
|
||||||
|
|
||||||
|
# This script must be run as root. It uninstalls the SSH login notification script,
|
||||||
|
# example config, updates PAM, and uninstalls the logrotate config in a transactional manner.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Ensure running as root
|
||||||
|
if [[ "$(id -u)" -ne 0 ]]; then
|
||||||
|
echo "Error: This script must be run as root." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create temporary directory for backups
|
||||||
|
TMPDIR="$(mktemp -d)"
|
||||||
|
BACKUP_DIR="${TMPDIR}/backup"
|
||||||
|
mkdir -p "$BACKUP_DIR"
|
||||||
|
|
||||||
|
# Rollback function on error
|
||||||
|
rollback() {
|
||||||
|
echo "Error encountered. Rolling back changes..." >&2
|
||||||
|
[[ -f "$BACKUP_DIR/sshd.bak" ]] && mv "$BACKUP_DIR/sshd.bak" /etc/pam.d/sshd
|
||||||
|
[[ -f "$BACKUP_DIR/ssh-notify.sh.bak" ]] && mv "$BACKUP_DIR/ssh-notify.sh.bak" /usr/local/sbin/ssh-notify.sh
|
||||||
|
[[ -f "$BACKUP_DIR/config.conf.bak" ]] && mv "$BACKUP_DIR/config.conf.bak" /etc/ssh-notify/config.conf
|
||||||
|
[[ -f "$BACKUP_DIR/ssh-notify.logrotate.bak" ]] && mv "$BACKUP_DIR/ssh-notify.logrotate.bak" /etc/logrotate.d/ssh-notify
|
||||||
|
rm -rf "$TMPDIR"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
trap rollback ERR
|
||||||
|
|
||||||
|
# Determine project root and destinations
|
||||||
|
_project_root="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
SCRIPT_DEST="/usr/local/sbin/ssh-notify.sh"
|
||||||
|
CONF_DIR="/etc/ssh-notify"
|
||||||
|
CONF_DEST="${CONF_DIR}/config.conf"
|
||||||
|
PAM_FILE="/etc/pam.d/sshd"
|
||||||
|
LOGROTATE_FILE="/etc/logrotate.d/ssh-notify"
|
||||||
|
|
||||||
|
# Step 1: Remove PAM exec entry and associated comment
|
||||||
|
if [[ -f "$PAM_FILE" ]]; then
|
||||||
|
cp "$PAM_FILE" "$BACKUP_DIR/sshd.bak"
|
||||||
|
# Filter out ssh‑notify lines and trim any trailing blank lines
|
||||||
|
awk '
|
||||||
|
# skip the install.sh comment
|
||||||
|
$0 ~ /^# Send notification upon successful login \(added by ssh‑notify install\.sh\)/ { next }
|
||||||
|
# skip the pam_exec line
|
||||||
|
$0 ~ /^session[[:space:]]+optional[[:space:]]+pam_exec\.so.*ssh‑notify\.sh/ { next }
|
||||||
|
# collect other lines
|
||||||
|
{ buf[++n] = $0 }
|
||||||
|
END {
|
||||||
|
# drop trailing empty lines
|
||||||
|
while (n > 0 && buf[n] == "") n--
|
||||||
|
for (i = 1; i <= n; i++) print buf[i]
|
||||||
|
}
|
||||||
|
' "$PAM_FILE" > "$PAM_FILE.tmp"
|
||||||
|
|
||||||
|
if ! cmp -s "$PAM_FILE" "$PAM_FILE.tmp"; then
|
||||||
|
mv "$PAM_FILE.tmp" "$PAM_FILE"
|
||||||
|
echo "Removed PAM exec entry for ssh-notify from $PAM_FILE"
|
||||||
|
else
|
||||||
|
rm -f "$PAM_FILE.tmp"
|
||||||
|
echo "PAM exec entry for ssh-notify not found in $PAM_FILE (no changes made)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "PAM file $PAM_FILE not found."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Step 2: Remove main script
|
||||||
|
if [[ -f "$SCRIPT_DEST" ]]; then
|
||||||
|
cp "$SCRIPT_DEST" "$BACKUP_DIR/ssh-notify.sh.bak"
|
||||||
|
rm "$SCRIPT_DEST"
|
||||||
|
echo "Removed script $SCRIPT_DEST"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Step 3: Remove configuration
|
||||||
|
depart_dir_config() {
|
||||||
|
if [[ -f "$CONF_DEST" ]]; then
|
||||||
|
cp "$CONF_DEST" "$BACKUP_DIR/config.conf.bak"
|
||||||
|
rm "$CONF_DEST"
|
||||||
|
echo "Removed config $CONF_DEST"
|
||||||
|
fi
|
||||||
|
if [[ -d "$CONF_DIR" ]]; then
|
||||||
|
rmdir "$CONF_DIR" 2>/dev/null || true
|
||||||
|
echo "Removed directory $CONF_DIR"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
depart_dir_config
|
||||||
|
|
||||||
|
# Step 4: Remove logrotate configuration
|
||||||
|
if [[ -f "$LOGROTATE_FILE" ]]; then
|
||||||
|
cp "$LOGROTATE_FILE" "$BACKUP_DIR/ssh-notify.logrotate.bak"
|
||||||
|
rm "$LOGROTATE_FILE"
|
||||||
|
echo "Removed logrotate file $LOGROTATE_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
trap - ERR
|
||||||
|
echo "Uninstallation completed successfully."
|
||||||
|
echo "Backup files are located in $BACKUP_DIR. You may delete this directory manually."
|
||||||
Reference in New Issue
Block a user