bypass PVEFW-VENET-IN|OUT for unfirewalled venet0 ips
[pve-firewall.git] / src / pvefw
CommitLineData
11388be7 1#!/usr/bin/perl -T
b6360c3f
DM
2
3use strict;
c2dca086
DM
4use warnings;
5
b6360c3f
DM
6use lib qw(.);
7use PVE::Firewall;
dddd9413 8
80bfe1ff
DM
9use PVE::SafeSyslog;
10use PVE::Cluster;
11use PVE::INotify;
12use PVE::RPCEnvironment;
b6360c3f 13
80bfe1ff
DM
14use PVE::JSONSchema qw(get_standard_option);
15
16use PVE::CLIHandler;
8f119284 17use PVE::API2::Firewall::Groups;
80bfe1ff
DM
18
19use base qw(PVE::CLIHandler);
20
8f119284
DM
21use Data::Dumper;
22
80bfe1ff
DM
23$ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin';
24
25initlog ('pvefw');
26
27die "please run as root\n" if $> != 0;
28
29PVE::INotify::inotify_init();
30
31my $rpcenv = PVE::RPCEnvironment->init('cli');
32
33$rpcenv->init_request();
34$rpcenv->set_language($ENV{LANG});
35$rpcenv->set_user('root@pam');
b6360c3f 36
80bfe1ff
DM
37__PACKAGE__->register_method ({
38 name => 'compile',
39 path => 'compile',
40 method => 'POST',
3fa83edf 41 description => "Compile amd print firewall rules. This is only for testing.",
80bfe1ff
DM
42 parameters => {
43 additionalProperties => 0,
3fa83edf
DM
44 properties => {
45 verbose => {
46 description => "Verbose output.",
47 type => "boolean",
48 optional => 1,
3fa83edf
DM
49 },
50 },
80bfe1ff
DM
51 },
52 returns => { type => 'null' },
53
54 code => sub {
55 my ($param) = @_;
56
e0809a95
DM
57 my $rpcenv = PVE::RPCEnvironment::get();
58
59 $param->{verbose} = 1
60 if !defined($param->{verbose}) && ($rpcenv->{type} eq 'cli');
61
06320eb0 62 my $code = sub {
3dfa8a7f 63 my ($ruleset, $ipset_ruleset) = PVE::Firewall::compile();
3f95d14a
DM
64
65 if ($param->{verbose}) {
dd7a13fd 66 my (undef, undef, $ipset_changes) = PVE::Firewall::get_ipset_cmdlist($ipset_ruleset, 1);
df7cb349 67 my (undef, $ruleset_changes) = PVE::Firewall::get_ruleset_cmdlist($ruleset, 1);
3f95d14a
DM
68 if ($ipset_changes || $ruleset_changes) {
69 print "detected changes\n";
70 } else {
71 print "no changes\n";
72 }
73 }
06320eb0
DM
74 };
75
76 PVE::Firewall::run_locked($code);
f789653a 77
5e1267a5
DM
78 return undef;
79 }});
80bfe1ff 80
6b9f68a2
DM
81__PACKAGE__->register_method ({
82 name => 'status',
83 path => 'status',
84 method => 'GET',
85 description => "Get firewall status.",
86 parameters => {
87 additionalProperties => 0,
88 properties => {},
89 },
90 returns => {
91 type => 'object',
92 additionalProperties => 0,
93 properties => {
94 status => {
95 type => 'string',
96 enum => ['unknown', 'stopped', 'active'],
97 },
98 changes => {
99 description => "Set when there are pending changes.",
100 type => 'boolean',
101 optional => 1,
102 }
103 },
104 },
105 code => sub {
106 my ($param) = @_;
107
108 my $rpcenv = PVE::RPCEnvironment::get();
109
110 $param->{verbose} = 1
111 if !defined($param->{verbose}) && ($rpcenv->{type} eq 'cli');
112
113 my $code = sub {
114 my $status = PVE::Firewall::read_pvefw_status();
115
116 my $res = { status => $status };
117 if ($status eq 'active') {
3dfa8a7f 118 my ($ruleset, $ipset_ruleset) = PVE::Firewall::compile();
6b9f68a2 119
dd7a13fd 120 my (undef, undef, $ipset_changes) = PVE::Firewall::get_ipset_cmdlist($ipset_ruleset);
df7cb349 121 my (undef, $ruleset_changes) = PVE::Firewall::get_ruleset_cmdlist($ruleset);
3f95d14a
DM
122 # fixme: ipset changes
123 $res->{changes} = ($ipset_changes || $ruleset_changes) ? 1 : 0;
6b9f68a2
DM
124 }
125
126 return $res;
127 };
128
129 return PVE::Firewall::run_locked($code);
130 }});
131
5e1267a5
DM
132__PACKAGE__->register_method ({
133 name => 'start',
134 path => 'start',
135 method => 'POST',
6b9f68a2 136 description => "Start (or simply update if already active) firewall.",
5e1267a5
DM
137 parameters => {
138 additionalProperties => 0,
3fa83edf
DM
139 properties => {
140 verbose => {
141 description => "Verbose output.",
142 type => "boolean",
143 optional => 1,
144 default => 0,
145 },
146 },
5e1267a5
DM
147 },
148 returns => { type => 'null' },
80bfe1ff 149
5e1267a5
DM
150 code => sub {
151 my ($param) = @_;
80bfe1ff 152
6b9f68a2 153 PVE::Firewall::update(1, $param->{verbose});
06320eb0 154
6b9f68a2
DM
155 return undef;
156 }});
157
158__PACKAGE__->register_method ({
159 name => 'update',
160 path => 'update',
161 method => 'POST',
162 description => "Check firewall rules. Then update the rules if the firewall is active.",
163 parameters => {
164 additionalProperties => 0,
165 properties => {
166 verbose => {
167 description => "Verbose output.",
168 type => "boolean",
169 optional => 1,
170 default => 0,
171 },
172 },
173 },
174 returns => { type => 'null' },
175
176 code => sub {
177 my ($param) = @_;
178
179 PVE::Firewall::update(0, $param->{verbose});
80bfe1ff
DM
180
181 return undef;
80bfe1ff
DM
182 }});
183
80bfe1ff
DM
184__PACKAGE__->register_method ({
185 name => 'stop',
186 path => 'stop',
187 method => 'POST',
a332200b 188 description => "Stop firewall. This will remove all rules installed by this script. The host is then unprotected.",
80bfe1ff
DM
189 parameters => {
190 additionalProperties => 0,
191 properties => {},
192 },
193 returns => { type => 'null' },
194
195 code => sub {
196 my ($param) = @_;
197
06320eb0 198 my $code = sub {
c4a2e5ae 199 PVE::Firewall::remove_pvefw_chains();
6b9f68a2 200 PVE::Firewall::save_pvefw_status('stopped');
06320eb0
DM
201 };
202
203 PVE::Firewall::run_locked($code);
80bfe1ff
DM
204
205 return undef;
206 }});
207
208my $nodename = PVE::INotify::nodename();
209
210my $cmddef = {
211 compile => [ __PACKAGE__, 'compile', []],
212 start => [ __PACKAGE__, 'start', []],
6b9f68a2
DM
213 update => [ __PACKAGE__, 'update', []],
214 status => [ __PACKAGE__, 'status', [], undef, sub {
215 my $res = shift;
216 if ($res->{changes}) {
217 print "Status: $res->{status} (pending changes)\n";
218 } else {
219 print "Status: $res->{status}\n";
220 }
221 }],
80bfe1ff 222 stop => [ __PACKAGE__, 'stop', []],
8f119284
DM
223
224 # This is for debugging
225 listgroups => [ 'PVE::API2::Firewall::Groups', 'list', [],
226 { node => $nodename }, sub {
227 my $res = shift;
228 print Dumper($res);
229 }],
d1c53b3e
DM
230 grouprules => [ 'PVE::API2::Firewall::Groups', 'get_rules', ['group'],
231 { node => $nodename }, sub {
232 my $res = shift;
233 print Dumper($res);
234 }],
80bfe1ff
DM
235};
236
237my $cmd = shift;
238
239PVE::CLIHandler::handle_cmd($cmddef, "pvefw", $cmd, \@ARGV, undef, $0);
b6360c3f
DM
240
241exit(0);
80bfe1ff 242