[FUGSPBR] FWD: Novidade no IPFW + Patch
Patrick Tracanelli
eeviac em fatectq.com.br
Qui Jul 5 14:13:01 BRT 2001
NEW FEATURE: Fine-grained control over dynamic rule expiration using
an optional per-rule expiration lifetime
When using stateful ipfw rules, the dynamic rule expiration times
are governed by the values of the net.inet.ip.fw.dyn_*_lifetime
variables. This is an excellent attribute of the ipfw stateful
rule system. System administrators can tune overall system
rule expiration times to tailor ipfw to best suit their needs.
Unfortunately, this global tuning of rule expiration times just does
not give the ipfw power user the fine-grained control he or she needs
or wants. For example, the default 300-second (5-minute) expiration
for TCP sessions (governed by the net.inet.ip.fw.dyn_ack_lifetime
sysctl variable) in the connected state works well for TCP protocols
like HTTP where the TCP session will very likely not idle beyond
that default expiration time. But for TCP sessions like telnet or
ssh where a user may let his or her connection idle longer than
that, it is extremely annoying to discover the session frozen
because the firewall expired the dynamic rule for the session.
The system administrator could just increase the rule expiration
time, but that breaks the elegance of the default (or admin.-tuned)
global expiration setting that works well and is desireable for
most connections.
The solution is quite simple: add an option to override the default
sysctl variable settings for TCP sessions in the connected state,
and also for UDP sessions. With such an option, ipfw rules that
do not use the option behave as they do now. Rules that use the
option can override the default sysctl settings on a per-rule basis.
Here's an example:
OLD IPFW RULES:
ipfw add check-state
ipfw add deny tcp from any to any established
ipfw add allow tcp from me to any keep-state out setup
...
ipfw add allow udp from me to any 53 keep-state out
ipfw add allow udp from me to ${icq} 4000 keep-state out
...
With the above rules, the host can create new outbound TCP sessions
using the default expiration times. However, users on the host who
make outbound telnet/ssh sessions (or other long-idleing sessions)
will be frusterated unless the admin. increases the global default
expiration lifetime. And if the admin. does this, he/she increases
consumption of system resources in cases of outbound TCP sessions
where the remote side of the connection dies during the connected
state without any indication or response, leaving the state as
connected, the dynamic rule persisting longer than would otherwise
be needed.
NEW IPFW RULES:
ipfw add check-state
ipfw add deny tcp from any to any established
ipfw add allow tcp from me to any 22,23 keep-state lifetime 3600 out setup
ipfw add allow tcp from me to any keep-state out setup
...
ipfw add allow udp from me to any 53 keep-state out
ipfw add allow udp from me to ${icq} 4000 keep-state lifetime 600 out
...
Now the administrator can use the default settings for most TCP and
UDP sessions, but override the settings for specific uses. This
flexibility is very desirable.
This feature is currently in use on several FreeBSD-STABLE machines
where I work, as well as on my home machine. I know that several
other FreeBSD users have at least downloaded and looked at the patches
that add this feature. I do not know if anyone else is using it
currently.
The patches below implement this feature. The patches included here
are against the latest CVS versions of the various files as of Wed.
4 July 2001 8:00 PM MST (-0600). I also have patches against -STABLE
if anyone wants them. I have been running this patch (the only changes
over time were very minimal, line offsets, etc. to keep the patch
working against -STABLE source changes over time) for well over a
year now and it has been rock solid on Internet web server hosts as
well as on various border firewall machines.
IPFW MAINTAINERS: PLEASE, please examine the patches. If there are
no glaring errors or omissions, please consider committing them.
* The patches update the 'ipfw' man page to document the new
feature.
* Compatibility: using an unpatched ipfw with a patched kernel
or using a patched ipfw with an unpatched kernel should work
just fine with normal rules (the 'lifetime' feature will not
work).
Thank you.
Aaron Gifford
<agifford em infowest.com>
*** NOTE: Patches to the latest CVS versions of the relevant source
*** files are included below in the "Fix:" section. These patches
*** should apply cleanly to FreeBSD-CURRENT. Feel free to e-mail
*** me for patches that apply cleanly to FreeBSD-STABLE.
>How-To-Repeat:
N/A - See above description or patches below
>Fix:
Commit the patches below.
--- /usr/src/sys/netinet/ip_fw.h.orig Tue Feb 20 11:39:17 2001
+++ /usr/src/sys/netinet/ip_fw.h Thu Jul 5 03:46:51 2001
@@ -74,6 +74,7 @@
u_short fu_skipto_rule; /* SKIPTO command rule number */
u_short fu_reject_code; /* REJECT response code */
struct sockaddr_in fu_fwd_ip;
+ u_int32_t fu_dyn_lifetime; /* Explicit dynamic rule lifetime */
} fw_un;
u_char fw_prot; /* IP protocol */
/*
@@ -122,6 +123,7 @@
#define fw_reject_code fw_un.fu_reject_code
#define fw_pipe_nr fw_un.fu_pipe_nr
#define fw_fwd_ip fw_un.fu_fwd_ip
+#define fw_dyn_lifetime fw_un.fu_dyn_lifetime
struct ip_fw_chain {
LIST_ENTRY(ip_fw_chain) next;
@@ -148,6 +150,7 @@
struct ipfw_flow_id mask ;
struct ip_fw_chain *chain ; /* pointer to parent rule */
u_int32_t type ; /* rule type */
+ u_int32_t lifetime ; /* per-rule specified lifetime */
u_int32_t expire ; /* expire time */
u_int64_t pcnt, bcnt; /* match counters */
u_int32_t bucket ; /* which bucket in hash table */
--- /usr/src/sys/netinet/ip_fw.c.orig Mon Jul 2 15:50:31 2001
+++ /usr/src/sys/netinet/ip_fw.c Thu Jul 5 03:46:51 2001
@@ -763,7 +763,7 @@
break ;
case TH_SYN | (TH_SYN << 8) :
/* move to established */
- q->expire = time_second + dyn_ack_lifetime ;
+ q->expire = time_second + (q->lifetime ? q->lifetime : dyn_ack_lifetime) ;
break ;
case TH_SYN | (TH_SYN << 8) | TH_FIN :
case TH_SYN | (TH_SYN << 8) | (TH_FIN << 8) :
@@ -788,7 +788,7 @@
}
} else {
/* should do something for UDP and others... */
- q->expire = time_second + dyn_short_lifetime ;
+ q->expire = time_second + (q->lifetime ? q->lifetime : dyn_short_lifetime) ;
}
if (match_direction)
*match_direction = dir ;
@@ -834,7 +834,13 @@
if (mask)
r->mask = *mask ;
r->id = *id ;
- r->expire = time_second + dyn_syn_lifetime ;
+ r->lifetime = chain->rule->fw_dyn_lifetime ;
+ if (r->lifetime)
+ r->expire = time_second + r->lifetime ;
+ else if (r->id.proto == IPPROTO_TCP)
+ r->expire = time_second + dyn_syn_lifetime ;
+ else
+ r->expire = time_second + dyn_short_lifetime ;
r->chain = chain ;
r->type = ((struct ip_fw_ext *)chain->rule)->dyn_type ;
--- /usr/src/sbin/ipfw/ipfw.c.orig Sun Jul 1 22:00:26 2001
+++ /usr/src/sbin/ipfw/ipfw.c Thu Jul 5 03:46:51 2001
@@ -377,6 +377,8 @@
printf(" keep-state %d", (int)chain->next_rule_ptr);
else
printf(" keep-state");
+ if (chain->fw_dyn_lifetime)
+ printf(" lifetime %d", (int)chain->fw_dyn_lifetime);
}
/* Direction */
if (chain->fw_flg & IP_FW_BRIDGED)
@@ -917,6 +919,7 @@
" tcpack {acknowledgement number}\n"
" tcpwin {window size}\n"
" icmptypes {type[, type]}...\n"
+" keep-state [lifetime {number of seconds}]\n"
" pipeconfig:\n"
" {bw|bandwidth} <number>{bit/s|Kbit/s|Mbit/s|Bytes/s|KBytes/s|MBytes/s}\n"
" {bw|bandwidth} interface_name\n"
@@ -1971,6 +1974,15 @@
if (ac > 0 && (type = atoi(*av)) != 0) {
(int)rule.next_rule_ptr = type;
av++; ac--;
+ }
+ if (ac > 0 && !strncmp(*av,"lifetime",strlen(*av))) {
+ u_long lifetime;
+
+ av++; ac--;
+ if (ac > 0 && (lifetime = atoi(*av)) != 0) {
+ rule.fw_dyn_lifetime = lifetime;
+ av++; ac--;
+ }
}
} else if (!strncmp(*av, "bridged", strlen(*av))) {
rule.fw_flg |= IP_FW_BRIDGED;
--- /usr/src/sbin/ipfw/ipfw.8.orig Wed Jun 6 20:56:56 2001
+++ /usr/src/sbin/ipfw/ipfw.8 Thu Jul 5 03:46:51 2001
@@ -640,18 +640,38 @@
interface.
.It Ar options :
.Bl -tag -width indent
-.It Cm keep-state Op Ar method
+.It Xo Cm keep-state Op Ar method
+.Op Cm lifetime Ar number
+.Xc
Upon a match, the firewall will create a dynamic rule, whose
-default behaviour is to matching bidirectional traffic between
+default behaviour is to match bidirectional traffic between
source and destination IP/port using the same protocol.
-The rule has a limited lifetime (controlled by a set of
+The rule has a limited lifetime controlled by a set of
.Xr sysctl 8
-variables), and the lifetime is refreshed every time a matching
-packet is found.
+variables that may be overridden on a per-rule basis.
+The lifetime is refreshed each time a matching packet is
+found.
.Pp
The actual behaviour can be modified by specifying a different
.Ar method ,
although at the moment only the default one is specified.
+.Pp
+The default rule lifetime may be overridden for a specific
+rule by appending
+.Cm lifetime Ar number
+to explicitly set the number of seconds for the dynamic rule
+lifetime.
+.Pp
+For TCP rules, explicitly setting a rule lifetime overrides the
+default setting stored in the
+.Xr sysctl 8
+variable
+.Em net.inet.ip.fw.dyn_ack_lifetime .
+For non-TCP rules, it overrides the
+.Xr sysctl 8
+variable
+.Em net.inet.ip.fw.dyn_short_lifetime
+instead.
.It Cm bridged
Matches only bridged packets.
This can be useful for multicast or broadcast traffic, which
----
Para sair da lista envie um e-mail para majordomo em fugspbr.org
com as palavras "unsubscribe fugspbr" no corpo da mensagem.
Mais detalhes sobre a lista de discussão freebsd