Import OPENBSD_4_3_BASE

This commit is contained in:
Max Laier 2008-12-10 20:59:26 +00:00
parent b39deb12b6
commit a13f3058fb
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/pf/dist/; revision=185880
svn path=/vendor/pf/4.3/; revision=185881; tag=vendor/pf/4.3
21 changed files with 1064 additions and 595 deletions

View File

@ -1,7 +1,11 @@
# $OpenBSD: Makefile,v 1.12 2004/04/25 19:24:52 deraadt Exp $
# $OpenBSD: Makefile,v 1.13 2008/02/14 01:49:17 mcbride Exp $
PROG= authpf
MAN= authpf.8
LINKS= ${BINDIR}/authpf ${BINDIR}/authpf-noip
MLINKS+=authpf.8 authpf-noip.8
BINOWN= root
BINGRP= authpf
BINMODE= 6555

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: authpf.8,v 1.44 2007/05/31 19:20:22 jmc Exp $
.\" $OpenBSD: authpf.8,v 1.45 2008/02/14 01:49:17 mcbride Exp $
.\"
.\" Copyright (c) 1998-2007 Bob Beck (beck@openbsd.org>. All rights reserved.
.\"
@ -14,14 +14,16 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate$
.Dd $Mdocdate: May 31 2007 $
.Dt AUTHPF 8
.Os
.Sh NAME
.Nm authpf
.Nm authpf ,
.Nm authpf-noip
.Nd authenticating gateway user shell
.Sh SYNOPSIS
.Nm authpf
.Nm authpf-noip
.Sh DESCRIPTION
.Nm
is a user shell for authenticating gateways.
@ -30,43 +32,63 @@ It is used to change
rules when a user authenticates and starts a session with
.Xr sshd 8
and to undo these changes when the user's session exits.
It is designed for changing filter and translation rules for an individual
source IP address as long as a user maintains an active
.Xr ssh 1
session.
Typical use would be for a gateway that authenticates users before
allowing them Internet use, or a gateway that allows different users into
different places.
Combined with properly set up filter rules and secure switches,
.Nm
logs the successful start and end of a session to
.Xr syslogd 8 .
This, combined with properly set up filter rules and secure switches,
can be used to ensure users are held accountable for their network traffic.
.Pp
.Nm
can add filter and translation rules using the syntax described in
.Xr pf.conf 5 .
.Nm
requires that the
.Xr pf 4
system be enabled before use.
.Nm
can also maintain the list of IP address of connected users
in the "authpf_users"
.Pa table .
.Pp
.Nm
is meant to be used with users who can connect via
It is meant to be used with users who can connect via
.Xr ssh 1
only.
On startup,
only, and requires the
.Xr pf 4
subsystem to be enabled.
.Pp
.Nm authpf-noip
is a user shell
which allows multiple connections to take
place from the same IP address.
It is useful primarily in cases where connections are tunneled via
the gateway system, and can be directly associated with the user name.
It cannot ensure accountability when
classifying connections by IP address;
in this case the client's IP address
is not provided to the packet filter via the
.Ar client_ip
macro or the
.Ar authpf users
table.
Additionally, states associated with the client IP address
are not purged when the session is ended.
.Pp
To use either
.Nm
or
.Nm authpf-noip ,
the user's shell needs to be set to
.Pa /usr/sbin/authpf
or
.Pa /usr/sbin/authpf-noip .
.Pp
.Nm
uses the
.Xr pf.conf 5
syntax to change filter and translation rules for an individual
user or client IP address as long as a user maintains an active
.Xr ssh 1
session, and logs the successful start and end of a session to
.Xr syslogd 8 .
.Nm
retrieves the client's connecting IP address via the
.Ev SSH_CLIENT
environment variable and, after performing additional access checks,
reads a template file to determine what filter and translation rules
(if any) to add.
On session exit the same rules that were added at startup are removed.
(if any) to add, and
maintains the list of IP addresses of connected users in the
.Ar authpf_users
table.
On session exit the same rules and table entries that were added at startup
are removed, and all states associated with the client's IP address are purged.
.Pp
Each
.Nm
@ -496,6 +518,31 @@ table <authpf_users> persist
anchor "authpf/*" from <authpf_users>
rdr-anchor "authpf/*" from <authpf_users>
.Ed
.Pp
.Sy Tunneled users
\- normally
.Nm
allows only one session per client IP address.
However in some cases, such as when connections are tunneled via
.Xr ssh 1
or
.Xr ipsec 4 ,
the connections can be authorized based on the userid of the user instead of
the client IP address.
In this case it is appropriate to use
.Nm authpf-noip
to allow multiple users behind a NAT gateway to connect.
In the
.Pa /etc/authpf/authpf.rules
example below, the remote user could tunnel a remote desktop session to their
workstation:
.Bd -literal
internal_if="bge0"
workstation_ip="10.2.3.4"
pass out on $internal_if from (self) to $workstation_ip port 3389 \e
user $user_id
.Ed
.Sh FILES
.Bl -tag -width "/etc/authpf/authpf.conf" -compact
.It Pa /etc/authpf/authpf.conf

View File

