OpenWrt Forum Archive

Topic: Brute force SSH fix? (OpenWRT / X-WRT)

The content of this topic has been archived on 26 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

I am suffering a lot of brute force SSH attempts and would like to implement a simple rule to fix this as explained here: http://www.macsat.com/macsat/content/vi … /#sshbrute

 iptables -t filter -A input_rule -i $WAN -p TCP --dport 22 -m recent --name SSH --rcheck --hitcount 3 --seconds 120 -j LOG --log-prefix "SSH_BRUTE "
 iptables -t filter -A input_rule -i $WAN -p TCP --dport 22 -m recent --name SSH --update --hitcount 3 --seconds 120 -j DROP
 iptables -t filter -A input_rule -i $WAN -p TCP --dport 22 -m recent --name SSH --set -j ACCEPT

I am using OpenWrt White Russian - With X-Wrt Extensions 0.9 and this uses two seperate files for setting up te firewall: /etc/firewall.user and /etc/config/firewall. The latter is used for the webif but uses a syntax I do not understand. Could anyone help me out how to implement the above rules in /etc/config/firewall? If I put them in /etc/firewall.user the rules don't seem to apply? I think that that the pre-build X-WRT already comes with the required packages.

My /etc/firewall.user:

#!/bin/sh
# Copyright (C) 2006 OpenWrt.org
iptables -F input_rule
iptables -F output_rule
iptables -F forwarding_rule
iptables -t nat -F prerouting_rule
iptables -t nat -F postrouting_rule

# The following chains are for traffic directed at the IP of the
# WAN interface

iptables -F input_wan
iptables -F forwarding_wan
iptables -t nat -F prerouting_wan

### Open port to WAN
## -- This allows port 22 to be answered by (dropbear on) the router
# iptables -t nat -A prerouting_wan -p tcp --dport 22 -j ACCEPT
# iptables        -A input_wan      -p tcp --dport 22 -j ACCEPT
iptables -t filter -A input_rule -i $WAN -p TCP --dport 22 -m recent --name SSH --rcheck --hitcount 3 --seconds 120 -j LOG --log-prefix "SSH_BRUTE "
iptables -t filter -A input_rule -i $WAN -p TCP --dport 22 -m recent --name SSH --update --hitcount 3 --seconds 120 -j DROP
iptables -t filter -A input_rule -i $WAN -p TCP --dport 22 -m recent --name SSH --set -j ACCEPT

### Port forwarding
## -- This forwards port 8080 on the WAN to port 80 on 192.168.1.2
# iptables -t nat -A prerouting_wan -p tcp --dport 8080 -j DNAT --to 192.168.1.2:80
# iptables        -A forwarding_wan -p tcp --dport 80 -d 192.168.1.2 -j ACCEPT

### DMZ
## -- Connections to ports not handled above will be forwarded to 192.168.1.2
# iptables -t nat -A prerouting_wan -j DNAT --to 192.168.1.2
# iptables        -A forwarding_wan -d 192.168.1.2 -j ACCEPT

My /etc/config/firewall:

accept:dport=22

Installed packages (ipkg list_installed |sort):

