Re: pfctl should allow administrator to flush _anchors

2019-03-26 Thread Alexandr Nedvedicky
Hello,

> > 
> > So how people feel about changing '-Fa' to kill all rules and tables, not 
> > just
> > those, which are attached to main ruleset (root)?
> > 
> > thanks and
> > regards
> > sashan
> > 
> 
> IMHO this is a needed feature, but I agree with your hesitation about
> using -Fa. This would be convenient to type, but the current documentation
> for pfctl -a says:
> 
> "In addition to the main ruleset, pfctl can load and manipulate
>additional rulesets by name, called anchors. The main ruleset is the
>default anchor."
> 
> The wording is slightly awkward but I read this as saying the current
> behaviour is intended.
> 
> There's an obvious alternative user interface for this. Currently
>  -a '*' is only described in conjunction with -s, but it would feel
> natural to allow this to be used with -F as well, e.g.
> 
># pfctl -a '*' -Fa
> 

I like this idea to interpret "-a '*'" option in conjunction with '-F...'
in the same way we do it for "-s" already.

I also like tedu's idea to introduce a '-Freset'. I'll try to cook up some
diffs. One diff will deal with "-a '*' -F..." the other will bring 
'-Freset'.

thanks and
regards
sashan



Re: pfctl should allow administrator to flush _anchors

