Files
2026-06-25 15:28:46 +03:00

103 lines
3.1 KiB
Bash

#!/usr/bin/env bash
#
# bt-access - network access controls for ButtonTask.
#
# Usage:
# bt-access status
# bt-access icmp <on|off>
# bt-access ssh <on|off>
# bt-access ssh-port <port>
set -euo pipefail
err() { echo "bt-access: $*" >&2; exit 1; }
SSH_DROPIN="/etc/ssh/sshd_config.d/99-buttontask.conf"
SYSCTL_DROPIN="/etc/sysctl.d/99-buttontask-access.conf"
valid_port() {
[[ "${1:-}" =~ ^[0-9]{1,5}$ ]] && [ "$1" -ge 1 ] && [ "$1" -le 65535 ]
}
ssh_unit() {
if systemctl list-unit-files ssh.service &>/dev/null; then
echo ssh.service
elif systemctl list-unit-files sshd.service &>/dev/null; then
echo sshd.service
else
echo ssh.service
fi
}
ssh_port() {
local port
if command -v sshd >/dev/null 2>&1; then
port="$(sshd -T 2>/dev/null | awk '$1 == "port" {print $2; exit}')"
if valid_port "${port:-}"; then
echo "$port"
return 0
fi
fi
port="$(awk 'tolower($1) == "port" {print $2; found=1} END {if (!found) print 22}' \
/etc/ssh/sshd_config "$SSH_DROPIN" 2>/dev/null | tail -n1)"
valid_port "${port:-}" && echo "$port" || echo 22
}
write_icmp() {
local state="$1" value
case "$state" in
on) value=0 ;;
off) value=1 ;;
*) err "icmp expects on or off" ;;
esac
printf 'net.ipv4.icmp_echo_ignore_all=%s\n' "$value" > "$SYSCTL_DROPIN"
sysctl -w "net.ipv4.icmp_echo_ignore_all=$value" >/dev/null
}
write_ssh_port() {
local port="$1"
valid_port "$port" || err "invalid ssh port"
install -d -m 0755 "$(dirname "$SSH_DROPIN")"
printf 'Port %s\n' "$port" > "$SSH_DROPIN"
systemctl restart "$(ssh_unit)" >/dev/null 2>&1 || true
}
set_ssh() {
local state="$1" unit
unit="$(ssh_unit)"
case "$state" in
on)
systemctl enable "$unit" >/dev/null 2>&1 || update-rc.d ssh defaults >/dev/null 2>&1 || true
systemctl start "$unit" >/dev/null 2>&1 || service ssh start >/dev/null 2>&1 || true
;;
off)
systemctl stop "$unit" >/dev/null 2>&1 || service ssh stop >/dev/null 2>&1 || true
systemctl disable "$unit" >/dev/null 2>&1 || update-rc.d -f ssh remove >/dev/null 2>&1 || true
;;
*) err "ssh expects on or off" ;;
esac
}
status() {
local icmp ssh_state port unit
icmp="$(sysctl -n net.ipv4.icmp_echo_ignore_all 2>/dev/null || echo 0)"
unit="$(ssh_unit)"
if systemctl is-active --quiet "$unit"; then
ssh_state=on
else
ssh_state=off
fi
port="$(ssh_port)"
printf '{"icmp":"%s","ssh":"%s","sshPort":%s}\n' \
"$([ "$icmp" = "1" ] && echo off || echo on)" \
"$ssh_state" \
"$port"
}
case "${1:-}" in
status) status ;;
icmp) [ "$#" -eq 2 ] || err "usage: bt-access icmp <on|off>"; write_icmp "$2"; status ;;
ssh) [ "$#" -eq 2 ] || err "usage: bt-access ssh <on|off>"; set_ssh "$2"; status ;;
ssh-port) [ "$#" -eq 2 ] || err "usage: bt-access ssh-port <port>"; write_ssh_port "$2"; status ;;
*) err "usage: bt-access {status|icmp <on|off>|ssh <on|off>|ssh-port <port>}" ;;
esac