Use a Python script to modify the Windows Firewall rules via netsh or PowerShell, then schedule it with schtasks to block SSH connections. This approach provides automated network security by disabling port 22 access on demand without requiring third-party firewall software.
Understanding the Security Context
Blocking SSH (Secure Shell) connections is a common requirement for temporary lockdowns during maintenance, incident response, or when a server is being decommissioned. While manual intervention through the Windows Defender Firewall console is straightforward, automating this process ensures consistency and reduces human error. By combining a Python script with a Windows Scheduled Task, you create a reliable mechanism that can trigger these changes based on time, events, or system state.
It is important to note that modifying firewall rules requires administrative privileges. The Python script must be executed in an environment where the user has sufficient permissions to alter network configurations. Additionally, care must be taken to ensure that the blocking mechanism does not lock you out of your own management interface if you rely on SSH for remote administration. Always maintain an alternative access method, such as a console session or a different management port, before implementing automated blocks.
Defender Recognizes Scheduled Task as Malicious: Unsigned Executable Daily highlights the importance of signing scripts or configuring exclusions, as security software may flag automated firewall modifications as suspicious activity. This is particularly relevant when using scheduled tasks to run external executables or scripts that interact with system networking components.Creating the Python Script
The core of this solution lies in a Python script that interacts with the operating system's firewall settings. There are two primary methods to achieve this: using the built-in netsh command-line utility or leveraging the subprocess module to call PowerShell cmdlets. The netsh approach is often simpler for basic rule additions because it does not require importing additional libraries beyond the standard library.
Below is an example of a Python script that uses subprocess to add a firewall rule that blocks inbound TCP traffic on port 22, which is the default port for SSH.
import subprocess
import sys
def block_ssh():
# Command to block inbound SSH traffic on port 22
# This adds a rule named "Block SSH Inbound"
command = [
'netsh', 'advfirewall', 'firewall', 'add', 'rule',
'name="Block SSH Inbound"',
'dir=in',
'action=block',
'protocol=TCP',
'localport=22'
]
try:
result = subprocess.run(command, check=True, capture_output=True, text=True)
print("SSH blocking rule added successfully.")
except subprocess.CalledProcessError as e:
print(f"Failed to add rule: {e.stderr}")
sys.exit(1)
if __name__ == "__main__":
block_ssh()
This script checks for errors during execution. If the netsh command fails, it prints the error message and exits with a non-zero status code, which is crucial for scheduled tasks to report failures correctly. You should test this script manually first by running it from an elevated command prompt to ensure it works as expected in your specific network environment.
Scheduling the Task in Windows
Once the Python script is verified, the next step is to automate its execution using the Windows Task Scheduler. This allows the SSH block to occur at specific times or under certain conditions. You can use the schtasks command-line tool to create the task programmatically, or use the graphical Task Scheduler interface.
To create a task that runs daily at midnight, you can use the following command in an elevated Command Prompt:
schtasks /create /tn "Block SSH Daily" /tr "python C:\Scripts\block_ssh.py" /sc daily /st 00:00 /ru SYSTEM
Here, /tn specifies the task name, /tr defines the path to the Python interpreter and the script, /sc sets the schedule type to daily, /st sets the start time, and /ru specifies the user context. Using SYSTEM ensures the task runs with high privileges, which is necessary for modifying firewall rules. However, be aware that running as SYSTEM might bypass some user-specific restrictions.
Alternative Approach: PowerShell Integration
For more complex firewall management, consider using PowerShell within the Python script. The New-NetFirewallRule cmdlet offers more granular control over rule properties, such as specifying profiles (Domain, Private, Public) and descriptions. This approach is preferred if you need to manage multiple ports or apply rules to specific network interfaces.
import subprocess
def block_ssh_powershell():
ps_command = '''
New-NetFirewallRule -DisplayName "Block SSH Inbound" `
-Direction Inbound `
-Action Block `
-Protocol TCP `
-LocalPort 22
'''
subprocess.run(['powershell.exe', '-Command', ps_command], check=True)
Maintaining Access and Troubleshooting
Automating security controls carries the risk of self-lockout. To mitigate this, always implement a "kill switch" or a way to quickly revert the changes. For instance, you could create a separate script that deletes the firewall rule, scheduled to run after a maintenance window ends. Alternatively, use conditional logic in your script to check for a specific file existence before applying the block.
If the scheduled task fails to execute, check the Task Scheduler history for error codes. Common issues include incorrect paths to the Python executable, insufficient permissions, or syntax errors in the script. Ensure that the full path to python.exe is used in the scheduled task action, especially if Python is installed in a user-specific directory like the Microsoft Store version.
Frequently Asked Questions
Can I block SSH without administrative privileges?
No, modifying Windows Firewall rules requires administrative rights. Standard users cannot add or delete firewall exceptions. You must run the Python script and the scheduled task under an account with elevated privileges, such as Administrator or SYSTEM.
How do I unblock SSH if I get locked out?
You can unblock SSH by removing the firewall rule using netsh advfirewall firewall delete rule name="Block SSH Inbound". If remote access is lost, you will need physical or console access to the machine to run this command or disable the scheduled task.
Will this block outgoing SSH connections?
The example script blocks only inbound traffic on port 22. Outgoing SSH connections remain unaffected unless you explicitly add another rule for outbound traffic. Be careful not to block outbound traffic if you need to connect to other servers via SSH.
Does this work on all Windows versions?
Yes, netsh advfirewall is supported on Windows Vista and later, including Windows 10, 11, and Windows Server editions. However, older systems like Windows XP use a different netsh syntax (netsh firewall), which is no longer recommended.
What happens if the Python script crashes?
If the script crashes, the scheduled task will log an error in the Event Viewer. The firewall rule will not be applied, so SSH will remain open. It is good practice to add logging to your script to track execution attempts and failures for debugging purposes.