# Drop DNS replies
{ action => 'DROP', proto => 'udp', sport => 53 },
],
+ 'PVEFW-logflags' => [
+ # same as shorewall logflags action. (fixme: enable/disable logging)
+ "-j LOG --log-prefix \"logflags-dropped:\" --log-level 4 --log-ip-options",
+ "-j DROP",
+ ],
+ 'PVEFW-tcpflags' => [
+ # same as shorewall tcpflags action.
+ # Packets arriving on this interface are checked for som illegal combinations of TCP flags
+ "-p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -g PVEFW-logflags",
+ "-p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -g PVEFW-logflags",
+ "-p tcp -m tcp --tcp-flags SYN,RST SYN,RST -g PVEFW-logflags",
+ "-p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -g PVEFW-logflags",
+ "-p tcp -m tcp --sport 0 --tcp-flags FIN,SYN,RST,ACK SYN -g PVEFW-logflags",
+ ],
+ 'PVEFW-smurflog' => [
+ # same as shorewall smurflog. (fixme: enable/disable logging)
+ "-j LOG --log-prefix \"smurfs-dropped\" --log-level 4",
+ "-j DROP",
+ ],
+ 'PVEFW-smurfs' => [
+ # same as shorewall smurfs action
+ # Filter packets for smurfs (packets with a broadcast address as the source).
+ "-s 0.0.0.0/32 -j RETURN",
+ "-m addrtype --src-type BROADCAST -g PVEFW-smurflog",
+ "-s 224.0.0.0/4 -g PVEFW-smurflog",
+ ],
};
# iptables -p icmp -h
ruleset_create_chain($ruleset, $tapchain);
+ if (!(defined($options->{nosmurfs}) && $options->{nosmurfs} == 0)) {
+ ruleset_addrule($ruleset, $tapchain, "-m conntrack --ctstate INVALID,NEW -j PVEFW-smurfs");
+ }
+
+ if ($options->{tcpflags}) {
+ ruleset_addrule($ruleset, $tapchain, "-p tcp -j PVEFW-tcpflags");
+ }
+
ruleset_addrule($ruleset, $tapchain, "-m conntrack --ctstate INVALID -j DROP");
ruleset_addrule($ruleset, $tapchain, "-m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT");
ruleset_addrule($ruleset, $tapchain, "-m mac ! --mac-source $macaddr -j DROP");
}
+
if ($rules) {
foreach my $rule (@$rules) {
next if $rule->{iface} && $rule->{iface} ne $netid;
if ($macro) {
foreach my $templ (@$macro) {
my $rule = {};
+ my $param_used = {};
foreach my $k (keys %$templ) {
my $v = $templ->{$k};
if ($v eq 'PARAM') {
$v = $param->{$k};
+ $param_used->{$k} = 1;
} elsif ($v eq 'DEST') {
$v = $param->{dest};
+ $param_used->{dest} = 1;
} elsif ($v eq 'SOURCE') {
$v = $param->{source};
+ $param_used->{source} = 1;
}
die "missing parameter '$k' in macro '$macro_name'\n" if !defined($v);
$rule->{$k} = $v;
}
+ foreach my $k (keys %$param) {
+ next if !defined($param->{$k});
+ next if $param_used->{$k};
+ if (defined($rule->{$k})) {
+ die "parameter '$k' already define in macro (value = '$rule->{$k}')\n"
+ if $rule->{$k} ne $param->{$k};
+ } else {
+ $rule->{$k} = $param->{$k};
+ }
+ }
push @$rules, $rule;
}
} else {
my ($opt, $value);
- if ($line =~ m/^(enable|macfilter):\s*(0|1)\s*$/i) {
+ if ($line =~ m/^(enable|macfilter|nosmurfs|tcpflags):\s*(0|1)\s*$/i) {
$opt = lc($1);
$value = int($2);
} elsif ($line =~ m/^(policy-(in|out)):\s*(ACCEPT|DROP|REJECT)\s*$/i) {