@ -1,4 +1,4 @@
/* $OpenBSD: authpf.c,v 1.104 2007/02/24 17:35:08 beck Exp $ */
/* $OpenBSD: authpf.c,v 1.107 2008/02/14 01:49:17 mcbride Exp $ */
/*
* Copyright (C) 1998 - 2007 Bob Beck (beck@openbsd.org).
@ -46,6 +46,7 @@ static void print_message(char *);
static int allowed_luser(char *);
static int check_luser(char *, char *);
static int remove_stale_rulesets(void);
static int recursive_ruleset_purge(char *, char *);
static int change_filter(int, const char *, const char *);
static int change_table(int, const char *);
static void authpf_kill_states(void);
@ -54,6 +55,7 @@ int dev; /* pf device */
char anchorname[PF_ANCHOR_NAME_SIZE] = "authpf";
char rulesetname[MAXPATHLEN - PF_ANCHOR_NAME_SIZE - 2];
char tablename[PF_TABLE_NAME_SIZE] = "authpf_users";
int user_ip = 1; /* controls whether $user_ip is set */
FILE *pidfp;
char luser[MAXLOGNAME]; /* username */
@ -65,6 +67,7 @@ struct timeval Tstart, Tend; /* start and end times of session */
volatile sig_atomic_t want_death;
static void need_death(int signo);
static __dead void do_death(int);
extern char *__progname; /* program name */
/*
* User shell for authenticating gateways. Sole purpose is to allow
@ -85,6 +88,9 @@ main(int argc, char *argv[])
char *shell;
login_cap_t *lc;
if (strcmp(__progname, "-authpf-noip") == 0)
user_ip = 0;
config = fopen(PATH_CONFFILE, "r");
if (config == NULL) {
syslog(LOG_ERR, "can not open %s (%m)", PATH_CONFFILE);
@ -139,7 +145,8 @@ main(int argc, char *argv[])
login_close(lc);
if (strcmp(shell, PATH_AUTHPF_SHELL)) {
if (strcmp(shell, PATH_AUTHPF_SHELL) &&
strcmp(shell, PATH_AUTHPF_SHELL_NOIP)) {
syslog(LOG_ERR, "wrong shell for user %s, uid %u",
pw->pw_name, pw->pw_uid);
if (shell != pw->pw_shell)
@ -171,8 +178,9 @@ main(int argc, char *argv[])
}
/* Make our entry in /var/authpf as /var/authpf/ipaddr */
n = snprintf(pidfile, sizeof(pidfile), "%s/%s", PATH_PIDFILE, ipsrc);
/* Make our entry in /var/authpf as ipaddr or username */
n = snprintf(pidfile, sizeof(pidfile), "%s/%s",
PATH_PIDFILE, user_ip ? ipsrc : luser);
if (n < 0 || (u_int)n >= sizeof(pidfile)) {
syslog(LOG_ERR, "path to pidfile too long");
goto die;
@ -292,7 +300,7 @@ main(int argc, char *argv[])
printf("Unable to modify filters\r\n");
do_death(0);
}
if (change_table(1, ipsrc) == -1) {
if (user_ip && change_table(1, ipsrc) == -1) {
printf("Unable to modify table\r\n");
change_filter(0, luser, ipsrc);
do_death(0);
@ -349,6 +357,8 @@ read_config(FILE *f)
}
i++;
len = strlen(buf);
if (len == 0)
continue;
if (buf[len - 1] != '\n' && !feof(f)) {
syslog(LOG_ERR, "line %d too long in %s", i,
PATH_CONFFILE);
@ -569,7 +579,7 @@ static int
remove_stale_rulesets(void)
{
struct pfioc_ruleset prs;
u_int32_t nr, mnr;
u_int32_t nr;
memset(&prs, 0, sizeof(prs));
strlcpy(prs.path, anchorname, sizeof(prs.path));
@ -580,13 +590,12 @@ remove_stale_rulesets(void)
return (1);
}
mnr = prs.nr;
nr = 0;
while (nr < mnr) {
nr = prs.nr;
while (nr) {
char *s, *t;
pid_t pid;
prs.nr = nr;
prs.nr = nr - 1;
if (ioctl(dev, DIOCGETRULESET, &prs))
return (1);
errno = 0;
@ -598,111 +607,156 @@ remove_stale_rulesets(void)
if (!prs.name[0] || errno ||
(*s && (t == prs.name || *s != ')')))
return (1);
if (kill(pid, 0) && errno != EPERM) {
int i;
struct pfioc_trans_e t_e[PF_RULESET_MAX+1];
struct pfioc_trans t;
bzero(&t, sizeof(t));
bzero(t_e, sizeof(t_e));
t.size = PF_RULESET_MAX+1;
t.esize = sizeof(t_e[0]);
t.array = t_e;
for (i = 0; i < PF_RULESET_MAX+1; ++i) {
t_e[i].rs_num = i;
snprintf(t_e[i].anchor, sizeof(t_e[i].anchor),
"%s/%s", anchorname, prs.name);
}
t_e[PF_RULESET_MAX].rs_num = PF_RULESET_TABLE;
if ((ioctl(dev, DIOCXBEGIN, &t) ||
ioctl(dev, DIOCXCOMMIT, &t)) &&
errno != EINVAL)
if ((kill(pid, 0) && errno != EPERM) || pid == getpid()) {
if (recursive_ruleset_purge(anchorname, prs.name))
return (1);
mnr--;
} else
nr++;
}
nr--;
}
return (0);
}
static int
recursive_ruleset_purge(char *an, char *rs)
{
struct pfioc_trans_e *t_e = NULL;
struct pfioc_trans *t = NULL;
struct pfioc_ruleset *prs = NULL;
int i;
/* purge rules */
errno = 0;
if ((t = calloc(1, sizeof(struct pfioc_trans))) == NULL)
goto no_mem;
if ((t_e = calloc(PF_RULESET_MAX+1,
sizeof(struct pfioc_trans_e))) == NULL)
goto no_mem;
t->size = PF_RULESET_MAX+1;
t->esize = sizeof(struct pfioc_trans_e);
t->array = t_e;
for (i = 0; i < PF_RULESET_MAX+1; ++i) {
t_e[i].rs_num = i;
snprintf(t_e[i].anchor, sizeof(t_e[i].anchor), "%s/%s", an, rs);
}
t_e[PF_RULESET_MAX].rs_num = PF_RULESET_TABLE;
if ((ioctl(dev, DIOCXBEGIN, t) ||
ioctl(dev, DIOCXCOMMIT, t)) &&
errno != EINVAL)
goto cleanup;
/* purge any children */
if ((prs = calloc(1, sizeof(struct pfioc_ruleset))) == NULL)
goto no_mem;
snprintf(prs->path, sizeof(prs->path), "%s/%s", an, rs);
if (ioctl(dev, DIOCGETRULESETS, prs)) {
if (errno != EINVAL)
goto cleanup;
errno = 0;
} else {
int nr = prs->nr;
while (nr) {
prs->nr = 0;
if (ioctl(dev, DIOCGETRULESET, prs))
goto cleanup;
if (recursive_ruleset_purge(prs->path, prs->name))
goto cleanup;
nr--;
}
}
no_mem:
if (errno == ENOMEM)
syslog(LOG_ERR, "calloc failed");
cleanup:
free(t);
free(t_e);
free(prs);
return (errno);
}
/*
* Add/remove filter entries for user "luser" from ip "ipsrc"
*/
static int
change_filter(int add, const char *luser, const char *ipsrc)
{
char *pargv[13] = {
"pfctl", "-p", "/dev/pf", "-q", "-a", "anchor/ruleset",
"-D", "user_ip=X", "-D", "user_id=X", "-f",
"file", NULL
};
char *fdpath = NULL, *userstr = NULL, *ipstr = NULL;
char *rsn = NULL, *fn = NULL;
pid_t pid;
gid_t gid;
int s;
if (luser == NULL || !luser[0] || ipsrc == NULL || !ipsrc[0]) {
syslog(LOG_ERR, "invalid luser/ipsrc");
goto error;
}
if (asprintf(&rsn, "%s/%s", anchorname, rulesetname) == -1)
goto no_mem;
if (asprintf(&fdpath, "/dev/fd/%d", dev) == -1)
goto no_mem;
if (asprintf(&ipstr, "user_ip=%s", ipsrc) == -1)
goto no_mem;
if (asprintf(&userstr, "user_id=%s", luser) == -1)
goto no_mem;
if (add) {
struct stat sb;
char *pargv[13] = {
"pfctl", "-p", "/dev/pf", "-q", "-a", "anchor/ruleset",
"-D", "user_id=X", "-D", "user_ip=X", "-f", "file", NULL
};
if (asprintf(&fn, "%s/%s/authpf.rules", PATH_USER_DIR, luser)
== -1)
if (luser == NULL || !luser[0] || ipsrc == NULL || !ipsrc[0]) {
syslog(LOG_ERR, "invalid luser/ipsrc");
goto error;
}
if (asprintf(&rsn, "%s/%s", anchorname, rulesetname) == -1)
goto no_mem;
if (asprintf(&fdpath, "/dev/fd/%d", dev) == -1)
goto no_mem;
if (asprintf(&ipstr, "user_ip=%s", ipsrc) == -1)
goto no_mem;
if (asprintf(&userstr, "user_id=%s", luser) == -1)
goto no_mem;
if (asprintf(&fn, "%s/%s/authpf.rules",
PATH_USER_DIR, luser) == -1)
goto no_mem;
if (stat(fn, &sb) == -1) {
free(fn);
if ((fn = strdup(PATH_PFRULES)) == NULL)
goto no_mem;
}
}
pargv[2] = fdpath;
pargv[5] = rsn;
pargv[7] = userstr;
pargv[9] = ipstr;
if (!add)
pargv[11] = "/dev/null";
else
pargv[11] = fn;
switch (pid = fork()) {
case -1:
syslog(LOG_ERR, "fork failed");
goto error;
case 0:
/* revoke group privs before exec */
gid = getgid();
if (setregid(gid, gid) == -1) {
err(1, "setregid");
pargv[2] = fdpath;
pargv[5] = rsn;
pargv[7] = userstr;
if (user_ip) {
pargv[9] = ipstr;
pargv[11] = fn;
} else {
pargv[8] = "-f";
pargv[9] = fn;
pargv[10] = NULL;
}
execvp(PATH_PFCTL, pargv);
warn("exec of %s failed", PATH_PFCTL);
_exit(1);
}
/* parent */
waitpid(pid, &s, 0);
if (s != 0) {
syslog(LOG_ERR, "pfctl exited abnormally");
goto error;
}
switch (pid = fork()) {
case -1:
syslog(LOG_ERR, "fork failed");
goto error;
case 0:
/* revoke group privs before exec */
gid = getgid();
if (setregid(gid, gid) == -1) {
err(1, "setregid");
}
execvp(PATH_PFCTL, pargv);
warn("exec of %s failed", PATH_PFCTL);
_exit(1);
}
/* parent */
waitpid(pid, &s, 0);
if (s != 0) {
syslog(LOG_ERR, "pfctl exited abnormally");
goto error;
}
if (add) {
gettimeofday(&Tstart, NULL);
syslog(LOG_INFO, "allowing %s, user %s", ipsrc, luser);
} else {
remove_stale_rulesets();
gettimeofday(&Tend, NULL);
syslog(LOG_INFO, "removed %s, user %s - duration %ld seconds",
ipsrc, luser, Tend.tv_sec - Tstart.tv_sec);
@ -819,9 +873,10 @@ do_death(int active)
if (active) {
change_filter(0, luser, ipsrc);
change_table(0, ipsrc);
authpf_kill_states();
remove_stale_rulesets();
if (user_ip) {
change_table(0, ipsrc);
authpf_kill_states();
}
}
if (pidfile[0] && (pidfp != NULL))
if (unlink(pidfile) == -1)

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pathnames.h,v 1.7 2004/04/25 18:40:42 beck Exp $ */
/* $OpenBSD: pathnames.h,v 1.8 2008/02/14 01:49:17 mcbride Exp $ */
/*
* Copyright (C) 2002 Chris Kuethe (ckuethe@ualberta.ca)
@ -35,4 +35,5 @@
#define PATH_DEVFILE "/dev/pf"
#define PATH_PIDFILE "/var/authpf"
#define PATH_AUTHPF_SHELL "/usr/sbin/authpf"
#define PATH_AUTHPF_SHELL_NOIP "/usr/sbin/authpf-noip"
#define PATH_PFCTL "/sbin/pfctl"

View File

@ -1,4 +1,4 @@
/* $OpenBSD: filter.c,v 1.6 2007/08/01 09:31:41 henning Exp $ */
/* $OpenBSD: filter.c,v 1.7 2008/02/26 18:52:53 henning Exp $ */
/*
* Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl>
@ -277,15 +277,13 @@ prepare_rule(u_int32_t id, int rs_num, struct sockaddr *src,
}
pfr.rule.dst.port_op = PF_OP_EQ;
pfr.rule.dst.port[0] = htons(d_port);
if (tagname != NULL)
strlcpy(pfr.rule.tagname, tagname, sizeof pfr.rule.tagname);
switch (rs_num) {
case PF_RULESET_FILTER:
/*
* pass quick [log] inet[6] proto tcp \
* pass [quick] [log] inet[6] proto tcp \
* from $src to $dst port = $d_port flags S/SA keep state
* (max 1) [queue qname]
* (max 1) [queue qname] [tag tagname]
*/
pfr.rule.action = PF_PASS;
pfr.rule.quick = 1;
@ -296,6 +294,11 @@ prepare_rule(u_int32_t id, int rs_num, struct sockaddr *src,
pfr.rule.max_states = 1;
if (qname != NULL)
strlcpy(pfr.rule.qname, qname, sizeof pfr.rule.qname);
if (tagname != NULL) {
pfr.rule.quick = 0;
strlcpy(pfr.rule.tagname, tagname,
sizeof pfr.rule.tagname);
}
break;
case PF_RULESET_NAT:
/*

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: ftp-proxy.8,v 1.10 2007/08/01 15:45:41 jmc Exp $
.\" $OpenBSD: ftp-proxy.8,v 1.11 2008/02/26 18:52:53 henning Exp $
.\"
.\" Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl>
.\"
@ -21,7 +21,7 @@
.Nm ftp-proxy
.Nd Internet File Transfer Protocol proxy daemon
.Sh SYNOPSIS
.Nm ftp-proxy
.Nm
.Bk -words
.Op Fl 6Adrv
.Op Fl a Ar address
@ -59,7 +59,7 @@ facility for this.
Assuming the FTP control connection is from $client to $server, the
proxy connected to the server using the $proxy source address, and
$port is negotiated, then
.Nm ftp-proxy
.Nm
adds the following rules to the various anchors.
(These example rules use inet, but the proxy also supports inet6.)
.Pp
@ -132,9 +132,19 @@ connections to another proxy.
Rewrite sourceport to 20 in active mode to suit ancient clients that insist
on this RFC property.
.It Fl T Ar tag
Automatically tag packets passing through the
The filter rules will add tag
.Ar tag
to data connections, and not match quick.
This way alternative rules that use the
.Ar tagged
keyword can be implemented following the
.Nm
anchor.
These rules can use special
.Xr pf 4
rule with the name supplied.
features like route-to, reply-to, label, rtable, overload, etc. that
.Nm
does not implement itself.
.It Fl t Ar timeout
Number of seconds that the control connection can be idle, before the
proxy will disconnect.
@ -177,7 +187,7 @@ does not allow the ruleset to be modified if the system is running at a
.Xr securelevel 7
higher than 1.
At that level
.Nm ftp-proxy
.Nm
cannot add rules to the anchors and FTP data connections may get blocked.
.Pp
Negotiated data connection ports below 1024 are not allowed.
@ -186,5 +196,5 @@ The negotiated IP address for active modes is ignored for security
reasons.
This makes third party file transfers impossible.
.Pp
.Nm ftp-proxy
.Nm
chroots to "/var/empty" and changes to user "proxy" to drop privileges.

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ftp-proxy.c,v 1.15 2007/08/15 15:18:02 camield Exp $ */
/* $OpenBSD: ftp-proxy.c,v 1.16 2008/02/26 18:52:53 henning Exp $ */
/*
* Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl>
@ -1117,6 +1117,7 @@ usage(void)
{
fprintf(stderr, "usage: %s [-6Adrv] [-a address] [-b address]"
" [-D level] [-m maxsessions]\n [-P port]"
" [-p port] [-q queue] [-R address] [-T tag] [-t timeout]\n", __progname);
" [-p port] [-q queue] [-R address] [-T tag]\n"
" [-t timeout]\n", __progname);
exit(1);
}

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: pf.4,v 1.59 2007/05/31 19:19:51 jmc Exp $
.\" $OpenBSD: pf.4,v 1.60 2007/12/02 12:08:04 pascoe Exp $
.\"
.\" Copyright (C) 2001, Kjell Wooding. All rights reserved.
.\"
@ -26,7 +26,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd $Mdocdate$
.Dd $Mdocdate: May 31 2007 $
.Dt PF 4
.Os
.Sh NAME
@ -292,14 +292,17 @@ if another process is concurrently updating a ruleset.
Add a state entry.
.Bd -literal
struct pfioc_state {
u_int32_t nr;
struct pf_state state;
struct pfsync_state state;
};
.Ed
.It Dv DIOCGETSTATE Fa "struct pfioc_state *ps"
Extract the entry with the specified number
.Va nr
from the state table.
Extract the entry identified by the
.Va id
and
.Va creatorid
fields of the
.Va state
structure from the state table.
.It Dv DIOCKILLSTATES Fa "struct pfioc_state_kill *psk"
Remove matching entries from the state table.
This ioctl returns the number of killed states in

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: pf.conf.5,v 1.383 2007/07/17 16:27:38 jmc Exp $
.\" $OpenBSD: pf.conf.5,v 1.393 2008/02/11 07:46:32 jmc Exp $
.\"
.\" Copyright (c) 2002, Daniel Hartmeier
.\" All rights reserved.
@ -27,7 +27,7 @@
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd $Mdocdate: June 26 2007 $
.Dd $Mdocdate: Febuary 1 2008 $
.Dt PF.CONF 5
.Os
.Sh NAME
@ -78,6 +78,17 @@ By default
enforces this order (see
.Ar set require-order
below).
.Pp
Comments can be put anywhere in the file using a hash mark
.Pq Sq # ,
and extend to the end of the current line.
.Pp
Additional configuration files can be included with the
.Ic include
keyword, for example:
.Bd -literal -offset indent
include "/etc/pf/sub.filter.conf"
.Ed
.Sh MACROS
Macros can be defined that will later be expanded in context.
Macro names must start with a letter, and may contain letters, digits
@ -327,7 +338,8 @@ With 9000 state table entries, the timeout values are scaled to 50%
(tcp.first 60, tcp.established 43200).
.Pp
.It Ar set loginterface
Enable collection of packet and byte count statistics for the given interface.
Enable collection of packet and byte count statistics for the given
interface or interface group.
These statistics can be viewed using
.Bd -literal -offset indent
# pfctl -s info
@ -808,7 +820,7 @@ assigned.
.Ar Priority
mainly controls the time packets take to get sent out, while
.Ar bandwidth
has primarily effects on throughput.
primarily affects throughput.
.Ar hfsc
supports both link-sharing and guaranteed real-time services.
It employs a service curve based QoS model,
@ -1163,7 +1175,7 @@ or to the firewall itself.
Note that redirecting external incoming connections to the loopback
address, as in
.Bd -literal -offset indent
rdr on ne3 inet proto tcp to port spamd -\*(Gt 127.0.0.1 port smtp
rdr on ne3 inet proto tcp to port smtp -\*(Gt 127.0.0.1 port spamd
.Ed
.Pp
will effectively allow an external host to connect to daemons
@ -1442,6 +1454,14 @@ the route back to the packet's source address.
Any address that matches the given table.
.El
.Pp
Ranges of addresses are specified by using the
.Sq -
operator.
For instance:
.Dq 10.1.1.10 - 10.1.1.12
means all addresses from 10.1.1.10 to 10.1.1.12,
hence addresses 10.1.1.10, 10.1.1.11, and 10.1.1.12.
.Pp
Interface names and interface group names can have modifiers appended:
.Pp
.Bl -tag -width xxxxxxxxxxxx -compact
@ -2023,8 +2043,8 @@ must be specified explicitly to apply options to a rule.
.Bl -tag -width xxxx -compact
.It Ar max Aq Ar number
Limits the number of concurrent states the rule may create.
When this limit is reached, further packets matching the rule that would
create state are dropped, until existing states time out.
When this limit is reached, further packets that would create
state will not match this rule until existing states time out.
.It Ar no-sync
Prevent state changes for states created by this rule from appearing on the
.Xr pfsync 4
@ -2442,10 +2462,8 @@ into the anchor.
.Pp
Optionally,
.Ar anchor
rules can specify the parameter's
direction, interface, address family, protocol and source/destination
address/port
using the same syntax as filter rules.
rules can specify packet filtering parameters using the same syntax as
filter rules.
When parameters are used, the
.Ar anchor
rule is only evaluated for matching packets.
@ -2526,8 +2544,8 @@ anchor "external" on egress {
.Ed
.Pp
Since the parser specification for anchor names is a string, any
reference to an anchor name containing solidus
.Pq Sq /
reference to an anchor name containing
.Sq /
characters will require double quote
.Pq Sq \&"
characters around the anchor name.
@ -2749,10 +2767,11 @@ in BNF:
.Bd -literal
line = ( option | pf-rule | nat-rule | binat-rule | rdr-rule |
antispoof-rule | altq-rule | queue-rule | trans-anchors |
anchor-rule | anchor-close | load-anchor | table-rule | )
anchor-rule | anchor-close | load-anchor | table-rule |
include )
option = "set" ( [ "timeout" ( timeout | "{" timeout-list "}" ) ] |
[ "ruleset-optimization" [ "none" | "basic" | "profile" ]] |
[ "ruleset-optimization" [ "none" | "basic" | "profile" ]] |
[ "optimization" [ "default" | "normal" |
"high-latency" | "satellite" |
"aggressive" | "conservative" ] ]
@ -2821,7 +2840,7 @@ queue-rule = "queue" string [ "on" interface-name ] queueopts-list
subqueue
anchor-rule = "anchor" [ string ] [ ( "in" | "out" ) ] [ "on" ifspec ]
[ af ] [ protospec ] [ hosts ] [ "{" ]
[ af ] [ protospec ] [ hosts ] [ filteropt-list ] [ "{" ]
anchor-close = "}"
@ -2956,8 +2975,6 @@ Default location of OS fingerprints.
Protocol name database.
.It Pa /etc/services
Service name database.
.It Pa /usr/share/pf
Example rulesets.
.El
.Sh SEE ALSO
.Xr carp 4 ,

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: pfsync.4,v 1.25 2007/05/31 19:19:51 jmc Exp $
.\" $OpenBSD: pfsync.4,v 1.26 2007/09/20 20:50:07 mpf Exp $
.\"
.\" Copyright (c) 2002 Michael Shalayeff
.\" Copyright (c) 2003-2004 Ryan McBride
@ -24,7 +24,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd $Mdocdate$
.Dd $Mdocdate: May 31 2007 $
.Dt PFSYNC 4
.Os
.Sh NAME
@ -199,8 +199,8 @@ traffic through.
The following should be added to the top of
.Pa /etc/pf.conf :
.Bd -literal -offset indent
pass quick on { sis2 } proto pfsync
pass on { sis0 sis1 } proto carp
pass quick on { sis2 } proto pfsync keep state (no-sync)
pass on { sis0 sis1 } proto carp keep state (no-sync)
.Ed
.Pp
If it is preferable that one firewall handle the traffic,

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pf_print_state.c,v 1.45 2007/05/31 04:13:37 mcbride Exp $ */
/* $OpenBSD: pf_print_state.c,v 1.46 2007/08/30 09:28:49 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@ -79,6 +79,19 @@ print_addr(struct pf_addr_wrap *addr, sa_family_t af, int verbose)
else
printf("<%s>", addr->v.tblname);
return;
case PF_ADDR_RANGE: {
char buf[48];
if (inet_ntop(af, &addr->v.a.addr, buf, sizeof(buf)) == NULL)
printf("?");
else
printf("%s", buf);
if (inet_ntop(af, &addr->v.a.mask, buf, sizeof(buf)) == NULL)
printf(" - ?");
else
printf(" - %s", buf);
break;
}
case PF_ADDR_ADDRMASK:
if (PF_AZERO(&addr->v.a.addr, AF_INET6) &&
PF_AZERO(&addr->v.a.mask, AF_INET6))
@ -108,7 +121,8 @@ print_addr(struct pf_addr_wrap *addr, sa_family_t af, int verbose)
}
/* mask if not _both_ address and mask are zero */
if (!(PF_AZERO(&addr->v.a.addr, AF_INET6) &&
if (addr->type != PF_ADDR_RANGE &&
!(PF_AZERO(&addr->v.a.addr, AF_INET6) &&
PF_AZERO(&addr->v.a.mask, AF_INET6))) {
int bits = unmask(&addr->v.a.mask, af);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pfctl.c,v 1.268 2007/06/30 18:25:08 henning Exp $ */
/* $OpenBSD: pfctl.c,v 1.273 2008/02/13 19:55:12 kettenis Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@ -119,8 +119,6 @@ int dev = -1;
int first_title = 1;
int labels = 0;
const char *infile;
#define INDENT(d, o) do { \
if (o) { \
int i; \
@ -955,7 +953,7 @@ pfctl_show_src_nodes(int dev, int opts)
struct pfioc_src_nodes psn;
struct pf_src_node *p;
char *inbuf = NULL, *newinbuf = NULL;
unsigned len = 0;
unsigned int len = 0;
int i;
memset(&psn, 0, sizeof(psn));
@ -1000,7 +998,7 @@ pfctl_show_states(int dev, const char *iface, int opts)
struct pfioc_states ps;
struct pfsync_state *p;
char *inbuf = NULL, *newinbuf = NULL;
unsigned len = 0;
unsigned int len = 0;
int i, dotitle = (opts & PF_OPT_SHOWALL);
memset(&ps, 0, sizeof(ps));
@ -1337,7 +1335,7 @@ pfctl_add_altq(struct pfctl *pf, struct pf_altq *a)
}
int
pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize,
pfctl_rules(int dev, char *filename, int opts, int optimize,
char *anchorname, struct pfr_buffer *trans)
{
#define ERR(x) do { warn(x); goto _error; } while(0)
@ -1373,7 +1371,6 @@ pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize,
if (strlcpy(trs.pfrt_anchor, anchorname,
sizeof(trs.pfrt_anchor)) >= sizeof(trs.pfrt_anchor))
ERRX("pfctl_rules: strlcpy");
infile = filename;
pf.dev = dev;
pf.opts = opts;
pf.optimize = optimize;
@ -1417,7 +1414,7 @@ pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize,
pfctl_get_ticket(t, PF_RULESET_TABLE, anchorname);
}
if (parse_rules(fin, &pf) < 0) {
if (parse_config(filename, &pf) < 0) {
if ((opts & PF_OPT_NOACTION) == 0)
ERRX("Syntax error in config file: "
"pf rules not loaded");
@ -1443,11 +1440,6 @@ pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize,
if (check_commit_altq(dev, opts) != 0)
ERRX("errors in altq config");
if (fin != stdin) {
fclose(fin);
fin = NULL;
}
/* process "load anchor" directives */
if (!anchorname[0])
if (pfctl_load_anchors(dev, &pf, t) == -1)
@ -1469,8 +1461,6 @@ pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize,
err(1, "DIOCXROLLBACK");
exit(1);
} else { /* sub ruleset */
if (fin != NULL && fin != stdin)
fclose(fin);
return (-1);
}
@ -1502,7 +1492,8 @@ pfctl_fopen(const char *name, const char *mode)
void
pfctl_init_options(struct pfctl *pf)
{
int mib[2], mem;
int64_t mem;
int mib[2];
size_t size;
pf->timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
@ -1533,7 +1524,7 @@ pfctl_init_options(struct pfctl *pf)
pf->limit[PF_LIMIT_TABLE_ENTRIES] = PFR_KENTRY_HIWAT;
mib[0] = CTL_HW;
mib[1] = HW_PHYSMEM;
mib[1] = HW_PHYSMEM64;
size = sizeof(mem);
(void) sysctl(mib, 2, &mem, &size, NULL, 0);
if (mem <= 100*1024*1024)
@ -1559,7 +1550,7 @@ pfctl_load_options(struct pfctl *pf)
}
/*
* If we've set the limit, but havn't explicitly set adaptive
* If we've set the limit, but haven't explicitly set adaptive
* timeouts, do it now with a start of 60% and end of 120%.
*/
if (pf->limit_set[PF_LIMIT_STATES] &&
@ -1957,7 +1948,6 @@ main(int argc, char *argv[])
int optimize = PF_OPTIMIZE_BASIC;
char anchorname[MAXPATHLEN];
char *path;
FILE *fin = NULL;
if (argc < 2)
usage();
@ -2292,15 +2282,6 @@ main(int argc, char *argv[])
}
}
if (rulesopt != NULL) {
if (strcmp(rulesopt, "-") == 0) {
fin = stdin;
rulesopt = "stdin";
} else {
if ((fin = pfctl_fopen(rulesopt, "r")) == NULL)
err(1, "%s", rulesopt);
}
}
if ((rulesopt != NULL) && (loadopt & PFCTL_FLAG_OPTION) &&
!anchorname[0])
if (pfctl_clear_interface_flags(dev, opts | PF_OPT_QUIET))
@ -2315,7 +2296,7 @@ main(int argc, char *argv[])
if (anchorname[0] == '_' || strstr(anchorname, "/_") != NULL)
errx(1, "anchor names beginning with '_' cannot "
"be modified from the command line");
if (pfctl_rules(dev, rulesopt, fin, opts, optimize,
if (pfctl_rules(dev, rulesopt, opts, optimize,
anchorname, NULL))
error = 1;
else if (!(opts & PF_OPT_NOACTION) &&

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pfctl.h,v 1.41 2007/05/31 04:13:37 mcbride Exp $ */
/* $OpenBSD: pfctl.h,v 1.42 2007/12/05 12:01:47 chl Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@ -48,7 +48,6 @@ struct pfr_buffer {
(var) != NULL; \
(var) = pfr_buf_next((buf), (var)))
void pfr_set_fd(int);
int pfr_get_fd(void);
int pfr_clr_tables(struct pfr_table *, int *, int);
int pfr_add_tables(struct pfr_table *, int, int *, int);
@ -63,9 +62,7 @@ int pfr_set_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
int *, int *, int *, int);
int pfr_get_addrs(struct pfr_table *, struct pfr_addr *, int *, int);
int pfr_get_astats(struct pfr_table *, struct pfr_astats *, int *, int);
int pfr_clr_astats(struct pfr_table *, struct pfr_addr *, int, int *, int);
int pfr_tst_addrs(struct pfr_table *, struct pfr_addr *, int, int *, int);
int pfr_set_tflags(struct pfr_table *, int, int, int, int *, int *, int);
int pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *,
int *, int, int);
void pfr_buf_clear(struct pfr_buffer *);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pfctl_altq.c,v 1.92 2007/05/27 05:15:17 claudio Exp $ */
/* $OpenBSD: pfctl_altq.c,v 1.93 2007/10/15 02:16:35 deraadt Exp $ */
/*
* Copyright (c) 2002
@ -138,8 +138,8 @@ qname_to_qid(const char *qname)
}
void
print_altq(const struct pf_altq *a, unsigned level, struct node_queue_bw *bw,
struct node_queue_opt *qopts)
print_altq(const struct pf_altq *a, unsigned int level,
struct node_queue_bw *bw, struct node_queue_opt *qopts)
{
if (a->qname[0] != 0) {
print_queue(a, level, bw, 1, qopts);
@ -175,10 +175,11 @@ print_altq(const struct pf_altq *a, unsigned level, struct node_queue_bw *bw,
}
void
print_queue(const struct pf_altq *a, unsigned level, struct node_queue_bw *bw,
int print_interface, struct node_queue_opt *qopts)
print_queue(const struct pf_altq *a, unsigned int level,
struct node_queue_bw *bw, int print_interface,
struct node_queue_opt *qopts)
{
unsigned i;
unsigned int i;
printf("queue ");
for (i = 0; i < level; ++i)

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pfctl_optimize.c,v 1.13 2006/10/31 14:17:45 mcbride Exp $ */
/* $OpenBSD: pfctl_optimize.c,v 1.16 2008/01/26 13:16:36 mcbride Exp $ */
/*
* Copyright (c) 2004 Mike Frantzen <frantzen@openbsd.org>
@ -395,7 +395,7 @@ optimize_superblock(struct pfctl *pf, struct superblock *block)
* out rules.
*/
/* shortcut. there will be alot of 1-rule superblocks */
/* shortcut. there will be a lot of 1-rule superblocks */
if (!TAILQ_NEXT(TAILQ_FIRST(&block->sb_rules), por_entry))
return (0);
@ -1313,8 +1313,9 @@ pf_opt_create_table(struct pfctl *pf, struct pf_opt_tbl *tbl)
if (pfctl_define_table(tbl->pt_name, PFR_TFLAG_CONST, 1,
pf->anchor->name, tbl->pt_buf, pf->anchor->ruleset.tticket)) {
warn("failed to create table %s", tbl->pt_name);
pf->astack[0]->name, tbl->pt_buf, pf->astack[0]->ruleset.tticket)) {
warn("failed to create table %s in %s",
tbl->pt_name, pf->astack[0]->name);
return (1);
}
return (0);
@ -1417,7 +1418,7 @@ superblock_inclusive(struct superblock *block, struct pf_opt_rule *por)
return (0);
/*
* Have to handle interface groups seperately. Consider the following
* Have to handle interface groups separately. Consider the following
* rules:
* block on EXTIFS to any port 22
* pass on em0 to any port 22
@ -1465,7 +1466,7 @@ superblock_inclusive(struct superblock *block, struct pf_opt_rule *por)
}
if (closest >= 0)
DEBUG("superblock break @ %d on %s+%xh",
DEBUG("superblock break @ %d on %s+%lxh",
por->por_rule.nr,
pf_rule_desc[closest].prf_name,
i - pf_rule_desc[closest].prf_offset -

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pfctl_parser.c,v 1.234 2006/10/31 23:46:24 mcbride Exp $ */
/* $OpenBSD: pfctl_parser.c,v 1.235 2007/10/15 02:16:35 deraadt Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@ -491,7 +491,7 @@ print_status(struct pf_status *s, int opts)
running = s->running ? "Enabled" : "Disabled";
if (s->since) {
unsigned sec, min, hrs, day = runtime;
unsigned int sec, min, hrs, day = runtime;
sec = day % 60;
day /= 60;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pfctl_parser.h,v 1.86 2006/10/31 23:46:25 mcbride Exp $ */
/* $OpenBSD: pfctl_parser.h,v 1.87 2007/10/13 16:35:18 deraadt Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@ -187,7 +187,7 @@ struct pf_opt_rule {
TAILQ_HEAD(pf_opt_queue, pf_opt_rule);
int pfctl_rules(int, char *, FILE *, int, int, char *, struct pfr_buffer *);
int pfctl_rules(int, char *, int, int, char *, struct pfr_buffer *);
int pfctl_optimize_ruleset(struct pfctl *, struct pf_ruleset *);
int pfctl_add_rule(struct pfctl *, struct pf_rule *, const char *);
@ -204,7 +204,7 @@ int pfctl_set_hostid(struct pfctl *, u_int32_t);
int pfctl_set_debug(struct pfctl *, char *);
int pfctl_set_interface_flags(struct pfctl *, char *, int, int);
int parse_rules(FILE *, struct pfctl *);
int parse_config(char *, struct pfctl *);
int parse_flags(char *);
int pfctl_load_anchors(int, struct pfctl *, struct pfr_buffer *);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pfctl_qstats.c,v 1.30 2004/04/27 21:47:32 kjc Exp $ */
/* $OpenBSD: pfctl_qstats.c,v 1.31 2007/10/15 02:16:35 deraadt Exp $ */
/*
* Copyright (c) Henning Brauer <henning@openbsd.org>
@ -233,8 +233,8 @@ pfctl_find_altq_node(struct pf_altq_node *root, const char *qname,
}
void
pfctl_print_altq_node(int dev, const struct pf_altq_node *node, unsigned level,
int opts)
pfctl_print_altq_node(int dev, const struct pf_altq_node *node,
unsigned int level, int opts)
{
const struct pf_altq_node *child;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pfctl_radix.c,v 1.27 2005/05/21 21:03:58 henning Exp $ */
/* $OpenBSD: pfctl_radix.c,v 1.28 2007/12/05 12:01:47 chl Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
@ -299,29 +299,6 @@ pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size,
return (0);
}
int
pfr_clr_astats(struct pfr_table *tbl, struct pfr_addr *addr, int size,
int *nzero, int flags)
{
struct pfioc_table io;
if (tbl == NULL || size < 0 || (size && addr == NULL)) {
errno = EINVAL;
return (-1);
}
bzero(&io, sizeof io);
io.pfrio_flags = flags;
io.pfrio_table = *tbl;
io.pfrio_buffer = addr;
io.pfrio_esize = sizeof(*addr);
io.pfrio_size = size;
if (ioctl(dev, DIOCRCLRASTATS, &io))
return (-1);
if (nzero != NULL)
*nzero = io.pfrio_nzero;
return (0);
}
int
pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags)
{
@ -343,32 +320,6 @@ pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags)
return (0);
}
int
pfr_set_tflags(struct pfr_table *tbl, int size, int setflag, int clrflag,
int *nchange, int *ndel, int flags)
{
struct pfioc_table io;
if (size < 0 || (size && !tbl)) {
errno = EINVAL;
return (-1);
}
bzero(&io, sizeof io);
io.pfrio_flags = flags;
io.pfrio_buffer = tbl;
io.pfrio_esize = sizeof(*tbl);
io.pfrio_size = size;
io.pfrio_setflag = setflag;
io.pfrio_clrflag = clrflag;
if (ioctl(dev, DIOCRSETTFLAGS, &io))
return (-1);
if (nchange)
*nchange = io.pfrio_nchange;
if (ndel)
*ndel = io.pfrio_ndel;
return (0);
}
int
pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
int *nmatch, int flags)

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: pflogd.8,v 1.35 2007/05/31 19:19:47 jmc Exp $
.\" $OpenBSD: pflogd.8,v 1.36 2008/01/14 17:03:42 okan Exp $
.\"
.\" Copyright (c) 2001 Can Erkin Acar. All rights reserved.
.\"
@ -24,7 +24,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd $Mdocdate$
.Dd $Mdocdate: May 31 2007 $
.Dt PFLOGD 8
.Os
.Sh NAME
@ -118,13 +118,12 @@ By default,
will use
.Ar pflog0 .
.It Fl p Ar pidfile
Writes a file containing the process ID of the program.
Writes a file containing the process ID of the program to
.Pa /var/run .
The file name has the form
.Pa /var/run/pidname.pid .
If the option is not given,
.Ar pidfile
defaults to
.Pa pflogd .
.Ao Ar pidfile Ac Ns .pid .
The default is
.Ar pflogd .
.It Fl s Ar snaplen
Analyze at most the first
.Ar snaplen