summaryrefslogtreecommitdiff
path: root/scripts/vyatta-conntrack-ignore.pl
blob: 80e745fba4f611d6c56571ecd86fc806adcdac4b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/perl

use lib "/opt/vyatta/share/perl5";
use warnings;
use strict;

use Vyatta::Config;
use Vyatta::Conntrack::RuleCT;
use Vyatta::Conntrack::RuleIgnore;
use Vyatta::IpTables::AddressFilter;
use Vyatta::Conntrack::ConntrackUtil;
use Getopt::Long;
use Vyatta::Zone;
use Sys::Syslog qw(:standard :macros);

#for future use when v6 ignore s 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 /usr/sbin/nfct";
my ($create, $delete, $update);
my $CTERROR = "Conntrack ignore  error:";
GetOptions("create=s"        => \$create,
           "delete=s"        => \$delete,
           "update=s"        => \$update,
);

update_config();

openlog("vyatta-conntrack", "pid", "local0");

sub remove_ignore_policy {
    my ($rule_string) = @_;
    my $iptables_cmd1 = "iptables -D VYATTA_CT_IGNORE -t raw $rule_string -j NOTRACK";
    my $iptables_cmd2 = "iptables -D VYATTA_CT_IGNORE -t raw $rule_string -j RETURN";
    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";    
    }
}

sub apply_ignore_policy {
   my ($rule_string1, $rule_string2, $rule, $num_rules) = @_;
   # insert at num_rules + 1 as there are so many rules already. 
   my $iptables_cmd1 = "iptables -I VYATTA_CT_IGNORE $num_rules -t raw $rule_string -j NOTRACK";
   $num_rules +=1;
   my $iptables_cmd2 = "iptables -I VYATTA_CT_IGNORE $num_rules -t raw $rule_string -j RETURN";
   $num_rules +=1;

   if ($rule_string2) {
     my $iptables_cmd3 = "iptables -I VYATTA_CT_IGNORE $num_rules -t raw $rule_string2 -j NOTRACK";
     $num_rules +=1;
     my $iptables_cmd4 = "iptables -I VYATTA_CT_IGNORE $num_rules -t raw $rule_string2 -j RETURN";
   }
   run_cmd($iptables_cmd1);
    if ($? >> 8) {
     print "$CTERROR failed to run $iptables_cmd1\n";    
     exit 1; 
   }
   run_cmd($iptables_cmd2);
    if ($? >> 8) {
     print "$CTERROR failed to run $iptables_cmd2\n";    
     exit 1; 
   }
   run_cmd($iptables_cmd3);
    if ($? >> 8) {
     print "$CTERROR failed to run $iptables_cmd3\n";    
     exit 1; 
   }
   run_cmd($iptables_cmd4);
    if ($? >> 8) {
     print "$CTERROR failed to run $iptables_cmd4\n";    
     exit 1; 
   }
}

sub handle_rule_creation {
  my ($rule, $num_rules) = @_;
  my $node = new Vyatta::Conntrack::RuleIgnore;
  my ($rule_string1, $rule_string2);

  do_minimalrule_check($rule);
  $node->setup("system conntrack ignore rule $rule");
  ($rule_string1, $rule_string2) = $node->rule();
  apply_ignore_policy($rule_string1, $rule_string2, $rule, $num_rules);
}

# mandate atleast inbound interface / source ip / dest ip or protocol per rule
sub do_minimalrule_check {
  my ($rule) = @_;
  my $config = new Vyatta::Config;
  my $intf = $config->exists("system conntrack ignore rule $rule inbound-interface");
  my $src = $config->exists("system conntrack ignore rule $rule source address");
  my $dst = $config->exists("system conntrack ignore rule $rule destination address");
  my $protocol = $config->exists("system conntrack ignore rule $rule protocol");

  if ( (!$intf) and (!$src) and (!$dst) and (!$protocol)) {
    Vyatta::Config::outputError(["Conntrack"], "Conntrack config error: No inbound-interface, source / destination address, protocol found in rule @_ ");
    exit 1;
  }
}

sub handle_rule_modification {
  my ($rule, $num_rules) = @_;
  do_minimalrule_check($rule);
  handle_rule_deletion($rule);
  handle_rule_creation($rule, $num_rules);
}

sub handle_rule_deletion {
  my ($rule) = @_;
  my $node = new Vyatta::Conntrack::RuleIgnore;
  my ($rule_string);
  $node->setupOrig("system conntrack ignore rule $rule");
  $rule_string = $node->rule();
  remove_ignore_policy($rule_string);
}

sub numerically { $a <=> $b; }

sub update_config {
  my $config = new Vyatta::Config;
  my %rules = (); #hash of ignore config rules  
  my $iptables_cmd = $cmd_hash{'ipv4'};

  $config->setLevel("system conntrack ignore rule");
  %rules = $config->listNodeStatus();

  my $iptablesrule = 1;
  foreach my $rule (sort numerically keys %rules) { 
    if ("$rules{$rule}" eq 'static') {
      $iptablesrule+=2;
    } elsif ("$rules{$rule}" eq 'added') {      
        handle_rule_creation($rule, $iptablesrule);
        $iptablesrule+=2;
    } elsif ("$rules{$rule}" eq 'changed') {
        handle_rule_modification($rule, $iptablesrule);
        $iptablesrule+=2;
    } elsif ("$rules{$rule}" eq 'deleted') {
        handle_rule_deletion($rule);
    }  
  }
}