base-files - 9 - OpenWrt filesystem structure and scripts
base-files-brcm - 2 - Board/architecture specific files
bridge - 1.0.6-1 - Ethernet bridging tools
busybox - 1.4.0-1 - Core utilities for embedded Linux systems
dnsmasq - 2.35-1 - A lightweight DNS and DHCP server
dropbear - 0.48.1-1 - a small SSH 2 server/client designed for small memory environments.
e2fsprogs - 1.38-1 -
ez-ipupdate - 3.0.11b8-2 - a client for dynamic DNS services
fdisk - 2.12r-1 -
haserl - 0.8.0-1 - a CGI wrapper to embed shell scripts in HTML documents
ip - 2.6.11-050330-1 - iproute2 routing control utility
ipkg - 0.99.149-2 - lightweight package management system
ipkg-upgrade-fix - 0.2-1 - Shows warning about 'ipkg upgrade' when user tries to use it.
iptables - 1.3.3-2 - The netfilter firewalling software for IPv4
iptables-mod-conntrack - 1.3.3-2 - Iptables (IPv4) extensions for connection tracking
iptables-mod-extra - 1.3.3-2 - Other extra Iptables (IPv4) extensions
iptables-mod-filter - 1.3.3-2 - Iptables (IPv4) extension for packet content inspection
iptables-mod-imq - 1.3.3-2 - Iptables (IPv4) extensions for Intermediate Queuing Device QoS-support
iptables-mod-ipopt - 1.3.3-2 - Iptables (IPv4) extensions for matching/changing IP packet options
iwlib - 29.pre10-1 - Library for setting up WiFi cards using the Wireless Extension
kernel - 2.4.30-brcm-5 -
kmod-brcm-wl - 2.4.30-brcm-5 - Proprietary driver for Broadcom Wireless chipsets
kmod-diag - 2.4.30-brcm-5 - Kernel modules for LEDs and buttons
kmod-ext2 - 2.4.30-brcm-5 - Kernel modules for EXT2 filesystem support
kmod-ext3 - 2.4.30-brcm-5 - Kernel modules for EXT3 filesystem support
kmod-imq - 2.4.30-brcm-5 - Kernel support for the Intermediate Queueing device
kmod-ipt-conntrack - 2.4.30-brcm-5 - Extra Netfilter (IPv4) kernel modules for connection tracking
kmod-ipt-extra - 2.4.30-brcm-5 - Other extra Netfilter (IPv4) kernel modules
kmod-ipt-filter - 2.4.30-brcm-5 - Netfilter (IPv4) kernel modules for packet content inspection
kmod-ipt-ipopt - 2.4.30-brcm-5 - Netfilter (IPv4) kernel modules for matching/changing IP packet options
kmod-ipt-nat-default - 2.4.30-brcm-5 - Default Netfilter (IPv4) NAT kernel modules for special protocols
kmod-ppp - 2.4.30-brcm-5 - PPP support
kmod-pppoe - 2.4.30-brcm-5 - PPP over Ethernet support
kmod-sched - 2.4.30-brcm-5 - Kernel schedulers for IP traffic
kmod-switch - 2.4.30-brcm-1 - switch driver for robo/admtek switch
kmod-tun - 2.4.30-brcm-5 - Kernel TUN/TAP extension
kmod-usb-core - 2.4.30-brcm-5 - Kernel Support for USB
kmod-usb-storage - 2.4.30-brcm-5 - Kernel modules for USB storage support
kmod-usb2 - 2.4.30-brcm-5 - Kernel driver for USB2 controllers
kmod-vfat - 2.4.30-brcm-5 - Kernel modules for VFAT filesystem support
kmod-wlcompat - 2.4.30-brcm-4 - Compatibility module for using the Wireless Extension with broadcom's wl
libgcc - 3.4.4-9 - GCC support library
liblzo - 2.02-1 - a real-time data compression library
libopenssl - 0.9.8d-1 - OpenSSL (Secure Socket Layer) libraries
miniupnpd - 1.0-RC3-1 - a small and capable UPNP daemon.
mtd - 4 - Tool for modifying the flash chip
nas - 3.90.37-17 - Proprietary Broadcom WPA Authenticator/Supplicant
ntpclient - 2003_194-2 - NTP client for setting system time from NTP servers.
nvram - 1 - NVRAM utility and libraries for Broadcom hardware
openvpn - 2.0.9-1 - Open source VPN solution using SSL
ppp - 2.4.3-7 - a PPP (Point-to-Point Protocol) daemon (with MPPE/MPPC support)
ppp-mod-pppoe - 2.4.3-7 - a PPPoE (PPP over Ethernet) plugin for PPP
qos-scripts - 0.9.4-1 - QoS scripts for OpenWrt
samba-server - 2.0.10-2 - NetBIOS/SMB file and print server
tc - 2.6.11-050330-1 - iproute2 traffic control utility
uclibc - 0.9.27-9 - Standard C library for embedded Linux systems
webif - 0.3-6 -
wificonf - 6 - Replacement utility for wlconf
wireless-tools - 29.pre10-1 - Tools for setting up WiFi cards using the Wireless Extension
wol - 0.7.1-1 - A Program to send magic Wake-on-LAN packets

