.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.28) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "IPTables::Parse 3pm" .TH IPTables::Parse 3pm "2015-11-08" "perl v5.20.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" IPTables::Parse \- Perl extension for parsing iptables and ip6tables policies .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use IPTables::Parse; \& \& my %opts = ( \& \*(Aquse_ipv6\*(Aq => 0, # can set to 1 to force ip6tables usage \& \*(Aqipt_rules_file\*(Aq => \*(Aq\*(Aq, # optional file path from \& # which to read iptables rules \& \*(Aqdebug\*(Aq => 0, \& \*(Aqverbose\*(Aq => 0 \& ); \& \& my $ipt_obj = IPTables::Parse\->new(%opts) \& or die "[*] Could not acquire IPTables::Parse object"; \& \& my $rv = 0; \& \& ### look for default DROP rules in the filter table INPUT chain \& my ($ipt_hr, $rv) = $ipt_obj\->default_drop(\*(Aqfilter\*(Aq, \*(AqINPUT\*(Aq); \& if ($rv) { \& if (defined $ipt_hr\->{\*(Aqall\*(Aq}) { \& print "The INPUT chain has a default DROP rule for all protocols.\en"; \& } else { \& my $found = 0; \& for my $proto (qw/tcp udp icmp/) { \& if (defined $ipt_hr\->{$proto}) { \& print "The INPUT chain drops $proto by default.\en"; \& $found = 1; \& } \& } \& unless ($found) { \& print "The INPUT chain does not have any default DROP rule.\en"; \& } \& } \& } else { \& print "[\-] Could not parse $ipt_obj\->{\*(Aq_ipt_bin_name\*(Aq} policy\en"; \& } \& \& ### look for default LOG rules in the filter table INPUT chain \& ($ipt_hr, $rv) = $ipt_obj\->default_log(\*(Aqfilter\*(Aq, \*(AqINPUT\*(Aq); \& if ($rv) { \& if (defined $ipt_hr\->{\*(Aqall\*(Aq}) { \& print "The INPUT chain has a default LOG rule for all protocols.\en"; \& } else { \& my $found = 0; \& for my $proto (qw/tcp udp icmp/) { \& if (defined $ipt_hr\->{$proto}) { \& print "The INPUT chain logs $proto by default.\en"; \& $found = 1; \& } \& } \& unless ($found) { \& print "The INPUT chain does not have any default LOG rule.\en"; \& } \& } \& } else { \& print "[\-] Could not parse $ipt_obj\->{\*(Aq_ipt_bin_name\*(Aq} policy\en"; \& } \& \& ### print all chains in the filter table \& for my $chain (@{$ipt_obj\->list_table_chains(\*(Aqfilter\*(Aq)}) { \& print $chain, "\en"; \& } .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" The \f(CW\*(C`IPTables::Parse\*(C'\fR package provides an interface to parse iptables or ip6tables rules on Linux systems through the direct execution of iptables/ip6tables commands, or from parsing a file that contains an iptables/ip6tables policy listing. Note that the 'firewalld' infrastructure on Fedora21 is also supported through execution of the 'firewall\-cmd' binary. By default, the path to iptables is assumed to be '/sbin/iptables', but if the firewall is 'firewalld', then the '/usr/bin/firewall\-cmd' is used. .PP With this module, you can get the current policy applied to a table/chain, look for a specific user-defined chain, check for a default \s-1DROP\s0 policy, or determine whether or not a default \s-1LOG\s0 rule exists. Also, you can get a listing of all rules in a chain with each rule parsed into its own hash. .PP Note that if you initialize the IPTables::Parse object with the 'ipt_rules_file' key, then all parsing routines will open the specified file for iptables rules data. So, you can create this file with a command like \&'iptables \-t filter \-nL \-v > ipt.rules', and then initialize the object with IPTables::Parse\->new('ipt_rules_file' => 'ipt.rules'). Further, if you are running on a system without iptables installed, but you have an iptables policy written to the ipt.rules file, then you can pass in 'skip_ipt_exec_check=>1' in order to analyze the file without having IPTables::Parse check for the iptables binary. .PP In summary, in addition to the hash keys mentioned above, optional keys that can be passed to \fInew()\fR include 'iptables' (set path to iptables binary), \&'firewall_cmd' (set path to 'firewall\-cmd' binary for systems with \&'firewalld'), 'fwd_args' (set 'firewall\-cmd' usage args; defaults to \&'\-\-direct \-\-passthrough ipv4'), 'ipv6' (set IPv6 mode for ip6tables), \&'debug', 'verbose', and 'lockless_ipt_exec' (disable usage of the iptables \&'\-w' argument that acquires an exclusive lock on command execution). .SH "FUNCTIONS" .IX Header "FUNCTIONS" The IPTables::Parse extension provides an object interface to the following functions: .ie n .IP "chain_policy($table, $chain)" 4 .el .IP "chain_policy($table, \f(CW$chain\fR)" 4 .IX Item "chain_policy($table, $chain)" This function returns the policy (e.g. '\s-1DROP\s0', '\s-1ACCEPT\s0', etc.) for the specified table and chain: .Sp .Vb 2 \& print "INPUT policy: ", \& $ipt_obj\->chain_policy(\*(Aqfilter\*(Aq, \*(AqINPUT\*(Aq), "\en"; .Ve .ie n .IP "chain_rules($table, $chain)" 4 .el .IP "chain_rules($table, \f(CW$chain\fR)" 4 .IX Item "chain_rules($table, $chain)" This function parses the specified chain and table and returns an array reference for all rules in the chain. Each element in the array reference is a hash with the following keys (that contain values depending on the rule): \f(CW\*(C`src\*(C'\fR, \f(CW\*(C`dst\*(C'\fR, \&\f(CW\*(C`protocol\*(C'\fR, \f(CW\*(C`s_port\*(C'\fR, \f(CW\*(C`d_port\*(C'\fR, \f(CW\*(C`target\*(C'\fR, \f(CW\*(C`packets\*(C'\fR, \f(CW\*(C`bytes\*(C'\fR, \f(CW\*(C`intf_in\*(C'\fR, \&\f(CW\*(C`intf_out\*(C'\fR, \f(CW\*(C`to_ip\*(C'\fR, \f(CW\*(C`to_port\*(C'\fR, \f(CW\*(C`state\*(C'\fR, \f(CW\*(C`raw\*(C'\fR, and \f(CW\*(C`extended\*(C'\fR. The \f(CW\*(C`extended\*(C'\fR element contains the rule output past the protocol information, and the \f(CW\*(C`raw\*(C'\fR element contains the complete rule itself as reported by iptables or ip6tables. Here is an example of checking whether the second rule in the \s-1INPUT\s0 chain (array index 1) allows traffic from any \s-1IP\s0 to \s-1TCP\s0 port 80: .Sp .Vb 1 \& $rules_ar = $ipt_obj\->chain_rules(\*(Aqfilter\*(Aq, \*(AqINPUT); \& \& if ($rules_ar\->[1]\->{\*(Aqsrc\*(Aq} eq \*(Aq0.0.0.0/0\*(Aq \& and $rules_ar\->[1]\->{\*(Aqprotocol\*(Aq} eq \*(Aqtcp\*(Aq \& and $rules_ar\->[1]\->{\*(Aqd_port\*(Aq} eq \*(Aq80\*(Aq \& and $rules_ar\->[1]\->{\*(Aqtarget\*(Aq} eq \*(AqACCEPT\*(Aq) { \& \& print "traffic accepted to TCP port 80 from anywhere\en"; \& } .Ve .ie n .IP "default_drop($table, $chain)" 4 .el .IP "default_drop($table, \f(CW$chain\fR)" 4 .IX Item "default_drop($table, $chain)" This function parses the running iptables or ip6tables policy in order to determine if the specified chain contains a default \s-1DROP\s0 rule. Two values are returned, a hash reference whose keys are the protocols that are dropped by default (if a global \s-1ACCEPT\s0 rule has not accepted matching packets first), along with a return value that tells the caller if parsing the iptables or ip6tables policy was successful. Note that if all protocols are dropped by default, then the hash key 'all' will be defined. .Sp .Vb 1 \& ($ipt_hr, $rv) = $ipt_obj\->default_drop(\*(Aqfilter\*(Aq, \*(AqINPUT\*(Aq); .Ve .ie n .IP "default_log($table, $chain)" 4 .el .IP "default_log($table, \f(CW$chain\fR)" 4 .IX Item "default_log($table, $chain)" This function parses the running iptables or ip6tables policy in order to determine if the specified chain contains a default \s-1LOG\s0 rule. Two values are returned, a hash reference whose keys are the protocols that are logged by default (if a global \s-1ACCEPT\s0 rule has not accepted matching packets first), along with a return value that tells the caller if parsing the iptables or ip6tables policy was successful. Note that if all protocols are logged by default, then the hash key 'all' will be defined. An example invocation is: .Sp .Vb 1 \& ($ipt_hr, $rv) = $ipt_obj\->default_log(\*(Aqfilter\*(Aq, \*(AqINPUT\*(Aq); .Ve .IP "list_table_chains($table)" 4 .IX Item "list_table_chains($table)" This function parses the specified table for all chains that are defined within the table. Data is returned as an array reference. For example, if there are no user-defined chains in the 'filter' table, then the returned array reference will contain the strings '\s-1INPUT\s0', '\s-1FORWARD\s0', and '\s-1OUTPUT\s0'. .Sp .Vb 3 \& for my $chain (@{$ipt_obj\->list_table_chains(\*(Aqfilter\*(Aq)}) { \& print $chain, "\en"; \& } .Ve .SH "AUTHOR" .IX Header "AUTHOR" Michael Rash, .SH "SEE ALSO" .IX Header "SEE ALSO" The IPTables::Parse module is used by the IPTables::ChainMgr extension in support of the psad and fwsnort projects to parse iptables or ip6tables policies (see the \fIpsad\fR\|(8), and \fIfwsnort\fR\|(8) man pages). As always, the \fIiptables\fR\|(8) and \fIip6tables\fR\|(8) man pages provide the best information on command line execution and theory behind iptables and ip6tables. .PP Although there is no mailing that is devoted specifically to the IPTables::Parse extension, questions about the extension will be answered on the following lists: .PP .Vb 2 \& The psad mailing list: http://lists.sourceforge.net/lists/listinfo/psad\-discuss \& The fwsnort mailing list: http://lists.sourceforge.net/lists/listinfo/fwsnort\-discuss .Ve .PP The latest version of the IPTables::Parse extension can be found on \s-1CPAN\s0 and also here: .PP .Vb 1 \& http://www.cipherdyne.org/modules/ .Ve .PP Source control is provided by git: .PP .Vb 1 \& https://github.com/mrash/IPTables\-Parse.git .Ve .SH "CREDITS" .IX Header "CREDITS" Thanks to the following people: .PP .Vb 5 \& Franck Joncourt \& Stuart Schneider \& Grant Ferley \& Fabien Mazieres \& Miloslav TrmaX .Ve .SH "AUTHOR" .IX Header "AUTHOR" The IPTables::Parse extension was written by Michael Rash \fI\fR to support the psad and fwsnort projects. Please send email to this address if there are any questions, comments, or bug reports. .SH "VERSION" .IX Header "VERSION" Version 1.6 (November, 2015) .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" Copyright (C) 2005\-2015 Michael Rash. All rights reserved. .PP This module is free software. You can redistribute it and/or modify it under the terms of the Artistic License 2.0. More information can be found here: http://www.perl.com/perl/misc/Artistic.html .PP This program is distributed \*(L"as is\*(R" in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.