summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rwxr-xr-xlib/Vyatta/Zone.pm43
-rw-r--r--scripts/vyatta-zone-ips.pl755
-rw-r--r--templates-cfg/zone-policy/node.def11
-rw-r--r--templates-cfg/zone-policy/zone/node.def36
-rw-r--r--templates-cfg/zone-policy/zone/node.tag/from/node.def28
-rw-r--r--templates-cfg/zone-policy/zone/node.tag/from/node.tag/content-inspection/.ipv6-enable/node.def46
-rw-r--r--templates-cfg/zone-policy/zone/node.tag/from/node.tag/content-inspection/enable/node.def46
-rw-r--r--templates-cfg/zone-policy/zone/node.tag/from/node.tag/content-inspection/node.def1
-rw-r--r--templates-cfg/zone-policy/zone/node.tag/interface/node.def34
-rw-r--r--templates-cfg/zone-policy/zone/node.tag/local-zone/node.def28
11 files changed, 996 insertions, 35 deletions
diff --git a/Makefile.am b/Makefile.am
index 0deeb65..f9a0f4c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3,7 +3,8 @@ opdir = $(datadir)/vyatta-op/templates
share_perl5dir = $(datarootdir)/perl5/Vyatta
bin_sudo_usersdir = $(bindir)/sudo-users
-sbin_SCRIPTS = scripts/vyatta-zone.pl
+sbin_SCRIPTS = scripts/vyatta-zone.pl
+sbin_SCRIPTS += scripts/vyatta-zone-ips.pl
share_perl5_DATA = lib/Vyatta/Zone.pm
diff --git a/lib/Vyatta/Zone.pm b/lib/Vyatta/Zone.pm
index b23bc74..0559753 100755
--- a/lib/Vyatta/Zone.pm
+++ b/lib/Vyatta/Zone.pm
@@ -34,21 +34,33 @@ my $debug="false";
my $syslog="false";
my $logger = 'sudo logger -t zone.pm -p local0.warn --';
+my %script_to_feature_hash = (
+ 'vyatta-zone.pl' => 'ZONE-FW',
+ 'vyatta-zone-ips.pl' => 'ZONE-IPS');
+
sub run_cmd {
my $cmd = shift;
my $error = system("$cmd");
if ($syslog eq "true") {
my $func = (caller(1))[3];
- system("$logger [$func] [$cmd] = [$error]");
+ my $feature = zone_feature((caller(1))[1]);
+ system("$logger [$feature] [$func] [$cmd] = [$error]");
}
if ($debug eq "true") {
my $func = (caller(1))[3];
- print "[$func] [$cmd] = [$error]\n";
+ my $feature = zone_feature((caller(1))[1]);
+ print "[$feature] [$func] [$cmd] = [$error]\n";
}
return $error;
}
+sub zone_feature {
+ my ($script) = @_;
+ $script =~ s/\/opt\/vyatta\/sbin\///;
+ return $script_to_feature_hash{$script};
+}
+
sub is_fwruleset_active {
my ($value_func, $ruleset_type, $fw_ruleset) = @_;
my $config = new Vyatta::Config;
@@ -86,12 +98,25 @@ sub is_local_zone {
return $config->$value_func("zone-policy zone $zone_name local-zone");
}
+sub is_ips_enabled {
+ my ($value_func, $zone_name, $from_zone, $ips_type) = @_;
+ $ips_type =~ s/name/enable/;
+ my $config = new Vyatta::Config;
+ return $config->$value_func("zone-policy zone $zone_name from $from_zone
+ content-inspection $ips_type")
+}
+
sub get_zone_default_policy {
my ($value_func, $zone_name) = @_;
my $config = new Vyatta::Config;
return $config->$value_func("zone-policy zone $zone_name default-action");
}
+sub get_ips_zone_default_policy {
+ my ($value_func, $zone_name) = @_;
+ return 'accept';
+}
+
sub rule_exists {
my ($command, $table, $chain_name, $target, $interface) = @_;
my $cmd =
@@ -107,7 +132,19 @@ sub rule_exists {
sub get_zone_chain {
my ($value_func, $zone, $localout) = @_;
- my $chain = "VZONE_$zone";
+ my $chain_prefix = "VZONE_$zone"; # should be same length as ips_zone_chain
+ return get_zone_chain_name($value_func, $zone, $localout, $chain_prefix);
+}
+
+sub get_ips_zone_chain {
+ my ($value_func, $zone, $localout) = @_;
+ my $chain_prefix = "VZIPS_$zone"; # should be same length as zone_chain
+ return get_zone_chain_name($value_func, $zone, $localout, $chain_prefix);
+}
+
+sub get_zone_chain_name {
+ my ($value_func, $zone, $localout, $chain_prefix) = @_;
+ my $chain = $chain_prefix;
if (defined(is_local_zone($value_func, $zone))) {
# local zone
if (defined $localout) {
diff --git a/scripts/vyatta-zone-ips.pl b/scripts/vyatta-zone-ips.pl
new file mode 100644
index 0000000..0c8e3d1
--- /dev/null
+++ b/scripts/vyatta-zone-ips.pl
@@ -0,0 +1,755 @@
+#!/usr/bin/perl
+#
+# Module: vyatta-zone.pl
+#
+# **** License ****
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 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.
+#
+# This code was originally developed by Vyatta, Inc.
+# Portions created by Vyatta are Copyright (C) 2010 Vyatta, Inc.
+# All Rights Reserved.
+#
+# Author: Mohit Mehta
+# Date: October 2010
+# Description: Script for Zone Based IPS
+#
+# **** End License ****
+#
+
+use Getopt::Long;
+use POSIX;
+
+use lib "/opt/vyatta/share/perl5";
+use Vyatta::Zone;
+use Vyatta::IpTables::Mgr;
+
+use warnings;
+use strict;
+
+# IPS mapping from config node to iptables command. Similar to FW.
+my %cmd_hash = ( 'name' => '/sbin/iptables',
+ 'ipv6-name' => '/sbin/ip6tables');
+
+# IPS mapping from config node to iptables/ip6tables table
+my %table_hash = ( 'name' => 'filter',
+ 'ipv6-name' => 'filter');
+
+# mapping from vyatta 'default-policy' to iptables jump target
+my %policy_hash = ( 'drop' => 'DROP',
+ 'reject' => 'REJECT',
+ 'accept' => 'RETURN');
+
+sub setup_default_policy {
+ my ($zone_name, $default_policy, $localoutchain) = @_;
+ my ($cmd, $error);
+ my $zone_chain=Vyatta::Zone::get_ips_zone_chain("exists",
+ $zone_name, $localoutchain);
+
+ # add default policy for zone chains in filter, ip6filter tables
+ foreach my $tree (keys %cmd_hash) {
+
+ # set default policy for zone chain
+ $cmd = "sudo $cmd_hash{$tree} -t $table_hash{$tree} -A " .
+ "$zone_chain -j $policy_hash{$default_policy}";
+ $error = Vyatta::Zone::run_cmd("$cmd");
+ return "Error: set default policy $zone_chain failed [$error]" if $error;
+
+ my $rule_cnt = Vyatta::IpTables::Mgr::count_iptables_rules($cmd_hash{$tree},
+ $table_hash{$tree}, $zone_chain);
+
+ # If there's a return all rule at rule_cnt - 1 then remove that.
+ # In IPS zone chain a return all target can only be for default policy
+ if ($rule_cnt > 1) {
+ my $in_intf = '$6';
+ # set IPv6 params if using ip6tables
+ if ($cmd_hash{$tree} =~ '6') {
+ $in_intf = '$5';
+ }
+ my $penultimate_rule_num=$rule_cnt-1;
+ $cmd = "sudo $cmd_hash{$tree} -t $table_hash{$tree} " .
+ "-L $zone_chain $penultimate_rule_num -v " .
+ "| awk {'print \$3\" \"$in_intf'}";
+ my $target=`$cmd`;
+ chomp $target;
+ if (defined $target && ($target eq 'RETURN any')) {
+ $cmd = "sudo $cmd_hash{$tree} -t $table_hash{$tree} -D " .
+ "$zone_chain $penultimate_rule_num";
+ $error = Vyatta::Zone::run_cmd("$cmd");
+ return "Error: delete rule $penultimate_rule_num with $target
+in $zone_name chain failed [$error]" if $error;
+ }
+ }
+ }
+ return;
+}
+
+sub create_zone_chain {
+ my ($zone_name, $localoutchain) = @_;
+ my ($cmd, $error);
+ my $zone_chain=Vyatta::Zone::get_ips_zone_chain("exists",
+ $zone_name, $localoutchain);
+
+ # create zone chains in filter, ip6filter tables
+ foreach my $tree (keys %cmd_hash) {
+ $cmd = "sudo $cmd_hash{$tree} -t $table_hash{$tree} " .
+ "-L $zone_chain >&/dev/null";
+ $error = Vyatta::Zone::run_cmd($cmd);
+ if ($error) {
+ # chain does not exist, go ahead create it
+ $cmd = "sudo $cmd_hash{$tree} -t $table_hash{$tree} -N $zone_chain";
+ $error = Vyatta::Zone::run_cmd($cmd);
+ return "Error: create $zone_name chain with failed [$error]" if $error;
+ }
+ }
+
+ return;
+}
+
+sub delete_zone_chain {
+ my ($zone_name, $localoutchain) = @_;
+ my ($cmd, $error);
+ my $zone_chain=Vyatta::Zone::get_ips_zone_chain("existsOrig",
+ $zone_name, $localoutchain);
+ # delete zone chains from filter, ip6filter tables
+ foreach my $tree (keys %cmd_hash) {
+ # flush all rules from zone chain
+ $cmd = "sudo $cmd_hash{$tree} -t $table_hash{$tree} -F $zone_chain";
+ $error = Vyatta::Zone::run_cmd($cmd);
+ return "Error: flush all rules in $zone_name chain failed [$error]" if $error;
+
+ # delete zone chain
+ $cmd = "sudo $cmd_hash{$tree} -t $table_hash{$tree} -X $zone_chain";
+ $error = Vyatta::Zone::run_cmd($cmd);
+ return "Error: delete $zone_name chain failed [$error]" if $error;
+ }
+ return;
+}
+
+sub insert_from_rule {
+ my ($zone_name, $from_zone, $interface, $ruleset_type, $ruleset,
+ $direction, $zone_chain) = @_;
+ my ($cmd, $error);
+ my $ruleset_name;
+
+ if (defined $ruleset) { # called from node.def
+ $ruleset_name=$ruleset;
+ } else { # called from do_ips_interface_zone()
+ $ruleset_name = 'VYATTA_SNORT_all_HOOK' if defined
+ Vyatta::Zone::is_ips_enabled("exists",
+ $zone_name, $from_zone, $ruleset_type);
+ }
+
+ if (defined $ruleset_name) {
+ # get number of rules in ruleset_name
+ my $rule_cnt = Vyatta::IpTables::Mgr::count_iptables_rules($cmd_hash{$ruleset_type},
+ $table_hash{$ruleset_type}, "$zone_chain");
+ # append rule before last RETURN all rule
+ my $insert_at_rule_num=1;
+ if ( $rule_cnt > 1 ) {
+ $insert_at_rule_num=$rule_cnt;
+ }
+ my $result = Vyatta::Zone::rule_exists ($cmd_hash{$ruleset_type},
+ $table_hash{$ruleset_type}, "$zone_chain", $ruleset_name, $interface);
+ if ($result < 1) {
+ # append rule before RETURN rule to jump to ruleset for in\out interface
+ $cmd = "sudo $cmd_hash{$ruleset_type} -t $table_hash{$ruleset_type} " .
+"-I $zone_chain $insert_at_rule_num $direction $interface -j $ruleset_name";
+ $error = Vyatta::Zone::run_cmd($cmd);
+ return "Error: insert rule for $direction $interface into zone-chain
+$zone_chain with target $ruleset_name failed [$error]" if $error;
+
+ }
+ }
+
+ return;
+}
+
+
+sub add_fromzone_intf_ruleset {
+ my ($zone_name, $from_zone, $interface, $ruleset_type, $ruleset) = @_;
+ my $zone_chain=Vyatta::Zone::get_ips_zone_chain("exists", $zone_name);
+ my $error = insert_from_rule ($zone_name, $from_zone, $interface,
+ $ruleset_type, $ruleset, '-i', $zone_chain);
+ return ($error, ) if $error;
+ return;
+}
+
+sub add_fromlocalzone_ruleset {
+ my ($zone_name, $from_zone, $interface, $ruleset_type, $ruleset) = @_;
+ my $zone_chain=Vyatta::Zone::get_ips_zone_chain("exists", $from_zone, "localout");
+
+ my $error = insert_from_rule ($zone_name, $from_zone, $interface,
+ $ruleset_type, $ruleset, '-o', $zone_chain);
+ return ($error, ) if $error;
+
+ return;
+}
+
+sub delete_from_rule {
+
+ my ($zone_name, $from_zone, $interface, $ruleset_type, $ruleset,
+ $direction, $zone_chain) = @_;
+ my ($cmd, $error);
+ my $ruleset_name;
+
+ if (defined $ruleset) { # called from node.def
+ $ruleset_name=$ruleset;
+ } else { # called from undo_ips_interface_zone()
+ $ruleset_name = 'VYATTA_SNORT_all_HOOK' if defined
+ Vyatta::Zone::is_ips_enabled("exists",
+ $zone_name, $from_zone, $ruleset_type);
+ }
+
+ if (defined $ruleset_name) {
+ # delete rule to jump to ruleset for in|out interface in zone chain
+ $cmd = "sudo $cmd_hash{$ruleset_type} -t $table_hash{$ruleset_type} " .
+ "-D $zone_chain $direction $interface -j $ruleset_name";
+ $error = Vyatta::Zone::run_cmd($cmd);
+ return "Error: call to delete rule for $direction $interface
+in zone chain $zone_chain with target $ruleset_name failed [$error]" if $error;
+ }
+
+ return;
+}
+
+sub delete_fromzone_intf_ruleset {
+ my ($zone_name, $from_zone, $interface, $ruleset_type, $ruleset) = @_;
+ my $zone_chain=Vyatta::Zone::get_ips_zone_chain("existsOrig", $zone_name);
+ my $error = delete_from_rule ($zone_name, $from_zone, $interface,
+ $ruleset_type, $ruleset, '-i', $zone_chain);
+ return ($error, ) if $error;
+ return;
+}
+
+sub delete_fromlocalzone_ruleset {
+ my ($zone_name, $from_zone, $interface, $ruleset_type, $ruleset) = @_;
+ my $zone_chain=Vyatta::Zone::get_ips_zone_chain("existsOrig",
+ $from_zone, "localout");
+
+ my ($cmd, $error);
+ $error = delete_from_rule ($zone_name, $from_zone, $interface,
+ $ruleset_type, $ruleset, '-o', $zone_chain);
+ return ($error, ) if $error;
+
+ return;
+}
+
+sub do_ips_interface_zone {
+ my ($zone_name, $interface) = @_;
+ my $zone_chain=Vyatta::Zone::get_ips_zone_chain("exists", $zone_name);
+ my ($cmd, $error);
+ foreach my $tree (keys %cmd_hash) {
+
+ my $result = Vyatta::Zone::rule_exists ($cmd_hash{$tree},
+ $table_hash{$tree}, "$zone_chain", "RETURN", $interface);
+ if ($result < 1) {
+ # add rule to allow same zone to same zone traffic
+ $cmd = "sudo $cmd_hash{$tree} -t $table_hash{$tree} -I $zone_chain " .
+ "-i $interface -j RETURN";
+ $error = Vyatta::Zone::run_cmd($cmd);
+ return "Error: call to add $interface to its zone-chain $zone_chain
+failed [$error]" if $error;
+ }
+
+ # need to do this as an append before ACCEPT rule at the end
+ my $rule_cnt = Vyatta::IpTables::Mgr::count_iptables_rules($cmd_hash{$tree},
+ $table_hash{$tree}, "VYATTA_POST_FW_FWD_HOOK");
+ my $insert_at_rule_num=1;
+ if ( $rule_cnt > 1 ) {
+ $insert_at_rule_num=$rule_cnt;
+ }
+ $result = Vyatta::Zone::rule_exists ($cmd_hash{$tree}, $table_hash{$tree},
+ "VYATTA_POST_FW_FWD_HOOK", "$zone_chain", $interface);
+ if ($result < 1) {
+ $cmd = "sudo $cmd_hash{$tree} -t $table_hash{$tree} -I VYATTA_POST_FW_FWD_HOOK " .
+ "$insert_at_rule_num -o $interface -j $zone_chain";
+ $error = Vyatta::Zone::run_cmd($cmd);
+ return "Error: call to add jump rule for outgoing interface $interface
+to its $zone_chain chain failed [$error]" if $error;
+ }
+ }
+
+ # get all zones in which this zone is being used as a from zone
+ # then in chains for those zones, add rules for this incoming interface
+ my @all_zones = Vyatta::Zone::get_all_zones("listNodes");
+ foreach my $zone (@all_zones) {
+ if (!($zone eq $zone_name)) {
+ my @from_zones = Vyatta::Zone::get_from_zones("listEffectiveNodes",
+ $zone);
+ if (scalar(grep(/^$zone_name$/, @from_zones)) > 0) {
+ foreach my $tree (keys %cmd_hash) {
+ # call function to append rules to $zone's chain
+ $error = add_fromzone_intf_ruleset($zone, $zone_name,
+ $interface, $tree);
+ return "Error: $error" if $error;
+ }
+ }
+ }
+ }
+
+ # if this zone has a local from zone, add interface to local zone out chain
+ my @my_from_zones = Vyatta::Zone::get_from_zones("listEffectiveNodes",
+ $zone_name);
+ foreach my $fromzone (@my_from_zones) {
+ if (defined(Vyatta::Zone::is_local_zone("exists", $fromzone))) {
+ foreach my $tree (keys %cmd_hash) {
+ $error = add_fromlocalzone_ruleset($zone_name, $fromzone,
+ $interface, $tree);
+ return "Error: $error" if $error;
+ }
+ }
+ }
+
+ return;
+}
+
+sub undo_ips_interface_zone {
+ my ($zone_name, $interface) = @_;
+ my ($cmd, $error);
+ my $zone_chain=Vyatta::Zone::get_ips_zone_chain("existsOrig", $zone_name);
+
+ foreach my $tree (keys %cmd_hash) {
+
+ # delete rule to allow same zone to same zone traffic
+ $cmd = "sudo $cmd_hash{$tree} -t $table_hash{$tree} -D VYATTA_POST_FW_FWD_HOOK " .
+ "-o $interface -j $zone_chain";
+ $error = Vyatta::Zone::run_cmd($cmd);
+ return "Error: call to delete jump rule for outgoing interface $interface
+to $zone_chain chain failed [$error]" if $error;
+
+ # delete ruleset jump for this in interface
+ $cmd = "sudo $cmd_hash{$tree} -t $table_hash{$tree} -D $zone_chain " .
+ "-i $interface -j RETURN";
+ $error = Vyatta::Zone::run_cmd($cmd);
+ return "Error: call to delete interface $interface from zone-chain
+$zone_chain with failed [$error]" if $error;
+ }
+
+ # delete rules for this intf where this zone is being used as a from zone
+ my @all_zones = Vyatta::Zone::get_all_zones("listOrigNodes");
+ foreach my $zone (@all_zones) {
+ if (!($zone eq $zone_name)) {
+ my @from_zones = Vyatta::Zone::get_from_zones("listEffectiveNodes",
+ $zone);
+ if (scalar(grep(/^$zone_name$/, @from_zones)) > 0) {
+ foreach my $tree (keys %cmd_hash) {
+ # call function to delete rules from $zone's chain
+ $error = delete_fromzone_intf_ruleset($zone, $zone_name,
+ $interface, $tree);
+ return "Error: $error" if $error;
+ }
+ }
+ }
+ }
+
+ # if you have local from zone, delete interface to local zone out chain
+ my @my_from_zones = Vyatta::Zone::get_from_zones("listEffectiveNodes",
+ $zone_name);
+ foreach my $fromzone (@my_from_zones) {
+ if (defined(Vyatta::Zone::is_local_zone("existsOrig", $fromzone))) {
+ foreach my $tree (keys %cmd_hash) {
+ $error = delete_fromlocalzone_ruleset($zone_name, $fromzone,
+ $interface, $tree);
+ return "Error: $error" if $error;
+ }
+ }
+ }
+
+ return;
+}
+
+sub do_ips_localzone {
+ my ($zone_name) = @_;
+ my ($cmd, $error);
+ my $zone_chain=Vyatta::Zone::get_ips_zone_chain("exists", $zone_name);
+ foreach my $tree (keys %cmd_hash) {
+
+ my $rule_cnt = Vyatta::IpTables::Mgr::count_iptables_rules($cmd_hash{$tree},
+ $table_hash{$tree}, "VYATTA_POST_FW_IN_HOOK");
+ my $insert_at_rule_num=1;
+ if ( $rule_cnt > 1 ) {
+ $insert_at_rule_num=$rule_cnt;
+ }
+ my $result = Vyatta::Zone::rule_exists ($cmd_hash{$tree},
+ $table_hash{$tree}, "VYATTA_POST_FW_IN_HOOK", $zone_chain);
+
+ if ($result < 1) {
+ # insert rule to filter local traffic from interface per ruleset
+ $cmd = "sudo $cmd_hash{$tree} -t $table_hash{$tree} -I " .
+ "VYATTA_POST_FW_IN_HOOK $insert_at_rule_num -j $zone_chain";
+ $error = Vyatta::Zone::run_cmd($cmd);
+ return "Error: call to add jump rule for local zone
+$zone_chain chain failed [$error]" if $error;
+ }
+ }
+
+ # get all zones in which local zone is being used as a from zone
+ # filter traffic from local zone to those zones
+ my @all_zones = Vyatta::Zone::get_all_zones("listNodes");
+ foreach my $zone (@all_zones) {
+ if (!($zone eq $zone_name)) {
+ my @from_zones = Vyatta::Zone::get_from_zones("listEffectiveNodes",
+ $zone);
+ if (scalar(grep(/^$zone_name$/, @from_zones)) > 0) {
+ foreach my $tree (keys %cmd_hash) {
+ my @zone_interfaces =
+ Vyatta::Zone::get_zone_interfaces("returnValues", $zone);
+ foreach my $intf (@zone_interfaces) {
+ $error = add_fromlocalzone_ruleset($zone, $zone_name,
+ $intf, $tree);
+ return "Error: $error" if $error;
+ }
+ }
+ }
+ }
+ }
+ return;
+}
+
+sub undo_ips_localzone {
+ my ($zone_name) = @_;
+ my ($cmd, $error);
+ my $zone_chain=Vyatta::Zone::get_ips_zone_chain("existsOrig", $zone_name);
+
+ foreach my $tree (keys %cmd_hash) {
+
+ # delete rule to filter traffic destined for system
+ $cmd = "sudo $cmd_hash{$tree} -t $table_hash{$tree} -D " .
+ "VYATTA_POST_FW_IN_HOOK -j $zone_chain";
+ $error = Vyatta::Zone::run_cmd($cmd);
+ return "Error: call to delete local zone
+$zone_chain chain failed [$error]" if $error;
+ }
+
+ # get all zones in which local zone is being used as a from zone
+ # remove filter for traffic from local zone to those zones
+ my @all_zones = Vyatta::Zone::get_all_zones("listOrigNodes");
+ foreach my $zone (@all_zones) {
+ if (!($zone eq $zone_name)) {
+ my @from_zones = Vyatta::Zone::get_from_zones("listEffectiveNodes",
+ $zone);
+ if (scalar(grep(/^$zone_name$/, @from_zones)) > 0) {
+ foreach my $tree (keys %cmd_hash) {
+ my @zone_interfaces =
+ Vyatta::Zone::get_zone_interfaces("returnOrigValues", $zone);
+ foreach my $intf (@zone_interfaces) {
+ $error = delete_fromlocalzone_ruleset($zone, $zone_name,
+ $intf, $tree);
+ return "Error: $error" if $error;
+ }
+ }
+ }
+ }
+ }
+ return;
+}
+
+sub add_zone {
+ my $zone_name = shift;
+ # perform IPS related actions for this zone
+ my $error = create_zone_chain ($zone_name);
+ return ($error, ) if $error;
+
+ if (defined(Vyatta::Zone::is_local_zone("exists", $zone_name))) {
+ # make local out chain as well
+ $error = create_zone_chain ($zone_name, "localout");
+ return ($error, ) if $error;
+
+ # allow traffic sourced from and destined to localhost
+ my $cmd;
+ my @localchains=();
+ $localchains[0] = Vyatta::Zone::get_ips_zone_chain("exists", $zone_name);
+ $localchains[1] = Vyatta::Zone::get_ips_zone_chain("exists", $zone_name,
+ 'localout');
+
+ foreach my $tree (keys %cmd_hash) {
+ foreach my $chain (@localchains) {
+ my $loopback_intf = '';
+ if ($chain =~ m/_IN/) {
+
+ # if the chain is INPUT chain
+ $loopback_intf = '$6';
+
+ # set IPv6 params if using ip6tables
+ if ($cmd_hash{$tree} =~ '6') {
+ $loopback_intf = '$5';
+ }
+
+ } else {
+
+ # if the chain is OUTPUT chain
+ $loopback_intf = '$7';
+
+ # set IPv6 params if using ip6tables
+ if ($cmd_hash{$tree} =~ '6') {
+ $loopback_intf = '$6';
+ }
+
+ }
+
+ $cmd = "sudo $cmd_hash{$tree} -t $table_hash{$tree} -L $chain 1 -vn " .
+ "| awk {'print \$3 \" \" $loopback_intf'} ".
+ "| grep 'RETURN lo\$' | wc -l";
+
+ my $result=`$cmd`;
+ if ($result < 1) {
+
+ $cmd = "sudo $cmd_hash{$tree} -t $table_hash{$tree} -I $chain ";
+
+ if ($chain =~ m/_IN/) {
+
+ # rule for INPUT chain
+ $cmd .= "-i lo -j RETURN";
+
+ } else {
+
+ # rule for OUTPUT chain
+ $cmd .= "-o lo -j RETURN";
+
+ }
+
+ $error = Vyatta::Zone::run_cmd($cmd);
+ return "Error: adding rule to allow localhost traffic failed [$error]" if $error;
+
+ }
+ }
+ }
+
+ }
+
+ # set default policy
+ my $default_policy = Vyatta::Zone::get_ips_zone_default_policy("returnValue",
+ $zone_name);
+ $error = set_default_policy($zone_name, $default_policy);
+ return $error if $error;
+
+ return;
+}
+
+sub delete_zone {
+ my $zone_name = shift;
+ # undo IPS related actions for this zone
+ my $error = delete_zone_chain ($zone_name);
+ return ($error, ) if $error;
+ if (defined(Vyatta::Zone::is_local_zone("existsOrig", $zone_name))) {
+ # delete local out chain as well
+ $error = delete_zone_chain ($zone_name, "localout");
+ return ($error, ) if $error;
+ }
+ return;
+}
+
+sub add_localzone {
+ my ($zone_name) = @_;
+ my $error;
+ # do IPS related stuff
+ $error = do_ips_localzone ($zone_name);
+ return ($error, ) if $error;
+ return;
+}
+
+sub delete_localzone {
+ my ($zone_name) = @_;
+ my $error;
+ # undo IPS related stuff
+ $error = undo_ips_localzone ($zone_name);
+ return ($error, ) if $error;
+ return;
+}
+
+sub add_zone_interface {
+ my ($zone_name, $interface) = @_;
+ return("Error: undefined interface", ) if ! defined $interface;
+ my $error;
+ # do IPS related stuff
+ $error = do_ips_interface_zone ($zone_name, $interface);
+ return ($error, ) if $error;
+ return;
+}
+
+sub delete_zone_interface {
+ my ($zone_name, $interface) = @_;
+ return("Error: undefined interface", ) if ! defined $interface;
+ # undo IPS related stuff
+ my $error = undo_ips_interface_zone ($zone_name, $interface);
+ return ($error, ) if $error;
+ return;
+}
+
+sub add_fromzone_ips {
+ my ($zone, $from_zone, $ruleset_type, $ruleset_name) = @_;
+ my ($cmd, $error);
+
+ # for all interfaces in from zone apply ruleset to filter traffic
+ # from this zone to specified zone (i.e. $zone)
+ my @from_zone_interfaces =
+ Vyatta::Zone::get_zone_interfaces("returnValues", $from_zone);
+ if (scalar(@from_zone_interfaces) > 0) {
+ foreach my $intf (@from_zone_interfaces) {
+ $error = add_fromzone_intf_ruleset($zone, $from_zone, $intf,
+ $ruleset_type, $ruleset_name);
+ return "Error: $error" if $error;
+ }
+ } else {
+ if (defined(Vyatta::Zone::is_local_zone("exists", $from_zone))) {
+ # local from zone
+ my @zone_interfaces =
+ Vyatta::Zone::get_zone_interfaces("returnValues", $zone);
+ foreach my $intf (@zone_interfaces) {
+ $error = add_fromlocalzone_ruleset($zone, $from_zone, $intf,
+ $ruleset_type, $ruleset_name);
+ return "Error: $error" if $error;
+ }
+ }
+
+ my $zone_chain=Vyatta::Zone::get_ips_zone_chain("exists",
+ $from_zone, 'localout');
+ # add jump to local-zone-out chain in OUTPUT chains for [ip and ip6]tables
+ foreach my $tree (keys %cmd_hash) {
+ # if jump to localzoneout chain not inserted, then insert rule
+ my $rule_cnt = Vyatta::IpTables::Mgr::count_iptables_rules($cmd_hash{$tree},
+ $table_hash{$tree}, "VYATTA_POST_FW_OUT_HOOK");
+ my $insert_at_rule_num=1;
+ if ( $rule_cnt > 1 ) {
+ $insert_at_rule_num=$rule_cnt;
+ }
+ my $result = Vyatta::Zone::rule_exists ($cmd_hash{$tree},
+ $table_hash{$tree}, "VYATTA_POST_FW_OUT_HOOK", $zone_chain);
+ if ($result < 1) {
+ my $cmd = "sudo $cmd_hash{$tree} -t $table_hash{$tree} " .
+ "-I VYATTA_POST_FW_OUT_HOOK $insert_at_rule_num -j $zone_chain";
+ $error = Vyatta::Zone::run_cmd($cmd);
+ return "Error: call to add jump rule for local zone out
+$zone_chain chain failed [$error]" if $error;
+ }
+ }
+
+ } # end of else
+
+ return;
+}
+
+sub delete_fromzone_ips {
+ my ($zone, $from_zone, $ruleset_type, $ruleset_name) = @_;
+ my ($cmd, $error);
+
+ # for all interfaces in from zone remove ruleset to filter traffic
+ # from this zone to specified zone (i.e. $zone)
+ my @from_zone_interfaces =
+ Vyatta::Zone::get_zone_interfaces("returnOrigValues", $from_zone);
+ if (scalar(@from_zone_interfaces) > 0) {
+ foreach my $intf (@from_zone_interfaces) {
+ $error = delete_fromzone_intf_ruleset($zone, $from_zone, $intf,
+ $ruleset_type, $ruleset_name);
+ return "Error: $error" if $error;
+ }
+ } else {
+ if (defined(Vyatta::Zone::is_local_zone("existsOrig", $from_zone))) {
+ # local from zone
+ my @zone_interfaces =
+ Vyatta::Zone::get_zone_interfaces("returnOrigValues", $zone);
+ foreach my $intf (@zone_interfaces) {
+ $error = delete_fromlocalzone_ruleset($zone, $from_zone, $intf,
+ $ruleset_type, $ruleset_name);
+ return "Error: $error" if $error;
+ }
+ }
+
+ my $zone_chain=Vyatta::Zone::get_ips_zone_chain("existsOrig",
+ $from_zone, 'localout');
+ # if only RETURN rule & localhost allow rule in $zone_chain in both
+ # [ip and ip6]tables then delete jump from OUTPUT chain in both
+ foreach my $tree (keys %cmd_hash) {
+ my $rule_cnt = Vyatta::IpTables::Mgr::count_iptables_rules($cmd_hash{$tree},
+ $table_hash{$tree}, $zone_chain);
+ if ($rule_cnt > 2) {
+ # atleast one of [ip or ip6]tables has local-zone as a from zone
+ return;
+ }
+ }
+
+ foreach my $tree (keys %cmd_hash) {
+ $cmd = "sudo $cmd_hash{$tree} -t $table_hash{$tree} " .
+ "-D VYATTA_POST_FW_OUT_HOOK -j $zone_chain";
+ $error = Vyatta::Zone::run_cmd($cmd);
+ return "Error: call to delete jump rule for local zone out
+$zone_chain chain failed [$error]" if $error;
+ }
+
+ } # end of else
+ return;
+}
+
+sub set_default_policy {
+ my ($zone, $default_policy) = @_;
+ # setup default policy for zone
+ my $error = setup_default_policy ($zone, $default_policy);
+ return ($error, ) if $error;
+ if (defined(Vyatta::Zone::is_local_zone("exists", $zone))) {
+ # set default policy for local out chain as well
+ $error = setup_default_policy ($zone, $default_policy, "localout");
+ return ($error, ) if $error;
+ }
+ return;
+}
+
+#
+# main
+#
+
+my ($action, $zone_name, $interface, $from_zone, $ruleset_type, $ruleset_name);
+
+GetOptions("action=s" => \$action,
+ "zone-name=s" => \$zone_name,
+ "interface=s" => \$interface,
+ "from-zone=s" => \$from_zone,
+ "ruleset-type=s" => \$ruleset_type,
+ "ruleset-name=s" => \$ruleset_name,
+);
+
+die "undefined action" if ! defined $action;
+die "undefined zone" if ! defined $zone_name;
+
+my ($error, $warning);
+
+($error, $warning) = add_zone($zone_name) if $action eq 'add-zone';
+
+($error, $warning) = delete_zone($zone_name) if $action eq 'delete-zone';
+
+($error, $warning) = add_zone_interface($zone_name, $interface)
+ if $action eq 'add-zone-interface';
+
+($error, $warning) = delete_zone_interface($zone_name, $interface)
+ if $action eq 'delete-zone-interface';
+
+($error, $warning) = add_fromzone_ips($zone_name, $from_zone, $ruleset_type,
+ $ruleset_name) if $action eq 'add-fromzone-ips';
+
+($error, $warning) = delete_fromzone_ips($zone_name, $from_zone, $ruleset_type,
+ $ruleset_name) if $action eq 'delete-fromzone-ips';
+
+($error, $warning) = add_localzone($zone_name)
+ if $action eq 'add-localzone';
+
+($error, $warning) = delete_localzone($zone_name)
+ if $action eq 'delete-localzone';
+
+if (defined $warning) {
+ print "$warning\n";
+}
+
+if (defined $error) {
+ print "$error\n";
+ exit 1;
+}
+
+exit 0;
+
+# end of file
diff --git a/templates-cfg/zone-policy/node.def b/templates-cfg/zone-policy/node.def
index 440d397..52a6b68 100644
--- a/templates-cfg/zone-policy/node.def
+++ b/templates-cfg/zone-policy/node.def
@@ -1,6 +1,11 @@
priority: 250 # after zone-policy/zone/node.tag/from/
+
help: Configure zone-policy
-begin:
-if ! /opt/vyatta/sbin/vyatta-zone.pl --action=validity-checks --zone-name=none --silent-validate=false; then
- exit 1
+
+begin:
+if ! /opt/vyatta/sbin/vyatta-zone.pl \
+ --action=validity-checks \
+ --zone-name=none \
+ --silent-validate=false; then
+ exit 1
fi
diff --git a/templates-cfg/zone-policy/zone/node.def b/templates-cfg/zone-policy/zone/node.def
index eb8c3c8..56c09c2 100644
--- a/templates-cfg/zone-policy/zone/node.def
+++ b/templates-cfg/zone-policy/zone/node.def
@@ -10,15 +10,31 @@ syntax:expression: pattern $VAR(@) "^[^-]" ; "Zone name cannot start with \"-\""
syntax:expression: pattern $VAR(@) "^[^;]*$" ; "Zone name cannot contain ';'"
create:
- if ! /opt/vyatta/sbin/vyatta-zone.pl \
- --action=add-zone \
- --zone-name="$VAR(@)"; then
- exit 1
- fi
+ # fw zone actions
+ if ! /opt/vyatta/sbin/vyatta-zone.pl \
+ --action=add-zone \
+ --zone-name="$VAR(@)"; then
+ exit 1
+ fi
+
+ # ips zone actions
+ if ! /opt/vyatta/sbin/vyatta-zone-ips.pl \
+ --action=add-zone \
+ --zone-name="$VAR(@)"; then
+ exit 1
+ fi
delete:
- if ! /opt/vyatta/sbin/vyatta-zone.pl \
- --action=delete-zone \
- --zone-name="$VAR(@)"; then
- exit 1
- fi
+ # fw zone actions
+ if ! /opt/vyatta/sbin/vyatta-zone.pl \
+ --action=delete-zone \
+ --zone-name="$VAR(@)"; then
+ exit 1
+ fi
+
+ # ips zone actions
+ if ! /opt/vyatta/sbin/vyatta-zone-ips.pl \
+ --action=delete-zone \
+ --zone-name="$VAR(@)"; then
+ exit 1
+ fi
diff --git a/templates-cfg/zone-policy/zone/node.tag/from/node.def b/templates-cfg/zone-policy/zone/node.tag/from/node.def
index 433f423..62cd3cb 100644
--- a/templates-cfg/zone-policy/zone/node.tag/from/node.def
+++ b/templates-cfg/zone-policy/zone/node.tag/from/node.def
@@ -9,8 +9,11 @@ allowed:
echo -n "${zones[@]}"
begin:
-if ! /opt/vyatta/sbin/vyatta-zone.pl --action=validity-checks --zone-name=none --silent-validate=true; then
- exit 1
+if ! /opt/vyatta/sbin/vyatta-zone.pl \
+ --action=validity-checks \
+ --zone-name=none \
+ --silent-validate=true; then
+ exit 1
fi
create:
@@ -33,10 +36,27 @@ create:
echo Undefined from zone [$VAR(@)] under zone $parent_zone
exit 1
else
- if ! /opt/vyatta/sbin/vyatta-zone.pl --action=add-zone --zone-name="$parent_zone"; then
+ # fw zone actions
+ if ! /opt/vyatta/sbin/vyatta-zone.pl \
+ --action=add-zone \
+ --zone-name="$parent_zone"; then
+ exit 1
+ fi
+ if ! /opt/vyatta/sbin/vyatta-zone.pl \
+ --action=add-zone \
+ --zone-name="$VAR(@)"; then
+ exit 1
+ fi
+
+ # ips zone actions
+ if ! /opt/vyatta/sbin/vyatta-zone-ips.pl \
+ --action=add-zone \
+ --zone-name="$parent_zone"; then
exit 1
fi
- if ! /opt/vyatta/sbin/vyatta-zone.pl --action=add-zone --zone-name="$VAR(@)"; then
+ if ! /opt/vyatta/sbin/vyatta-zone-ips.pl \
+ --action=add-zone \
+ --zone-name="$VAR(@)"; then
exit 1
fi
fi
diff --git a/templates-cfg/zone-policy/zone/node.tag/from/node.tag/content-inspection/.ipv6-enable/node.def b/templates-cfg/zone-policy/zone/node.tag/from/node.tag/content-inspection/.ipv6-enable/node.def
new file mode 100644
index 0000000..87a2ea1
--- /dev/null
+++ b/templates-cfg/zone-policy/zone/node.tag/from/node.tag/content-inspection/.ipv6-enable/node.def
@@ -0,0 +1,46 @@
+help: Option to enable IPv6 content-inspection
+
+# check if traffic-filter is set
+commit:expression:
+exec "
+if cli-shell-api existsEffective \
+content-inspection traffic-filter ipv6-preset; then \
+ exit 0; \
+fi; \
+if cli-shell-api existsEffective \
+content-inspection traffic-filter ipv6-custom; then \
+ exit 0; \
+fi; \
+echo IPv6 content-inspection traffic-filter not set; \
+exit 1"
+
+# make sure inspect-all is not enabled
+commit:expression:
+exec "
+if ! cli-shell-api existsEffective \
+content-inspection inspect-all ipv6-enable; then \
+ exit 0; \
+fi; \
+echo IPv6 content-inspection enabled for all traffic. Not \
+allowed to configure inspection on a per-zone basis.; \
+exit 1"
+
+create:
+ if ! /opt/vyatta/sbin/vyatta-zone-ips.pl \
+ --action=add-fromzone-ips \
+ --zone-name="$VAR(../../../@)" \
+ --from-zone="$VAR(../../@)" \
+ --ruleset-type=ipv6-name \
+ --ruleset-name=VYATTA_SNORT_all_HOOK; then
+ exit 1
+ fi
+
+delete:
+ if ! /opt/vyatta/sbin/vyatta-zone-ips.pl \
+ --action=delete-fromzone-ips \
+ --zone-name="$VAR(../../../@)" \
+ --from-zone="$VAR(../../@)" \
+ --ruleset-type=ipv6-name \
+ --ruleset-name=VYATTA_SNORT_all_HOOK; then
+ exit 1
+ fi
diff --git a/templates-cfg/zone-policy/zone/node.tag/from/node.tag/content-inspection/enable/node.def b/templates-cfg/zone-policy/zone/node.tag/from/node.tag/content-inspection/enable/node.def
new file mode 100644
index 0000000..484780a
--- /dev/null
+++ b/templates-cfg/zone-policy/zone/node.tag/from/node.tag/content-inspection/enable/node.def
@@ -0,0 +1,46 @@
+help: Option to enable IPv4 content-inspection
+
+# check if traffic-filter is set
+commit:expression:
+exec "
+if cli-shell-api existsEffective \
+content-inspection traffic-filter preset; then \
+ exit 0; \
+fi; \
+if cli-shell-api existsEffective \
+content-inspection traffic-filter custom; then \
+ exit 0; \
+fi; \
+echo IPv4 content-inspection traffic-filter not set; \
+exit 1"
+
+# make sure inspect-all is not enabled
+commit:expression:
+exec "
+if ! cli-shell-api existsEffective \
+content-inspection inspect-all enable; then \
+ exit 0; \
+fi; \
+echo IPv4 content-inspection enabled for all traffic. Not \
+allowed to configure inspection on a per-zone basis.; \
+exit 1"
+
+create:
+ if ! /opt/vyatta/sbin/vyatta-zone-ips.pl \
+ --action=add-fromzone-ips \
+ --zone-name="$VAR(../../../@)" \
+ --from-zone="$VAR(../../@)" \
+ --ruleset-type=name \
+ --ruleset-name=VYATTA_SNORT_all_HOOK; then
+ exit 1
+ fi
+
+delete:
+ if ! /opt/vyatta/sbin/vyatta-zone-ips.pl \
+ --action=delete-fromzone-ips \
+ --zone-name="$VAR(../../../@)" \
+ --from-zone="$VAR(../../@)" \
+ --ruleset-type=name \
+ --ruleset-name=VYATTA_SNORT_all_HOOK; then
+ exit 1
+ fi
diff --git a/templates-cfg/zone-policy/zone/node.tag/from/node.tag/content-inspection/node.def b/templates-cfg/zone-policy/zone/node.tag/from/node.tag/content-inspection/node.def
new file mode 100644
index 0000000..9ba25ef
--- /dev/null
+++ b/templates-cfg/zone-policy/zone/node.tag/from/node.tag/content-inspection/node.def
@@ -0,0 +1 @@
+help: Content-inspection options
diff --git a/templates-cfg/zone-policy/zone/node.tag/interface/node.def b/templates-cfg/zone-policy/zone/node.tag/interface/node.def
index 36ff3e2..c9137c4 100644
--- a/templates-cfg/zone-policy/zone/node.tag/interface/node.def
+++ b/templates-cfg/zone-policy/zone/node.tag/interface/node.def
@@ -8,17 +8,35 @@ syntax:expression: $VAR(@) != "lo" ; "Cannot assign loopback interface to a tran
create: /opt/vyatta/sbin/vyatta-interfaces.pl --dev=$VAR(@) --warn
create:
- if ! /opt/vyatta/sbin/vyatta-zone.pl \
- --action=add-zone-interface \
- --zone-name="$VAR(../@)" \
- --interface="$VAR(@)"; then
+ # fw zone actions
+ if ! /opt/vyatta/sbin/vyatta-zone.pl \
+ --action=add-zone-interface \
+ --zone-name="$VAR(../@)" \
+ --interface="$VAR(@)"; then
+ exit 1
+ fi
+
+ # ips zone actions
+ if ! /opt/vyatta/sbin/vyatta-zone-ips.pl \
+ --action=add-zone-interface \
+ --zone-name="$VAR(../@)" \
+ --interface="$VAR(@)"; then
exit 1
fi
delete:
- if ! /opt/vyatta/sbin/vyatta-zone.pl \
- --action=delete-zone-interface \
- --zone-name="$VAR(../@)" \
- --interface="$VAR(@)"; then
+ # fw zone actions
+ if ! /opt/vyatta/sbin/vyatta-zone.pl \
+ --action=delete-zone-interface \
+ --zone-name="$VAR(../@)" \
+ --interface="$VAR(@)"; then
+ exit 1
+ fi
+
+ # ips zone actions
+ if ! /opt/vyatta/sbin/vyatta-zone-ips.pl \
+ --action=delete-zone-interface \
+ --zone-name="$VAR(../@)" \
+ --interface="$VAR(@)"; then
exit 1
fi
diff --git a/templates-cfg/zone-policy/zone/node.tag/local-zone/node.def b/templates-cfg/zone-policy/zone/node.tag/local-zone/node.def
index 4db0f63..07c3d55 100644
--- a/templates-cfg/zone-policy/zone/node.tag/local-zone/node.def
+++ b/templates-cfg/zone-policy/zone/node.tag/local-zone/node.def
@@ -1,15 +1,31 @@
help: Zone to be local-zone
create:
- if ! /opt/vyatta/sbin/vyatta-zone.pl \
- --action=add-localzone \
- --zone-name="$VAR(../@)"; then
+ # fw zone actions
+ if ! /opt/vyatta/sbin/vyatta-zone.pl \
+ --action=add-localzone \
+ --zone-name="$VAR(../@)"; then
+ exit 1
+ fi
+
+ # ips zone actions
+ if ! /opt/vyatta/sbin/vyatta-zone-ips.pl \
+ --action=add-localzone \
+ --zone-name="$VAR(../@)"; then
exit 1
fi
delete:
- if ! /opt/vyatta/sbin/vyatta-zone.pl \
- --action=delete-localzone \
- --zone-name="$VAR(../@)"; then
+ # fw zone actions
+ if ! /opt/vyatta/sbin/vyatta-zone.pl \
+ --action=delete-localzone \
+ --zone-name="$VAR(../@)"; then
+ exit 1
+ fi
+
+ # ips zone actions
+ if ! /opt/vyatta/sbin/vyatta-zone-ips.pl \
+ --action=delete-localzone \
+ --zone-name="$VAR(../@)"; then
exit 1
fi