summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorGaurav <gaurav.sinha@vyatta.com>2012-03-20 18:47:33 -0700
committerGaurav <gaurav.sinha@vyatta.com>2012-03-20 18:47:33 -0700
commit7330d01fd5ac752e265cf868b3a7f9ef30af9a93 (patch)
treef60b385fa08b035e2fa6f629c98d3f7064263e67 /scripts
parent613330a8acca0535df5bc1fc839fb29ce1261272 (diff)
parent0f71f18eaec8643d8f78b95bb1657734b3f5b368 (diff)
downloadvyatta-conntrack-7330d01fd5ac752e265cf868b3a7f9ef30af9a93.tar.gz
vyatta-conntrack-7330d01fd5ac752e265cf868b3a7f9ef30af9a93.zip
Merge branch 'cttimeout_pacifica' into oxnard
Brings in the changes needed for connection tracking timeouts per connection. Conflicts: .frlog debian/changelog
Diffstat (limited to 'scripts')
-rw-r--r--scripts/vyatta-conntrack-timeouts.pl174
1 files changed, 174 insertions, 0 deletions
diff --git a/scripts/vyatta-conntrack-timeouts.pl b/scripts/vyatta-conntrack-timeouts.pl
new file mode 100644
index 0000000..525a438
--- /dev/null
+++ b/scripts/vyatta-conntrack-timeouts.pl
@@ -0,0 +1,174 @@
+#!/usr/bin/perl
+
+use lib "/opt/vyatta/share/perl5";
+use warnings;
+use strict;
+
+use Vyatta::Config;
+use Vyatta::Conntrack::RuleCT;
+use Vyatta::IpTables::AddressFilter;
+use Getopt::Long;
+use Vyatta::Zone;
+use Sys::Syslog qw(:standard :macros);
+
+#for future use when v6 timeouts need to be set
+my %cmd_hash = ( 'ipv4' => 'iptables',
+ 'ipv6' => 'ip6tables');
+# Enable printing debug output to stdout.
+my $debug_flag = 0;
+
+# Enable sending debug output to syslog.
+my $syslog_flag = 0;
+my $nfct = "sudo /opt/vyatta/sbin/nfct";
+my ($create, $delete, $update);
+my $CTERROR = "Conntrack timeout error:";
+GetOptions("create=s" => \$create,
+ "delete=s" => \$delete,
+ "update=s" => \$update,
+);
+
+update_config();
+
+openlog("vyatta-conntrack", "pid", "local0");
+
+sub log_msg {
+ my $message = shift;
+
+ print "DEBUG: $message\n" if $debug_flag;
+ syslog(LOG_DEBUG, "%s", $message) if $syslog_flag;
+}
+# Run command and capture output
+# run_cmd("$iptables_cmd -t $table -F $name", 1);
+# if command fails, then send output to syslog
+sub run_cmd {
+ my ($cmd_to_run, $redirect) = @_;
+
+ log_msg("Running: $cmd_to_run");
+# print "$cmd_to_run\n";
+
+ if ($redirect) {
+ open (my $out, '-|', $cmd_to_run . ' 2>&1')
+ or die "Can't run command \"$cmd_to_run\": $!";
+ my @cmd_out = <$out>;
+
+ # if command suceeds to do nothing.
+ return if (close ($out));
+
+ foreach my $line (@cmd_out) {
+ chomp $line;
+ syslog(LOG_INFO, "%s", $line);
+ }
+ } else {
+ system($cmd_to_run);
+ }
+}
+
+sub remove_timeout_policy {
+ my ($rule_string, $timeout_policy) = @_;
+ my @tokens = split (' ', $timeout_policy);
+ # First remove the iptables rules before removing policy.
+ my $iptables_cmd1 = "iptables -D PREROUTING -t raw $rule_string -j CT --timeout $tokens[0]";
+ my $iptables_cmd2 = "iptables -D OUTPUT -t raw $rule_string -j CT --timeout $tokens[0]";
+ my $nfct_timeout_cmd = "$nfct timeout delete $timeout_policy";
+ run_cmd($iptables_cmd2);
+ if ($? >> 8) {
+ print "$CTERROR failed to run $iptables_cmd2\n";
+ #dont exit, try to clean as much.
+ }
+ run_cmd($iptables_cmd1);
+ if ($? >> 8) {
+ print "$CTERROR failed to run $iptables_cmd1\n";
+ }
+ run_cmd($nfct_timeout_cmd);
+ if ($? >> 8) {
+ print "$CTERROR failed to run $nfct_timeout_cmd\n";
+ }
+}
+
+# nfct-timeout create policy1 tcp established 1200 close-wait 100 fin-wait 10
+# iptables -I PREROUTING -t raw -s 1.1.1.1 -d 2.2.2.2 -j CT --timeout policy1
+sub apply_timeout_policy {
+ my ($rule_string, $timeout_policy, $rule) = @_;
+ my $nfct_timeout_cmd = "$nfct timeout add $timeout_policy";
+ my @tokens = split (' ', $timeout_policy);
+ my $iptables_cmd1 = "iptables -I PREROUTING -t raw $rule_string -j CT --timeout $tokens[0]";
+ my $iptables_cmd2 = "iptables -I OUTPUT -t raw $rule_string -j CT --timeout $tokens[0]";
+ run_cmd($nfct_timeout_cmd);
+ if ($? >> 8) {
+ print "$CTERROR failed to run $nfct_timeout_cmd\n";
+ exit 1;
+ }
+ run_cmd($iptables_cmd1);
+ if ($? >> 8) {
+ #cleanup the policy before exit.
+ run_cmd("nfct timeout delete policy_timeout_$rule");
+ print "$CTERROR failed to run $iptables_cmd1\n";
+ exit 1;
+ }
+ run_cmd($iptables_cmd2);
+ if ($? >> 8) {
+ run_cmd("nfct timeout delete policy_timeout_$rule");
+ run_cmd("iptables -D PREROUTING -t raw $rule_string -j CT --timeout $tokens[0]");
+ print "$CTERROR failed to run $iptables_cmd2\n";
+ exit 1;
+ }
+}
+
+sub handle_rule_creation {
+ my ($rule) = @_;
+ my $node = new Vyatta::Conntrack::RuleCT;
+ my ($rule_string, $timeout_policy);
+ do_protocol_check($rule);
+ $node->setup("system conntrack timeout custom rule $rule");
+ $rule_string = $node->rule();
+ $timeout_policy = $node->get_policy_command("add"); #nfct-timeout command string
+ apply_timeout_policy($rule_string, $timeout_policy, $rule);
+}
+
+# we mandate only one protocol configuration per rule
+sub do_protocol_check {
+ my ($rule) = @_;
+ my $config = new Vyatta::Config;
+ my $protocol_nos = $config->listNodes("system conntrack timeout custom rule $rule protocol");
+ if (($protocol_nos > 1) or ($protocol_nos < 1)) {
+ Vyatta::Config::outputError(["Conntrack"], "Conntrack config error: please configure exactly one protocol in rule $rule");
+ exit 1;
+ }
+}
+
+sub handle_rule_modification {
+ my ($rule) = @_;
+ do_protocol_check($rule);
+ handle_rule_deletion($rule);
+ handle_rule_creation($rule);
+}
+
+sub handle_rule_deletion {
+ my ($rule) = @_;
+ my $node = new Vyatta::Conntrack::RuleCT;
+ my ($rule_string, $timeout_policy);
+ $node->setupOrig("system conntrack timeout custom rule $rule");
+ $rule_string = $node->rule();
+ $timeout_policy = $node->get_policy_command("delete"); #nfct-timeout command string
+ remove_timeout_policy($rule_string, $timeout_policy);
+}
+
+sub update_config {
+ my $config = new Vyatta::Config;
+ my %rules = (); #hash of timeout config rules
+ my $iptables_cmd = $cmd_hash{'ipv4'};
+
+ $config->setLevel("system conntrack timeout custom rule");
+ %rules = $config->listNodeStatus();
+ foreach my $rule (sort keys %rules) {
+ if ("$rules{$rule}" eq 'static') {
+ } elsif ("$rules{$rule}" eq 'added') {
+ handle_rule_creation($rule);
+ } elsif ("$rules{$rule}" eq 'changed') {
+ handle_rule_modification($rule);
+ } elsif ("$rules{$rule}" eq 'deleted') {
+ handle_rule_deletion($rule);
+ }
+ }
+}
+