# HG changeset patch # User Carl Byington # Date 1213318293 25200 # Node ID 180d26aa2a17f0b68c66e604531ea2dd4d80f44a # Parent 4a81cc2da570775e826e4d9b58b5bb66f5d54050 Fedora 9 compile and const correctness. diff -r 4a81cc2da570 -r 180d26aa2a17 ChangeLog --- a/ChangeLog Thu May 22 20:39:52 2008 -0700 +++ b/ChangeLog Thu Jun 12 17:51:33 2008 -0700 @@ -1,4 +1,4 @@ -1.0.1 2008-04-06 +1.0.1 2008-06-12 Initial release. diff -r 4a81cc2da570 -r 180d26aa2a17 Makefile.am --- a/Makefile.am Thu May 22 20:39:52 2008 -0700 +++ b/Makefile.am Thu Jun 12 17:51:33 2008 -0700 @@ -7,7 +7,7 @@ htmldir = ${datadir}/doc/@PACKAGE@-@VERSION@ html_DATA = AUTHORS COPYING ChangeLog NEWS README CLEANFILES = routeflapper xml/routeflapper xml/Makefile -EXTRA_DIST = routeflapper.conf routeflapper.spec $(wildcard xml/h*) $(wildcard xml/M*) $(wildcard xml/s*) +EXTRA_DIST = routeflapper.conf routeflapper.spec $(wildcard xml/h*) $(wildcard xml/M*) $(wildcard xml/r*) routeflapper: routeflapper.rc cat routeflapper.rc | \ diff -r 4a81cc2da570 -r 180d26aa2a17 NEWS --- a/NEWS Thu May 22 20:39:52 2008 -0700 +++ b/NEWS Thu Jun 12 17:51:33 2008 -0700 @@ -1,1 +1,1 @@ -1.0.1 2008-04-06 Initial release. +1.0.1 2008-06-12 Initial release. diff -r 4a81cc2da570 -r 180d26aa2a17 html/index.html --- a/html/index.html Thu May 22 20:39:52 2008 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ - - -routeflapper

routeflapper


Packages

The various source and binary packages are available at http://www.five-ten-sg.com/routeflapper/packages/ - The most recent documentation is available at http://www.five-ten-sg.com/routeflapper/ -

A Mercurial source - code repository for this project is available at http://hg.five-ten-sg.com/routeflapper/. -

Table of Contents

routeflapper - detects suspicious routes
routeflapper.conf - configuration file for routeflapper
diff -r 4a81cc2da570 -r 180d26aa2a17 html/rn01re01.html --- a/html/rn01re01.html Thu May 22 20:39:52 2008 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +0,0 @@ - - -routeflapper

Name

routeflapper — detects suspicious routes

Synopsis

routeflapper [-c] [-d n]

Description

routeflapper is a daemon that monitors BGP - updates and SMTP connections to discover whether SMTP connections are - coming from ip addresses whose best route is suspicious.

The routeflapper.conf(5) file specifies the syslog files - to be monitored, and the regular expressions (regex(7)) to be applied to new lines in those files.

The discussion has focused on syslog files, but any ascii text - file can be used, so long as some other process appends lines to that - file, and those lines containing bgp updates can be matched - with some regular expression.

Considering syslog files in particular, these are normally rotated - via logrotate. routeflapper properly detects and - handles this case by closing the old file, and reopening the newly - created file.

Options

-c

- Load the configuration file, print a cannonical form - of the configuration on stdout, and exit. -

-d n

- Set the debug level to n. -

Usage

routeflapper -d 2

Configuration

- The configuration file is documented in routeflapper.conf(5). Any change to the config file will cause it to be - reloaded within three minutes. -

Introduction

- Consider the hypothetical case of a spammer who is connected via a - provider that does not filter BGP routing announcements. The spammer - then has some options to announce ip address space to be used for - sending spam. Note that we only consider cases where the spammer - simply wants to anonymously use some ip address space. This is very - different from the case where the attacker wants to use some specific - address space belonging to another organization in order to impersonate - some service provided by that other organization. -

- They can announce a more specific route, for example a /24, inside a - larger block. For example, consider 169.232.0.0/16. If the spammer - pokes around, they can probably find an unused /24 in there. So they - announce 169.232.240.0/24 and then send spam from that block. There - are two problems with this scheme. First, the announcement of such a - smaller block may be filtered out by many BGP routers, reducing their - reachability to their spam targets. Second, they may have made a - mistake, and that /24 is actually in use by some UCLA service that - will notice their hijack. -

- They can announce a less specific route, for example a /16, covering - some individual smaller blocks. For example, they could announce - 52.129.0.0/16. The spammer could then avoid the four existing - announcements inside that block, and instead spam from - 52.129.128.0/17. That gives them 32K ip addresses to work with. The - advantage here is that their announcement of a large block won't be - filtered out by as many (if any) BGP routers, giving them better reachability - to their spam targets. And they know they won't interfere with any - existing use of that address space, since there was no previous BGP - announcement of that /17 or any subset of it. -

- Or they can simply announce a prefix that is not assigned to anyone. - For example, they could simply start announcing 185.10.0.0/16. This - has many of the same advantages as the previous scheme, but some BGP - routers may be configured to drop such bogon announcements. -

- In each of these cases, the spammer can use BGP to announce some - address space, then send spam from those addresses, and then withdraw - the route annoucement. This would make it difficult for the recipient of - such spam to determine who actually sent it. -

- In a paper from 2006 published at - http://www-static.cc.gatech.edu/~feamster/publications/p396-ramachandran.pdf - , Ramachandran and Feamster claim evidence for the statement - that spammers are using such short-lived bogus BGP route announcements - to send spam from hijacked parts of the IPv4 address space. -

- The question is, are spammers actually doing this today, or is this - just a hypothetical spam tactic that they could use in the future? To - help answer that question, this package monitors BGP annoucements, - classifies some of them as suspicious, and logs instances of SMTP - connections from suspicious prefixes. -

