Make ipfw's logging more dynamic. Now, log will use the default limit
_or_ you may specify "log logamount number" to set logging specifically the rule. In addition, "ipfw resetlog" has been added, which will reset the logging counters on any/all rule(s). ipfw resetlog does not affect the packet/byte counters (as ipfw reset does), and is the only "set" command that can be run at securelevel >= 3. This should address complaints about not being able to set logging amounts, not being able to restart logging at a high securelevel, and not being able to just reset logging without resetting all of the counters in a rule.
This commit is contained in:
parent
6e7b8c218d
commit
0b6c1a832d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=49350
@ -1,5 +1,5 @@
|
||||
.\"
|
||||
.\" $Id: ipfw.8,v 1.53 1999/06/15 12:56:38 ru Exp $
|
||||
.\" $Id: ipfw.8,v 1.54 1999/06/19 18:43:18 green Exp $
|
||||
.\"
|
||||
.Dd July 20, 1996
|
||||
.Dt IPFW 8
|
||||
@ -30,6 +30,12 @@ flush
|
||||
zero
|
||||
.Op Ar number ...
|
||||
.Nm ipfw
|
||||
.Oo
|
||||
.Fl q
|
||||
.Oc
|
||||
resetlog
|
||||
.Op Ar number ...
|
||||
.Nm ipfw
|
||||
delete
|
||||
.Ar number ...
|
||||
.Nm ipfw
|
||||
@ -49,7 +55,7 @@ show
|
||||
add
|
||||
.Op Ar number
|
||||
.Ar action
|
||||
.Op log
|
||||
.Op log Op Ar logamount Ar number
|
||||
.Ar proto
|
||||
from
|
||||
.Ar src
|
||||
@ -227,6 +233,10 @@ The show command is equivalent to
|
||||
The zero operation zeroes the counters associated with rule number
|
||||
.Ar number .
|
||||
.Pp
|
||||
The resetlog operation resets the logging counters associated with
|
||||
rule number
|
||||
.Ar number .
|
||||
.Pp
|
||||
The flush operation removes all rules.
|
||||
.Pp
|
||||
Any command beginning with a
|
||||
@ -265,7 +275,7 @@ Don't ask for confirmation for commands that can cause problems if misused
|
||||
.Ar Note ,
|
||||
if there is no tty associated with the process, this is implied.
|
||||
.It Fl q
|
||||
While adding, zeroing or flushing, be quiet about actions (implies
|
||||
While adding, zeroing, resetlogging or flushing, be quiet about actions (implies
|
||||
.Fl f Ns ).
|
||||
This is useful for adjusting rules by executing multiple
|
||||
.Nm
|
||||
@ -411,15 +421,22 @@ then when a packet matches a rule with the
|
||||
keyword a message will be printed on the console.
|
||||
If the kernel was compiled with the
|
||||
.Dv IPFIREWALL_VERBOSE_LIMIT
|
||||
option, then logging will cease after the number of packets
|
||||
specified by the option are received for that particular
|
||||
chain entry. Logging may then be re-enabled by clearing
|
||||
the packet counter for that entry.
|
||||
option, then by default logging will cease after the number
|
||||
of packets specified by the option are received for that
|
||||
particular chain entry. However, if
|
||||
.Ar logamount Ar number
|
||||
is used, that
|
||||
.Ar number
|
||||
will be the default logging limit rather than
|
||||
.Dv IPFIREWALL_VERBOSE_LIMIT .
|
||||
Logging may then be re-enabled by clearing the logging counter
|
||||
or the packet counter for that entry.
|
||||
.Pp
|
||||
Console logging and the log limit are adjustable dynamically
|
||||
through the
|
||||
.Xr sysctl 8
|
||||
interface.
|
||||
interface in the MIB base of
|
||||
.Dv net.inet.ip.fw .
|
||||
.Pp
|
||||
.Ar proto :
|
||||
.Bl -hang -offset flag -width 1234567890123456
|
||||
|
@ -20,13 +20,14 @@
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"$Id: ipfw.c,v 1.70 1999/06/11 09:43:53 ru Exp $";
|
||||
"$Id: ipfw.c,v 1.71 1999/06/19 18:43:15 green Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
@ -247,8 +248,11 @@ show_ipfw(struct ip_fw *chain, int pcwidth, int bcwidth)
|
||||
errx(EX_OSERR, "impossible");
|
||||
}
|
||||
|
||||
if (chain->fw_flg & IP_FW_F_PRN)
|
||||
if (chain->fw_flg & IP_FW_F_PRN) {
|
||||
printf(" log");
|
||||
if (chain->fw_logamount)
|
||||
printf(" logamount %d", chain->fw_logamount);
|
||||
}
|
||||
|
||||
pe = getprotobynumber(chain->fw_prot);
|
||||
if (pe)
|
||||
@ -599,12 +603,13 @@ show_usage(const char *fmt, ...)
|
||||
" [pipe] list [number ...]\n"
|
||||
" [pipe] show [number ...]\n"
|
||||
" zero [number ...]\n"
|
||||
" resetlog [number ...]\n"
|
||||
" pipe number config [pipeconfig]\n"
|
||||
" rule: action proto src dst extras...\n"
|
||||
" action:\n"
|
||||
" {allow|permit|accept|pass|deny|drop|reject|unreach code|\n"
|
||||
" reset|count|skipto num|divert port|tee port|fwd ip|\n"
|
||||
" pipe num} [log]\n"
|
||||
" pipe num} [log [logamount count]]\n"
|
||||
" proto: {ip|tcp|udp|icmp|<number>}\n"
|
||||
" src: from [not] {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n"
|
||||
" dst: to [not] {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n"
|
||||
@ -1164,6 +1169,18 @@ add(ac,av)
|
||||
if (ac && !strncmp(*av,"log",strlen(*av))) {
|
||||
rule.fw_flg |= IP_FW_F_PRN; av++; ac--;
|
||||
}
|
||||
if (ac && !strncmp(*av,"logamount",strlen(*av))) {
|
||||
if (!(rule.fw_flg & IP_FW_F_PRN))
|
||||
show_usage("``logamount'' not valid without ``log''");
|
||||
ac--; av++;
|
||||
if (!ac)
|
||||
show_usage("``logamount'' requires argument");
|
||||
rule.fw_logamount = atoi(*av);
|
||||
if (rule.fw_logamount <= 0)
|
||||
show_usage("``logamount'' argument must be greater "
|
||||
"than 0");
|
||||
ac--; av++;
|
||||
}
|
||||
|
||||
/* protocol */
|
||||
if (ac == 0)
|
||||
@ -1385,6 +1402,17 @@ add(ac,av)
|
||||
if (rule.fw_nports)
|
||||
show_usage("can't mix 'frag' and port specifications");
|
||||
}
|
||||
if (rule.fw_flg & IP_FW_F_PRN) {
|
||||
if (!rule.fw_logamount) {
|
||||
size_t len = sizeof(int);
|
||||
|
||||
if (sysctlbyname("net.inet.ip.fw.verbose_limit",
|
||||
&rule.fw_logamount, &len, NULL, 0) == -1)
|
||||
errx(1, "sysctlbyname(\"%s\")",
|
||||
"net.inet.ip.fw.verbose_limit");
|
||||
}
|
||||
rule.fw_loghighest = rule.fw_logamount;
|
||||
}
|
||||
|
||||
if (!do_quiet)
|
||||
show_ipfw(&rule, 10, 10);
|
||||
@ -1432,6 +1460,45 @@ zero (ac, av)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
resetlog (ac, av)
|
||||
int ac;
|
||||
char **av;
|
||||
{
|
||||
av++; ac--;
|
||||
|
||||
if (!ac) {
|
||||
/* clear all entries */
|
||||
if (setsockopt(s,IPPROTO_IP,IP_FW_RESETLOG,NULL,0)<0)
|
||||
err(EX_UNAVAILABLE, "setsockopt(%s)", "IP_FW_RESETLOG");
|
||||
if (!do_quiet)
|
||||
printf("Logging counts reset.\n");
|
||||
} else {
|
||||
struct ip_fw rule;
|
||||
int failed = EX_OK;
|
||||
|
||||
memset(&rule, 0, sizeof rule);
|
||||
while (ac) {
|
||||
/* Rule number */
|
||||
if (isdigit(**av)) {
|
||||
rule.fw_number = atoi(*av); av++; ac--;
|
||||
if (setsockopt(s, IPPROTO_IP,
|
||||
IP_FW_RESETLOG, &rule, sizeof rule)) {
|
||||
warn("rule %u: setsockopt(%s)", rule.fw_number,
|
||||
"IP_FW_RESETLOG");
|
||||
failed = EX_UNAVAILABLE;
|
||||
}
|
||||
else if (!do_quiet)
|
||||
printf("Entry %d logging count reset\n",
|
||||
rule.fw_number);
|
||||
} else
|
||||
show_usage("invalid rule number ``%s''", *av);
|
||||
}
|
||||
if (failed != EX_OK)
|
||||
exit(failed);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ipfw_main(ac,av)
|
||||
int ac;
|
||||
@ -1527,6 +1594,8 @@ ipfw_main(ac,av)
|
||||
}
|
||||
} else if (!strncmp(*av, "zero", strlen(*av))) {
|
||||
zero(ac,av);
|
||||
} else if (!strncmp(*av, "resetlog", strlen(*av))) {
|
||||
resetlog(ac,av);
|
||||
} else if (!strncmp(*av, "print", strlen(*av))) {
|
||||
list(--ac,++av);
|
||||
} else if (!strncmp(*av, "list", strlen(*av))) {
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)in.h 8.3 (Berkeley) 1/3/94
|
||||
* $Id: in.h,v 1.41 1999/05/04 16:20:29 luigi Exp $
|
||||
* $Id: in.h,v 1.42 1999/05/08 14:28:52 peter Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETINET_IN_H_
|
||||
@ -322,6 +322,7 @@ struct ip_opts {
|
||||
#define IP_FW_FLUSH 52 /* flush firewall rule chain */
|
||||
#define IP_FW_ZERO 53 /* clear single/all firewall counter(s) */
|
||||
#define IP_FW_GET 54 /* get entire firewall rule chain */
|
||||
#define IP_FW_RESETLOG 55 /* reset logging counters */
|
||||
|
||||
#define IP_DUMMYNET_CONFIGURE 60 /* add/configure a dummynet pipe */
|
||||
#define IP_DUMMYNET_DEL 61 /* delete a dummynet pipe from chain */
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* This software is provided ``AS IS'' without any warranties of any kind.
|
||||
*
|
||||
* $Id: ip_fw.c,v 1.114 1999/06/19 18:43:28 green Exp $
|
||||
* $Id: ip_fw.c,v 1.115 1999/07/28 22:27:27 green Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -106,6 +106,7 @@ SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit, CTLFLAG_RW,
|
||||
static int add_entry __P((struct ip_fw_head *chainptr, struct ip_fw *frwl));
|
||||
static int del_entry __P((struct ip_fw_head *chainptr, u_short number));
|
||||
static int zero_entry __P((struct ip_fw *));
|
||||
static int resetlog_entry __P((struct ip_fw *));
|
||||
static int check_ipfw_struct __P((struct ip_fw *m));
|
||||
static __inline int
|
||||
iface_match __P((struct ifnet *ifp, union ip_fw_if *ifu,
|
||||
@ -306,10 +307,11 @@ ipfw_report(struct ip_fw *f, struct ip *ip,
|
||||
struct tcphdr *const tcp = (struct tcphdr *) ((u_int32_t *) ip+ ip->ip_hl);
|
||||
struct udphdr *const udp = (struct udphdr *) ((u_int32_t *) ip+ ip->ip_hl);
|
||||
struct icmp *const icmp = (struct icmp *) ((u_int32_t *) ip + ip->ip_hl);
|
||||
int count;
|
||||
u_int64_t count;
|
||||
|
||||
count = f ? f->fw_pcnt : ++counter;
|
||||
if (fw_verbose_limit != 0 && count > fw_verbose_limit)
|
||||
if ((f == NULL && fw_verbose_limit != 0 && count > fw_verbose_limit) ||
|
||||
(f && f->fw_logamount != 0 && count > f->fw_loghighest))
|
||||
return;
|
||||
|
||||
/* Print command name */
|
||||
@ -409,9 +411,11 @@ ipfw_report(struct ip_fw *f, struct ip *ip,
|
||||
if ((ip->ip_off & IP_OFFMASK))
|
||||
printf(" Fragment = %d",ip->ip_off & IP_OFFMASK);
|
||||
printf("\n");
|
||||
if (fw_verbose_limit != 0 && count == fw_verbose_limit)
|
||||
printf("ipfw: limit reached on rule #%d\n",
|
||||
f ? f->fw_number : -1);
|
||||
if ((f ? f->fw_logamount != 0 : 1) &&
|
||||
count == (f ? f->fw_loghighest : fw_verbose_limit))
|
||||
printf("ipfw: limit %d reached on rule #%d\n",
|
||||
f ? f->fw_logamount : fw_verbose_limit,
|
||||
f ? f->fw_number : -1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1069,6 +1073,7 @@ zero_entry(struct ip_fw *frwl)
|
||||
s = splnet();
|
||||
for (fcp = LIST_FIRST(&ip_fw_chain); fcp; fcp = LIST_NEXT(fcp, chain)) {
|
||||
fcp->rule->fw_bcnt = fcp->rule->fw_pcnt = 0;
|
||||
fcp->rule->fw_loghighest = fcp->rule->fw_logamount;
|
||||
fcp->rule->timestamp = 0;
|
||||
}
|
||||
splx(s);
|
||||
@ -1086,6 +1091,8 @@ zero_entry(struct ip_fw *frwl)
|
||||
s = splnet();
|
||||
while (fcp && frwl->fw_number == fcp->rule->fw_number) {
|
||||
fcp->rule->fw_bcnt = fcp->rule->fw_pcnt = 0;
|
||||
fcp->rule->fw_loghighest =
|
||||
fcp->rule->fw_logamount;
|
||||
fcp->rule->timestamp = 0;
|
||||
fcp = LIST_NEXT(fcp, chain);
|
||||
}
|
||||
@ -1107,6 +1114,55 @@ zero_entry(struct ip_fw *frwl)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
resetlog_entry(struct ip_fw *frwl)
|
||||
{
|
||||
struct ip_fw_chain *fcp;
|
||||
int s, cleared;
|
||||
|
||||
if (frwl == 0) {
|
||||
s = splnet();
|
||||
for (fcp = LIST_FIRST(&ip_fw_chain); fcp; fcp = LIST_NEXT(fcp, chain))
|
||||
fcp->rule->fw_loghighest = fcp->rule->fw_pcnt +
|
||||
fcp->rule->fw_logamount;
|
||||
splx(s);
|
||||
}
|
||||
else {
|
||||
cleared = 0;
|
||||
|
||||
/*
|
||||
* It's possible to insert multiple chain entries with the
|
||||
* same number, so we don't stop after finding the first
|
||||
* match if zeroing a specific entry.
|
||||
*/
|
||||
for (fcp = LIST_FIRST(&ip_fw_chain); fcp; fcp = LIST_NEXT(fcp, chain))
|
||||
if (frwl->fw_number == fcp->rule->fw_number) {
|
||||
s = splnet();
|
||||
while (fcp && frwl->fw_number == fcp->rule->fw_number) {
|
||||
fcp->rule->fw_loghighest =
|
||||
fcp->rule->fw_pcnt +
|
||||
fcp->rule->fw_logamount;
|
||||
fcp = LIST_NEXT(fcp, chain);
|
||||
}
|
||||
splx(s);
|
||||
cleared = 1;
|
||||
break;
|
||||
}
|
||||
if (!cleared) /* we didn't find any matching rules */
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (fw_verbose) {
|
||||
if (frwl)
|
||||
printf("ipfw: Entry %d logging count reset.\n",
|
||||
frwl->fw_number);
|
||||
else
|
||||
printf("ipfw: All logging counts cleared.\n");
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
check_ipfw_struct(struct ip_fw *frwl)
|
||||
{
|
||||
@ -1241,8 +1297,12 @@ ip_fw_ctl(struct sockopt *sopt)
|
||||
struct ip_fw_chain *fcp;
|
||||
struct ip_fw frwl;
|
||||
|
||||
/* Disallow sets in really-really secure mode. */
|
||||
if (sopt->sopt_dir == SOPT_SET && securelevel >= 3)
|
||||
/*
|
||||
* Disallow sets in really-really secure mode, but still allow
|
||||
* the logging counters to be reset.
|
||||
*/
|
||||
if (sopt->sopt_dir == SOPT_SET && securelevel >= 3 &&
|
||||
sopt->sopt_name != IP_FW_RESETLOG)
|
||||
return (EPERM);
|
||||
error = 0;
|
||||
|
||||
@ -1320,6 +1380,17 @@ ip_fw_ctl(struct sockopt *sopt)
|
||||
}
|
||||
break;
|
||||
|
||||
case IP_FW_RESETLOG:
|
||||
if (sopt->sopt_val != 0) {
|
||||
error = sooptcopyin(sopt, &frwl, sizeof frwl,
|
||||
sizeof frwl);
|
||||
if (error || (error = resetlog_entry(&frwl)))
|
||||
break;
|
||||
} else {
|
||||
error = resetlog_entry(0);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("ip_fw_ctl invalid option %d\n", sopt->sopt_name);
|
||||
error = EINVAL ;
|
||||
@ -1373,7 +1444,7 @@ ip_fw_init(void)
|
||||
if (fw_verbose_limit == 0)
|
||||
printf("unlimited logging\n");
|
||||
else
|
||||
printf("logging limited to %d packets/entry\n",
|
||||
printf("logging limited to %d packets/entry by default\n",
|
||||
fw_verbose_limit);
|
||||
#endif
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
*
|
||||
* This software is provided ``AS IS'' without any warranties of any kind.
|
||||
*
|
||||
* $Id: ip_fw.h,v 1.38 1999/06/19 18:43:30 green Exp $
|
||||
* $Id: ip_fw.h,v 1.39 1999/07/28 22:22:57 green Exp $
|
||||
*/
|
||||
|
||||
#ifndef _IP_FW_H
|
||||
@ -85,6 +85,8 @@ struct ip_fw {
|
||||
void *next_rule_ptr ; /* next rule in case of match */
|
||||
uid_t fw_uid; /* uid to match */
|
||||
gid_t fw_gid; /* gid to match */
|
||||
int fw_logamount; /* amount to log */
|
||||
u_int64_t fw_loghighest; /* highest number packet to log */
|
||||
};
|
||||
|
||||
#define IP_FW_GETNSRCP(rule) ((rule)->fw_nports & 0x0f)
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)raw_ip.c 8.7 (Berkeley) 5/15/95
|
||||
* $Id: raw_ip.c,v 1.58 1999/04/27 11:17:36 phk Exp $
|
||||
* $Id: raw_ip.c,v 1.59 1999/05/03 23:57:30 billf Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -293,6 +293,7 @@ rip_ctloutput(so, sopt)
|
||||
case IP_FW_DEL:
|
||||
case IP_FW_FLUSH:
|
||||
case IP_FW_ZERO:
|
||||
case IP_FW_RESETLOG:
|
||||
if (ip_fw_ctl_ptr == 0)
|
||||
error = ENOPROTOOPT;
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user