#!/usr/bin/env bash # # JbTecWiz Support Centre -- generated fix script # # Fault : sshd will not start, or refuses connections after a configuration change # Fix : Use the session you still have properly # Source: https://jbtecwiz.com/support/lnx-net-sshd-config # # Run as : The existing SSH session # Expect : 15 minutes # Risk : low # Reversible : yes # # WHEN THIS IS THE RIGHT FIX # You have one working session left. Do not close it, and do not restart # sshd yet. # # HOW TO UNDO IT # The lifeline on 2222 remains available until you stop it. # # Walks the fix one step at a time and asks before each. Steps with no # command are yours to do -- it prints those and waits. DRYRUN=1 prints # without executing; UNATTENDED=1 does not ask. # # -------------------------------------------------------------------- # NO WARRANTY - USE AT YOUR OWN RISK # # This script is provided by JbTecWiz as-is and with no warranty of any # kind, express or implied. You run it entirely at your own risk. # # JbTecWiz accepts no liability for any loss or damage arising from its # use, including but not limited to data loss, downtime, or configuration # changes that turn out to be wrong for your system. # # You are responsible for reading this script before running it, for # satisfying yourself that it suits the machine in front of you, and for # having a working backup first. Some steps cannot be undone. # -------------------------------------------------------------------- set -uo pipefail DRYRUN="${DRYRUN:-0}" UNATTENDED="${UNATTENDED:-0}" failed=0 rule() { printf "\n%s\n" "$(printf '-%.0s' $(seq 1 70))"; if [ $# -gt 0 ]; then echo "$1"; fi; } prose() { echo "$1" | fold -s -w 74 | sed "s/^/ /"; } # Returns 0 when the caller should run the command, 1 when it should not. # A manual step always returns 1 -- there is nothing for the caller to run. step() { # step [command lines...] local n="$1" dotext="$2" why="$3" mode="$4"; shift 4 rule " Step $n of 5" prose "$dotext" if [ -n "$why" ]; then echo; prose "$why"; fi if [ "$mode" = "manual" ]; then echo; echo " -> Do this yourself, then press Enter to carry on." if [ "$UNATTENDED" = "0" ] && [ "$DRYRUN" = "0" ]; then read -r _; fi return 1 fi echo; printf " %s\n" "$@"; echo if [ "$DRYRUN" = "1" ]; then echo " (dry run -- not executed)"; return 1; fi if [ "$UNATTENDED" = "0" ]; then read -r -p " Run this step? [Y]es / [S]kip / [Q]uit " a case "$a" in [Qq]*) echo " Stopped at your request."; exit 0 ;; [Ss]*) echo " Skipped."; return 1 ;; esac fi return 0 } rule echo " sshd will not start, or refuses connections after a configuration change" echo " Use the session you still have properly" echo echo " Risk: low Reversible 15 minutes" echo prose 'No warranty. Use at your own risk - JbTecWiz accepts no liability. Read it before you run it, and have a backup.' rule echo if [ "$UNATTENDED" = "0" ] && [ "$DRYRUN" = "0" ]; then read -r -p " Ready? [y/N] " go case "$go" in [Yy]*) ;; *) echo " Nothing was changed."; exit 0;; esac fi step 1 'Do not close this session. An open connection survives an sshd restart; a closed one cannot be re-established if the configuration is wrong.' '' manual || true if step 2 'Test the configuration before applying it.' 'This validates the file and prints the offending line number without touching the running service. It takes one second and prevents the entire class of lockout.' cmd 'sudo sshd -t'; then sudo sshd -t if [ $? -ne 0 ]; then failed=$((failed+1)) echo " Step 2 failed. The rest of the fix may depend on it." >&2 fi fi if step 3 'Start a second sshd on another port as a lifeline before restarting the main one.' '' cmd 'sudo /usr/sbin/sshd -p 2222 -o PidFile=/run/sshd-test.pid'; then sudo /usr/sbin/sshd -p 2222 -o PidFile=/run/sshd-test.pid if [ $? -ne 0 ]; then failed=$((failed+1)) echo " Step 3 failed. The rest of the fix may depend on it." >&2 fi fi if step 4 'Open a new connection on port 2222 from another terminal and confirm it works before restarting the main service.' '' cmd 'ssh -p 2222 user@server'; then ssh -p 2222 user@server if [ $? -ne 0 ]; then failed=$((failed+1)) echo " Step 4 failed. The rest of the fix may depend on it." >&2 fi fi if step 5 'Now restart the main service, verify a new connection on port 22, then stop the lifeline.' '' cmd 'sudo systemctl restart sshd' 'sudo kill $(cat /run/sshd-test.pid)'; then sudo systemctl restart sshd sudo kill $(cat /run/sshd-test.pid) if [ $? -ne 0 ]; then failed=$((failed+1)) echo " Step 5 failed. The rest of the fix may depend on it." >&2 fi fi rule " Confirm it worked" prose 'A brand new connection on the normal port succeeds before the lifeline is removed.' rule if [ "$failed" -gt 0 ]; then echo " Finished with $failed failed step(s)." echo " Read the full write-up at https://jbtecwiz.com/support/lnx-net-sshd-config" else echo " Finished." fi echo prose 'To undo: The lifeline on 2222 remains available until you stop it.' rule