- We track the history of the AS adjacency graph, by computing the union - of all AS adjacent pairs over all the announced prefixes. For example, - 137.169.0.0/16 is currently announced here with an AS path of '22298 - 19080 3549 6517 14981', so we add (22298,19080) (19080,3549) - (3549,6517) and (6517,14981) as valid adjacent AS pairs. -

- We track the history of the origin AS for each announced prefix. Both - the origin AS and AS adjacency pairs are tracked over a timescale of - 100 hours, with an exponential decay half-life of 100 hours. -

- A prefix announcement is suspicious if the origin AS is not in the - historical AS set for that prefix at least 20% of the time, or if the - AS path contains any adjacent AS pair that is not in the historical AS - adjacency graph at least 40% of the time. -

- PHAS is another - system that attempts to detect address space hijacking, but it is not - correlated with SMTP connections or spam attempts. -

- IAR is - another system that attempts to detect address space hijacking, but it - is not correlated with SMTP connections or spam attempts. IAR uses - methods detailed in PGBGP - to detect suspicious routes. One problem with PGBGP as applied to our - hypothetical spammer problem, is that PGBGP is primarily looking for - hijacks where the attacker actually wants some specific ip address - space, either for a denial of service, or to impersonate the actual - owner. Our hypothetical spammer does not care about that - they only - care about sending spam anonymously. In particular, PGBGP ignores - super-prefix hijacks, but it seems likely that that is the preferred - method for our hypothetical spammer. However, the PGBGP paper does provide - useful data on the required timescale to avoid most of the normal AS - origin changes. -

TODO

- None. -

Copyright

- Copyright (C) 2008 by 510 Software Group <carl@five-ten-sg.com> -

- This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3, or (at your option) any - later version. -

- You should have received a copy of the GNU General Public License along - with this program; see the file COPYING. If not, please write to the - Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. -

Version

- 1.0.1 -

diff -r 4a81cc2da570 -r 180d26aa2a17 html/rn01re02.html --- a/html/rn01re02.html Thu May 22 20:39:52 2008 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ - - -routeflapper.conf

Name

routeflapper.conf — configuration file for routeflapper

Synopsis

routeflapper.conf

Description

The routeflapper.conf configuration file is - specified by this partial bnf description. The entire config file - is case sensitive. All the keywords are lower case. -

-CONFIG    := {FILE}+
-FILE      := "file" FILENAME "{" PATTERN+ "};"
-PATTERN   := PATH | ANNOUNCE | WITHDRAW | IP
-PATH      := "path" REGEX "{" INDEXPATH         '}' ";"
-ANNOUNCE  := "path" REGEX "{" INDEXVAL INDEXLEN '}' ";"
-WITHDRAW  := "path" REGEX "{" INDEXVAL INDEXLEN '}' ";"
-IP        := "path" REGEX "{" INDEXIP           '}' ";"
-INDEXPATH := "index_path"   REGEX-INTEGER-VALUE ";"
-INDEXVAL  := "index_value"  REGEX-INTEGER-VALUE ";"
-INDEXLEN  := "index_length" REGEX-INTEGER-VALUE ";"
-INDEXIP   := "index_ip"     REGEX-INTEGER-VALUE ";"

Sample

-file "/var/log/bgp" {
-    path " rcvd UPDATE w.* path (([0-9]| )*[0-9])" {
-        index_path 1;
-    };
-    announce " rcvd (([0-9]|\.)*)/([0-9]*)$" {
-        index_value  1;
-        index_length 3;
-    };
-    withdraw " rcvd UPDATE about (([0-9]|\.)*)/([0-9]*) -- withdrawn" {
-        index_value  1;
-        index_length 3;
-    };
-};
-
-file "/var/log/maillog" {
-    ip "NOQUEUE: connect from.* \[(.*)\]" {
-        index_ip 1;
-    };
-};

Version

- 1.0.1 -