(Last edited by 500gx on 21 Apr 2007, 12:05)

Hi,
I would rather create a new target to be able to watch the traffic.

You have all required modules installed (kmod-ipt-extra, iptables-mod-extra).

insert into /etc/firewall.user, below the "### Open port to WAN" rules:

# insert required modules
[ -z "$(lsmod | grep "^ipt_recent")" ] && insmod ipt_recent
[ -z "$(lsmod | grep "^ipt_LOG")" ] && insmod ipt_LOG
# create the target
iptables -N SSH_BRUTE
# tell the kernel where to jump, set the counter
iptables -A input_wan      -p tcp --dport 22 -m state --state NEW -m recent --name SSH --set --rsource -j SSH_BRUTE
iptables -A forwarding_wan -p tcp --dport 22 -m state --state NEW -m recent --name SSH --set --rsource -j SSH_BRUTE
# enable some whitelist
#iptables -A SSH_BRUTE -s <my known address> -j ACCEPT
# the real "magic": check hitcount
iptables -A SSH_BRUTE -m recent ! --rcheck --seconds 60 --hitcount 3 --name SSH --rsource -j ACCEPT
# log the bad guy
iptables -A SSH_BRUTE -j LOG --log-prefix "SSH_BRUTE: "
# drop the connection
iptables -A SSH_BRUTE -p tcp -j DROP
# or if you are brute too let him wait, wait, wait...
# insert required modules
#[ -z "$(lsmod | grep "^ipt_TARPIT")" ] && insmod ipt_TARPIT
#iptables -A SSH_BRUTE -p tcp -j TARPIT

Warning: the TARPIT consumes tracked connections!

Your /etc/config/firewall is not right, it should be:

accept:proto=tcp dport=22

You must restart the firewall for the /etc/firewall.user to be in effect:

/etc/init.d/S35firewall

Quote: “Trust yourself. You know more than you think you do.”

you could do it the easy way, don't use passwords only pubkey authentication and use another port than 22, e.g. 48483.

Alternatively, if you're only going to be logging in from a few static sources, set up a whitelist for the port.

the methode posted http://oldwiki.openwrt.org/ThrottleConn … HowTo.html does not work:

/etc/init.d/firewall restart
Loading defaults
Loading synflood protection
Adding custom chains
Loading zones
Loading forwarding
Loading redirects
Loading rules
Loading includes
iptables v1.4.3.2:
The "nat" table is not intended for filtering, the use of DROP is therefore inhibited.

someone know how to fix it?

Yes, the more recent iptables checks this (just fell into this some minutes ago).
Just redirect to an unused port and reject it in the filter chains input and forward:
Example:

# Brute Force Protection (BFP) adapted from http://forum.openwrt.org/viewtopic.php?pid=34522#p34522
# For "-m recent" in Kamikaze 8.0.9 the packages "iptables-mod-conntrack-extra" and "kmod-ipt-conntrack-extra" are needed (files: libxt_recent.so & xt_recent.ko)

# As target REJECT is not allowed in nat/prerouting, redirect to an unused port and reject it in filter/input and filter/forwarding
echo ' ...establishing reject rules for prerouting'
BFP_REJECTPORT=55555
# nat chain that redirects to reject port
iptables -t nat -N prerouting_REJECT
iptables -t nat -A prerouting_REJECT -p tcp -j DNAT --to :${BFP_REJECTPORT}
iptables -t nat -A prerouting_REJECT -p udp -j DNAT --to :${BFP_REJECTPORT}
# filter rules that will finally reject
iptables -A input_wan      -p tcp  --dport ${BFP_REJECTPORT} -j reject
iptables -A forwarding_wan -p tcp  --dport ${BFP_REJECTPORT} -j reject
iptables -A input_wan      -p udp  --dport ${BFP_REJECTPORT} -j reject
iptables -A forwarding_wan -p udp  --dport ${BFP_REJECTPORT} -j reject


