]>
Commit | Line | Data |
---|---|---|
1 | #!/usr/bin/perl -w | |
2 | ||
3 | use strict; | |
4 | use lib qw(.); | |
5 | use PVE::Firewall; | |
6 | use File::Path; | |
7 | use IO::File; | |
8 | ||
9 | ||
10 | my $vmdata = { | |
11 | qemu => { | |
12 | 100 => { | |
13 | net0 => 'rtl8139=9A:42:2D:0C:01:FF,bridge=vmbr0', | |
14 | }, | |
15 | 101 => { | |
16 | net0 => 'rtl8139=0E:9D:ED:CC:9B:ED,bridge=vmbr0', | |
17 | }, | |
18 | 102 => { | |
19 | zone => 'z1', | |
20 | net0 => 'rtl8139=0E:9D:ED:CC:AA:ED,bridge=vmbr0', | |
21 | net1 => 'rtl8139=0E:9D:ED:CC:CC:ED,bridge=vmbr1', | |
22 | }, | |
23 | 103 => { | |
24 | zone => 'z1', | |
25 | net0 => 'rtl8139=0E:9D:ED:CC:BC:ED,bridge=vmbr0', | |
26 | net1 => 'rtl8139=0E:9D:ED:CC:BC:AA,tag=5,bridge=vmbr0', | |
27 | }, | |
28 | }, | |
29 | }; | |
30 | ||
31 | sub parse_fw_rules { | |
32 | my ($filename, $fh) = @_; | |
33 | ||
34 | my $section; | |
35 | ||
36 | my $res = { in => [], out => [] }; | |
37 | ||
38 | while (defined(my $line = <$fh>)) { | |
39 | next if $line =~ m/^#/; | |
40 | next if $line =~ m/^\s*$/; | |
41 | ||
42 | if ($line =~ m/^\[(in|out)\]\s*$/i) { | |
43 | $section = lc($1); | |
44 | next; | |
45 | } | |
46 | next if !$section; | |
47 | ||
48 | my ($action, $iface, $source, $dest, $proto, $dport, $sport) = | |
49 | split(/\s+/, $line); | |
50 | ||
51 | if (!($action && $iface && $source && $dest)) { | |
52 | warn "skip incomplete line\n"; | |
53 | next; | |
54 | } | |
55 | ||
56 | if ($action !~ m/^(ACCEPT|DROP)$/) { | |
57 | warn "unknown action '$action'\n"; | |
58 | next; | |
59 | } | |
60 | ||
61 | if ($iface !~ m/^(all|net0|net1|net2|net3|net4|net5)$/) { | |
62 | warn "unknown interface '$iface'\n"; | |
63 | next; | |
64 | } | |
65 | ||
66 | if ($proto && $proto !~ m/^(icmp|tcp|udp)$/) { | |
67 | warn "unknown protokol '$proto'\n"; | |
68 | next; | |
69 | } | |
70 | ||
71 | if ($source !~ m/^(any)$/) { | |
72 | warn "unknown source '$source'\n"; | |
73 | next; | |
74 | } | |
75 | ||
76 | if ($dest !~ m/^(any)$/) { | |
77 | warn "unknown destination '$dest'\n"; | |
78 | next; | |
79 | } | |
80 | ||
81 | my $rule = { | |
82 | action => $action, | |
83 | iface => $iface, | |
84 | source => $source, | |
85 | dest => $dest, | |
86 | proto => $proto, | |
87 | dport => $dport, | |
88 | sport => $sport, | |
89 | }; | |
90 | ||
91 | push @{$res->{$section}}, $rule; | |
92 | } | |
93 | ||
94 | return $res; | |
95 | } | |
96 | ||
97 | my $testdir = "./testdir"; | |
98 | rmtree($testdir); | |
99 | mkdir $testdir; | |
100 | ||
101 | my $rules = {}; | |
102 | foreach my $vmid (keys %{$vmdata->{qemu}}) { | |
103 | my $filename = "config/$vmid.fw"; | |
104 | my $fh = IO::File->new($filename, O_RDONLY); | |
105 | next if !$fh; | |
106 | ||
107 | $rules->{$vmid} = parse_fw_rules($filename, $fh); | |
108 | } | |
109 | ||
110 | PVE::Firewall::compile($testdir, $vmdata, $rules); | |
111 | ||
112 | PVE::Tools::run_command(['shorewall', 'check', $testdir]); | |
113 | ||
114 | exit(0); |