2019-03-26 Thread Stuart Henderson
On 2019/03/26 09:38, Alexandr Nedvedicky wrote:
> On Mon, Mar 25, 2019 at 10:28:40PM -0400, Ted Unangst wrote:
> > Alexandr Nedvedicky wrote:
> > > it is, however -Fall operates on main ruleset only. -Fall also does
> > > not reset limits and timeouts. Hence my first idea was to introduce
> > > '-FNuke', which kills all rulesets and tables.
> > > 
> > > I don't want to change behaviour of existing option ('-Fall'), 
> > > therefore
> > > I'm in favor to introduce a new option. Either '-FNuke' or '-U' works
> > > for me. I'm the most concerned about flushing all rulesets.
> > 
> > Is the existing behavior intentional or an oversight? I don't know when I
> > would want to use -Fall, but keep the old timeouts, and depend on that. I'd
> > guess most people using -Fall are keeping old timeout only by happen stance,
> > and not because they desire that.
> 
> I had similar question on my mind when I came to PF for the first time.
> my expectations about '-Fall' were the option removes all rules (and 
> tables)
> from kernel module. But it is not the case it acts on main ruleset only.
> Given '-Fall' works like that for ages, I see changing '-Fall' to remove
> all rules as disturbing (hence I'm in favor to introduce a new option). On
> the other hand if there will be consensus to fix '-Fall' so it will remove
> all rules (not just main ruleset), then we can forget about '-U'.
> 
> With '-Fall' changed, we can further fix pfctl. The proposed '-U', will
> be achieved by combination of various '-F' modifiers:
>   pfctl -FA -FS -Fs -Freset
> command above should revert PF driver state back to initial.
> 
> > 
> > In any case, if you're seeking input on the name, something like -Freset 
> > says
> > to me that it resets pf back to its initial state.
> 
> I like the '-Fresst' to reset all PF settings (variables modified by 
> 'set')
> back to defaults.
> 
> So how people feel about changing '-Fa' to kill all rules and tables, not just
> those, which are attached to main ruleset (root)?
> 
> thanks and
> regards
> sashan
> 

IMHO this is a needed feature, but I agree with your hesitation about
using -Fa. This would be convenient to type, but the current documentation
for pfctl -a says:

"In addition to the main ruleset, pfctl can load and manipulate
   additional rulesets by name, called anchors. The main ruleset is the
   default anchor."

The wording is slightly awkward but I read this as saying the current
behaviour is intended.

There's an obvious alternative user interface for this. Currently
 -a '*' is only described in conjunction with -s, but it would feel
natural to allow this to be used with -F as well, e.g.

   # pfctl -a '*' -Fa



Re: pfctl should allow administrator to flush _anchors

2019-03-26 Thread Alexandr Nedvedicky
On Mon, Mar 25, 2019 at 10:28:40PM -0400, Ted Unangst wrote:
> Alexandr Nedvedicky wrote:
> > it is, however -Fall operates on main ruleset only. -Fall also does
> > not reset limits and timeouts. Hence my first idea was to introduce
> > '-FNuke', which kills all rulesets and tables.
> > 
> > I don't want to change behaviour of existing option ('-Fall'), therefore
> > I'm in favor to introduce a new option. Either '-FNuke' or '-U' works
> > for me. I'm the most concerned about flushing all rulesets.
> 
> Is the existing behavior intentional or an oversight? I don't know when I
> would want to use -Fall, but keep the old timeouts, and depend on that. I'd
> guess most people using -Fall are keeping old timeout only by happen stance,
> and not because they desire that.

I had similar question on my mind when I came to PF for the first time.
my expectations about '-Fall' were the option removes all rules (and tables)
from kernel module. But it is not the case it acts on main ruleset only.
Given '-Fall' works like that for ages, I see changing '-Fall' to remove
all rules as disturbing (hence I'm in favor to introduce a new option). On
the other hand if there will be consensus to fix '-Fall' so it will remove
all rules (not just main ruleset), then we can forget about '-U'.

With '-Fall' changed, we can further fix pfctl. The proposed '-U', will
be achieved by combination of various '-F' modifiers:
pfctl -FA -FS -Fs -Freset
command above should revert PF driver state back to initial.

> 
> In any case, if you're seeking input on the name, something like -Freset says
> to me that it resets pf back to its initial state.

I like the '-Fresst' to reset all PF settings (variables modified by 'set')
back to defaults.

So how people feel about changing '-Fa' to kill all rules and tables, not just
those, which are attached to main ruleset (root)?

thanks and
regards
sashan



Re: pfctl should allow administrator to flush _anchors

2019-03-25 Thread Ted Unangst
Alexandr Nedvedicky wrote:
> it is, however -Fall operates on main ruleset only. -Fall also does
> not reset limits and timeouts. Hence my first idea was to introduce
> '-FNuke', which kills all rulesets and tables.
> 
> I don't want to change behaviour of existing option ('-Fall'), therefore
> I'm in favor to introduce a new option. Either '-FNuke' or '-U' works
> for me. I'm the most concerned about flushing all rulesets.

Is the existing behavior intentional or an oversight? I don't know when I
would want to use -Fall, but keep the old timeouts, and depend on that. I'd
guess most people using -Fall are keeping old timeout only by happen stance,
and not because they desire that.

In any case, if you're seeking input on the name, something like -Freset says
to me that it resets pf back to its initial state.



Re: pfctl should allow administrator to flush _anchors

2019-03-25 Thread Theo de Raadt
Alexandr Nedvedicky  wrote:

> how about making the '-U' (or whatever name we agree) undocumented. We can
> also make the option available if pfctl will get compiled with 'DEBUG'
> option (assuming we are doing regress on debug bits anyway).

no, it should be documented.

but few people will use it, and that's fine



Re: pfctl should allow administrator to flush _anchors

2019-03-25 Thread Alexandr Nedvedicky
Hello,

> > > > Isn't -U pretty close to -Fall ?
> > > > 
> > > 
> > > it is, however -Fall operates on main ruleset only. -Fall also does
> > > not reset limits and timeouts. Hence my first idea was to introduce
> > > '-FNuke', which kills all rulesets and tables.
> > > 
> > > I don't want to change behaviour of existing option ('-Fall'), 
> > > therefore
> > > I'm in favor to introduce a new option. Either '-FNuke' or '-U' works
> > > for me. I'm the most concerned about flushing all rulesets.
> > > 
> > > Also making "pfctl -a '_1/_2' -Fr" to remove PF 'private' rulesets 
> > > works
> > > for me. Actually this is the most important thing I'd like to achieve.
> > 
> > whatever gets done here, the initial-raw-state-forcing should be 1 
> > operation.
> > not multiple operations acting on aspects of pf.
> > 
> > I think if it is multiple operations, people won't ever get comfortable
> > using it.
> 
> Not sure about that: I wont be comfortable anyway, as it can cause all sorts
> of problems on a running system.
> 
> When i reset things to the boot state, i would expect thats not a simple
> thing and not without issues.
> 
> I consider this as a cleanup op, most useful for regress tests, developers
> testing stuff etc. In normal sysadmin work i never needed it.

I think this is a good point. I don't expect experienced admins, who
maintain production systems to use an unconfigure operation. It's indeed
more useful for regression tests and people who are configuring their PF
in sandbox/testing environment.

how about making the '-U' (or whatever name we agree) undocumented. We can
also make the option available if pfctl will get compiled with 'DEBUG'
option (assuming we are doing regress on debug bits anyway).

sashan



Re: pfctl should allow administrator to flush _anchors

2019-03-25 Thread Sebastian Benoit
Theo de Raadt(dera...@openbsd.org) on 2019.03.24 10:22:25 -0600:
> Alexandr Nedvedicky  wrote:
> 
> > On Sun, Mar 24, 2019 at 09:51:13AM +0100, Denis Fondras wrote:
> > > On Sun, Mar 24, 2019 at 09:24:34AM +0100, Alexandr Nedvedicky wrote:
> > > > I think all the above calls for a new standalone option, which I named 
> > > > as
> > > > 'Unconfigure'.  Patch below suggest unconfigure behavior for PF.
> > > > Doing 'pfctl -U' will bring PF back to its initial state (e.g. right 
> > > > before
> > > > pf.conf got processed during the system boot). In case of PF the 
> > > > proposed -U
> > > > will do following:
> > > > - remove all rulesets and tables
> > > > - remove all states and source nodes
> > > > - remove all OS fingerprints
> > > > - set all limits, timeouts and options to their defaults
> > > > 
> > > 
> > > Isn't -U pretty close to -Fall ?
> > > 
> > 
> > it is, however -Fall operates on main ruleset only. -Fall also does
> > not reset limits and timeouts. Hence my first idea was to introduce
> > '-FNuke', which kills all rulesets and tables.
> > 
> > I don't want to change behaviour of existing option ('-Fall'), therefore
> > I'm in favor to introduce a new option. Either '-FNuke' or '-U' works
> > for me. I'm the most concerned about flushing all rulesets.
> > 
> > Also making "pfctl -a '_1/_2' -Fr" to remove PF 'private' rulesets works
> > for me. Actually this is the most important thing I'd like to achieve.
> 
> whatever gets done here, the initial-raw-state-forcing should be 1 operation.
> not multiple operations acting on aspects of pf.
> 
> I think if it is multiple operations, people won't ever get comfortable
> using it.

Not sure about that: I wont be comfortable anyway, as it can cause all sorts
of problems on a running system.

When i reset things to the boot state, i would expect thats not a simple
thing and not without issues.

I consider this as a cleanup op, most useful for regress tests, developers
testing stuff etc. In normal sysadmin work i never needed it.



Re: pfctl should allow administrator to flush _anchors

2019-03-24 Thread Theo de Raadt
Alexandr Nedvedicky  wrote:

> On Sun, Mar 24, 2019 at 09:51:13AM +0100, Denis Fondras wrote:
> > On Sun, Mar 24, 2019 at 09:24:34AM +0100, Alexandr Nedvedicky wrote:
> > > I think all the above calls for a new standalone option, which I named as
> > > 'Unconfigure'.  Patch below suggest unconfigure behavior for PF.
> > > Doing 'pfctl -U' will bring PF back to its initial state (e.g. right 
> > > before
> > > pf.conf got processed during the system boot). In case of PF the proposed 
> > > -U
> > > will do following:
> > > - remove all rulesets and tables
> > > - remove all states and source nodes
> > > - remove all OS fingerprints
> > > - set all limits, timeouts and options to their defaults
> > > 
> > 
> > Isn't -U pretty close to -Fall ?
> > 
> 
> it is, however -Fall operates on main ruleset only. -Fall also does
> not reset limits and timeouts. Hence my first idea was to introduce
> '-FNuke', which kills all rulesets and tables.
> 
> I don't want to change behaviour of existing option ('-Fall'), therefore
> I'm in favor to introduce a new option. Either '-FNuke' or '-U' works
> for me. I'm the most concerned about flushing all rulesets.
> 
> Also making "pfctl -a '_1/_2' -Fr" to remove PF 'private' rulesets works
> for me. Actually this is the most important thing I'd like to achieve.

whatever gets done here, the initial-raw-state-forcing should be 1 operation.
not multiple operations acting on aspects of pf.

I think if it is multiple operations, people won't ever get comfortable
using it.



Re: pfctl should allow administrator to flush _anchors

2019-03-24 Thread Alexandr Nedvedicky
On Sun, Mar 24, 2019 at 09:51:13AM +0100, Denis Fondras wrote:
> On Sun, Mar 24, 2019 at 09:24:34AM +0100, Alexandr Nedvedicky wrote:
> > I think all the above calls for a new standalone option, which I named as
> > 'Unconfigure'.  Patch below suggest unconfigure behavior for PF.
> > Doing 'pfctl -U' will bring PF back to its initial state (e.g. right before
> > pf.conf got processed during the system boot). In case of PF the proposed -U
> > will do following:
> > - remove all rulesets and tables
> > - remove all states and source nodes
> > - remove all OS fingerprints
> > - set all limits, timeouts and options to their defaults
> > 
> 
> Isn't -U pretty close to -Fall ?
> 

it is, however -Fall operates on main ruleset only. -Fall also does
not reset limits and timeouts. Hence my first idea was to introduce
'-FNuke', which kills all rulesets and tables.

I don't want to change behaviour of existing option ('-Fall'), therefore
I'm in favor to introduce a new option. Either '-FNuke' or '-U' works
for me. I'm the most concerned about flushing all rulesets.

Also making "pfctl -a '_1/_2' -Fr" to remove PF 'private' rulesets works
for me. Actually this is the most important thing I'd like to achieve.

sashan



Re: pfctl should allow administrator to flush _anchors

2019-03-24 Thread Denis Fondras
On Sun, Mar 24, 2019 at 09:24:34AM +0100, Alexandr Nedvedicky wrote:
> I think all the above calls for a new standalone option, which I named as
> 'Unconfigure'.  Patch below suggest unconfigure behavior for PF.
> Doing 'pfctl -U' will bring PF back to its initial state (e.g. right before
> pf.conf got processed during the system boot). In case of PF the proposed -U
> will do following:
> - remove all rulesets and tables
> - remove all states and source nodes
> - remove all OS fingerprints
> - set all limits, timeouts and options to their defaults
> 

Isn't -U pretty close to -Fall ?



Re: pfctl should allow administrator to flush _anchors

2019-03-24 Thread Alexandr Nedvedicky
Hello,

I received a feedback suggesting to come up with better name than 'Nuke'

> not sure about the name.
> 
> i've often want a similar operation for network interfaces, which
> returns them to 'raw' state.
> 
> and there's also been people who want the same for the routing
> table
> 
> if we ever do such a thing for all of these things, i think we should
> use the same word
> 
> 'nuke' sounds like the wrong word, it is a 'destroy' operation rather
> than 'return to unitialized'.

I think all the above calls for a new standalone option, which I named as
'Unconfigure'.  Patch below suggest unconfigure behavior for PF.
Doing 'pfctl -U' will bring PF back to its initial state (e.g. right before
pf.conf got processed during the system boot). In case of PF the proposed -U
will do following:
- remove all rulesets and tables
- remove all states and source nodes
- remove all OS fingerprints
- set all limits, timeouts and options to their defaults

thanks and
regards
sashan

8<---8<---8<--8<
diff --git a/sbin/pfctl/pfctl.8 b/sbin/pfctl/pfctl.8
index 48b2893cfcd..562e03b3477 100644
--- a/sbin/pfctl/pfctl.8
+++ b/sbin/pfctl/pfctl.8
@@ -644,6 +644,9 @@ This flag is set when per-address counters are enabled on 
the table.
 .El
 .It Fl t Ar table
 Specify the name of the table.
+.It Fl U
+Unconfigure firewall. All rules, states and tables are removed. All limits
+and timeouts are reset to default values.
 .It Fl V Ar rdomain
 Select the routing domain to be used to kill states by host or by label.
 The rdomain of a state is displayed in parentheses before the host by
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 493ff47af2f..19f63db56f2 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -54,6 +54,8 @@
 
 #include 
 
+#include 
+
 #include "pfctl_parser.h"
 #include "pfctl.h"
 
@@ -63,7 +65,7 @@ intpfctl_disable(int, int);
 voidpfctl_clear_queues(struct pf_qihead *);
 voidpfctl_clear_stats(int, const char *, int);
 voidpfctl_clear_interface_flags(int, int);
-voidpfctl_clear_rules(int, int, char *);
+int pfctl_clear_rules(int, int, char *);
 voidpfctl_clear_src_nodes(int, int);
 voidpfctl_clear_states(int, const char *, int);
 struct addrinfo *
@@ -105,6 +107,14 @@ int pfctl_load_rule(struct pfctl *, char *, struct 
pf_rule *, int);
 const char *pfctl_lookup_option(char *, const char **);
 void   pfctl_state_store(int, const char *);
 void   pfctl_state_load(int, const char *);
+intpfctl_walk_show(int, struct pfioc_ruleset *, void *);
+intpfctl_walk_get(int, struct pfioc_ruleset *, void *);
+intpfctl_walk_anchors(int, int, char *, void *,
+int(*)(int, struct pfioc_ruleset *, void *));
+struct pfr_anchors *
+   pfctl_get_anchors(int, int);
+intpfctl_nuke_anchors(int, int);
+void   pfctl_set_defaults(int, int);
 
 const char *clearopt;
 char   *rulesopt;
@@ -124,6 +134,7 @@ char*state_kill[2];
 int dev = -1;
 int first_title = 1;
 int labels = 0;
+int exit_val = 0;
 
 #define INDENT(d, o)   do {\
if (o) {\
@@ -232,7 +243,6 @@ static const char *optiopt_list[] = {
 struct pf_qihead qspecs = TAILQ_HEAD_INITIALIZER(qspecs);
 struct pf_qihead rootqs = TAILQ_HEAD_INITIALIZER(rootqs);
 
-
 __dead void
 usage(void)
 {
@@ -249,6 +259,40 @@ usage(void)
exit(1);
 }
 
+void
+pfctl_err(int opts, int eval, const char *fmt, ...)
+{
+   va_list ap;
+
+   va_start(ap, fmt);
+
+   if ((opts & PF_OPT_IGNFAIL) == 0)
+   verr(1, fmt, ap);
+   else
+   vwarn(fmt, ap);
+
+   va_end(ap);
+
+   exit_val = eval;
+}
+
+void
+pfctl_errx(int opts, int eval, const char *fmt, ...)
+{
+   va_list ap;
+
+   va_start(ap, fmt);
+
+   if ((opts & PF_OPT_IGNFAIL) == 0)
+   verrx(1, fmt, ap);
+   else
+   vwarnx(fmt, ap);
+
+   va_end(ap);
+
+   exit_val = eval;
+}
+
 int
 pfctl_enable(int dev, int opts)
 {
@@ -287,10 +331,10 @@ pfctl_clear_stats(int dev, const char *iface, int opts)
memset(, 0, sizeof(pi));
if (iface != NULL && strlcpy(pi.pfiio_name, iface,
sizeof(pi.pfiio_name)) >= sizeof(pi.pfiio_name))
-   errx(1, "invalid interface: %s", iface);
+   pfctl_errx(opts, 1, "invalid interface: %s", iface);
 
if (ioctl(dev, DIOCCLRSTATUS, ))
-   err(1, "DIOCCLRSTATUS");
+   pfctl_err(opts, 1, "DIOCCLRSTATUS");
if ((opts & PF_OPT_QUIET) == 0) {
fprintf(stderr, "pf: statistics cleared");
if (iface != NULL)
@@ -309,32 +353,36 @@ pfctl_clear_interface_flags(int dev, int opts)
pi.pfiio_flags = PFI_IFLAG_SKIP;
 
if (ioctl(dev, DIOCCLRIFFLAG, ))
-   

Re: pfctl should allow administrator to flush _anchors

2019-03-21 Thread Alexandr Nedvedicky
Hello,

I'm giving up on identifying unreferenced/orphaned rulesets. It seems to me
like too much work/complexity, which invites more troubles. I prefer to keep
things simple, hence I'm proposing new modifier for Flush option:

-F Nuke   Flush all rulesets and tables.

The option is meant to be used when things will get too messy.  It removes all
tables and rulesets from kernel allowing admin to quickly start from scratch
without doing reboot.

so here is my first question:

does proposal for the 'Nuke' flush modifier sound good?
or is it completely off?

Proposed change below splits current pfctl_show_anchors() to two functions:

pfctl_walk_anchors(), which implements ruleset/anchor traversal

pfctl_walk_show(), which prints full path to every anchor, while
anchors are traversed. the pfctl_walk_show() is passed
as argument to pfctl_walk_anchors()

The implementation of Nuke modifier comes with its own callback
pfctl_walk_get(), which collects anchors to SLIST during anchor tree
traversal. As soon as all anchors/rulesets are collected
we effectively apply:
pfctl -a ... -FT
pfctl -a ... -Fr
to every anchor/ruleset found in the list.

If you think the change is too big to be done in one step, then
I can split the diff to two steps:

split pfctl_show_anchors() in the first step

then send an updated diff, which just adds 'Nuke' modifier to F
option.

thanks and
regards
sashan

8<---8<---8<--8<
diff --git a/sbin/pfctl/pfctl.8 b/sbin/pfctl/pfctl.8
index 48b2893cfcd..06e76e35b68 100644
--- a/sbin/pfctl/pfctl.8
+++ b/sbin/pfctl/pfctl.8
@@ -199,6 +199,8 @@ Flush the tables.
 Flush the passive operating system fingerprints.
 .It Fl F Cm all
 Flush all of the above.
+.It Fl F Cm Nuke
+Flush all rulesets and tables.
 .El
 .It Fl f Ar file
 Replace the current ruleset with
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 493ff47af2f..fc909ade507 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -63,7 +63,7 @@ intpfctl_disable(int, int);
 voidpfctl_clear_queues(struct pf_qihead *);
 voidpfctl_clear_stats(int, const char *, int);
 voidpfctl_clear_interface_flags(int, int);
-voidpfctl_clear_rules(int, int, char *);
+int pfctl_clear_rules(int, int, char *);
 voidpfctl_clear_src_nodes(int, int);
 voidpfctl_clear_states(int, const char *, int);
 struct addrinfo *
@@ -105,6 +105,13 @@ int pfctl_load_rule(struct pfctl *, char *, struct 
pf_rule *, int);
 const char *pfctl_lookup_option(char *, const char **);
 void   pfctl_state_store(int, const char *);
 void   pfctl_state_load(int, const char *);
+intpfctl_walk_show(int, struct pfioc_ruleset *, void *);
+intpfctl_walk_get(int, struct pfioc_ruleset *, void *);
+intpfctl_walk_anchors(int, int, char *, void *,
+int(*)(int, struct pfioc_ruleset *, void *));
+struct pfr_anchors *
+   pfctl_get_anchors(int, int);
+intpfctl_nuke_anchors(int, int);
 
 const char *clearopt;
 char   *rulesopt;
@@ -205,7 +212,8 @@ static const struct {
 };
 
 static const char *clearopt_list[] = {
-   "rules", "Sources", "states", "info", "Tables", "osfp", "all", NULL
+   "rules", "Sources", "states", "info", "Tables", "osfp", "all",
+   "Nuke", NULL
 };
 
 static const char *showopt_list[] = {
@@ -232,7 +240,6 @@ static const char *optiopt_list[] = {
 struct pf_qihead qspecs = TAILQ_HEAD_INITIALIZER(qspecs);
 struct pf_qihead rootqs = TAILQ_HEAD_INITIALIZER(rootqs);
 
-
 __dead void
 usage(void)
 {
@@ -315,19 +322,29 @@ pfctl_clear_interface_flags(int dev, int opts)
}
 }
 
-void
+int
 pfctl_clear_rules(int dev, int opts, char *anchorname)
 {
-   struct pfr_buffer t;
+   struct pfr_buffer   t;
+   int rv = 0;
 
memset(, 0, sizeof(t));
t.pfrb_type = PFRB_TRANS;
if (pfctl_add_trans(, PF_TRANS_RULESET, anchorname) ||
pfctl_trans(dev, , DIOCXBEGIN, 0) ||
-   pfctl_trans(dev, , DIOCXCOMMIT, 0))
-   err(1, "pfctl_clear_rules");
-   if ((opts & PF_OPT_QUIET) == 0)
+   pfctl_trans(dev, , DIOCXCOMMIT, 0)) {
+   if (opts & PF_OPT_IGNFAIL) {
+   if ((opts & PF_OPT_QUIET) == 0) {
+   warn("%s", __func__);
+   }
+   rv = 1;
+   } else {
+   err(1, "%s", __func__);
+   }
+   } else if ((opts & PF_OPT_QUIET) == 0)
fprintf(stderr, "rules cleared\n");
+
+   return (rv);
 }
 
 void
@@ -2107,13 +2124,59 @@ pfctl_debug(int dev, u_int32_t level, int opts)
 }
 
 int
-pfctl_show_anchors(int dev, int opts, char *anchorname)
+pfctl_walk_show(int opts, struct pfioc_ruleset *pr, void *warg)
+{
+   if (pr->path[0]) {
+   if (pr->path[0] != '_' || (opts & PF_OPT_VERBOSE))
+   printf("  %s/%s\n", 

Re: pfctl should allow administrator to flush _anchors

2019-02-22 Thread Klemens Nanni
On Fri, Feb 22, 2019 at 03:02:07PM +0100, Alexandr Nedvedicky wrote:
> so the option '-F Anchors' will also perform a '-Fr' on main ruleset, is
> that correct?
No, my `-f /etc/pf.conf' is the equivalent to your `-F rules' here.

> And also one more thing, which comes to my mind. How '-F Anchors' should
> treat tables attached to anchors?
If an unreferenced anchor contains a table, either destroy that table
as well since it cannot be referenced or abort garbage collecting
anchor completely, possibly prompting the user to clean tables in
besaid anchors as well.

I tend towards the first option since anchors may contain tables that
were automatically created due to ruleset optimization.  That is to say,
while enforcing manual removal of tables as well, this may become
annoying for big optimized rulesets where administrators would have to
wield `-F Tables' and or `-a aname -T kill -t tname' before having
`-F Anchors' run cleanly.

Does that make sense?

> the firewall service (which is a kind of rc-script in fact)  on Solaris,
> kills (removes) all tables first, then it removes anchors.
> 
> What shall we do in case of '-F Anchors'? do we want '-F Anchors' to
> kill attached tables too? Or should it just report "anchor can't be
> removed, because table is still attached?"
See above.  What this "service" roughly seems like what I have in mind.

> It looks like '-F Anchors' shifts pfctl(8) from simple tool, which does
> exactly what it's told to do, to advanced tool, which does more things at
> one step.
But isn't that a perfect job for pfctl?  It manipulates everything, it's
the single interface for firewall related and that's a good.  Cleaning
things up after work is done is a necessity; this is about adding the
missing peaces, imho.

> The simple tools just seem to be more friendly for scripts, while advanced
> tool is easier to use by human.
pfctl is well suited for both, and it always should be.



Re: pfctl should allow administrator to flush _anchors

2019-02-22 Thread Alexandr Nedvedicky
Hello Klemens,

I just need to clarify some details.


> > the 'unreferenced' means the anchor is not reachable by any packet.
> > like there is no path for packet between main ruleset and that 
> > particular
> > anchor (and all its descendants).
> Yes.  With the regress suite for example, the following should leave no
> trace of regress anchors or rules:
> 
>   make
>   pfctl -f /etc/pf.conf
>   pfctl -F Anchors

so the option '-F Anchors' will also perform a '-Fr' on main ruleset, is
that correct?

And also one more thing, which comes to my mind. How '-F Anchors' should
treat tables attached to anchors?

the firewall service (which is a kind of rc-script in fact)  on Solaris,
kills (removes) all tables first, then it removes anchors.

What shall we do in case of '-F Anchors'? do we want '-F Anchors' to
kill attached tables too? Or should it just report "anchor can't be
removed, because table is still attached?"

It looks like '-F Anchors' shifts pfctl(8) from simple tool, which does
exactly what it's told to do, to advanced tool, which does more things at
one step.

The simple tools just seem to be more friendly for scripts, while advanced
tool is easier to use by human.

thanks and
regards
sasha



Re: pfctl should allow administrator to flush _anchors

2019-02-22 Thread Klemens Nanni
On Fri, Feb 22, 2019 at 12:42:02PM +0100, Alexandr Nedvedicky wrote:
> yes, that's what I thought. We have a kind 'service' on Solaris, which
> wraps pfctl to manage firewall. If firewall is being enabled, the service
> cleans up all rules (anchors). We basically dump the rulesets (pfctl -vsA)
> and then traverse from leaves to root to clean it up.
That's probaly how I'd approach `-F Anchors'.

> so if I understand you right, your scenario for ruleset from my
> first email works as follows:
>   pfctl -Fr   # makes the anchors _1 and _1/_2 unreferenced
>   # (they are not reachable from root any more)
> 
>   pfctl -FAnchors # purge all unreferenced anchors.
> 
> the 'unreferenced' means the anchor is not reachable by any packet.
> like there is no path for packet between main ruleset and that particular
> anchor (and all its descendants).
Yes.  With the regress suite for example, the following should leave no
trace of regress anchors or rules:

make
pfctl -f /etc/pf.conf
pfctl -F Anchors

> sure, I agree, adding -FAnchors options i more systemic approach, though
> such change is more complex. I think I can give it a try to prototype it.
Cool! I'm happy to help here.



Re: pfctl should allow administrator to flush _anchors

2019-02-22 Thread Alexandr Nedvedicky
Hello,

On Fri, Feb 22, 2019 at 10:55:17AM +0100, Klemens Nanni wrote:
> On Fri, Feb 22, 2019 at 01:52:24AM +0100, Alexandr Nedvedicky wrote:
>  
> > so far so good. Now let's flush the rules from kernel:
> > 
> > lumpy# ./pfctl -Fr
> > rules cleared
> > lumpy# ./pfctl -sr
> > lumpy#
> > 
> > However the underscore anchors are still there:
> Any unreferenced anchor will remain, not just internal ones.  We have no
> code/logic that clears them automatically.

yes, that's what I thought. We have a kind 'service' on Solaris, which
wraps pfctl to manage firewall. If firewall is being enabled, the service
cleans up all rules (anchors). We basically dump the rulesets (pfctl -vsA)
and then traverse from leaves to root to clean it up.
> 
> > lumpy# ./pfctl -vsA
> >   _1
> >   _1/_2
> > lumpy# 
> That's a known issue, easily visible if you run the pfctl regress tests.
> I've been pondering this with different attempts but haven't come up
> with a good/safe one yet.

unlike named anchors, the Solaris service can't remove the 'underscore'
anchors.  my patch solves that glitch for Solaris.
I was looking for the smallest change possible, which will fix Solaris
without introducing too much risk/changes in upstream.

> 
> Perhaps we can teach pfctl something like `-F Anchors`, such that it
> looks at the ruleset as well as all anchors and removes those which are
> not referenced.

so if I understand you right, your scenario for ruleset from my
first email works as follows:
pfctl -Fr   # makes the anchors _1 and _1/_2 unreferenced
# (they are not reachable from root any more)

pfctl -FAnchors # purge all unreferenced anchors.

the 'unreferenced' means the anchor is not reachable by any packet.
like there is no path for packet between main ruleset and that particular
anchor (and all its descendants).
> 
> The benefits are that we do not require any further
> starts-with-underscore quirks and it remains a wilful action done by
> root.

sure, I agree, adding -FAnchors options i more systemic approach, though
such change is more complex. I think I can give it a try to prototype it.

> 
> > I could not figure out any existing way to remove them, hence I'm proposing
> > small patch, which allows me to remove those 'underscore' anchors by doing
> > this:
> > 
> > lumpy# ./pfctl -a _1/_2 -Fr
> > rules cleared
> > lumpy# ./pfctl -a _1 -Fr
> > rules cleared
> Did you look at happens with _1/_2 when you flush _1 directly?

yes, the ruleset becomes empty, but it still hanging around,
because its descendant (_1/_2) contains the block rule.
the terminal looks as follows:

lumpy# pfctl -f /tmp/pf.conf  
lumpy# ./pfctl -Fr  
   
rules cleared
lumpy# ./pfctl -a _1 -Fr
rules cleared
lumpy# ./pfctl -vsA 
   
  _1
  _1/_2
lumpy# ./pfctl -a _1 -sr
lumpy# ./pfctl -a _1/_2 -sr
block drop all
lumpy# 

> 
> > Does patch below make sense? Or are there some pitfalls I'm not aware of?
> Given your example, using named anchors seems like the right approach.
> 
> > +   /*
> > +* we want enable administrator to flush anonymous anchors,
> > +* thus '_' should be allowed for '-Fr' only.  Also make sure
> > +* we fail in case of option combination as follows:
> > +*  pfctl -a _1 -Fr -f /some/rules.conf
> > +*/
> > if (mode == O_RDWR && tblcmdopt == NULL &&
> > +   (clearopt == NULL || *clearopt != 'r' ||
> > +   rulesopt != NULL) &&
> I'm not fond of adding an exception to what already is an exception.
> The anchor handling code is tricky already and has big potential for
> pitfalls and subtle bugs (as seen in the past).

I completely agree here.

> 
> > (anchoropt[0] == '_' || strstr(anchoropt, "/_") != NULL))
> > errx(1, "anchor names beginning with '_' cannot "
> > "be modified from the command line");
> 
> That said, I think the internal semantics should stay purely internal to
> avoid another can of worms.

I partially agree here. As I don't think the current semantics is purely
internal. IMO the underscore just denotes a kind of namespace, which
requires special handling. I read it as 'name created by PF'. And as such
is too weak to constitute a 'purely internal', because the rules contained
in _1 anchor are coming from administrator not from PF itself.

I agree with 'can of worms'. So let's see what else I'm going to find
when I'll try to prototype '-FAnchors'.

thanks and
regards
sashan



Re: pfctl should allow administrator to flush _anchors

2019-02-22 Thread Klemens Nanni
On Fri, Feb 22, 2019 at 01:52:24AM +0100, Alexandr Nedvedicky wrote:
 
> so far so good. Now let's flush the rules from kernel:
> 
> lumpy# ./pfctl -Fr
> rules cleared
> lumpy# ./pfctl -sr
> lumpy#
> 
> However the underscore anchors are still there:
Any unreferenced anchor will remain, not just internal ones.  We have no
code/logic that clears them automatically.

> lumpy# ./pfctl -vsA
>   _1
>   _1/_2
> lumpy# 
That's a known issue, easily visible if you run the pfctl regress tests.
I've been pondering this with different attempts but haven't come up
with a good/safe one yet.

Perhaps we can teach pfctl something like `-F Anchors`, such that it
looks at the ruleset as well as all anchors and removes those which are
not referenced.

The benefits are that we do not require any further
starts-with-underscore quirks and it remains a wilful action done by
root.

> I could not figure out any existing way to remove them, hence I'm proposing
> small patch, which allows me to remove those 'underscore' anchors by doing
> this:
> 
> lumpy# ./pfctl -a _1/_2 -Fr
> rules cleared
> lumpy# ./pfctl -a _1 -Fr
> rules cleared
Did you look at happens with _1/_2 when you flush _1 directly?

> Does patch below make sense? Or are there some pitfalls I'm not aware of?
Given your example, using named anchors seems like the right approach.

> + /*
> +  * we want enable administrator to flush anonymous anchors,
> +  * thus '_' should be allowed for '-Fr' only.  Also make sure
> +  * we fail in case of option combination as follows:
> +  *  pfctl -a _1 -Fr -f /some/rules.conf
> +  */
>   if (mode == O_RDWR && tblcmdopt == NULL &&
> + (clearopt == NULL || *clearopt != 'r' ||
> + rulesopt != NULL) &&
I'm not fond of adding an exception to what already is an exception.
The anchor handling code is tricky already and has big potential for
pitfalls and subtle bugs (as seen in the past).

>   (anchoropt[0] == '_' || strstr(anchoropt, "/_") != NULL))
>   errx(1, "anchor names beginning with '_' cannot "
>   "be modified from the command line");

That said, I think the internal semantics should stay purely internal to
avoid another can of worms.



pfctl should allow administrator to flush _anchors

2019-02-21 Thread Alexandr Nedvedicky
Hello,

This issue has been reported by one of our customers.

consider pf.conf comes with rules as follows:

anchor {
pass all
anchor {
block all
}
}

We load pf.conf to kernel and (pfctl -f pf.conf) and display what got loaded:

lumpy# ./pfctl -f /tmp/pf.conf
lumpy# ./pfctl -sr
anchor all {
  pass all flags S/SA
  anchor all {
block drop all
  }
}

so far so good. Now let's flush the rules from kernel:

lumpy# ./pfctl -Fr
rules cleared
lumpy# ./pfctl -sr
lumpy#

However the underscore anchors are still there:

lumpy# ./pfctl -vsA
  _1
  _1/_2
lumpy# 

I could not figure out any existing way to remove them, hence I'm proposing
small patch, which allows me to remove those 'underscore' anchors by doing
this:

lumpy# ./pfctl -a _1/_2 -Fr
rules cleared
lumpy# ./pfctl -a _1 -Fr
rules cleared
lumpy# ./pfctl -vsA
lumpy# 

Does patch below make sense? Or are there some pitfalls I'm not aware of?

thanks and
regards
sashan

8<---8<---8<--8<
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -2445,7 +2445,16 @@ main(int argc, char *argv[])
warnx("anchors apply to -f, -F, -s, and -T only");
usage();
}
+
+   /*
+* we want enable administrator to flush anonymous anchors,
+* thus '_' should be allowed for '-Fr' only.  Also make sure
+* we fail in case of option combination as follows:
+*  pfctl -a _1 -Fr -f /some/rules.conf
+*/
if (mode == O_RDWR && tblcmdopt == NULL &&
+   (clearopt == NULL || *clearopt != 'r' ||
+   rulesopt != NULL) &&
(anchoropt[0] == '_' || strstr(anchoropt, "/_") != NULL))
errx(1, "anchor names beginning with '_' cannot "
"be modified from the command line");