### SSH/Dropbear (TCP-22)
SERVICE=SSH
PROTO=tcp
PORT=22
BFP_START=6
echo " ...establishing ${SERVICE} rules for ${PROTO}-${PORT}"
## nat chain that updates connections and rejects
iptables -t nat -N prerouting_wan_BFP_${PROTO}${PORT}
iptables -t nat -A prerouting_wan_BFP_${PROTO}${PORT} -p ${PROTO} --dport ${PORT}  -m recent --name ATTACKER_${PROTO}${PORT} --rsource --update                                      -j prerouting_REJECT
## nat/prerouting
# immediately jumps to update+reject chain if remote source already in BFP mode (avoids multiple bruteforce log entries)
iptables -t nat -A prerouting_wan -p ${PROTO} --dport ${PORT} -m state --state NEW -m recent --name ATTACKER_${PROTO}${PORT} --rsource --rcheck --seconds 60 --hitcount ${BFP_START} -j prerouting_wan_BFP_${PROTO}${PORT}
# adds/updates remote source in list
iptables -t nat -A prerouting_wan -p ${PROTO} --dport ${PORT} -m state --state NEW -m recent --name ATTACKER_${PROTO}${PORT} --rsource --set
# check if BFP mode for remote source applies, if so log bruteforce and reject
iptables -t nat -A prerouting_wan -p ${PROTO} --dport ${PORT} -m state --state NEW -m recent --name ATTACKER_${PROTO}${PORT} --rsource --update --seconds 60 --hitcount ${BFP_START} -j LOG --log-level warn --log-prefix "BRUTEFORCE-${SERVICE} "
iptables -t nat -A prerouting_wan -p ${PROTO} --dport ${PORT} -m state --state NEW -m recent --name ATTACKER_${PROTO}${PORT} --rsource --rcheck --seconds 60 --hitcount ${BFP_START} -j prerouting_wan_BFP_${PROTO}${PORT}
## filter/input
iptables        -A input_wan      -p ${PROTO} --dport ${PORT} -m state --state NEW -j LOG --log-level info --log-prefix "${SERVICE} "
iptables        -A input_wan      -p ${PROTO} --dport ${PORT} -m state --state NEW -j ACCEPT

Works perfectly.

P.S.:
There's another thread also dealing with this.

Update:
Created a flexible plugin for this, that can be used for any service.

(Last edited by maddes.b on 8 Jul 2009, 11:25)

thanks works perfect!

My additions to the bruteforce protections.
The scripts on this page are detecting the bruteforce based on the number of recent NEW connects to the SSH port.

I choose a slightly different approach here and block on the number of recent closed ssh sessions. Furthermore, once the bruteforcer hits the limit of three closed ssh sessions, each new session would update the counter leaving him in the jail.

comments/suggestions are welcome

#!/bin/bash

case $1 in

enable)
        iptables -N ssh_attack_check
        iptables -I INPUT 1 -p tcp --dport 22 -j ssh_attack_check
        iptables -I INPUT 2 -m recent --name sshattack --seconds 180 --hitcount 3 --update -j DROP

        iptables -A ssh_attack_check -p tcp --dport 22 -m recent -m state --state ESTABLISHED --tcp-flags FIN,ACK FIN,ACK  --name sshattack --set
        iptables -A ssh_attack_check -p tcp --dport 22 -m recent -m state --state ESTABLISHED --tcp-flags RST     RST      --name sshattack --set
        iptables -A ssh_attack_check -p tcp --dport 22 -m recent -m state --state NEW           --name sshattack --seconds 180 --hitcount 3 --update
        iptables -A ssh_attack_check -p tcp --dport 22 -m recent                                --name sshattack --seconds 180 --hitcount 3 --update -j LOG -m limit --limit 12/m --log-prefix "FW_SSH bforce"
;;

disable)
        iptables -D INPUT -p tcp --dport 22 -j ssh_attack_check
        iptables -D INPUT -m recent --name sshattack --seconds 180 --hitcount 3 --update -j DROP
        iptables -F ssh_attack_check
        iptables -X ssh_attack_check
;;

status)
        iptables -L INPUT -vn
        echo -e "\n\n\n"
        iptables -L ssh_attack_check -vn
        echo -e "\n\n\n"
        cat /proc/net/xt_recent/sshattack
;;

*)
        echo "Usage: $0 {enable|disable|status}"
;;

esac

The discussion might have continued from here.