We can do a lot on the fly with flowdumper and can aggregate data nicely with flow-stat, but the detailed data provided by Netflow should let you do just about any sort of report. You should easily be able to list all SMTP connection attempts to systems that aren't supposed to be SMTP servers. Perhaps you could write the flowdumper Expression from the Infernal Regions to accomplish this, but there are better ways--especially if you intend to use this report repeatedly. The
flow-nfilter(1) program lets you write detailed reports on Netflow data.
Flow-nfilter's configuration relies on "primitives": small definitions that describe one characteristic of traffic--a network port, an IP address, and so on. It assembles these primitives into larger rules that constitute reports. By default, flow-nfilter stores these primitives and definitions in /usr/local/etc/flow-tools/filter.cfg. I will start with primitives and proceed to building actual reports.
Every primitive definition starts with the
filter-primitive label and a name. It then contains the type of primitive. The man page lists many different types of primitives that cover every situation, but this list is too much to read for common situations. (Read the man page for flow-nfilter for a list of the available filtering primitives, but the handful below will get you started.) The most commonly used primitives include
ip-address-prefix. The following example is a primitive for the TCP protocol:
filter-primitive TCP type ip-protocol permit tcp default deny
While its name is
permit statement tells the primitive that it matches anything of protocol type
tcp. You could also use 6, the protocol number for TCP as defined in /etc/protocols. The
default deny at the end means the primitive doesn't match anything that isn't TCP. (Primitives have an implicit
default deny, but I find explicit statements more comfortable.)
ip-port primitive type matches TCP or UDP ports. This primitive,
smtpports, matches connections to port 25 and only port 25:
filter-primitive smtpports type ip-port permit 25 default deny
The adept among you can already see where this is heading; TCP connections to port 25 are either SMTP conversations or masquerading as SMTP conversations.
You can define entire networks with the
ip-address-prefix primitive type. The
hostingnet primitive matches the entire 192.168.88.0 network:
filter-primitive hostingnet type ip-address-prefix permit 192.168.88.0/24 default deny
Finally, you can match individual IP addresses with the
filter-primitive local_mailservers type ip-address permit 192.168.88.33 default deny
Primitives can get quite complicated. For example, suppose I want to make a filter primitive that includes everything that isn't a mail server. The trick to this is to start small and gradually grow.
filter-primitive local_not_mailservers type ip-address deny 192.168.88.33 permit 192.168.88.0/24 default deny
The primitive itself is an IP address--actually, a set of them. It isn't a network, because there's a hole in it. I started by denying my actual mail server's IP. I then accepted the whole block of addresses in the network. At the end, if an IP isn't explicitly permitted, it's denied. This primitive will match any IP address from 192.168.88.0 through 192.168.88.32 and from 192.168.88.34 through 192.168.88.254.
You can list several related items in a single primitive. For example, my company's security policy forbids use of telnet (port 23) and MS SQL (port 1433) connections over the public internet. If I see this traffic on my network, something interesting is going on. This primitive matches both of these.
filter-primitive redflags type ip-port permit 23 permit 1433 default deny
Similarly, you could have a list of IP addresses in permit statements. You can't combine unrelated items in a primitive, however; to combine
port 25 and
protocol tcp, you must create a rule.