2007-03-15 22:55:22 +01:00
|
|
|
#
|
2007-06-11 21:39:30 +02:00
|
|
|
# Shorewall-perl 4.0 -- /usr/share/shorewall-perl/Shorewall/Tunnels.pm
|
2007-03-15 22:55:22 +01:00
|
|
|
#
|
|
|
|
# This program is under GPL [http://www.gnu.org/copyleft/gpl.htm]
|
|
|
|
#
|
|
|
|
# (c) 2007 - Tom Eastep (teastep@shorewall.net)
|
|
|
|
#
|
|
|
|
# Complete documentation is available at http://shorewall.net
|
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of Version 2 of the GNU General Public License
|
|
|
|
# as published by the Free Software Foundation.
|
|
|
|
#
|
|
|
|
# This program is distributed 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. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software
|
|
|
|
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
|
|
|
|
#
|
2007-04-19 01:55:25 +02:00
|
|
|
# This module handles the /etc/shorewall/tunnels file.
|
2007-03-15 22:55:22 +01:00
|
|
|
#
|
2007-03-15 02:15:05 +01:00
|
|
|
package Shorewall::Tunnels;
|
|
|
|
require Exporter;
|
|
|
|
use Shorewall::Common;
|
|
|
|
use Shorewall::Config;
|
|
|
|
use Shorewall::Zones;
|
|
|
|
use Shorewall::Chains;
|
|
|
|
|
|
|
|
use strict;
|
|
|
|
|
|
|
|
our @ISA = qw(Exporter);
|
|
|
|
our @EXPORT = qw( setup_tunnels );
|
|
|
|
our @EXPORT_OK = ( );
|
2007-07-01 02:08:23 +02:00
|
|
|
our $VERSION = 4.00;
|
2007-03-15 02:15:05 +01:00
|
|
|
|
|
|
|
#
|
|
|
|
# Here starts the tunnel stuff -- we really should get rid of this crap...
|
|
|
|
#
|
|
|
|
sub setup_tunnels() {
|
|
|
|
|
|
|
|
sub setup_one_ipsec {
|
|
|
|
my ($inchainref, $outchainref, $kind, $source, $dest, $gatewayzones) = @_;
|
|
|
|
|
2007-05-17 16:10:46 +02:00
|
|
|
( $kind, my ( $qualifier , $remainder ) ) = split( /:/, $kind, 3 );
|
|
|
|
|
|
|
|
fatal_error "Invalid IPSEC modified ($qualifier:$remainder)" if defined $remainder;
|
2007-03-15 02:15:05 +01:00
|
|
|
|
2007-03-30 04:05:11 +02:00
|
|
|
fatal_error "Invalid IPSEC modifier ($qualifier)" if $qualifier && ( $qualifier ne 'noah' );
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
my $noah = $qualifier || ($kind ne 'ipsec' );
|
|
|
|
|
2007-05-04 21:57:01 +02:00
|
|
|
my $options = '-m state --state NEW -j ACCEPT';
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-04-08 16:42:26 +02:00
|
|
|
add_rule $inchainref, "-p 50 $source -j ACCEPT";
|
|
|
|
add_rule $outchainref, "-p 50 $dest -j ACCEPT";
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
unless ( $noah ) {
|
2007-04-08 16:42:26 +02:00
|
|
|
add_rule $inchainref, "-p 51 $source -j ACCEPT";
|
|
|
|
add_rule $outchainref, "-p 51 $dest -j ACCEPT";
|
2007-03-15 02:15:05 +01:00
|
|
|
}
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
add_rule $outchainref, "-p udp $dest --dport 500 $options";
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
if ( $kind eq 'ipsec' ) {
|
2007-05-04 22:18:31 +02:00
|
|
|
add_rule $inchainref, "-p udp $source --dport 500 $options";
|
2007-03-15 02:15:05 +01:00
|
|
|
} else {
|
2007-03-22 23:31:08 +01:00
|
|
|
add_rule $inchainref, "-p udp $source -m multiport --dports 500,4500 $options";
|
|
|
|
add_rule $outchainref, "-p udp $dest -m multiport --dports 500,4500 $options";
|
2007-03-15 02:15:05 +01:00
|
|
|
}
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-05-04 20:55:57 +02:00
|
|
|
unless ( $gatewayzones eq '-' ) {
|
|
|
|
for my $zone ( split /,/, $gatewayzones ) {
|
2007-05-05 06:35:55 +02:00
|
|
|
fatal_error "Unknown zone ($zone)" unless $zones{$zone};
|
2007-05-04 20:55:57 +02:00
|
|
|
fatal_error "Invalid zone ($zone)" unless $zones{$zone}{type} eq 'ipv4';
|
|
|
|
$inchainref = ensure_filter_chain "${zone}2${firewall_zone}", 1;
|
|
|
|
$outchainref = ensure_filter_chain "${firewall_zone}2${zone}", 1;
|
|
|
|
|
|
|
|
unless ( $capabilities{POLICY_MATCH} ) {
|
|
|
|
add_rule $inchainref, "-p 50 $source -j ACCEPT";
|
|
|
|
add_rule $outchainref, "-p 50 $dest -j ACCEPT";
|
|
|
|
|
|
|
|
unless ( $noah ) {
|
|
|
|
add_rule $inchainref, "-p 51 $source -j ACCEPT";
|
|
|
|
add_rule $outchainref, "-p 51 $dest -j ACCEPT";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( $kind eq 'ipsec' ) {
|
|
|
|
add_rule $inchainref, "-p udp $source --dport 500 $options";
|
|
|
|
add_rule $outchainref, "-p udp $dest --dport 500 $options";
|
|
|
|
} else {
|
|
|
|
add_rule $inchainref, "-p udp $source -m multiport --dports 500,4500 $options";
|
|
|
|
add_rule $outchainref, "-p udp $dest -m multiport --dports 500,4500 $options";
|
2007-03-15 02:15:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
sub setup_one_other {
|
2007-05-05 00:31:48 +02:00
|
|
|
my ($inchainref, $outchainref, $source, $dest , $protocol) = @_;
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
add_rule $inchainref , "-p $protocol $source -j ACCEPT";
|
|
|
|
add_rule $outchainref , "-p $protocol $dest -j ACCEPT";
|
|
|
|
}
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
sub setup_pptp_client {
|
|
|
|
my ($inchainref, $outchainref, $kind, $source, $dest ) = @_;
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
add_rule $outchainref, "-p 47 $dest -j ACCEPT";
|
|
|
|
add_rule $inchainref, "-p 47 $source -j ACCEPT";
|
|
|
|
add_rule $outchainref, "-p tcp --dport 1723 $dest -j ACCEPT"
|
|
|
|
}
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
sub setup_pptp_server {
|
|
|
|
my ($inchainref, $outchainref, $kind, $source, $dest ) = @_;
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
add_rule $inchainref, "-p 47 $dest -j ACCEPT";
|
|
|
|
add_rule $outchainref, "-p 47 $source -j ACCEPT";
|
|
|
|
add_rule $inchainref, "-p tcp --dport 1723 $dest -j ACCEPT"
|
|
|
|
}
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
sub setup_one_openvpn {
|
|
|
|
my ($inchainref, $outchainref, $kind, $source, $dest) = @_;
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
my $protocol = 'udp';
|
|
|
|
my $port = 1194;
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-05-17 16:10:46 +02:00
|
|
|
( $kind, my ( $proto, $p, $remainder ) ) = split( /:/, $kind, 4 );
|
|
|
|
|
|
|
|
fatal_error "Invalid port ($p:$remainder)" if defined $remainder;
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-05-05 02:02:21 +02:00
|
|
|
if ( defined $p && $p ne '' ) {
|
2007-03-19 05:50:37 +01:00
|
|
|
$port = $p;
|
|
|
|
$protocol = $proto;
|
2007-05-05 02:18:45 +02:00
|
|
|
} elsif ( defined $proto && $proto ne '' ) {
|
2007-04-09 21:33:30 +02:00
|
|
|
if ( "\L$proto" =~ /udp|tcp/ ) {
|
|
|
|
$protocol = $proto;
|
|
|
|
} else {
|
|
|
|
$port = $proto;
|
|
|
|
}
|
2007-03-19 05:50:37 +01:00
|
|
|
}
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
add_rule $inchainref, "-p $protocol $source --dport $port -j ACCEPT";
|
|
|
|
add_rule $outchainref, "-p $protocol $dest --dport $port -j ACCEPT";
|
|
|
|
}
|
|
|
|
|
|
|
|
sub setup_one_openvpn_client {
|
|
|
|
my ($inchainref, $outchainref, $kind, $source, $dest) = @_;
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
my $protocol = 'udp';
|
|
|
|
my $port = 1194;
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-05-17 16:10:46 +02:00
|
|
|
( $kind, my ( $proto, $p , $remainder ) ) = split( /:/, $kind, 4 );
|
|
|
|
|
|
|
|
fatal_error "Invalid port ($p:$remainder)" if defined $remainder;
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-05-05 02:02:21 +02:00
|
|
|
if ( defined $p && $p ne '' ) {
|
2007-03-19 05:50:37 +01:00
|
|
|
$port = $p;
|
|
|
|
$protocol = $proto;
|
2007-05-05 02:18:45 +02:00
|
|
|
} elsif ( defined $proto && $proto ne '' ) {
|
2007-04-09 21:33:30 +02:00
|
|
|
if ( "\L$proto" =~ /udp|tcp/ ) {
|
|
|
|
$protocol = $proto;
|
|
|
|
} else {
|
|
|
|
$port = $proto;
|
|
|
|
}
|
2007-03-19 05:50:37 +01:00
|
|
|
}
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
add_rule $inchainref, "-p $protocol $source --sport $port -j ACCEPT";
|
|
|
|
add_rule $outchainref, "-p $protocol $dest --dport $port -j ACCEPT";
|
|
|
|
}
|
|
|
|
|
|
|
|
sub setup_one_openvpn_server {
|
|
|
|
my ($inchainref, $outchainref, $kind, $source, $dest) = @_;
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
my $protocol = 'udp';
|
|
|
|
my $port = 1194;
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-05-17 16:10:46 +02:00
|
|
|
( $kind, my ( $proto, $p , $remainder ) ) = split( /:/, $kind, 4 );
|
|
|
|
|
|
|
|
fatal_error "Invalid port ($p:$remainder)" if defined $remainder;
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-05-05 02:02:21 +02:00
|
|
|
if ( defined $p && $p ne '' ) {
|
2007-03-19 05:50:37 +01:00
|
|
|
$port = $p;
|
|
|
|
$protocol = $proto;
|
2007-05-05 02:18:45 +02:00
|
|
|
} elsif ( defined $proto && $proto ne '' ) {
|
2007-05-05 01:03:41 +02:00
|
|
|
if ( "\L$proto" =~ /udp|tcp/ ) {
|
|
|
|
$protocol = $proto;
|
|
|
|
} else {
|
|
|
|
$port = $proto;
|
|
|
|
}
|
2007-03-19 05:50:37 +01:00
|
|
|
}
|
2007-03-15 02:15:05 +01:00
|
|
|
|
|
|
|
add_rule $inchainref, "-p $protocol $source --dport $port -j ACCEPT";
|
|
|
|
add_rule $outchainref, "-p $protocol $dest --sport $port -j ACCEPT";
|
|
|
|
}
|
|
|
|
|
|
|
|
sub setup_one_generic {
|
|
|
|
my ($inchainref, $outchainref, $kind, $source, $dest) = @_;
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
my $protocol = 'udp';
|
|
|
|
my $port = '--dport 5000';
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
if ( $kind =~ /.*:.*:.*/ ) {
|
|
|
|
( $kind, $protocol, $port) = split /:/, $kind;
|
|
|
|
$port = "--dport $port";
|
|
|
|
} else {
|
|
|
|
$port = '';
|
|
|
|
( $kind, $protocol ) = split /:/ , $kind if $kind =~ /.*:.*/;
|
|
|
|
}
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
add_rule $inchainref, "-p $protocol $source $port -j ACCEPT";
|
|
|
|
add_rule $outchainref, "-p $protocol $dest $port -j ACCEPT";
|
|
|
|
}
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
sub setup_one_tunnel($$$$) {
|
|
|
|
my ( $kind , $zone, $gateway, $gatewayzones ) = @_;
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-05-05 06:35:55 +02:00
|
|
|
fatal_error "Unknown zone ($zone)" unless $zones{$zone};
|
2007-05-05 02:47:15 +02:00
|
|
|
|
2007-03-30 04:05:11 +02:00
|
|
|
fatal_error "Invalid zone ($zone)" unless $zones{$zone}{type} eq 'ipv4';
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
my $inchainref = ensure_filter_chain "${zone}2${firewall_zone}", 1;
|
|
|
|
my $outchainref = ensure_filter_chain "${firewall_zone}2${zone}", 1;
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
my $source = match_source_net $gateway;
|
|
|
|
my $dest = match_dest_net $gateway;
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
my %tunneltypes = ( 'ipsec' => { function => \&setup_one_ipsec , params => [ $kind, $source, $dest , $gatewayzones ] } ,
|
2007-05-05 01:03:41 +02:00
|
|
|
'ipsecnat' => { function => \&setup_one_ipsec , params => [ $kind, $source, $dest , $gatewayzones ] } ,
|
|
|
|
'ipip' => { function => \&setup_one_other, params => [ $source, $dest , 4 ] } ,
|
|
|
|
'gre' => { function => \&setup_one_other, params => [ $source, $dest , 47 ] } ,
|
|
|
|
'6to4' => { function => \&setup_one_other, params => [ $source, $dest , 41 ] } ,
|
|
|
|
'pptpclient' => { function => \&setup_pptp_client, params => [ $kind, $source, $dest ] } ,
|
|
|
|
'pptpserver' => { function => \&setup_pptp_server, params => [ $kind, $source, $dest ] } ,
|
|
|
|
'openvpn' => { function => \&setup_one_openvpn, params => [ $kind, $source, $dest ] } ,
|
|
|
|
'openvpnclient' => { function => \&setup_one_openvpn_client, params => [ $kind, $source, $dest ] } ,
|
|
|
|
'openvpnserver' => { function => \&setup_one_openvpn_server, params => [ $kind, $source, $dest ] } ,
|
|
|
|
'generic' => { function => \&setup_one_generic , params => [ $kind, $source, $dest ] } ,
|
|
|
|
);
|
2007-03-15 02:15:05 +01:00
|
|
|
|
|
|
|
$kind = "\L$kind";
|
|
|
|
|
|
|
|
(my $type) = split /:/, $kind;
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
my $tunnelref = $tunneltypes{ $type };
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-30 04:05:11 +02:00
|
|
|
fatal_error "Tunnels of type $type are not supported" unless $tunnelref;
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
$tunnelref->{function}->( $inchainref, $outchainref, @{$tunnelref->{params}} );
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
progress_message " Tunnel \"$line\" $done";
|
|
|
|
}
|
2007-03-29 20:57:53 +02:00
|
|
|
|
|
|
|
my $first_entry = 1;
|
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
#
|
|
|
|
# Setup_Tunnels() Starts Here
|
|
|
|
#
|
2007-03-30 17:57:08 +02:00
|
|
|
my $fn = open_file 'tunnels';
|
2007-03-15 02:15:05 +01:00
|
|
|
|
2007-03-29 19:02:13 +02:00
|
|
|
while ( read_a_line ) {
|
2007-03-15 02:15:05 +01:00
|
|
|
|
2007-03-29 20:57:53 +02:00
|
|
|
if ( $first_entry ) {
|
2007-04-08 16:42:26 +02:00
|
|
|
progress_message2 "$doing $fn...";
|
2007-03-29 20:57:53 +02:00
|
|
|
$first_entry = 0;
|
|
|
|
}
|
|
|
|
|
2007-05-10 17:29:41 +02:00
|
|
|
my ( $kind, $zone, $gateway, $gatewayzones ) = split_line1 2, 4, 'tunnels file';
|
2007-05-09 21:03:09 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
if ( $kind eq 'COMMENT' ) {
|
2007-05-09 20:22:40 +02:00
|
|
|
process_comment;
|
2007-03-15 02:15:05 +01:00
|
|
|
} else {
|
|
|
|
setup_one_tunnel $kind, $zone, $gateway, $gatewayzones;
|
|
|
|
}
|
|
|
|
}
|
2007-03-27 01:17:46 +02:00
|
|
|
|
2007-03-15 02:15:05 +01:00
|
|
|
$comment = '';
|
2007-03-27 01:17:46 +02:00
|
|
|
}
|
2007-03-15 02:15:05 +01:00
|
|
|
|
|
|
|
1;
|