Module: SSH Hardening
Main file: ssh_hardening.py
Platform: Linux / Ubuntu
Language: Python 3
Technologies: Python, OpenSSH, systemd
Project: ServerGuard
Purpose of the module:
Automated hardening of SSH server security,
OpenSSH configuration verification, backup,
application of a controlled security policy
and safe restoration of the SSH configuration.
1. GENERAL DESCRIPTION
SSH Hardening is a server module of ServerGuard designed for automatic management of OpenSSH security settings.
The module allows you to:
- check user privileges;
- determine the SSH service;
- check SSH status;
- create the required directories;
- create a backup of the configuration;
- create the ServerGuard configuration;
- verify the OpenSSH configuration;
- apply the changes;
- reload the SSH service;
- verify the parameters actually applied;
- determine the hardening state;
- remove the ServerGuard configuration;
- restore the previous configuration;
- perform a rollback on error.
The main idea of the module:
ServerGuard does not modify the entire /etc/ssh/sshd_config.
Instead, a separate configuration fragment is used:
/etc/ssh/sshd_config.d/99-serverguard-hardening.conf
The main file:
/etc/ssh/sshd_config
while remaining separate.
This approach allows ServerGuard to apply its own SSH policy without completely rewriting the administrator's existing configuration.
2. WHAT SSH HARDENING IS
Hardening is the strengthening of system security by restricting unnecessary or potentially dangerous capabilities.
In the context of SSH, this means changing the OpenSSH policy so that the server allows only the necessary features.
ServerGuard sets the following parameters:
PermitEmptyPasswords no
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
MaxAuthTries 3
LoginGraceTime 30
Compression no
PermitRootLogin prohibit-password
This restricts:
- empty passwords;
- root password authentication;
- the number of authentication attempts;
- the authentication time;
- X11 forwarding;
- TCP forwarding;
- SSH Agent Forwarding;
- SSH compression.
3. SSH HARDENING IS NOT BRUTE-FORCE PROTECTION
It is important to separate the two tasks.
SSH Hardening is responsible for:
SSH POLICY
That is:
which capabilities are allowed;
which capabilities are prohibited;
which restrictions are applied.
The Security module is responsible for:
ATTACK DETECTION
For example:
- analysis of failed logins;
- detection of a large number of attempts;
- IP analysis;
- IP blocking;
- brute-force protection.
Therefore:
SSH Hardening
=
OpenSSH configuration hardening
and:
Security
=
detection and blocking of suspicious activity.
These mechanisms complement each other.
4. MODULE ARCHITECTURE
General architecture:
ServerGuard
|
| SSH
v
Linux Server
|
v
ssh_hardening.py
|
+------------------------+
| |
v v
OpenSSH configuration systemd
| |
v v
sshd_config.d SSH service
| |
+------------+-----------+
|
v
OpenSSH
|
v
Effective config
|
v
Verification
The module interacts with:
1. the Linux file system;
2. OpenSSH;
3. systemd;
4. the SSH daemon;
5. the backup system.
5. MAIN PATHS
Main ServerGuard directory:
/opt/serverguard
Backup directory:
/opt/serverguard/backups
Main OpenSSH configuration:
/etc/ssh/sshd_config
ServerGuard configuration:
/etc/ssh/sshd_config.d/99-serverguard-hardening.conf
Thus:
/etc/ssh/
|
+-- sshd_config
|
+-- sshd_config.d/
|
+-- 99-serverguard-hardening.conf
6. TECHNOLOGIES
The module is written in:
Python 3
Standard Python libraries are used:
sys
os
shutil
subprocess
datetime
No additional Python packages are required.
The following Linux system components are used for operation:
systemctl
sshd
Python acts as a control layer between ServerGuard and the operating system.
Simplified:
Python
|
+---- file system
|
+---- OpenSSH
|
+---- systemd
|
+---- backup
|
+---- configuration verification
7. PYTHON IMPORTS
The module uses:
import sys
import os
import shutil
import subprocess
from datetime import datetime
sys
Used for:
- processing command-line arguments;
- terminating the program;
- returning the exit code.
For example:
python3 ssh_hardening.py apply
passes:
apply
through:
sys.argv
os
Used to work with the Linux file system.
In particular:
- checking for root;
- checking whether files exist;
- creating directories;
- deleting files;
- setting permissions;
- constructing paths.
shutil
Used for copying files.
Main function:
shutil.copy2()
Used for:
- creating a backup;
- restoring the configuration.
subprocess
Used to run system commands.
For example:
sshd -t
sshd -T
systemctl is-active ssh
systemctl reload ssh
datetime
Used to generate timestamps.
For example:
20260930_215300
As a result, a backup may be named:
sshd_config_20260930_215300.backup
8. PRIVILEGE REQUIREMENTS
Modifying:
/etc/ssh/
and managing the SSH service require elevated privileges.
Therefore, the module performs a root check.
The following is used:
os.geteuid() == 0
If the program is run without root:
ERROR: This script must be run as root.
The operation is terminated.
This is necessary for working with:
/etc/ssh/sshd_config
/etc/ssh/sshd_config.d/
/opt/serverguard/backups
and systemd.
9. EXECUTING LINUX COMMANDS
To run system commands, the following is used:
run_command(command, check=False)
Internally, it uses:
subprocess.run()
The function receives:
command
and returns:
returncode
stdout
stderr
Example:
code, stdout, stderr = run_command(
["sshd", "-t"]
)
If:
code == 0
the command completed successfully.
If the command failed, the following is used:
stderr
for diagnostics.
Thus, the Python module does not implement its own SSH daemon but manages the existing OpenSSH through standard Linux commands.
10. SSH SERVICE DISCOVERY
In Linux, the SSH service may be named:
ssh
or:
sshd
Therefore, the module must not depend rigidly on a single name.
The function:
get_ssh_service()
determines the service name in use.
After discovery, the result is used in subsequent operations.
For example:
systemctl is-active ssh
or:
systemctl is-active sshd
Similarly, the following is executed:
systemctl reload ssh
or:
systemctl reload sshd
11. SSH SERVICE CHECK
The function:
check_ssh_service()
checks:
- whether the SSH service was found;
- whether the SSH service is active.
The following is used:
systemctl is-active <service>
If the result is:
active
SSH is considered running.
Example:
SSH service: ACTIVE
If the service is inactive, its state is displayed to the user.
12. BACKUP
Modifying the SSH configuration is a potentially dangerous operation.
An error in the configuration can cause new SSH connections to be unable to establish.
Therefore, ServerGuard uses the principle:
BACKUP BEFORE CHANGE
Before changing the configuration, a backup is created.
The backup is located at:
/opt/serverguard/backups
13. BACKUP OF THE MAIN CONFIGURATION
The function:
backup_main_config()
works with:
/etc/ssh/sshd_config
A file is created:
sshd_config_YYYYMMDD_HHMMSS.backup
For example:
sshd_config_20260930_215300.backup
Copying uses:
shutil.copy2()
The timestamp allows multiple backups to be stored.
14. BACKUP OF THE SERVERGUARD CONFIGURATION
If the following already exists:
/etc/ssh/sshd_config.d/99-serverguard-hardening.conf
it may also be saved before creating a new version.
Example:
99-serverguard-hardening_20260930_215300.backup
This way, the previous version of the ServerGuard policy can be preserved.
Important:
the main sshd_config
and:
ServerGuard hardening config
are backed up separately.
15. CREATING THE HARDENING CONFIGURATION
The function:
create_hardening_config()
creates:
/etc/ssh/sshd_config.d/99-serverguard-hardening.conf
The ServerGuard policy is written to the file.
Main parameters:
PermitEmptyPasswords no
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
MaxAuthTries 3
LoginGraceTime 30
Compression no
PermitRootLogin prohibit-password
After creation, the permissions are set:
0644
16. PermitEmptyPasswords
The parameter:
PermitEmptyPasswords no
prohibits the use of an empty password during SSH authentication.
The idea of the setting:
empty password
|
v
SSH authentication
|
v
prohibited
This eliminates the possibility of using an empty password as an SSH authentication mechanism.
17. X11Forwarding
ServerGuard sets:
X11Forwarding no
X11 Forwarding allows X11 graphics to be transmitted over SSH.
If the server is used primarily for:
- server applications;
- administration;
- development;
- background services;
X11 forwarding may not be needed.
Therefore, ServerGuard disables this capability.
Important:
SSH is NOT disabled by this.
Only X11 forwarding is disabled.
18. AllowTcpForwarding
ServerGuard sets:
AllowTcpForwarding no
TCP forwarding allows SSH to be used for network tunneling.
For example:
client
|
| SSH
v
server
|
v
another network resource
If the server uses SSH tunnels, disabling TCP forwarding may change the existing workflow.
Therefore, this setting must be taken into account before applying hardening.
19. AllowAgentForwarding
ServerGuard sets:
AllowAgentForwarding no
SSH Agent Forwarding allows the SSH agent to be used over a remote connection.
This can be convenient when administering multiple servers.
If the server does not require this capability, ServerGuard disables it.
20. MaxAuthTries
ServerGuard sets:
MaxAuthTries 3
The parameter limits the number of authentication attempts within a single SSH connection.
Important:
MaxAuthTries 3
does not mean:
"the IP is blocked after three attempts".
These are different mechanisms.
IP blocking belongs to the separate Security system.
21. LoginGraceTime
ServerGuard sets:
LoginGraceTime 30
The client is given a limited time to complete authentication.
In the ServerGuard policy:
30 seconds
This reduces the lifetime of an unauthenticated connection.
22. Compression
ServerGuard sets:
Compression no
SSH compression is disabled.
This reduces the number of available SSH features if compression is not required by a particular server.
23. PermitRootLogin
ServerGuard sets:
PermitRootLogin prohibit-password
This means that root password authentication over SSH is prohibited.
At the same time, root key authentication may remain available if other OpenSSH settings allow it.
Thus:
root + password
|
v
prohibited
root + SSH key
|
v
may be allowed
This differs from:
PermitRootLogin no
With:
PermitRootLogin no
root is completely prohibited over SSH.
24. WHY prohibit-password IS USED
ServerGuard intentionally uses:
PermitRootLogin prohibit-password
rather than:
PermitRootLogin no
This preserves the possibility of administrative access via an SSH key.
The final login capability still depends on other OpenSSH parameters.
For example:
PubkeyAuthentication
PasswordAuthentication
AuthorizedKeysFile
and other settings.
Therefore, the final state is recommended to be verified via:
sshd -T
25. CONFIGURATION VERIFICATION
Before reload, ServerGuard uses:
sshd -t
The command checks the OpenSSH configuration for errors.
Conditionally:
sshd -t
|
+---- 0
| |
| v
| VALID
|
+---- != 0
|
v
INVALID
If the configuration is invalid, the apply operation must not continue as successful.
26. WHY sshd -t IS IMPORTANT
Imagine:
ServerGuard
|
v
creates config
|
v
sshd -t
|
+---+
| |
OK ERROR
| |
v v
reload rollback
Thus, a syntax error is detected before the configuration is actually applied.
27. RELOAD SSH
After a successful check, the following is executed:
systemctl reload <ssh-service>
The following is used:
reload
rather than the mandatory:
restart
This allows the running SSH daemon to reread the configuration.
On a successful reload, the module continues with verification.
28. EFFECTIVE CONFIGURATION
After applying, the following is used:
sshd -T
The command shows the effective OpenSSH configuration.
This is especially important because OpenSSH may use multiple configuration files.
For example:
/etc/ssh/sshd_config
and:
/etc/ssh/sshd_config.d/*.conf
Therefore, the contents of a single file do not always equal the final SSH daemon configuration.
ServerGuard checks specifically the result of:
sshd -T
29. RETRIEVING VALUES
The function:
get_config_value(config, name)
retrieves the value of a parameter from the result of:
sshd -T
For example:
permitrootlogin prohibit-password
is parsed as:
name:
permitrootlogin
value:
prohibit-password
The comparison is performed case-insensitively.
If the parameter is missing:
unknown
30. VALUE COMPARISON
The function:
value_matches(actual, expected)
compares:
the actual value
and:
the expected value.
For:
prohibit-password
the following may also be taken into account:
without-password
This is due to differences in how this setting is represented across OpenSSH versions.
31. HARDENING CHECK
The main function:
check_hardening()
first checks:
/etc/ssh/sshd_config.d/99-serverguard-hardening.conf
If the file does not exist:
ServerGuard hardening: NOT INSTALLED
If the file exists, the following is executed:
sshd -T
After that, the parameters are checked.
32. PARAMETERS CHECKED
The following are checked:
PermitRootLogin
PasswordAuthentication
PubkeyAuthentication
PermitEmptyPasswords
MaxAuthTries
LoginGraceTime
X11Forwarding
AllowTcpForwarding
AllowAgentForwarding
Compression
However, not all parameters are strict requirements.
33. REQUIRED PARAMETERS
The following parameters must match the ServerGuard policy:
PermitRootLogin
prohibit-password
PermitEmptyPasswords
no
MaxAuthTries
3
LoginGraceTime
30
X11Forwarding
no
AllowTcpForwarding
no
AllowAgentForwarding
no
Compression
no
If the value matches:
[OK]
If it differs:
[FAIL]
34. INFORMATIONAL PARAMETERS
For:
PasswordAuthentication
and:
PubkeyAuthentication
the module outputs the actual value as information.
That is, these parameters are shown to the user but are not used as a strict condition for successful hardening.
For example:
[INFO] PasswordAuthentication yes
does not necessarily mean an error.
35. CHECK RESULT
If all required parameters match the policy:
ServerGuard hardening: ENABLED
If at least one required parameter differs:
ServerGuard hardening: PARTIALLY APPLIED
This allows distinguishing between:
the file exists
and:
the policy is actually applied.
36. REMOVING HARDENING
The function:
remove_hardening_config()
removes:
/etc/ssh/sshd_config.d/99-serverguard-hardening.conf
If the file does not exist, this is not considered a critical error.
Removal is used, in particular, during rollback.
37. THE COMPLETE APPLY PROCESS
The command:
ssh_hardening.py apply
starts the hardening application process.
The general sequence:
1. Root check
|
v
2. Creating directories
|
v
3. Backup sshd_config
|
v
4. Backup of the old ServerGuard config
|
v
5. Creating the new config
|
v
6. sshd -t
|
+---- ERROR ---> rollback
|
v
7. systemctl reload
|
+---- ERROR ---> rollback
|
v
8. sshd -T
|
v
9. Parameter check
|
v
10. Result
38. BACKUP BEFORE APPLY
Before modifying the main SSH configuration file, a backup is created.
If the backup could not be created:
APPLY
is cancelled.
The principle:
backup failed
|
v
hardening cancelled
This prevents changing the configuration without the ability to return to a saved version.
39. ROLLBACK ON sshd -t ERROR
If, after creating the ServerGuard configuration:
sshd -t
returns an error:
1. the error is output;
2. ServerGuard removes the created hardening config;
3. the operation is considered unsuccessful.
Diagram:
CREATE
|
v
sshd -t
|
v
ERROR
|
v
REMOVE CONFIG
|
v
CANCEL
40. ROLLBACK ON RELOAD ERROR
If:
sshd -t
is successful, but:
systemctl reload
ends with an error:
1. the error is output;
2. the hardening config is removed;
3. the operation is considered unsuccessful.
Diagram:
CONFIG
|
v
sshd -t
|
v
OK
|
v
reload
|
v
ERROR
|
v
remove config
41. FINAL VERIFICATION
After a successful reload, ServerGuard executes:
check_hardening()
Internally, the following is used:
sshd -T
After that, the actual parameter values are checked.
Thus, the following sequence is used:
CREATE
|
v
VALIDATE
|
v
RELOAD
|
v
EFFECTIVE CONFIG
|
v
VERIFY
This is more important than merely checking whether the file exists.
42. APPLY RESULT
On complete success:
SSH HARDENING APPLIED SUCCESSFULLY
If the required parameters do not match the policy:
ServerGuard hardening was not fully applied.
Thus, the presence of the configuration file by itself is not considered sufficient proof of successful application.
43. VIEWING BACKUPS
The function:
list_backups()
shows the contents of:
/opt/serverguard/backups
Backup files are sorted so that newer versions are displayed before older ones.
For example:
1. sshd_config_20260930_215300.backup
2. sshd_config_20260930_204100.backup
3. sshd_config_20260929_190000.backup
The number is used when selecting a backup.
44. RESTORE
The module supports restoring the main SSH configuration.
The command:
ssh_hardening.py restore <backup_file>
uses the selected backup.
The main file being restored:
/etc/ssh/sshd_config
Important:
backup ServerGuard hardening config
is not the same as a backup of the main sshd_config.
The configurations are stored separately.
45. EMERGENCY COPY BEFORE RESTORE
Before restoration, the current:
/etc/ssh/sshd_config
is saved separately.
For example:
before_restore_20260930_215500.backup
This is an emergency backup.
It is needed to enable rollback if the selected old configuration turns out to be invalid.
46. RESTORE VERIFICATION
After copying the backup, the following is executed:
sshd -t
If the configuration is valid:
the process continues.
If the configuration is invalid:
ServerGuard attempts to restore the emergency backup.
Diagram:
RESTORE
|
v
sshd -t
|
+--+--+
| |
OK FAIL
| |
v v
RELOAD ROLLBACK
47. PROTECTION AGAINST PATH TRAVERSAL
The command:
ssh_hardening.py restore <backup_file>
accepts a backup name.
However, the user must not be able to pass an arbitrary file path.
Therefore, the backup name is validated.
Dangerous elements are prohibited:
/
\
..
For example, the following must be rejected:
../../etc/passwd
../backup
/tmp/file
..\file
Goal:
allow operation only within
/opt/serverguard/backups
This is protection against Path Traversal.
48. BACKUP TYPE VERIFICATION
Even if the file exists, its name is additionally checked.
Allowed types:
sshd_config_*.backup
and:
before_restore_*.backup
If the name does not match an allowed type:
Unsupported backup type.
Thus, a single existence check of the file is not sufficient.
49. THE CHECK COMMAND
The following is supported:
ssh_hardening.py check
The command performs an SSH check.
The following are checked:
- the SSH service name;
- the SSH state;
- the presence of hardening;
- effective configuration;
- required parameters;
- informational parameters.
Simplified:
CHECK
|
+-- SSH service
|
+-- Hardening file
|
+-- sshd -T
|
+-- Policy verification
50. THE APPLY COMMAND
The command:
ssh_hardening.py apply
starts the full application of the policy.
Main stages:
root check
|
v
backup
|
v
create config
|
v
sshd -t
|
v
reload SSH
|
v
sshd -T
|
v
verify
51. THE RESTORE COMMAND
The command:
ssh_hardening.py restore <backup_file>
performs:
- root check;
- backup name validation;
- existence check;
- backup type validation;
- creation of an emergency backup;
- restoration;
- sshd -t;
- rollback on error;
- reload SSH.
52. PROGRAM COMMANDS
Main syntax:
ssh_hardening.py [check|apply|restore]
Check:
python3 ssh_hardening.py check
Apply:
python3 ssh_hardening.py apply
Restore:
python3 ssh_hardening.py restore sshd_config_20260930_215300.backup
An unknown command results in the message:
Unknown command
and the output of the correct syntax.
53. ENTRY POINT
At the end of the file, the standard Python construct is used:
if __name__ == "__main__":
sys.exit(main())
This means: if the file is run directly:
python3 ssh_hardening.py
the following is called:
main()
The main() function analyzes:
sys.argv
and determines the required operation.
54. COMMAND HANDLING
The following are supported:
check
apply
restore
The logic:
check
|
v
command_check()
apply
|
v
command_apply()
restore
|
v
command_restore()
An unknown command fails with an error.
55. THE COMPLETE APPLY SCENARIO
The administrator runs:
python3 ssh_hardening.py apply
Step 1:
Root check.
Step 2:
Creating the required directories.
Step 3:
Backup:
/etc/ssh/sshd_config
Step 4:
Backup of the previous ServerGuard config,
if it exists.
Step 5:
Creating:
/etc/ssh/sshd_config.d/99-serverguard-hardening.conf
Step 6:
Check:
sshd -t
Step 7:
Reload:
systemctl reload ssh
or:
systemctl reload sshd
Step 8:
Retrieving:
sshd -T
Step 9:
Policy check.
Step 10:
Generating the result.
56. SUCCESSFUL APPLY SCENARIO
Diagram:
root
|
v
backup
|
v
create config
|
v
sshd -t
|
v
VALID
|
v
reload
|
v
sshd -T
|
v
verify
|
v
SUCCESS
Result:
SSH HARDENING APPLIED SUCCESSFULLY
57. ERROR SCENARIO
If:
sshd -t
returns an error:
CREATE
|
v
sshd -t
|
v
ERROR
|
v
REMOVE HARDENING CONFIG
|
v
CANCEL
Thus, an incorrect ServerGuard fragment must not remain as a result of a failed application.
58. FAILED RELOAD SCENARIO
Scenario:
CREATE
|
v
sshd -t
|
v
SUCCESS
|
v
systemctl reload
|
v
ERROR
|
v
REMOVE HARDENING CONFIG
|
v
ERROR
The apply operation is considered unsuccessful.
59. RESTORE SCENARIO
The administrator selects:
sshd_config_20260930_210000.backup
ServerGuard performs:
1. Root check.
2. Name validation.
3. Existence check.
4. Allowed type check.
5. Creation of an emergency backup.
6. Copying the selected backup.
7. sshd -t.
8. Rollback on error.
9. Reload SSH.
Diagram:
SELECT BACKUP
|
v
VALIDATE INPUT
|
v
EMERGENCY BACKUP
|
v
RESTORE
|
v
sshd -t
|
+--+--+
| |
OK FAIL
| |
v v
RELOAD ROLLBACK
|
v
SUCCESS
60. MODULE SECURITY
The module implements several protective mechanisms.
1. ROOT CHECK
Only root can perform privileged operations.
2. BACKUP BEFORE CHANGE
A backup is created before any change.
3. CONFIG VALIDATION
The following is used:
sshd -t
4. EFFECTIVE CONFIG CHECK
The following is used:
sshd -T
5. EMERGENCY BACKUP
Before restore, the current configuration is saved.
6. ROLLBACK
If there is a problem with restoration, the emergency backup is used.
7. PATH TRAVERSAL PROTECTION
Dangerous path elements are prohibited.
8. BACKUP TYPE VALIDATION
Only the provided backup types are allowed.
61. WHAT EXACTLY SSH HARDENING PROTECTS
The module changes the OpenSSH policy.
It restricts:
- empty passwords;
- root password login;
- the number of authentication attempts;
- authentication time;
- X11 forwarding;
- TCP forwarding;
- SSH Agent Forwarding;
- SSH compression.
This is protection specifically at the level of:
SSH daemon configuration.
62. WHAT THE MODULE DOES NOT DO
SSH Hardening is NOT:
- an antivirus;
- a firewall;
- IDS/IPS;
- an IP blocking system;
- a network packet analysis system;
- a file monitoring system;
- a malware detection system;
- a full-fledged DDoS protection.
It is responsible for the OpenSSH configuration.
For example:
MaxAuthTries 3
does not mean:
"the IP will be blocked after three attempts".
A separate ServerGuard Security logic is used for IP detection and blocking.
63. SSH HARDENING AND SECURITY
The ServerGuard architecture separates responsibilities.
SSH Hardening:
OpenSSH configuration
|
+-- authentication limits
+-- root login policy
+-- forwarding
+-- compression
+-- empty passwords
Security:
SSH activity
|
+-- failed login detection
+-- IP analysis
+-- brute-force detection
+-- blocking
One module does not replace the other.
64. SSH HARDENING AND FIREWALL
SSH Hardening is not a firewall.
It is not responsible for:
UFW rules
packet filtering
IP blocking
The levels can be represented as follows:
Internet
|
v
Firewall
|
v
SSH service
|
v
SSH authentication
|
v
SSH Hardening policy
Each level performs its own task.
65. FOR BEGINNERS
To explain the module as simply as possible:
SSH Hardening is a program that tells SSH:
"Use stricter security rules."
For example:
MaxAuthTries 3
means:
limit the number of authentication attempts
within a single SSH connection.
The parameter:
PermitEmptyPasswords no
means:
do not use empty passwords for SSH authentication.
The parameter:
X11Forwarding no
means:
disable X11 forwarding.
After the change, ServerGuard checks:
sshd -t
and then:
sshd -T
66. FOR EXPERIENCED DEVELOPERS
From a technical standpoint, ssh_hardening.py is a control layer over OpenSSH.
Main principles:
- declarative security policy;
- configuration fragment;
- backup before mutation;
- validation before reload;
- effective configuration verification;
- controlled rollback;
- restricted restore input.
The main sequence:
BACKUP
|
v
GENERATE
|
v
VALIDATE
|
v
RELOAD
|
v
EFFECTIVE CONFIG
|
v
VERIFY
67. WHY A CONFIGURATION FRAGMENT IS USED
Instead of fully modifying:
/etc/ssh/sshd_config
ServerGuard creates:
/etc/ssh/sshd_config.d/99-serverguard-hardening.conf
The advantage of this approach:
the main configuration file remains separate;
the ServerGuard policy has its own file;
updating ServerGuard does not require completely rewriting
the administrator's configuration;
rollback of the ServerGuard configuration can be performed separately.
68. WHY sshd -t IS USED
The command:
sshd -t
is a barrier before reload.
Conditionally:
sshd -t
|
+-- 0
| |
| v
| VALID
|
+-- != 0
|
v
ERROR
Without this check, an incorrect configuration could be applied without the error being detected in advance.
69. WHY sshd -T IS USED
The command:
sshd -T
shows the resulting OpenSSH configuration.
This is especially important when the following are present:
/etc/ssh/sshd_config
and:
/etc/ssh/sshd_config.d/*.conf
ServerGuard checks not merely the created file but the resulting state that OpenSSH sees.
70. EFFECTIVE CONFIGURATION
Two concepts can be distinguished.
CONFIGURATION FILE:
99-serverguard-hardening.conf
and:
EFFECTIVE CONFIGURATION:
the result of sshd -T
The first shows:
what ServerGuard wrote.
The second shows:
what OpenSSH actually uses.
Therefore:
the file exists
does not necessarily mean:
the parameter is actually applied.
71. FUNCTION STRUCTURE
Main functions of the module:
run_command()
launching Linux commands
check_root()
root check
create_directories()
creating directories
get_ssh_service()
determining the SSH service
check_ssh_service()
checking the SSH state
backup_main_config()
backup sshd_config
backup_hardening_config()
backup ServerGuard config
create_hardening_config()
creating the hardening config
validate_ssh_config()
running sshd -t
reload_ssh()
reload SSH
get_effective_config()
retrieving sshd -T
get_config_value()
retrieving a parameter
value_matches()
comparing the value
check_hardening()
checking the policy
remove_hardening_config()
removing the ServerGuard config
apply_hardening()
full apply
list_backups()
list of backups
restore_configuration()
restore
command_check()
the check command
command_apply()
the apply command
command_restore()
the restore command
main()
program control point
72. HARDENING LIFECYCLE
The configuration goes through:
NOT INSTALLED
|
v
APPLY
|
v
BACKUP
|
v
CREATE
|
v
VALIDATE
|
v
RELOAD
|
v
VERIFY
|
v
ENABLED
On error:
APPLY
|
v
ERROR
|
v
REMOVE / ROLLBACK
|
v
CANCEL
73. RESTORE LIFECYCLE
Restore:
SELECT BACKUP
|
v
VALIDATE INPUT
|
v
EMERGENCY BACKUP
|
v
RESTORE
|
v
VALIDATE
|
+--+--+
| |
OK FAIL
| |
v v
RELOAD ROLLBACK
|
v
SUCCESS
74. IMPORTANT FEATURE OF RESTORE
Restoring the main configuration modifies:
/etc/ssh/sshd_config
But the ServerGuard hardening is located separately:
/etc/ssh/sshd_config.d/99-serverguard-hardening.conf
Therefore:
restore sshd_config
does not automatically mean:
remove ServerGuard hardening.
After restoration, the resulting configuration should be verified via:
sshd -T
or:
python3 ssh_hardening.py check
75. PERMISSIONS OF THE HARDENING CONFIGURATION
After creation, the permissions are set:
0644
That is:
owner:
read + write
group:
read
others:
read
The SSH daemon can read the configuration.
Modifying the file requires the appropriate privileges.
76. CONSOLE INTERFACE
The module uses ANSI colors:
RED
GREEN
YELLOW
CYAN
RESET
Purpose:
GREEN
successful operation
RED
error
YELLOW
warning
CYAN
informational message
This does not affect the operation of OpenSSH and is used only for the administrator's convenience when working with the console.
77. EXAMPLE OF A CONFIGURATION CHANGE
Before applying hardening:
PermitEmptyPasswords yes
MaxAuthTries 6
LoginGraceTime 120
X11Forwarding yes
ServerGuard applies:
PermitEmptyPasswords no
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
Also:
AllowTcpForwarding no
AllowAgentForwarding no
Compression no
PermitRootLogin prohibit-password
After reload, the following is executed:
sshd -T
and the obtained values are checked.
78. EXAMPLE OF A SUCCESSFUL RESULT
As an example, the console may show:
[OK] SSH service: ACTIVE
[OK] PermitRootLogin: prohibit-password
[OK] PermitEmptyPasswords: no
[OK] MaxAuthTries: 3
[OK] LoginGraceTime: 30
[OK] X11Forwarding: no
[OK] AllowTcpForwarding: no
[OK] AllowAgentForwarding: no
[OK] Compression: no
After which:
ServerGuard hardening: ENABLED
79. EXAMPLE OF PARTIAL APPLICATION
If some parameters match the policy and some differ:
[OK] MaxAuthTries: 3
[OK] LoginGraceTime: 30
[FAIL] X11Forwarding: yes
then the result is:
ServerGuard hardening: PARTIALLY APPLIED
This means:
the ServerGuard configuration exists,
but:
the actual SSH configuration does not fully match
the ServerGuard policy.
80. WHY CHECKING AFTER RELOAD IS NECESSARY
Just:
systemctl reload
is not enough.
The correct logic:
create the configuration
|
v
check the syntax
|
v
reload
|
v
obtain the effective config
|
v
check the values
This makes it possible to detect situations where the configuration file exists but the resulting OpenSSH policy differs from the expected one.
81. IMPORTANT LIMITATIONS
Some hardening settings reduce SSH functionality.
For example:
AllowTcpForwarding no
may disable SSH tunnels.
AllowAgentForwarding no
may disrupt Agent Forwarding.
X11Forwarding no
disables X11 forwarding.
Compression no
disables SSH compression.
Therefore, applying hardening must take the purpose of the server into account.
82. IMPORTANT FOR ADMINISTRATORS
Before applying, it is recommended to make sure that a working administrative access exists.
It is especially important to check:
- the administrator's SSH key;
- the administrator user;
- the ability to log in;
- root policy;
- forwarding requirements;
- the presence of a backup or second access channel.
Despite the presence of backup and rollback, the administrator must understand which SSH capabilities are used by a particular server.
83. DIFFERENCE FROM MANUAL EDITING
The manual approach:
nano /etc/ssh/sshd_config
assumes that the administrator independently:
- changes the settings;
- saves a backup;
- checks the syntax;
- reload SSH;
- checks the result;
- performs a rollback if necessary.
ServerGuard combines these operations:
BACKUP
|
v
GENERATE
|
v
VALIDATE
|
v
RELOAD
|
v
VERIFY
|
v
RESULT
84. SERVERGUARD C++ AND PYTHON
In the ServerGuard architecture, the user interface may reside in a C++ application, while the Linux logic is performed by a Python module.
Simplified:
ServerGuard C++
|
| SSH
v
Linux Server
|
v
ssh_hardening.py
|
+---- OpenSSH
|
+---- systemd
|
+---- filesystem
C++ may be responsible for:
- GUI;
- the SSH connection;
- passing commands;
- managing modules;
- displaying results.
The Python module is directly responsible for the Linux operations of SSH Hardening.
85. COMPLETE DIAGRAM
SERVERGUARD
|
v
SSH CONNECTION
|
v
LINUX SERVER
|
v
ssh_hardening.py
|
+---------------+---------------+
| | |
v v v
Filesystem systemctl sshd
| | |
v v v
/etc/ssh/ SSH service OpenSSH
|
v
99-serverguard-hardening.conf
|
v
sshd -t
|
v
SSH reload
|
v
sshd -T
|
v
Effective config
|
v
Verification
86. COMMANDS FOR THE ADMINISTRATOR
Check SSH Hardening:
sudo python3 ssh_hardening.py check
Apply:
sudo python3 ssh_hardening.py apply
Restore a backup:
sudo python3 ssh_hardening.py restore <backup_file>
Check the OpenSSH syntax directly:
sudo sshd -t
View the effective configuration:
sudo sshd -T
Check a specific parameter:
sudo sshd -T | grep -i permitrootlogin
Check the SSH state:
sudo systemctl status ssh
or:
sudo systemctl status sshd
87. FILE CHECK
The main SSH file:
/etc/ssh/sshd_config
The ServerGuard file:
/etc/ssh/sshd_config.d/99-serverguard-hardening.conf
Backup:
/opt/serverguard/backups/
To view the ServerGuard configuration:
sudo cat /etc/ssh/sshd_config.d/99-serverguard-hardening.conf
To view the backup:
sudo ls -lah /opt/serverguard/backups/
88. TYPICAL DIAGNOSTIC SEQUENCE
If hardening does not work as expected:
1. Check the SSH service.
2. Check the existence of:
99-serverguard-hardening.conf
3. Run:
sshd -t
4. Run:
sshd -T
5. Check a specific parameter.
6. Run:
python3 ssh_hardening.py check
7. View the backup if necessary.
89. WHAT TO CHECK WHEN PROBLEMS OCCUR
If SSH Hardening is not applied, the following must be checked:
- whether the script is run as root;
- whether /etc/ssh/ exists;
- whether sshd exists;
- whether the systemd service is found;
- whether systemctl is available;
- whether sshd_config exists;
- whether the sshd_config.d directory is accessible;
- whether sshd -t passes;
- what result sshd -T gives;
- whether the backup exists;
- whether a setting that conflicts with the policy is in use.
90. THE PRINCIPLE OF BACKUP RECOVERY
The main principle:
NEVER MODIFY THE SSH CONFIGURATION
WITHOUT THE ABILITY TO REVERT.
Therefore:
APPLY
|
v
BACKUP
|
v
CHANGE
And for restore:
CURRENT CONFIG
|
v
EMERGENCY BACKUP
|
v
RESTORE
|
v
VALIDATE
|
+---- FAIL
|
v
ROLLBACK
91. KEY PRINCIPLE OF THE MODULE
SSH Hardening is built around the sequence:
BACKUP
↓
CONFIGURE
↓
VALIDATE
↓
RELOAD
↓
VERIFY
↓
SUCCESS
On a problem:
ERROR
↓
ROLLBACK
It is precisely this sequence that is the main architectural idea of the module.
92. SHORT DESCRIPTION FOR THE README
ServerGuard SSH Hardening is a Linux module for automated hardening of the OpenSSH configuration.
The module creates:
/etc/ssh/sshd_config.d/99-serverguard-hardening.conf
and applies the following restrictions:
- prohibition of empty passwords;
- prohibition of root password login;
- MaxAuthTries = 3;
- LoginGraceTime = 30;
- disabling X11 Forwarding;
- disabling TCP Forwarding;
- disabling SSH Agent Forwarding;
- disabling SSH Compression.
A backup is created before the change.
After creation, the configuration is verified via:
sshd -t
After reload, the effective configuration is verified via:
sshd -T
The module also supports:
- backup;
- restore;
- emergency backup;
- rollback;
- verification of the effective configuration;
- protection against Path Traversal.
93. CONCLUSION
ServerGuard SSH Hardening is a separate security layer of ServerGuard intended specifically for managing the OpenSSH policy.
The main task of the module:
not just to change the SSH configuration,
but to perform a controlled process:
1. check privileges;
2. determine the SSH service;
3. save the original configuration;
4. create the ServerGuard policy;
5. check the syntax;
6. apply the configuration;
7. check the actual values;
8. report the result;
9. perform restoration if necessary.
The main architectural diagram:
BACKUP
↓
CONFIGURE
↓
VALIDATE
↓
RELOAD
↓
VERIFY
↓
SUCCESS
On error:
ERROR
↓
ROLLBACK
Thus, SSH Hardening is not merely a set of OpenSSH parameters but an automated mechanism for managing, verifying, and restoring the SSH configuration of a Linux server.