Do you care about WHOIS contact information?

David Wolfskill david at catwhisker.org
Wed Jul 29 09:44:27 PDT 2009


On Thu, Jul 23, 2009 at 06:32:34AM -0700, David Wolfskill wrote:
> ...
> Over the years, I've developed an approach for addressing (no pun
> intended) this situation, but before I explain that, I'd like to
> do a reality check and ask y'all what you (would) do about it.
> ...

There were a handful of replies, some of which were thoughtful &
on-point.  My thanks to those who responded.

Since I did offer that bit of a teaser, I thought I'd try to get
the promised explanation out before I go wandering off-Net for
several days.

I'll sketch a bit of context first, then go over what the approach
I generally use is.  Please note that the below is intended as a
description of an approach to be used by a human being; it is nowhere
near precise enough to automate: there are points at which human
judgement is called for.  And in general, it's my understanding
that automating some of the stuff I do is a fairly effective way
to perform a self-inflicted DoS attack on the resource one is trying
to protect.  And while I admit to having made mistakes (and intending
to live long enough to make some new ones), I like to think that
I'm not stupid.  :-}

First, all exposed services from the network in question run on
FreeBSD systems -- and there aren't many exposed services (SSH,
SMTP, NTP (with certain hosts), HTTP{,S}, and DNS should be about
it).  I have a static /32; a FreeBSD machine with 3 NICs acts as
my router/packet filter and the gateway between the Internet and
my home networks.  That machine actually provides the externally-facing
SMTP, NTP, and DNS services; SSH and HTTP{,S} are port-forwarded
to internal hosts.  SSH is configured to only permit public key
authentication via SSHv2 protocol.

For a packet filter, I (still) use FreeBSD's IPFW.  (Darren Reed's
ipfilter & OpenBSD's pf are also available, but IPFW suits my
purposes and I've been using it for over a decade.  "Use what you
know," yeah?)

The packet filter plays a moderately important role in what follows,
so I'll go into that in a bit of detail now.

One of the things IPFW provides in its packet-filtering rules is
the ability to test a source or destination address to see if it's
in a "table" -- which uses the same structure and search mechanisms
as the routing table in the IP stack.  (I.e., it is stored as a
Radix tree, vs. a simple list, and the most specific match wins.)
Each entry in one of these tables consists of a CIDR block specification
and a 32-bit "tag"; I don't use the tag.

Among the various IPFW rules I use (anti-spoofing; ensuring that
only desired services are offered to the outside world; ...), I
have created 3 (so far) such IPFW tables.  (I also implement them
in the IPFW rules I run on my laptop, since it is sometimes in
direct contact with hosts outside my control.  Yes, I run FreeBSD
on my laptop.  And in response to one correspondent, I actually
update the FreeBSD image I run rather frequently: on the laptop,
daily; on the other machines, usually every couple of weeks.  I
also maintain a couple of private mirrors of the FreeBSD CVS & SVN
repositories (updated nightly), one set of which resides on my
laptop.)

* For table 1, there are 2 rules.  One of them blocks all traffic
  from any IP address in the table; the other blocks all traffic
  to any such address.  Thus, any entry in this table effectively
  gets dyked out of my view of the Internet.

* For table 2, there is a rule that disallows a 22/tcp SYN packet
  from any IP address in the table; thus, hosts using such IP
  addresses cannot initiate an SSH session to my network (or laptop).

* Table 3 is like table 2, but for HTTP{,S}.  I don't use this much,
  but sometimes my patience wears a bit thin.

I could easily add other tables; I've considered replacing much of
the sendmail "access.db" with (say) IPFW table 4: attempts to pass
a 25/tcp SYN from such an IP address would be rejected.

Another thing I do with the IPFW rules (in addition to logging
blocked traffic) is log every successful 22/tcp SYN packet -- i.e.,
every apparent attempt to initiate an SSH session.

My SSH server also logs every attempt it sees to initiate an SSH
session.

One of the things I check when I review the logs is to look for
glaring discrepancies between the above 2 log (extracts): I've been
seeing the following pattern often enough that it's a concern --
the packet filtyer will log a bunch of 22/tcp SYN packets from a
certain address, but the SSH server won't show any attempts to
actually establish a session.

In this case, I perform a WHOIS query against the address, and for
most of the world, I then peform a WHOIS query against the Netname
returned, extract all of the CIDR blocks for each of the returned
results, and add them to table 2.  ("Most of the world" because
LACNIC doesn't use Netnames; it uses Inetnum -- a CIDR address.  So
for LACNIC nets, I use their Inetnum.)   I do not attempt to notify
anyone about this, as I haven't figured out a way to explain what
seems to be going on in a way that I'd be willing to read if I
received such a missive.

While I don't believe I have much (if any) exposure, the discrepancy
makes me a little nervous, and I will protect my network.  And while
I could use port-knocking or other bits of Rube Goldberg-inspired
protocol design, I'm not yet willing to complicate my life that
much.

For the more common case of a flurry of SSH session-initiation
attempts, usually from the same IP address, I perform a WHOIS query
against the address, check to see if I've corresponded with whoever
is claimed to be responsible about this sort of thing before, and
take one of a couple of steps:

