Feb 19
    Change language to:

Below is a short little script that i wrote with some help of some FreeBSD Perl developers (Thanks mat and siks).

The script should be runned with root permissions, sudo could be used for that:

For example with the follwing information in /usr/local/etc/sudoers (or where your configfile lives)

User_Alias MRTG = mrtg
MRTG NOPASSWD: /sbin/pfctl -si

The script will run /sbin/pfctl -si which will give you statistical output which can be used for processing by mrtg after running pf.pl. Do note that the current markup might not fit on the script. Please click on the Plain text button to see the original script in a new window, which will fit.

PERL:
  1. #!/usr/bin/perl -w
  2.  
  3. # $Id: pf-to-mrtg.pl 831 2008-09-07 13:45:27Z remko $
  4. #
  5. # (c) 2005 Remko Lodder <remko@elvandar.org>
  6. # (c) 2008 Remko Lodder <remko@FreeBSD.org>
  7. # Based upon ipf.pl by Ronald Florence <ron@18james.com>
  8. # last modified remko@elvandar.org, 05 Sept 2009
  9. # Made the script working again.
  10.  
  11. # Example output from pfctl -si
  12. #Interface Stats for fxp0              IPv4             IPv6
  13. #  Bytes In                          156041                0
  14. #  Bytes Out                        1895602                0
  15. #  Packets In
  16. #    Passed                            1504                0
  17. #    Blocked                            256                0
  18. #  Packets Out
  19. #    Passed                            1756                0
  20. #    Blocked                              0                0
  21. #
  22. #State Table                          Total             Rate
  23. #  current entries                       33               
  24. #  searches                            8865           10.7/s
  25. #  inserts                              204            0.2/s
  26. #  removals                             171            0.2/s
  27. #Counters
  28. #  match                                460            0.6/s
  29. #  bad-offset                             0            0.0/s
  30. #  fragment                               0            0.0/s
  31. #  short                                  0            0.0/s
  32. #  normalize                              0            0.0/s
  33. #  memory                                 0            0.0/s
  34.  
  35. use strict;
  36. use Getopt::Std;
  37.  
  38. # prototype variables.
  39. my($inp,$outp) = 0;
  40.  
  41. my ($out,$in,$uptime,$firewall);
  42. my(@pfctl);
  43. my(%option);
  44.  
  45. # define some variables upfront
  46. my $scriptname = __FILE__;
  47. my $version = "2.0";
  48.  
  49. # Index our options
  50. getopts("bBfimMnpsS", \%option);
  51.  
  52. my $pass_flag   = 1 if $option{p};
  53. my $block_flag  = 1 if $option{b};
  54. my $bytes_flag  = 1 if $option{B};
  55. my $state_flag  = 1 if $option{s};
  56. my $search_flag = 1 if $option{S};
  57. my $inres_flag  = 1 if $option{i};
  58. my $match_flag  = 1 if $option{m};
  59. my $frag_flag   = 1 if $option{f};
  60. my $short_flag  = 1 if $option{n};
  61. my $memory_flag = 1 if $option{M};
  62.  
  63. @pfctl=`/sbin/pfctl -si`;
  64.  
  65. foreach my $packetfilter (@pfctl) {
  66.         if ($pass_flag || $block_flag) {
  67.                 if ($packetfilter =~ /Packets In/) { $in = 1; $out = 0; }
  68.                 if ($packetfilter =~ /Packets Out/) { $in = 0; $out = 1; }
  69.                 if ($pass_flag) {
  70.                         if ($packetfilter =~ /Passed\s+(\d+)/) { if ($in) { $inp += $1; } }
  71.                         if ($packetfilter =~ /Passed\s+(\d+)/) { if ($out) { $outp += $1; } }
  72.                 }
  73.                 if ($block_flag) {
  74.                         if ($packetfilter =~ /Blocked\s+(\d+)/) { if ($in) { $inp += $1; } }
  75.                         if ($packetfilter =~ /Blocked\s+(\d+)/) { if ($out) { $outp += $1; } }
  76.                 }
  77.         }
  78.  
  79.         elsif ($bytes_flag) {
  80.                 if ($packetfilter =~ /Bytes\sIn\s+(\d+)/)  { $inp += $1; }
  81.                 if ($packetfilter =~ /Bytes\sOut\s+(\d+)/) { $outp += $1; }
  82.         }
  83.         elsif ($state_flag) {
  84.                 if ($packetfilter =~ /current entries\s+(\d+)/) { $inp += $1 }
  85.                 $outp = 0;
  86.         }
  87.         elsif ($search_flag) {
  88.                 if ($packetfilter =~ /searches\s+(\d+)/) { $inp += $1 }
  89.                 if ($packetfilter =~ /searches\s+\d+\s+(\d+)/) { $outp += $1 }
  90.         }
  91.         elsif ($inres_flag) {
  92.                 if ($packetfilter =~ /inserts\s+(\d+)/) { $inp += $1 }
  93.                 if ($packetfilter =~ /removals\s+(\d+)/) { $outp += $1 }
  94.         }
  95.         elsif ($match_flag) {
  96.                 if ($packetfilter =~ /match\s+(\d+)/) { $inp += $1 }
  97.                 if ($packetfilter =~ /match\s+\d+\s+(\d+)/) { $outp += $1 }
  98.         }
  99.         elsif ($frag_flag) {
  100.                 if ($packetfilter =~ /bad-offset\s+(\d+)/) { $inp += $1 }
  101.                 if ($packetfilter =~ /fragment\s+(\d+)/) { $outp += $1 }
  102.         }
  103.         elsif ($short_flag) {
  104.                 if ($packetfilter =~ /short\s+(\d+)/) { $inp += $1 }
  105.                 if ($packetfilter =~ /normalize\s+(\d+)/) { $outp += $1 }
  106.         }
  107.         elsif ($memory_flag) {
  108.                 if ($packetfilter =~ /memory\s+(\d+)/) { $inp += $1 }
  109.                 if ($packetfilter =~ /memory\s+\d+\s+(\d+)/) { $outp += $1 }
  110.         }
  111.         else {
  112.                 print("Usage:\t$scriptname [ -b ] [ -B ] [ -f ] [ -i ] [ -m ] [ -M ] [ -n ] [ -p ] [ -s ] [ -S ]
  113. \t-b\tIndex blocked packets incoming and outgoing.
  114. \t-B\tIndex bytes incoming and outgoing
  115. \t-f\tIndex bad-offsets and fragments
  116. \t-i\tIndex inserts and removals
  117. \t-m\tIndex matched packets current values and usage rate
  118. \t-M\tIndex memory usage current values and usage rate
  119. \t-n\tIndex short packets and normalized packets
  120. \t-p\tIndex passed packets incoming and outgoing.
  121. \t-s\tIndex states other value will be zero (0)
  122. \t-S\tIndex searches current searches and search rate
  123. Version: $version
  124. Originally written by Remko Lodder <remko\@FreeBSD.org>.\n");
  125.                 exit(1);
  126.         }
  127. }
  128.  
  129. print "$inp\n",
  130.       "$outp\n";
  131.  
  132. $_ = `/usr/bin/uptime`;
  133. ($uptime) = /up\s+(.*),\s+.+user/;
  134. $uptime =~ s/(^1\s+day)\s/1/;
  135.  
  136. chop($firewall = `uname -nm`);
  137. print "$uptime\n",
  138.  
  139. __END__
  140.  
  141. =head1 NAME
  142.  
  143.   pf-to-mrtg.pl -  generates statistics for use with MRTG
  144.  
  145. =head1 SYNOPSIS
  146.  
  147.   Two example configuration options for MRTG:
  148.  
  149.   Target[connections]: `/path/to/pf-to-mrtg.pl -p`
  150.   Options[connections]: growright, perhour
  151.   MaxBytes[connections]: 50000
  152.   Title[connections]: Firewall Connections
  153.   PageTop[connections]: <h3>Firewall Connections</h3>
  154.   YLegend[connections]: packets/hr
  155.   ShortLegend[connections]: pkts/h
  156.   Legend1[connections]: Incoming Connections
  157.   Legend2[connections]: Outgoing Connections
  158.  
  159.   Target[state]: `/path/to/pf-to-mrtg.pl -s`
  160.   Options[state]: growright, gauge, integer
  161.   MaxBytes[state]: 2048
  162.   Title[state]: State Table
  163.   PageTop[state]: <h3>NAT &amp; IP state tables</h3>
  164.   YLegend[state]: states
  165.   ShortLegend[state]: states
  166.   Legend1[state]: NAT states
  167.   Legend2[state]: IP states
  168.   LegendI[state]: nat:
  169.   LegendO[state]: ip:
  170.  
  171.   Other available targets are `pf-to-mrtg.pl -b`
  172.                               `pf-to-mrtg.pl -B`
  173.                               `pf-to-mrtg.pl -f`
  174.                               `pf-to-mrtg.pl -i`
  175.                               `pf-to-mrtg.pl -m`
  176.                               `pf-to-mrtg.pl -M`
  177.                               `pf-to-mrtg.pl -n`
  178.                               `pf-to-mrtg.pl -p`
  179.                               `pf-to-mrtg.pl -s`
  180.                               `pf-to-mrtg.pl -S`
  181.  
  182.   See the instructions in the help to see what they represent.
  183.  
  184. =head1 DESCRIPTION
  185.  
  186.     The purpose of this script is to be able to create statistics
  187.     from various PF counters.  By using this script you will be
  188.     able to see what your firewall does, how it behaves, and see
  189.     trends.  Note: Due to MRTG's nature you will get spikes after
  190.     rebooting the machine.
  191. =head1 LICENSE
  192.     This module is licensed under the BSD license.
  193. =head1 AUTHOR
  194.     Remko Lodder <remko@FreeBSD.org> with additional help from
  195.     Mattieu Arnold <mat@FreeBSD.org> and Pasi Hirvonen.
  196.     Originally based on work from Ron James (before this was entirely rewritten).
  197. =cut

written by Remko