-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsshd_configure.bash
More file actions
159 lines (138 loc) · 5.81 KB
/
sshd_configure.bash
File metadata and controls
159 lines (138 loc) · 5.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/bin/bash
# Set bash execution flags:
# - Treat unset variables as an error when substituting
# - Exit immediately if a command exits with a non-zero status
# - Print each command to stdout before executing it (useful for debugging)
set -u
# set -e
# set -x
# ANSI Colors
RED='\033[0;31m' # Error
GREEN='\033[0;32m' # Success
BLUE='\033[0;34m' # Info
YELLOW='\033[0;93m' # Warning/Useful info
NC='\033[0m' # No Color
# Usage example: show_usage
show_usage() {
echo "= = Usage = ="
echo " Directly in CLI:"
echo " $0 [setting_name] [value]"
echo " Examples:"
echo " $0 Port 2222"
echo " $0 PermitRootLogin no"
echo " $0 PasswordAuthentication no"
echo " From WEB:"
echo " To run the script from the internet use:"
echo " curl:"
echo " curl -Ls https://raw.githubusercontent.com/voiduin/linux-host-setup/main/sshd_configure.bash | sudo bash -s [setting_name] [value]"
echo " wget:"
echo " wget -qO - https://raw.githubusercontent.com/voiduin/linux-host-setup/main/sshd_configure.bash | sudo bash -s [setting_name] [value]"
echo -e "\n"
echo "Requirements:"
echo " - Run as root"
echo "Supported settings:"
echo " - Port, PermitRootLogin, PasswordAuthentication, and other valid sshd settings"
echo "Config file requirements:"
echo " - The file must contain one active or commented 'Port' line"
echo -e "\n"
echo "Script created by \"Voiduin\""
echo "Source available at https://github.com/voiduin/linux-host-setup"
}
# Exit with an error message and show usage
# Usage example: exit_with_err "Error message"
exit_with_err() {
local message="$1"
echo -e "${RED}Error: $message${NC}"
echo -e "\n"
show_usage
exit 1
}
# Usage example: assert_run_as_root
assert_run_as_root() {
if [[ $EUID -ne 0 ]]; then
exit_with_err "This script must be run as root"
fi
}
# Usage example: assert_file_exists "/path/to/file"
assert_file_exists() {
local file_path="$1"
if [[ ! -f "$file_path" ]]; then
exit_with_err "The specified file does not exist: $file_path"
fi
}
# Check SSHD configuration for a specified setting
# check_sshd_config_setting <!config_file!> <!setting_name!>
# Usage example:
# check_sshd_config_setting "/etc/ssh/sshd_config" "Port"
check_sshd_config_setting() {
local config_file="$1"
local setting_name="$2"
# Find active setting lines and their line numbers.
# This line must catch incorrect lines, e.g., lines with non-digit value:
# Port new_port # Changed by root on 2024-03-18, 12:24:41
local setting_lines_info=$(grep -nE "^[[:blank:]]*${setting_name}[[:blank:]]" "${config_file}")
# Count the number of active setting lines
# Calculate active lines only if 'setting_lines_info' is not empty
local active_lines
if [[ -n "${setting_lines_info}" ]]; then
active_lines=$(echo "${setting_lines_info}" | wc -l)
else
active_lines=0
fi
if [[ $active_lines -eq 1 ]]; then
# OK
local line_info=$(echo "$setting_lines_info" | awk -F ":" '{printf "%s\n%s\n", " Line number " $1 ":", " "$2}')
echo " - One active '$setting_name' line found in \"$config_file\":"
echo "$line_info"
elif [[ $active_lines -gt 1 ]]; then
# ERR
echo " - Multiple active '$setting_name' lines found in \"$config_file\":"
echo "$setting_lines_info" | awk -F ":" '{printf "%s\n%s\n", " Line number " $1 ":", " "$2}'
exit_with_err "Multiple active '$setting_name' lines found. Please clean up the file."
else
echo " - No active '$setting_name' line found in \"$config_file\""
echo " A new one will be added"
fi
}
# Usage example: set_new_sshd_config "/etc/ssh/sshd_config" Port 2222
set_new_sshd_config() {
local config_file="${1}"
local setting="${2}"
local value="${3}"
local modifying_user="${SUDO_USER:-$(whoami)}"
# Time delimiter set as "-" for easy AWK processing of "grep -n" output, which has the line number format "256:<string_value>"
local modifying_time="$(date +'%Y-%m-%d, %H-%M-%S')"
local original_line_val=$(grep -nE "^[[:blank:]]*${setting}[[:blank:]]" "${config_file}")
local original_line_number=$(echo "$original_line_val" | cut -d':' -f1)
# TODO: Return logic display previous value which set now
# local original_port=$(echo "$original_line_val" | grep -Po '(?<=Port\s)\d+')
local comment="# Changed by script on ${modifying_time} by user \"${modifying_user}\""
if [[ ! -z "${original_line_number}" ]]; then
sed -i "${original_line_number}s/.*/$setting $value ${comment}/" "$config_file"
echo " > ${setting} changed to $value on line ${original_line_number} in $config_file."
else
# Add new line in file end
echo "${setting} ${value} ${comment}" >> "${config_file}"
echo " > ${setting} added with value \"${value}\" in \"${config_file}\""
fi
}
main() {
local config_file_path="/etc/ssh/sshd_config"
local setting="$1"
local value="$2"
if [[ $# -gt 2 ]]; then
exit_with_err "Too many arguments. Please provide only two arguments [name] [value]."
fi
# TODO: Return check on port value
# if ! [[ "$new_port" =~ ^[0-9]+$ ]] || [ "$new_port" -lt 1024 ] || [ "$new_port" -gt 65535 ]; then
# exit_with_err "Invalid port number: $new_port. Please specify a number between 1024 and 65535."
# fi
if [[ -z "$setting" ]] || [[ -z "$value" ]]; then
exit_with_err "ERR: Missing arguments. Please specify a setting and a value."
fi
assert_run_as_root
assert_file_exists "${config_file_path}"
check_sshd_config_setting "${config_file_path}" "${setting}"
set_new_sshd_config "${config_file_path}" "${setting}" "$value"
}
main "$@"