-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathREADME.TXT
More file actions
312 lines (256 loc) · 17.4 KB
/
README.TXT
File metadata and controls
312 lines (256 loc) · 17.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
README blacklist.pl Version 0.1
===============================================================
This script is a modification of the original sshblack.pl script.
The major change is the support for configuration files.
The functionality is the same as the original script, however a
configuration file can be used to specify the settings for a
specific log file. Thus, multiple copies of the of the script
can run using different config files each with its own specific
settings for a unique log file.
This is a work in progress, and is not recommended to be used.
Please use the original script for securing your systems.
---------------------------------------------------------------
The original readme file follows:
===============================================================
README.TXT for sshblack Version 2.8.1
see http://www.pettingers.org/code/sshblack.html
pettingers (at) gmail.com
================================================
Background and Release Notes
----------------------------
I originally stumbled on to mailmgr.pl written by Julian Haight when I was
looking for some good anti-spam tools. Mr. Haight is the man behind the
fantastic spamcop.net site and the accompanying real-time DNS blacklist. The
mailmgr script was a stand-alone blacklisting script that could be used with
almost any mail program to monitor log files and manage an iptables blacklist
based on the activities recorded in the log. At the time, I didn't see the need
for blacklisting smtp traffic as most relay attempts come and go pretty quickly
and real-time DNS blacklists work very well.
However, I liked the idea of tailing a log file and decided to apply the concept
to both web site logs (http://www.pettingers.org/code/davblack.html) and ssh
logs (http://www.pettingers.org/code/sshblack.html). Starting in the spring of
2004 (and some historical sites report it long before that) I noticed a large
amount of ssh hacking attempts on my Linux hosts. They were clearly bots or
trojans, none successfully entering my system but it left hundreds of lines of
hack attempts in my logs and struck me as something very unhealthy.
Version 1. The original sshblack script simply monitored my /var/log/secure
file and looked for tale-tell signs of the hacking attempts. By far most of
them were identified by attempts at the username "test" and "guest" and -- for
some odd reason -- "jordan". So if I saw any of those login failures I would
add the originating IP address to a chain in my iptables configuration. I could
not watch for ANY failed log in attempts because there was always the
possibility that I would mis-type my password and I didn't want to blacklist
myself. The script also had a rudimentary FIFO set up so that after 100
addresses got added to the list, the oldest addresses would be removed. This
worked well enough and put a significant dent in the amount of hacking in my log
files. It had several problems that I attempted to resolve in the next version.
Version 2. This was a major re-write and had significant improvements over the
older version. The older Version 1 code had an annoying habit of duplicating
blacklist entries because it blindly added entries to the blacklist without any
historical perspective. When my machines would get hit simultaneously by the
same attacking host, those attackers ended up being listed two or three times in
the blacklist. Truthfully, this didn't matter too much because being listed
once in a blacklist is just as good as being listed three times. It was messy
though.
Also, the FIFO idea was problematic in that it would push out entries that I
wanted to be permanent. It also didn't clear out dynamic addresses quickly
enough (this was mostly a problem for the web-based version of my program,
davblack.pl). All of these problems could be solved by keeping a separate
database of attackers. This would allow me to keep track of each attacker to
add and delete them from the blacklist as required.
The database would also add some historical perspective to the code in that I
could watch ALL failed log-in attempts and see how quickly they are coming in.
So I could blacklist login attempts for not only "guest" and "temp" and "jordan"
but also my real usernames and root. I could set the threshold high enough that
one password failure for root would not cause a blacklisting but four of them
within two minutes WOULD cause a blacklisting.
Version 2.1 and 2.2. These were maintenance releases that fixed minor bugs and
typos. Nothing interesting.
Version 2.3. This version introduced some denial-of-service avoidance code.
Much of the discussion and comments about the script centered on the assertion
that, if someone knew you were running the script, they could spoof source
addresses and get you to blacklist yourself. This is not, and never was, the
case. A whitelist was included since Version 1 and there are other fallacies
regarding this theoretical weakness but that is beyond the scope of this
document. However, someone did point out that if an attacker could cause the
script to detect enough spoofed attacks, the iptables chain could grow without
bounds. However, there are (at least) two problems with this theory also.
First, my experience shows that iptables chains can become enormous without
significantly affecting the operation of the machine or traffic flow. This
assumes that your iptables are constructed efficiently and utilize things like
ipconntrack. Secondly, I'm not convinced that a simple source spoofing or SYN
attack could cause the script to fire. Anyway, I decided that I could easily
add some sanity checks to the database. So if there are more than 50
(adjustable) entries in the database, the script goes into hibernation for a
period of time and expects you to solve the problem. Resolving the DoS is left
as an exercise to the student.
Version 2.4. This is a very minor upgrade from 2.3. Users of 2.3 will see no
major improvements in performance and could easily ignore this release. Version
2.4 adds some comments to the code (for those interested) and also adds some
logging improvements. I had been receiving some very appropriate questions
about what the script is actually doing, or if it was doing anything at all!
This stemmed from the rather terse output from the script. So I added some
verbosity that can be turned off for those that don't want a chatty script.
It now tells you not only that it is "Initializing" but also that it is
"monitoring for future attacks" which will hopefully eliminate the source of
confusion for a number of users. It also gives you output for EVERY "attack" it
notices, not just those that actually cause blacklisting. This is helpful for
testing and also gives you information about attackers that might be dancing
lightly to avoid attention (e.g. manual attacks rather than trojans and
scripts).
Version 2.5. This version introduced the use of the Proc::Daemon module to
automatically put the script into the background. It makes things a bit more
tidy in terms of logging output (another user-configured parameter was added for
this) and its a bit easier for less experienced users who don't know how to get
things in the background. By far most of the heavy-lifting code is identical to
Version 2.4.
Version 2.6 and 2.6 Daemon. One of my users noted that there are a large number
of machines that don't have iptables available. However many of them (if not
all) have route. He also pointed out a little trick of routing a host to
localhost which effectively buries the packets. I do not believe it is as
secure as iptables but it is a good option for people that want to use it. I
also took this opportunity to clean up the code and make things more obvious and
more maintainable. It is now extremely easy to make the script use route,
iptables or ipchains or execute any command you like. I still don't like the
idea of forcing a Perl module on people, even if it is a tiny and useful one
like Proc::Daemon. So I have kept the version number the same at 2.6 but now
have a daemon version which uses Proc::Daemon and a non-daemon version which can
be placed into the background manually.
Version 2.7 and 2.7 Daemon. The logging is now much neater and is done by a
separate subroutine. This same logging subroutine will also send an E-mail to
the administrator if you so desire. I have also included some simple utility
scripts that can do blacklisting and un-blacklisting but also modify the actual
CACHE file used by sshblack. It does this "behind the back" of sshblack and there
is no file locking when it does this (that's for another version). However the
chances of a collision are probably small.
Version 2.8. With the help of one of my users, I implemented a very simple fork
to place the script in the background. This eliminates the need for Proc::Daemon
and allows the user to decide how to do this with a configuration variable. This
version also allows you to customize the E-mail address for notices instead of
only sending to root. This version also originally had reverse DNS lookups
enabled where it would look up the FQDN of the IP address and report that in the
E-mails and logs. I pulled this at the last minute over concerns about DNS
failures/delays and what it would do to script execution. This capability may
make it back into a future version.
Version 2.8.1. The is a minor fix to address a potential DoS attack against
sshblack. This potential attack could be minimized by proper use of the
whitelist however the ability of attacker to fill up your blacklist quickly
still exists without this fix. The attack vulnerability arises when an attacker
places dotted IP addresses in the username field of their SSH initiation. So if
the attacker uses something like 192.168.100.100 for their username, the log lines
appears as:
Nov 11 19:17:57 stinky sshd[31205]: Invalid user 192.168.100.100 from 209.131.36.158
Previous versions of sshblack would pick up the first IP address in the log lines,
not the last. So in this example, it would eventually blacklist 192.168.100.100
instead of the actual attacker at 209.131.36.158. This was easy to solve by
modifying the REGEX that looks for the IP address. This was the only functional
change made from Version 2.8.
FAQ (No, really, I get these all the time)
Please also see http://www.pettingers.org/code/sshblack-notes.html for things
not covered here.
-------------------
1) What is sshblack?
The sshblack script is a real-time security tool for secure shell (ssh). It
monitors *nix log files for suspicious activity and reacts appropriately to
aggressive attackers by adding them to a "blacklist" created using various
firewalling tools -- such as iptables -- available in most modern versions of
Unix and Linux. The blacklist is simply a list of source IP addresses that are
prohibited from making ssh connections to the protected host. Once a
predetermined amount of time has passed, the offending IP address is removed
from the blacklist.
It is written in Perl but requires no special modules or libraries unless you
utilize the daemon version which only requires one tiny module.
What defines an "attack" is determined by a variable in the source code.
This is usually a character string like "Failed password" or "Illegal user" but
can be anything that the administrator deems as an undesirable activity.
2) How do I install it?
Please see the INSTALL.TXT file which should accompany the distribution
3) Where can I get the latest details and stuff?
See http://www.pettingers.org/code/sshblack.html or http://sshblack.com
4) Do I need superuser privileges?
Yes. Because the script modifies iptables, you will need to have root
privileges on the host. Commonly the security log files that sshblack monitors
are also privileged files.
5) What is the white-list and what do I need to do to set it up?
The white-list is one of the most important aspects of the script. It should
be configured even if nothing else is changed from the default configuration.
The whitelist is a list of hosts and/or networks that will NEVER be blacklisted,
even if they attack the protected host in such a way that they would normally
get blacklisted. The list is formulated with a regular expression (REGEX) and a
complete tutorial on REGEX is beyond the scope of this document but hopefully
this will help:
Let's take a look at our whitelist string from the default code. Remember,
any address that shows up in this whitelist will effectively be ignored by the
script.
my($LOCALNET) = '^(?:127\.0\.0\.1|192\.168\.0)';
What that tells us is that we are going to trust all those IP addresses that
come from 127.0.0.1 and 192.168.0. We know 127.0.0.1 is the address reserved for
localhost. That is, this address is ourself. But wait. 192.168.0 is only three
numbers! IPv4 requires four numbers/octets/tuples.
True, but when we parse, we can use a subset of that for our filter. So all we
are saying is that we are going to trust anything that has AT LEAST those three
numbers in the IP address. So 192.168.0.1 is fine, 192.168.0.254 is fine and so
is everything in between. It's a wildcard for the 192.168.0.0/24 network.
What about that vertical bar, the pipe character? The pipe | is treated as an
"or" in this REGEX. That's pretty much all you need to know about it. You can
use as many of these as you need.
The backslashes are there to tell Perl that the dots are literal dots. Dots
normally mean something else in Perl and in REGEX generally so, although it is
visually confusing, you need the backslashes. The caret symbol ^ is used to
anchor the search the start of the line. This allows us to match 192.168.0.x
but won't match x.192.168.0
So lets do an example with some other (fictional) addresses.
Say the machine I'm trying to protect is at 220.50.50.1
Let's say my machine sits on a Class C network with other machines that I
trust implicitly. That network is going to be 220.50.50.0/24 or
220.50.50.0/255.255.255.0 or however you want to note it. But remember, the
sshblack script doesn't think of these addresses as IP addresses, it is looking
at them as a string, as text. So we only need the first three numbers -- we are
ignoring or wild-carding the last number.
So this REGEX is going to become 220\.50\.50
Let's also say that we want to make sure we don't blacklist ourselves as we
log in from our office address which resides on the other side of town on a
fixed IP of 66.249.64.68 but I don't trust anyone around that address so I'm not
going to wildcard anything there.
This REGEX becomes 66\.249\.64\.68
Now let's put all this together for our whitelist ($LOCALNET) definition.
my($LOCALNET) = '^(?:127\.0\.0\.1|220\.50\.50|66\.249\.64\.68)';
Note I've used the pipe character (|) between all my entries and I didn't
forget that pesky semi-colon at the end of the line.
Hope this helps some folks. The whitelisting function is pretty important.
6) How do I integrate this with my iptables configuration?
It has become obvious that there are dozens of common "firewall" scripts
being used out there and an infinite number of existing iptables configurations.
See the INSTALL.TXT file for a complete discussion of this. You might also look
at http://www.pettingers.org/firewall.html for some thoughts on a simple set-up.
Certainly you can choose to have the script add it's "-j DROP" or "-j REJECT"
jumps directly to the INPUT chain and you will not be required to modify your
iptables configuration (assuming you have the script install these jumps in the
right order in your INPUT chain). Actually, this should work even for a virgin
iptables configuration. However, it makes things a bit neater if you set up a
custom chain for the blacklist. Simply, the vision for how this script would
work with such a custom iptables chain is as follows.
a) Packets will enter the INPUT chain. Here they will pass through
whatever existing chains and filters are currently set up, including accounting
for things like "state RELATED, ESTABLISHED". It is assumed that the INPUT
chain will have a policy (-P) of DROP meaning that everything that falls through
all INPUT rules will be dropped.
b) Before an SSH packet is finally accepted or dropped/rejected in the
INPUT chain, it will be passed through the BLACKLIST chain which is created to
support sshblack.
c) If an IP is listed in BLACKLIST, it will be dropped. If it is not
listed, the packet will RETURN TO THE INPUT CHAIN for further processing.
d) Back at the input chain, the packet will be processed for acceptance or
rejection by other chains and/or rules. If these rules do not explicitly
accept the packet, it will be dropped.
It is important to recognize in the discussion above that there must either
be 1) a rule to explicitly accept the packet after it is passed through the
BLACKLIST chain and back to INPUT or 2) the INPUT chain must be set to policy
ACCEPT. We recommend the former, not the latter. Firewalls should always be
designed to IMPLICTLY deny all packets and EXPLICITLY accept certain packets.
You want to think about what is going to happen to your packets as they pass
through ALL the chains in your iptables setup and be careful or you will lock
yourself out. For example, if you blindly add the BLACKLIST chain but never add
a rule in the INPUT chain to accept SSH, you will lock out all SSH packets even
though there are no listings in the BLACKLIST chain. Again, see INSTALL.TXT for
more on this if you still have questions.