* If this appears to be a repeat offender, I will use my judgement
  to determine whether to send a(nother) notification or not.  If
  the allegedly-responsible party seemed at least marginally
  responsive, I'll probably send another note, along with the most
  recent log extracts.

  If they were less than marginally responsive, I do the above-sketeched
  WHOIS queries and add the resulting CIDR blocks to table 1.

* If this appears to not be a repeat offender, I send a notification
  that the unwanted activity was noticed.

  Some responses I get are clearly from auto-bots, and that's OK.

  Sometimes I get bounce-o-grams.  My reaction to that is to
  immediately place all CIDR blocks I find that allegedly have the
  same "responsible party" in table 1.  Thus, for example, any
  network I see that is part of CHINANET will be added to table 1
  with no further attempt at correspondence.

  While I've not had the response that one correspondent cited (of
  verbal abuse or legal threats), I expect that were I receive such
  a response, that would also warrant augmenting table 1.

I also keep copies of all such correspondence (when I send
notifications, I Bcc: myself).  And all of my notifications are
signed (in the PGP/GPG sense).

In a similar vein, I look for odd-looking attempts to provoke my
Web server into doing something I don't desire, and similarly attempt
to notify the responsible folks.  Again, a bounce-o-gram will get
the CIDR blocks added to table 1, while too many repeats from the
same netblock will get it added to table 3.

The basic idea should be apparent: if I can't report abuse involving
the netblock in a way that I consider reasonable, I want nothing
to with them, and will take action accordingly.  And for specific
services that appear to be targeted, I will take steps to mitigate
the exposure.


As for the mechanics, I've semi-automated the table updates, by
using a fairly ugly, hacked-up combination of Makefiles, Perl
scripts, and shell scripts that depends (in large part) on the
meanings of command-line flags to FreeBSD's whois(1) program.

I have one directory for each of the tables in question.  Each such
directory contains:
* a Makefile
* a flat file named .table, which is an ordered list of CIDR blocks,
  one per line.
* subdirectories, each of which has a name corresponding to a
  registry-selection flag for whois(1), such as "a" (for ARIN), "A"
  (for APNIC), "f" (for AfriNIC), "l" (for LACNIC), or "r" (for
  RIPE).

  Each entry in each of the subsdirectories is a flat file containing
  an unordered list of CIDR blocks, one per line.  For LACNIC
  subsdirectories, the file name is typically an IPv4 address (in
  dotted-quad form); for the others, the file name is the Netname
  (e.g.  CHINANET-SH).

The Makefile's default target is .table.  The dependencies for
.table are the subdirectories themselves; those for the subdirectories
are the files within them.  The action taken for each file that was
updated more recently than its containing subdirectory is to perform
a WHOIS query (using the name of the subdirectory as a registry-selecting
command-line flag), then parsing the result to extract whatever
appears to be a specification for the netblock, convert it to CIDR
(if necessary) and update the file with it.  Note that the whois(1)
program, when given a query such as "whois -A CHUNGHWA-TELECOM-TY-TW"
may well return information on several netblocks/netranges; the
approach used collects them all.

Lastly, all of the CIDR specifications are collected, ordered, and
an attempt is made to remove duplicate specifications; the result
replaces
.table.

Practically speaking, to add (say) netname FOO from ARIN to table
1, I'd cd to the directory and:

* touch a/FOO
* touch a/FOO
* make
* sudo mk_table -t 1 !-2:$

(where "mk_table" is a shell script that actually adds the specified
CIDR entries to the specified IPFW table.  The duplication of the
touch(1) invocation is to ensure that the mtime of the file is more
recent than that of the subdirectory.  Yeah, that's a hack.)

mk_table is also used during the boot process to initialize a given
IPFW table from the contents of the .table for for the table in
question.  (This reduces the time it would otherwise take to go
read all of the files.)


There's a moderately-interesting side-effect in this:  sometimes a
would-be correspondent's domain's nameservers are in a netblock
that I've dyked out of my view of the Net.  In that case, sendmail
(which I still use) refuses to accept the mail, as it can't resolve
the sender's domain.  Evidence to date suggests that (nearly?) all
of these messages are actually spam; accordingly, I don't consider
it a problem (for me, anyway).


One other noteworthy observation:  I do not provide for a specific
mechanism to remove entries.  Should an occasion warrant, removing
the appropriate file(s) (& re-creating the .table file) will deal
with the next reboot, and I suppose I could issue the IPFW commands
to delete entries within tables.  But so far, I've had no such
occasion present itself.

And I freely admit that I can get away with some of this because the
only network I'm directly affecting is my own -- not a network I'm
administering on behalf of someone else.  So there are definite
limitations on how readily something even vaguely like this might be
implementable in many situations.  But it might also encourage a bit of
thought....  :-}

Peace,
david
-- 
David H. Wolfskill				david at catwhisker.org
Depriving a girl or boy of an opportunity for education is evil.

See http://www.catwhisker.org/~david/publickey.gpg for my public key.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
URL: <http://www.baylisa.org/pipermail/baylisa/attachments/20090729/70cb8216/attachment.bin>


More information about the Baylisa mailing list