If you're running Cygwin's SSH daemon on Windows Server 2008, you've probably noticed relentless brute force attacks in your Event Viewer logs. These attacks typically show:
- 5-6 failed login attempts per second
- Multiple IP addresses rotating
- Dictionary-based username/password combinations
Manually adding IPs to the Windows Firewall is:
- Time-consuming
- Reactive rather than proactive
- Ineffective against distributed attacks
The most effective approach is to install Fail2Ban, which can:
# Install required packages
apt-cyg install python python-setuptools git
git clone https://github.com/fail2ban/fail2ban.git
cd fail2ban
python setup.py install
Create a custom jail configuration:
[cygwin-ssh]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
Since Cygwin logs differently than Linux, create a custom filter:
[Definition]
failregex = ^.*sshd.*Failed password for .* from <HOST> port \d+.*$
ignoreregex =
For those preferring PowerShell, here's a script to parse Event Viewer:
# PowerShell script to block repeated offenders
$failedLogins = Get-WinEvent -LogName "Application" |
Where-Object {$_.Id -eq 0} |
Group-Object -Property {$_.Properties[0].Value}
foreach ($ip in $failedLogins | Where-Object Count -gt 3) {
New-NetFirewallRule -DisplayName "Block SSH $($ip.Name)" -Direction Inbound -Action Block -RemoteAddress $ip.Name
}
Regularly check your blocked IPs with:
# View current bans
fail2ban-client status cygwin-ssh
# Unban an IP if needed
fail2ban-client set cygwin-ssh unbanip 192.168.1.1
When running Cygwin's SSHD service on Windows Server 2008, you'll inevitably face brute force attacks. The default configuration makes your server a tempting target for automated login attempts. The Windows Event Viewer shows these failed attempts piling up at alarming rates - sometimes 5-6 per second from various IPs.
Manually adding each malicious IP to the firewall is impractical. The volume of attacks makes this approach unsustainable. We need an automated solution that can:
- Parse Windows Event Logs for failed SSH attempts
- Identify repeat offenders
- Add firewall rules dynamically
- Optionally whitelist known good IPs
Here's a PowerShell script that monitors failed logins and blocks suspicious IPs automatically. Save this as SSH-Blocker.ps1:
# SSH-Blocker.ps1 - Automated IP blocking for Cygwin SSHD
$maxAttempts = 5 # Block after this many failures
$blockDuration = 24 # Hours to block the IP
$logPath = 'C:\cygwin\var\log\sshd.log' # Cygwin SSH log path
# Parse logs and find offenders
$failedAttempts = Select-String -Path $logPath -Pattern 'Failed password' |
ForEach-Object {
if ($_ -match 'from (\d+\.\d+\.\d+\.\d+)') {
$matches[1]
}
}
# Count and filter IPs
$offenders = $failedAttempts | Group-Object |
Where-Object { $_.Count -ge $maxAttempts } |
Select-Object -ExpandProperty Name
# Add firewall rules for offenders
foreach ($ip in $offenders) {
$ruleName = "Block SSH $ip"
if (-not (Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue)) {
New-NetFirewallRule -DisplayName $ruleName -Direction Inbound -Action Block
-RemoteAddress $ip -Protocol TCP -LocalPort 22
Write-Host "Blocked IP: $ip"
}
}
For a more robust solution, consider setting up Fail2Ban within Cygwin:
# Install Fail2Ban in Cygwin
apt-cyg install fail2ban
# Configure /etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/sshd.log
maxretry = 5
bantime = 86400
When implementing these solutions, remember that Windows Firewall rules take precedence. Ensure your automated solution:
- Doesn't conflict with existing rules
- Properly handles rule expiration if desired
- Logs its actions for review
Set up scheduled tasks to run your blocking script regularly. For the PowerShell solution, create a scheduled task to run every 5 minutes:
# Create scheduled task via PowerShell
$action = New-ScheduledTaskAction -Execute 'Powershell.exe'
-Argument '-NoProfile -ExecutionPolicy Bypass -File "C:\scripts\SSH-Blocker.ps1"'
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 5)
Register-ScheduledTask -TaskName "SSH Brute Force Blocker" -Action $action -Trigger $trigger -RunLevel Highest