diff -r 4a81cc2da570 -r 180d26aa2a17 html/routeflapper.pdf Binary file html/routeflapper.pdf has changed diff -r 4a81cc2da570 -r 180d26aa2a17 info/db2texi.refs --- a/info/db2texi.refs Thu May 22 20:39:52 2008 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -{ - 'SYSLOG2IPTABLES.CONF.5' => 'syslog2iptables.conf', - '' => '', - 'SYSLOG2IPTABLES.1' => 'syslog2iptables', - 'ROUTEFLAPPER.1' => 'routeflapper', - 'ROUTEFLAPPER.CONF.5' => 'routeflapper.conf', - '' => '' -} diff -r 4a81cc2da570 -r 180d26aa2a17 info/routeflapper.texi --- a/info/routeflapper.texi Thu May 22 20:39:52 2008 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,230 +0,0 @@ -routeflapper -Packages - -The various source and binary packages are available at SGMLS_Attribute=ARRAY(0x8b71cc0), @uref{1http://www.five-ten-sg.com/routeflapper/packages/} - The most recent documentation is available at SGMLS_Attribute=ARRAY(0x8b45ae8), @uref{1http://www.five-ten-sg.com/routeflapper/} - - -A SGMLS_Attribute=ARRAY(0x8b45a04), @uref{1Mercurial} source - code repository for this project is available at SGMLS_Attribute=ARRAY(0x8b4c5fc), @uref{1http://hg.five-ten-sg.com/routeflapper/}. - 2008-04-12 - -@node routeflapper -@subsubsection routeflapper - - -@unnumberedsubsubsec Name -routeflapper --- detects suspicious routes -@unnumberedsubsubsec Synopsis -Synopsis -routeflapper-c-d n\nn@unnumberedsubsubsec Description - -routeflapper is a daemon that monitors BGP - updates and SMTP connections to discover whether SMTP connections are - coming from ip addresses whose best route is suspicious. - -The routeflapper.conf(5) file specifies the syslog files - to be monitored, and the regular expressions (regex(7)) to be applied to new lines in those files. - -The discussion has focused on syslog files, but any ascii text - file can be used, so long as some other process appends lines to that - file, and those lines containing bgp updates can be matched - with some regular expression. - -Considering syslog files in particular, these are normally rotated - via logrotate. routeflapper properly detects and - handles this case by closing the old file, and reopening the newly - created file.\nn@unnumberedsubsubsec Options -@table @asis - -@item -c - Load the configuration file, print a cannonical form - of the configuration on stdout, and exit. - - -@item -d n - Set the debug level to n. - -@end table -\nn@unnumberedsubsubsec Usage - -routeflapper -d 2\nn@unnumberedsubsubsec Configuration - - The configuration file is documented in routeflapper.conf(5). Any change to the config file will cause it to be - reloaded within three minutes. - \nn@unnumberedsubsubsec Introduction - - Consider the hypothetical case of a spammer who is connected via a - provider that does not filter BGP routing announcements. The spammer - then has some options to announce ip address space to be used for - sending spam. Note that we only consider cases where the spammer - simply wants to anonymously use some ip address space. This is very - different from the case where the attacker wants to use some specific - address space belonging to another organization in order to impersonate - some service provided by that other organization. - - - They can announce a more specific route, for example a /24, inside a - larger block. For example, consider 169.232.0.0/16. If the spammer - pokes around, they can probably find an unused /24 in there. So they - announce 169.232.240.0/24 and then send spam from that block. There - are two problems with this scheme. First, the announcement of such a - smaller block may be filtered out by many BGP routers, reducing their - reachability to their spam targets. Second, they may have made a - mistake, and that /24 is actually in use by some UCLA service that - will notice their hijack. - - - They can announce a less specific route, for example a /16, covering - some individual smaller blocks. For example, they could announce - 52.129.0.0/16. The spammer could then avoid the four existing - announcements inside that block, and instead spam from - 52.129.128.0/17. That gives them 32K ip addresses to work with. The - advantage here is that their announcement of a large block won't be - filtered out by as many (if any) BGP routers, giving them better reachability - to their spam targets. And they know they won't interfere with any - existing use of that address space, since there was no previous BGP - announcement of that /17 or any subset of it. - - - Or they can simply announce a prefix that is not assigned to anyone. - For example, they could simply start announcing 185.10.0.0/16. This - has many of the same advantages as the previous scheme, but some BGP - routers may be configured to drop such bogon announcements. - - - In each of these cases, the spammer can use BGP to announce some - address space, then send spam from those addresses, and then withdraw - the route annoucement. This would make it difficult for the recipient of - such spam to determine who actually sent it. - - - In a paper from 2006 published at SGMLS_Attribute=ARRAY(0x8b728e8), @uref{1 http://www-static.cc.gatech.edu/~feamster/publications/p396-ramachandran.pdf - }, Ramachandran and Feamster claim evidence for the statement - that spammers are using such short-lived bogus BGP route announcements - to send spam from hijacked parts of the IPv4 address space. - - - The question is, are spammers actually doing this today, or is this - just a hypothetical spam tactic that they could use in the future? To - help answer that question, this package monitors BGP annoucements, - classifies some of them as suspicious, and logs instances of SMTP - connections from suspicious prefixes. - - - We track the history of the AS adjacency graph, by computing the union - of all AS adjacent pairs over all the announced prefixes. For example, - 137.169.0.0/16 is currently announced here with an AS path of '22298 - 19080 3549 6517 14981', so we add (22298,19080) (19080,3549) - (3549,6517) and (6517,14981) as valid adjacent AS pairs. - - - We track the history of the origin AS for each announced prefix. Both - the origin AS and AS adjacency pairs are tracked over a timescale of - 100 hours, with an exponential decay half-life of 100 hours. - - - A prefix announcement is suspicious if the origin AS is not in the - historical AS set for that prefix at least 20% of the time, or if the - AS path contains any adjacent AS pair that is not in the historical AS - adjacency graph at least 40% of the time. - - - SGMLS_Attribute=ARRAY(0x8b4c728), @uref{1PHAS} is another - system that attempts to detect address space hijacking, but it is not - correlated with SMTP connections or spam attempts. - - - SGMLS_Attribute=ARRAY(0x8b72f78), @uref{1IAR} is - another system that attempts to detect address space hijacking, but it - is not correlated with SMTP connections or spam attempts. IAR uses - methods detailed in SGMLS_Attribute=ARRAY(0x8b4c794), @uref{1PGBGP} - to detect suspicious routes. One problem with PGBGP as applied to our - hypothetical spammer problem, is that PGBGP is primarily looking for - hijacks where the attacker actually wants some specific ip address - space, either for a denial of service, or to impersonate the actual - owner. Our hypothetical spammer does not care about that - they only - care about sending spam anonymously. In particular, PGBGP ignores - super-prefix hijacks, but it seems likely that that is the preferred - method for our hypothetical spammer. However, the PGBGP paper does provide - useful data on the required timescale to avoid most of the normal AS - origin changes. - \nn@unnumberedsubsubsec TODO - - None. - \nn@unnumberedsubsubsec Copyright - - Copyright (C) 2008 by 510 Software Group - - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3, or (at your option) any - later version. - - - You should have received a copy of the GNU General Public License along - with this program; see the file COPYING. If not, please write to the - Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - \nn@unnumberedsubsubsec Version - - 1.0.1 - 2008-04-12 - -@node routeflapper.conf -@subsubsection routeflapper.conf - - -@unnumberedsubsubsec Name -routeflapper.conf --- configuration file for routeflapper -@unnumberedsubsubsec Synopsis -Synopsis -routeflapper.conf\nn@unnumberedsubsubsec Description - -The routeflapper.conf configuration file is - specified by this partial bnf description. The entire config file - is case sensitive. All the keywords are lower case. - - -@example -CONFIG := @{FILE@}+ -FILE := "file" FILENAME "@{" PATTERN+ "@};" -PATTERN := PATH | ANNOUNCE | WITHDRAW | IP -PATH := "path" REGEX "@{" INDEXPATH '@}' ";" -ANNOUNCE := "path" REGEX "@{" INDEXVAL INDEXLEN '@}' ";" -WITHDRAW := "path" REGEX "@{" INDEXVAL INDEXLEN '@}' ";" -IP := "path" REGEX "@{" INDEXIP '@}' ";" -INDEXPATH := "index_path" REGEX-INTEGER-VALUE ";" -INDEXVAL := "index_value" REGEX-INTEGER-VALUE ";" -INDEXLEN := "index_length" REGEX-INTEGER-VALUE ";" -INDEXIP := "index_ip" REGEX-INTEGER-VALUE ";" - -@end example -\nn@unnumberedsubsubsec Sample - -@example -file "/var/log/bgp" @{ - path " rcvd UPDATE w.* path (([0-9]| )*[0-9])" @{ - index_path 1; - @}; - announce " rcvd (([0-9]|\.)*)/([0-9]*)$" @{ - index_value 1; - index_length 3; - @}; - withdraw " rcvd UPDATE about (([0-9]|\.)*)/([0-9]*) -- withdrawn" @{ - index_value 1; - index_length 3; - @}; -@}; - -file "/var/log/maillog" @{ - ip "NOQUEUE: connect from.* \[(.*)\]" @{ - index_ip 1; - @}; -@}; - -@end example -\nn@unnumberedsubsubsec Version - - 1.0.1 - \ No newline at end of file diff -r 4a81cc2da570 -r 180d26aa2a17 man/routeflapper.1 --- a/man/routeflapper.1 Thu May 22 20:39:52 2008 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -.\"Generated by db2man.xsl. Don't modify this, modify the source. -.de Sh \" Subsection -.br -.if t .Sp -.ne 5 -.PP -\fB\\$1\fR -.PP -.. -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Ip \" List item -.br -.ie \\n(.$>=3 .ne \\$3 -.el .ne 3 -.IP "\\$1" \\$2 -.. -.TH "ROUTEFLAPPER" 1 "2008-04-12" "" "" -.SH NAME -routeflapper \- detects suspicious routes -.SH "SYNOPSIS" -.ad l -.hy 0 -.HP 13 -\fBrouteflapper\fR [\fB\-c\fR] [\fB\-d\ \fIn\fR\fR] -.ad -.hy - -.SH "DESCRIPTION" - -.PP -\fBrouteflapper\fR is a daemon that monitors BGP updates and SMTP connections to discover whether SMTP connections are coming from ip addresses whose best route is suspicious\&. - -.PP -The \fBrouteflapper\&.conf\fR(5) file specifies the syslog files to be monitored, and the regular expressions (\fBregex\fR(7)) to be applied to new lines in those files\&. - -.PP -The discussion has focused on syslog files, but any ascii text file can be used, so long as some other process appends lines to that file, and those lines containing bgp updates can be matched with some regular expression\&. - -.PP -Considering syslog files in particular, these are normally rotated via logrotate\&. \fBrouteflapper\fR properly detects and handles this case by closing the old file, and reopening the newly created file\&. - -.SH "OPTIONS" - -.TP -\-c -Load the configuration file, print a cannonical form of the configuration on stdout, and exit\&. - -.TP -\-d \fIn\fR -Set the debug level to \fIn\fR\&. - -.SH "USAGE" - -.PP -\fBrouteflapper\fR \-d 2 - -.SH "CONFIGURATION" - -.PP -The configuration file is documented in \fBrouteflapper\&.conf\fR(5)\&. Any change to the config file will cause it to be reloaded within three minutes\&. - -.SH "INTRODUCTION" - -.PP -Consider the hypothetical case of a spammer who is connected via a provider that does not filter BGP routing announcements\&. The spammer then has some options to announce ip address space to be used for sending spam\&. Note that we only consider cases where the spammer simply wants to anonymously use some ip address space\&. This is very different from the case where the attacker wants to use some specific address space belonging to another organization in order to impersonate some service provided by that other organization\&. - -.PP -They can announce a more specific route, for example a /24, inside a larger block\&. For example, consider 169\&.232\&.0\&.0/16\&. If the spammer pokes around, they can probably find an unused /24 in there\&. So they announce 169\&.232\&.240\&.0/24 and then send spam from that block\&. There are two problems with this scheme\&. First, the announcement of such a smaller block may be filtered out by many BGP routers, reducing their reachability to their spam targets\&. Second, they may have made a mistake, and that /24 is actually in use by some UCLA service that will notice their hijack\&. - -.PP -They can announce a less specific route, for example a /16, covering some individual smaller blocks\&. For example, they could announce 52\&.129\&.0\&.0/16\&. The spammer could then avoid the four existing announcements inside that block, and instead spam from 52\&.129\&.128\&.0/17\&. That gives them 32K ip addresses to work with\&. The advantage here is that their announcement of a large block won't be filtered out by as many (if any) BGP routers, giving them better reachability to their spam targets\&. And they know they won't interfere with any existing use of that address space, since there was no previous BGP announcement of that /17 or any subset of it\&. - -.PP -Or they can simply announce a prefix that is not assigned to anyone\&. For example, they could simply start announcing 185\&.10\&.0\&.0/16\&. This has many of the same advantages as the previous scheme, but some BGP routers may be configured to drop such bogon announcements\&. - -.PP -In each of these cases, the spammer can use BGP to announce some address space, then send spam from those addresses, and then withdraw the route annoucement\&. This would make it difficult for the recipient of such spam to determine who actually sent it\&. - -.PP -In a paper from 2006 published at http://www\-static\&.cc\&.gatech\&.edu/~feamster/publications/p396\-ramachandran\&.pdf : \fIhttp://www-static.cc.gatech.edu/~feamster/publications/p396-ramachandran.pdf\fR, Ramachandran and Feamster claim evidence for the statement that spammers are using such short\-lived bogus BGP route announcements to send spam from hijacked parts of the IPv4 address space\&. - -.PP -The question is, are spammers actually doing this today, or is this just a hypothetical spam tactic that they could use in the future? To help answer that question, this package monitors BGP annoucements, classifies some of them as suspicious, and logs instances of SMTP connections from suspicious prefixes\&. - -.PP -We track the history of the AS adjacency graph, by computing the union of all AS adjacent pairs over all the announced prefixes\&. For example, 137\&.169\&.0\&.0/16 is currently announced here with an AS path of '22298 19080 3549 6517 14981', so we add (22298,19080) (19080,3549) (3549,6517) and (6517,14981) as valid adjacent AS pairs\&. - -.PP -We track the history of the origin AS for each announced prefix\&. Both the origin AS and AS adjacency pairs are tracked over a timescale of 100 hours, with an exponential decay half\-life of 100 hours\&. - -.PP -A prefix announcement is suspicious if the origin AS is not in the historical AS set for that prefix at least 20% of the time, or if the AS path contains any adjacent AS pair that is not in the historical AS adjacency graph at least 40% of the time\&. - -.PP - PHAS: \fIhttp://phas.netsec.colostate.edu/\fR is another system that attempts to detect address space hijacking, but it is not correlated with SMTP connections or spam attempts\&. - -.PP - IAR: \fIhttp://cs.unm.edu/~karlinjf/IAR/index.php\fR is another system that attempts to detect address space hijacking, but it is not correlated with SMTP connections or spam attempts\&. IAR uses methods detailed in PGBGP: \fIhttp://www.cs.unm.edu/~treport/tr/06-06/pgbgp3.pdf\fR to detect suspicious routes\&. One problem with PGBGP as applied to our hypothetical spammer problem, is that PGBGP is primarily looking for hijacks where the attacker actually wants some specific ip address space, either for a denial of service, or to impersonate the actual owner\&. Our hypothetical spammer does not care about that \- they only care about sending spam anonymously\&. In particular, PGBGP ignores super\-prefix hijacks, but it seems likely that that is the preferred method for our hypothetical spammer\&. However, the PGBGP paper does provide useful data on the required timescale to avoid most of the normal AS origin changes\&. - -.SH "TODO" - -.PP -None\&. - -.SH "COPYRIGHT" - -.PP -Copyright (C) 2008 by 510 Software Group - -.PP -This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version\&. - -.PP -You should have received a copy of the GNU General Public License along with this program; see the file COPYING\&. If not, please write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA\&. - -.SH "VERSION" - -.PP -1\&.0\&.1 - diff -r 4a81cc2da570 -r 180d26aa2a17 man/routeflapper.conf.5 --- a/man/routeflapper.conf.5 Thu May 22 20:39:52 2008 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -.\"Generated by db2man.xsl. Don't modify this, modify the source. -.de Sh \" Subsection -.br -.if t .Sp -.ne 5 -.PP -\fB\\$1\fR -.PP -.. -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Ip \" List item -.br -.ie \\n(.$>=3 .ne \\$3 -.el .ne 3 -.IP "\\$1" \\$2 -.. -.TH "ROUTEFLAPPER.CONF" 5 "2008-04-12" "" "" -.SH NAME -routeflapper.conf \- configuration file for routeflapper -.SH "SYNOPSIS" -.ad l -.hy 0 -.HP 18 -\fBrouteflapper\&.conf\fR -.ad -.hy - -.SH "DESCRIPTION" - -.PP -The \fBrouteflapper\&.conf\fR configuration file is specified by this partial bnf description\&. The entire config file is case sensitive\&. All the keywords are lower case\&. - -.nf - -CONFIG := {FILE}+ -FILE := "file" FILENAME "{" PATTERN+ "};" -PATTERN := PATH | ANNOUNCE | WITHDRAW | IP -PATH := "path" REGEX "{" INDEXPATH '}' ";" -ANNOUNCE := "path" REGEX "{" INDEXVAL INDEXLEN '}' ";" -WITHDRAW := "path" REGEX "{" INDEXVAL INDEXLEN '}' ";" -IP := "path" REGEX "{" INDEXIP '}' ";" -INDEXPATH := "index_path" REGEX\-INTEGER\-VALUE ";" -INDEXVAL := "index_value" REGEX\-INTEGER\-VALUE ";" -INDEXLEN := "index_length" REGEX\-INTEGER\-VALUE ";" -INDEXIP := "index_ip" REGEX\-INTEGER\-VALUE ";" -.fi - -.SH "SAMPLE" - -.nf - -file "/var/log/bgp" { - path " rcvd UPDATE w\&.* path (([0\-9]| )*[0\-9])" { - index_path 1; - }; - announce " rcvd (([0\-9]|\\\&.)*)/([0\-9]*)$" { - index_value 1; - index_length 3; - }; - withdraw " rcvd UPDATE about (([0\-9]|\\\&.)*)/([0\-9]*) \-\- withdrawn" { - index_value 1; - index_length 3; - }; -}; - -file "/var/log/maillog" { - ip "NOQUEUE: connect from\&.* \\[(\&.*)\\]" { - index_ip 1; - }; -}; -.fi - -.SH "VERSION" - -.PP -1\&.0\&.1 - diff -r 4a81cc2da570 -r 180d26aa2a17 routeflapper.spec.in --- a/routeflapper.spec.in Thu May 22 20:39:52 2008 -0700 +++ b/routeflapper.spec.in Thu Jun 12 17:51:33 2008 -0700 @@ -9,14 +9,12 @@ Source: http://www.five-ten-sg.com/%{name}/packages/%{name}-%{version}.tar.gz BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) URL: http://www.five-ten-sg.com/%{name}/ -AutoReqProv: no Requires(post,preun): /sbin/chkconfig Requires(post,preun): /sbin/service Requires: quagga Requires: coreutils BuildRequires: gcc gcc-c++ -Requires: libc.so.6, libgcc_s.so.1, libm.so.6, libpthread.so.0, libstdc++.so.6 %description @@ -38,7 +36,8 @@ rm -rf $RPM_BUILD_ROOT make DESTDIR=$RPM_BUILD_ROOT install mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d -mv -f $RPM_BUILD_ROOT%{_sysconfdir}/%{name} $RPM_BUILD_ROOT/etc/rc.d/init.d +mv -f $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/%{name} $RPM_BUILD_ROOT/etc/rc.d/init.d +mkdir -p $RPM_BUILD_ROOT/var/run/%{name} %clean @@ -69,9 +68,10 @@ %{_datadir}/doc/%{name}-%{version} %config(noreplace) %{_sysconfdir}/%{name}.conf /etc/rc.d/init.d/%{name} +%dir %attr(0750,%{name},root) /var/run/%{name} %changelog -* Tue Apr 01 2008 Carl Byington - 1.0.1 +* Thu Jun 12 2008 Carl Byington - 1.0.1-1 - initial version diff -r 4a81cc2da570 -r 180d26aa2a17 src/includes.h --- a/src/includes.h Thu May 22 20:39:52 2008 -0700 +++ b/src/includes.h Thu Jun 12 17:51:33 2008 -0700 @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include "tokenizer.h" #include "routeconfig.h" diff -r 4a81cc2da570 -r 180d26aa2a17 src/routeconfig.cpp --- a/src/routeconfig.cpp Thu May 22 20:39:52 2008 -0700 +++ b/src/routeconfig.cpp Thu Jun 12 17:51:33 2008 -0700 @@ -20,21 +20,21 @@ #include #include -char *token_announce; -char *token_file; -char *token_include; -char *token_index_ip; -char *token_index_length; -char *token_index_path; -char *token_index_value; -char *token_ip; -char *token_lbrace; -char *token_path; -char *token_rbrace; -char *token_reset; -char *token_semi; -char *token_slash; -char *token_withdraw; +const char *token_announce; +const char *token_file; +const char *token_include; +const char *token_index_ip; +const char *token_index_length; +const char *token_index_path; +const char *token_index_value; +const char *token_ip; +const char *token_lbrace; +const char *token_path; +const char *token_rbrace; +const char *token_reset; +const char *token_semi; +const char *token_slash; +const char *token_withdraw; const int training = 100; // need 100 hours uptime before using the statistics const float origin_threshold = 2.9; // a bit less than 1 + decay + decay^2 @@ -142,9 +142,9 @@ //////////////////////////////////////////////// // -char *suspicious_name(suspicion s) +const char *suspicious_name(suspicion s) { - char *ss = ""; + const char *ss = ""; switch (s) { case suspicious_none: ss = "none"; break; case suspicious_origin: ss = "origin"; break; @@ -191,7 +191,7 @@ ctime_r(&t, ctbuf); int ii = strlen(ctbuf); if (ii > 1) ctbuf[ii-1] = '\0'; // remove trailing newline - snprintf(buf, sizeof(buf), "*** smtp connection at %s from %s via prefix %s/%d being removed", ctbuf, adr, name(prefix_length).c_str(), prefix_length); + snprintf(buf, sizeof(buf), "*** smtp connection at %s from %s via prefix %s being removed", ctbuf, adr, name(prefix_length).c_str()); my_syslog(buf); } } @@ -480,7 +480,7 @@ if (!stable) return suspicious_none; suspicion rc = suspicious_none; route_prefix *r1 = NULL; - int pl; + int pl = 0; pthread_mutex_lock(&rib_mutex); for (int i=32; i>=0; i--) { route_prefixes &p = prefixes[i]; @@ -573,7 +573,7 @@ //////////////////////////////////////////////// // -ROUTECONFIG::ROUTECONFIG(TOKEN &tok, char *file_name_) { +ROUTECONFIG::ROUTECONFIG(TOKEN &tok, const char *file_name_) { tokp = &tok; file_name = file_name_; open(true); @@ -700,8 +700,8 @@ //////////////////////////////////////////////// // -int ip_address(char *have); -int ip_address(char *have) { +int ip_address(const char *have); +int ip_address(const char *have) { int ipaddr = 0; in_addr ip; if (inet_aton(have, &ip)) ipaddr = ip.s_addr; @@ -716,7 +716,7 @@ //////////////////////////////////////////////// // -PATTERN::PATTERN(TOKEN &tok, pattern_style style_, char *pattern_, int index1_, int index2_) +PATTERN::PATTERN(TOKEN &tok, pattern_style style_, const char *pattern_, int index1_, int index2_) { style = style_; pattern = pattern_; @@ -741,7 +741,7 @@ } -bool PATTERN::process(char *buf, CONFIG &con, char *file_name, int pattern_index) +bool PATTERN::process(char *buf, CONFIG &con, const char *file_name, int pattern_index) { if (pattern) { const int nmatch = max(index1, index2) + 1; @@ -811,7 +811,7 @@ } -void PATTERN::dump(int level, int index, char *token) +void PATTERN::dump(int level, int index, const char *token) { char indent[maxlen]; int i = min(maxlen-1, level*4); @@ -859,7 +859,7 @@ // void discard(string_set &s) { for (string_set::iterator i=s.begin(); i!=s.end(); i++) { - free(*i); + free((void*)*i); } s.clear(); } @@ -868,7 +868,7 @@ //////////////////////////////////////////////// // helper to register a string in a string set // -char* register_string(string_set &s, char *name) { +const char* register_string(string_set &s, const char *name) { string_set::iterator i = s.find(name); if (i != s.end()) return *i; char *x = strdup(name); @@ -880,7 +880,7 @@ //////////////////////////////////////////////// // register a global string // -char* register_string(char *name) { +const char* register_string(const char *name) { return register_string(all_strings, name); } @@ -903,9 +903,9 @@ //////////////////////////////////////////////// // -bool tsa(TOKEN &tok, char *token); -bool tsa(TOKEN &tok, char *token) { - char *have = tok.next(); +bool tsa(TOKEN &tok, const char *token); +bool tsa(TOKEN &tok, const char *token) { + const char *have = tok.next(); if (have == token) return true; tok.token_error(token, have); return false; @@ -914,13 +914,13 @@ //////////////////////////////////////////////// // -bool parse_path(TOKEN &tok, ROUTECONFIG &con, char *tokk, pattern_style style); -bool parse_path(TOKEN &tok, ROUTECONFIG &con, char *tokk, pattern_style style) { - char *pattern = tok.next(); +bool parse_path(TOKEN &tok, ROUTECONFIG &con, const char *tokk, pattern_style style); +bool parse_path(TOKEN &tok, ROUTECONFIG &con, const char *tokk, pattern_style style) { + const char *pattern = tok.next(); int index = 0; if (!tsa(tok, token_lbrace)) return false; while (true) { - char *have = tok.next(); + const char *have = tok.next(); if (!have) break; if (have == token_rbrace) break; if (have == tokk) { @@ -938,12 +938,12 @@ bool parse_announce_withdraw(TOKEN &tok, ROUTECONFIG &con, pattern_style style); bool parse_announce_withdraw(TOKEN &tok, ROUTECONFIG &con, pattern_style style) { - char *pattern = tok.next(); + const char *pattern = tok.next(); int index1 = 0; int index2 = 0; if (!tsa(tok, token_lbrace)) return false; while (true) { - char *have = tok.next(); + const char *have = tok.next(); if (!have) break; if (have == token_rbrace) break; if (have == token_index_value) { @@ -965,7 +965,7 @@ bool parse_routeconfig(TOKEN &tok, CONFIG &dc); bool parse_routeconfig(TOKEN &tok, CONFIG &dc) { - char *name = tok.next(); + const char *name = tok.next(); if (!tsa(tok, token_lbrace)) return false; ROUTECONFIGP con = new ROUTECONFIG(tok, name); if (con->failed()) { @@ -974,7 +974,7 @@ } dc.add_routeconfig(con); while (true) { - char *have = tok.next(); + const char *have = tok.next(); if (!have) break; if (have == token_rbrace) break; if (have == token_reset) { @@ -1005,11 +1005,11 @@ //////////////////////////////////////////////// // parse a config file // -bool load_conf(CONFIG &dc, char *fn) { +bool load_conf(CONFIG &dc, const char *fn) { int count = 0; TOKEN tok(fn, &dc.config_files); while (true) { - char *have = tok.next(); + const char *have = tok.next(); if (!have) break; if (have == token_file) { if (!parse_routeconfig(tok, dc)) return false; diff -r 4a81cc2da570 -r 180d26aa2a17 src/routeconfig.h --- a/src/routeconfig.h Thu May 22 20:39:52 2008 -0700 +++ b/src/routeconfig.h Thu Jun 12 17:51:33 2008 -0700 @@ -15,15 +15,15 @@ class PATTERN { pattern_style style; - char * pattern; // owned by the string table + const char * pattern; // owned by the string table regex_t re; int index1; // zero based substring of the regex match that contains the as list or prefix value int index2; // zero based substring of the regex match that contains the prefix length public: ~PATTERN(); - PATTERN(TOKEN &tok, pattern_style style_, char *pattern_, int index1_, int index2_); - bool process(char *buf, CONFIG &con, char *file_name, int pattern_index); - void dump(int level, int index, char *token); + PATTERN(TOKEN &tok, pattern_style style_, const char *pattern_, int index1_, int index2_); + bool process(char *buf, CONFIG &con, const char *file_name, int pattern_index); + void dump(int level, int index, const char *token); void dump(int level); }; @@ -35,14 +35,14 @@ class ROUTECONFIG { TOKEN * tokp; - char * file_name; // name of the syslog file + const char * file_name; // name of the syslog file pattern_list patterns; // owns the patterns int fd; struct stat openfdstat; int len; // bytes in the buffer char buf[buflen]; public: - ROUTECONFIG(TOKEN &tok, char *file_name_); + ROUTECONFIG(TOKEN &tok, const char *file_name_); ~ROUTECONFIG(); bool failed() { return (fd == -1); }; void open(bool msg); @@ -71,27 +71,27 @@ }; void discard(string_set &s); -char* register_string(string_set &s, char *name); -char* register_string(char *name); +const char* register_string(string_set &s, const char *name); +const char* register_string(const char *name); void clear_strings(); void clear_rib(); -int ip_address(char *have); -bool load_conf(CONFIG &dc, char *fn); +int ip_address(const char *have); +bool load_conf(CONFIG &dc, const char *fn); void routing_hourly_update(); void token_init(); -extern char *token_announce_aslist_index; -extern char *token_announce_pattern; -extern char *token_announce_prelen_index; -extern char *token_announce_preval_index; -extern char *token_file; -extern char *token_include; -extern char *token_lbrace; -extern char *token_rbrace; -extern char *token_semi; -extern char *token_slash; -extern char *token_withdraw_aslist_index; -extern char *token_withdraw_pattern; -extern char *token_withdraw_prelen_index; -extern char *token_withdraw_preval_index; +extern const char *token_announce_aslist_index; +extern const char *token_announce_pattern; +extern const char *token_announce_prelen_index; +extern const char *token_announce_preval_index; +extern const char *token_file; +extern const char *token_include; +extern const char *token_lbrace; +extern const char *token_rbrace; +extern const char *token_semi; +extern const char *token_slash; +extern const char *token_withdraw_aslist_index; +extern const char *token_withdraw_pattern; +extern const char *token_withdraw_prelen_index; +extern const char *token_withdraw_preval_index; diff -r 4a81cc2da570 -r 180d26aa2a17 src/routeflapper.cpp --- a/src/routeflapper.cpp Thu May 22 20:39:52 2008 -0700 +++ b/src/routeflapper.cpp Thu Jun 12 17:51:33 2008 -0700 @@ -48,7 +48,7 @@ //////////////////////////////////////////////// // syslog a message // -void my_syslog(char *text) +void my_syslog(const char *text) { if (use_syslog) { pthread_mutex_lock(&syslog_mutex); @@ -106,6 +106,7 @@ if (!loader_run) break; // ... so we only wait about 3 minutes to terminate routing_hourly_update(); // roughly an hour } + return NULL; } @@ -125,7 +126,7 @@ struct stat st; bool reload = false; for (string_set::iterator i=dc.config_files.begin(); i!=dc.config_files.end(); i++) { - char *fn = *i; + const char *fn = *i; if (stat(fn, &st)) reload = true; // file disappeared else if (st.st_mtime > then) reload = true; // file modified if (reload) break; diff -r 4a81cc2da570 -r 180d26aa2a17 src/routeflapper.h --- a/src/routeflapper.h Thu May 22 20:39:52 2008 -0700 +++ b/src/routeflapper.h Thu Jun 12 17:51:33 2008 -0700 @@ -6,5 +6,5 @@ */ -void my_syslog(char *text); +void my_syslog(const char *text); extern int debug_syslog; diff -r 4a81cc2da570 -r 180d26aa2a17 src/tokenizer.cpp --- a/src/tokenizer.cpp Thu May 22 20:39:52 2008 -0700 +++ b/src/tokenizer.cpp Thu Jun 12 17:51:33 2008 -0700 @@ -287,7 +287,7 @@ }; -TOKEN::TOKEN(char *fn, string_set *includes) { +TOKEN::TOKEN(const char *fn, string_set *includes) { pushed = false; include_files = includes; include(fn); @@ -301,7 +301,7 @@ void TOKEN::pop() { ifstream *is = streams.front(); - char *fn = filenames.front(); + const char *fn = filenames.front(); streams.pop_front(); filenamess.erase(fn); if (filenames.size() > 1) filenames.pop_front(); @@ -339,7 +339,7 @@ } -bool TOKEN::include(char *fn) { +bool TOKEN::include(const char *fn) { string_set::iterator i = filenamess.find(fn); if (i != filenamess.end()) { token_error("redundant or recursive include file detected"); @@ -363,9 +363,9 @@ } -char *TOKEN::next() { +const char *TOKEN::next() { if (!pending_tokens.empty()) { - char *t = pending_tokens.front(); + const char *t = pending_tokens.front(); pending_tokens.pop_front(); return t; } @@ -445,10 +445,10 @@ buffer[count] = '\0'; if (count == 0) return NULL; - char *t = register_string((char*)buffer); + const char *t = register_string((char*)buffer); if (t == token_include) { - char *f = next(); // should be file name - char *s = next(); // should be semicolon + const char *f = next(); // should be file name + const char *s = next(); // should be semicolon if (s == token_semi) { include(f); return next(); @@ -464,7 +464,7 @@ int TOKEN::nextint() { - char *t = next(); + const char *t = next(); char *e; long i = strtol(t, &e, 10); if (*e != '\0') { @@ -516,10 +516,10 @@ void TOKEN::token_error() { token_error("syntax error at line %d in file %s -- ", cur_line(), cur_fn()); line_list::iterator j = linenumbers.begin(); - string_list::iterator i = filenames.begin(); + string_list::const_iterator i = filenames.begin(); for (; i!=filenames.end(); i++,j++) { if (i != filenames.begin()) { - char *fn = (*i); + const char *fn = (*i); int li = (*j); token_error(" included from line %d in file %s -- ", li, fn); } diff -r 4a81cc2da570 -r 180d26aa2a17 src/tokenizer.h --- a/src/tokenizer.h Thu May 22 20:39:52 2008 -0700 +++ b/src/tokenizer.h Thu Jun 12 17:51:33 2008 -0700 @@ -10,14 +10,14 @@ using namespace std; struct ltstr { - bool operator()(char* s1, char* s2) const { + bool operator()(const char* s1, const char* s2) const { return strcmp(s1, s2) < 0; } }; typedef list stream_list; -typedef list string_list; -typedef set string_set; +typedef list string_list; +typedef set string_set; typedef list line_list; class TOKEN { @@ -35,13 +35,13 @@ void push_char(u_char c); public: - TOKEN(char *fn, string_set *includes); + TOKEN(const char *fn, string_set *includes); ~TOKEN(); - bool include(char *fn); - char *next(); // return next token + bool include(const char *fn); + const char *next(); // return next token int nextint(); void skipeol(); // skip to eol - void push(char *token) {pending_tokens.push_front(token);}; + void push(const char *token) {pending_tokens.push_front(token);}; const char *cur_fn() {return filenames.empty() ? "" : filenames.front();}; int cur_line() {return linenumbers.empty() ? 0 : linenumbers.front();}; void token_error(const char *err); diff -r 4a81cc2da570 -r 180d26aa2a17 xml/routeflapper.in --- a/xml/routeflapper.in Thu May 22 20:39:52 2008 -0700 +++ b/xml/routeflapper.in Thu Jun 12 17:51:33 2008 -0700 @@ -19,7 +19,7 @@ - 2008-05-13 + 2008-06-12 @@ -260,7 +260,7 @@ - 2008-05-13 + 2008-06-12