#--------------------------------------------------------------------
#--------------------------------------------------------------------
#-----------------
#--------------------------------------------------------------------
- runwhile_http.sh (simple START for nginx)
- runwhile_ssh.sh (simple START for ssh)
- fwtrash.py (script that do the work)
- modules/http.py (used optionaly)
- modules/ssh.py (used optionaly)
- rules/http.rules (used optionaly)
- rules/ssh.rules (used optionaly)
- run_http.sh (used with runwhile_http.sh)
- run_ssh.sh (used with runwhile_ssh.sh)
- fw.sh ( iptables script that was used in v0.1 maybe in future can be included again )
- other files created by script or just trash...
- modules/http.py
- modules/ssh.py
- rules/http.rules
- rules/ssh.rules
#--
nohup ./runwhile_http.sh&
nohup ./runwhile_ssh.sh&
tail -f run_http.out
tail -f run_ssh.out
#-- Examples with arguments and options from run_http.sh, run_ssh.sh
tail -f /var/log/nginx/access.log | ./fwtrash.py -P rules/http.rules -o badips.out -O trash_http.out -p modules.http -s "date,ip,repeat,req;60,ref;20,ua;20,code,len" -S "[--DATE] - ([--REPEAT],[--CODE],[--LEN]) [--IP] => [--REQ] ua: [--UA], ref: [--REF]" -c "iptables -A INPUT -s [--IP]/32 -j DROP" -b "key:1,climit:3,tlimit:5;key:2,climit:3,tlimit:6"
tail -f /var/log/auth.log | ./fwtrash.py -o badips.out -O trash_ssh.out -P rules/ssh.rules -p modules.ssh -s "date,ip,repeat,message;100" -S "[--DATE] --IP => [--MESSAGE]" -c "iptables -A INPUT -s [--IP]/32 -j DROP" -b "key:0,climit:3,tlimit:60;key:1,climit:3,tlimit:120"
#.) Example module tcpdump
tcpdump -r out.cap -nn -s0 port 443 or 80 -W 99 -l |
python fwtrash.py -D -d -P rules/tcpdump.rules
-a allowedips.txt -o badips_tcpdump.out -O trash_tcpdump.out
-p modules.tcpdump -c "echo "BADIP: [--IP]""
#.) Get process pid from name with ps or pgrep
ps aux | grep nginx
pgrep -l nginx
#.) Example read process memory with ps
ps -p 582341 -o "%cpu %mem"
#-- To get more help write "./fwtrash.py -h"
#------------------------------------
#------------------------------------ Can be used to block bad ips, ips that send suspicious requests. Can be used to analyze requests or generating statistics. Can be used with any program that send data to stdout or trough bash pipes.
How it works is that you should load multiple rules on which program recognize bad requests, bad lines of data.
Modules are used to parse/split line of data into values which are compared with rules if they have such configuration. Rules are writed in JSON. Each line is json array that can contain multiple objects. Object should contain specific keys:values.
Default keys for rules:
- key # KEY => can be used depend on module you are using. For ex. for module "logtrash_http" keys: # ip, date, req, code, len, ref, ua, repeat, hash, last_ts. # If you open with text editor file: modules/logtrash_http.py you will find keys that can be used within rules.
- type # TYPE => is used to define what kind of comparing you wish to use when searching for bad data. # 1: base64+regex, 2: regex, 3: plain compare, 4-8 are length comparing. 4:>=, 5:>, 6:<=, 7:<, 8:==
- data # DATA => is used to set string that will be compared with value of specific key inside of object. Additional keys:
- bruteforce_count_key # is number 1-999 and is used to set additional options for specific rule. # Options: key, climit & tlimit. tlimit is optional and is used to specify time in seconds. # Ex.: -b "key:1,climit:3,tlimit:5;key:2,climit:5"
Default keys for modules:
- date
- ip ( Can be empty. Depent on rule what can capture. )
- repeat ( Integer. Number of times trash repeated. )
- blocked ( True | False )
- bruteforced ( True | False )
- hash ( crc32b )
- last_ts ( timestamp in sec ) Other keys can be found by viewing modules/http.py or modules/ssh.py and check what keys xobj object contain.
#---------------
#---------------
#--------------------------------------------------------------------
(9.8.23) Thinking on new functionality that can block users that have been accepted/approved into ssh but ip is not between alowed!
#-------------------------------------------------------------------- Aug 9 07:02:08 ip-172-31-3-59 sshd[331537]: AuthorizedKeysCommand /usr/share/ec2-instance-connect/eic_run_authorized_keys someuser SHA256:VL35fr4lfd8qW0MgKevJgrrreWlyVWsq8 failed, status 22 Aug 9 07:02:09 ip-172-31-3-59 sshd[331537]: AuthorizedKeysCommand /usr/share/ec2-instance-connect/eic_run_authorized_keys someuser SHA256:hw1EXBX79sIgrrrfolVFjxCKasddrmD86ns8 failed, status 22 Aug 9 07:02:25 ip-172-31-3-59 sshd[331537]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.123.123 user=someuser Aug 9 07:02:27 ip-172-31-3-59 sshd[331537]: Failed password for someuser from 192.168.123.123 port 54636 ssh2 Aug 9 07:02:31 ip-172-31-3-59 sshd[331537]: Accepted password for someuser from 192.168.123.123 port 54636 ssh2 Aug 9 07:02:31 ip-172-31-3-59 sshd[331537]: pam_unix(sshd:session): session opened for user someuser by (uid=0) Aug 9 07:02:31 ip-172-31-3-59 systemd-logind[34426]: New session 3050 of user someuser. Aug 9 07:02:36 ip-172-31-3-59 sshd[331928]: Received disconnect from 192.168.123.123 port 54636:11: disconnected by user Aug 9 07:02:36 ip-172-31-3-59 sshd[331928]: Disconnected from user someuser 192.168.123.123 port 54636 Aug 9 07:02:36 ip-172-31-3-59 sshd[331537]: pam_unix(sshd:session): session closed for user someuser Aug 9 07:02:36 ip-172-31-3-59 systemd-logind[34426]: Session 3050 logged out. Waiting for processes to exit. Aug 9 07:02:36 ip-172-31-3-59 systemd-logind[34426]: Removed session 3050.
#--------------------------------------------------------------------
-
v0.6 - 03.02.2026 Updates and bugfixes for previous versions. Update for python 3.14 Updates and bugfixes of modules Added module.tcpdump (specially focused on spoofed attack to http server) Examples tcpdump:
#--------------------------------------------------- tcpdump -r out.cap -nn -s0 port 443 or 80 -W 99 -l |
python fwtrash.py -D -d -P rules/tcpdump.rules
-a allowedips.txt -o badips_tcpdump.out -O trash_tcpdump.out
-p modules.tcpdump -c "echo "BADIP: [--IP]""#---------------------------------------------------
#-- tcpdump -r out.cap -nn -s0 port 443 or 80 -W 99 -l | awk /.*\[S\].*win.64240,.options.\[mss.1300\,nop\,wscale.8\,nop\,nop\,sackOK\]\,.length.0/'{print $3}' | awk -F'.' '{print $1"."$2"."$3}' | uniq -c | sort | awk '{print $2}' | uniq -c | sort #--------------------------------------------------------------------
-
version 0.5 Added clearing of bruteforce stats into thread Stats() that run in loop and sleep 1/s so is perfect for clearing. Added option to stop the program when new day begin. Useful because system logs create new file so running of program is no more useful if is not restarted with new log..
#--------------------------------------------------------------------
- 19.10.21 version 0.4 Moved modules and rules as submodules of fwtrash.git repository. Updates of readme..:)
#--------------------------------------------------------------------
- 18.10.21 version 0.3 Separated parsing of data by creating modules. Updated syntax of rules. Line is array that can contain multiple objects. Object is rule constructed with keys&values. If there is more objects in array they get compared between each other. If all are succesfuly compared line of data is marked as bad line.. Added bruteforce detection.
#--------------------------------------------------------------------
- 11.10.21 version 0.2 Updated display of statistics by flushing and overwriting to stdout. Added option to execute a command when new bad ip is found. Updated usage with linux pipes ex.: tail -f /var/log/nginx/access.log | ./fwtrash.py -o badips.out -O trash.out -c "iptables -A INPUT -s [--RIP -J DROP]" > stats.out& tail -f stats.out # to run program in background and just tailing the statistics.
#--------------------------------------------------------------------
- x.10.21 version 0.1 This version is useful to run in bash loop like that script is monitoring all the time trafic to server. To run FWTrash in bash loop is created script "fwtrash.sh".
Other usage is trough linux pipes and commands like "cat" or "tail". Ex.: cat /var/log/nginx/access.log | ./fwtrash.py -o badips.out
Happy hunting...