荔园在线
荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀
[回到开始]
[上一篇][下一篇]
发信人: georgehill (清风浮云 人生), 信区: Linux
标 题: ipfilter-howto(26-36)(转寄)
发信站: BBS 荔园晨风站 (Thu Nov 2 23:07:41 2000), 站内信件
【 以下文字转载自 georgehill 的信箱 】
【 原文由 georgehill.bbs@smth.org 所发表 】
发信人: snofe ([听潮阁主人]), 信区: FreeBSD
标 题: ipfilter-howto(26-36)(转寄)
发信站: BBS 水木清华站 (Tue Oct 31 13:49:32 2000)
-26-
bimap tun0 192.168.1.1/32 -> 20.20.20.1/32
will accomplish the mapping for one host.
4.4. Spoofing Services
Spoofing services? What does that have to do with any-
thing? Plenty. Lets pretend that we have a web server
running on 20.20.20.5, and since we've gotten increasingly
suspicious of our network security, we desire to not run
this server on port 80 since that requires a brief lifespan
as the root user. But how do we run it on a less
privledged port of 8000 in this world of "anything dot com"?
How will anyone find our server? We can use the redirection
facilities of NAT to solve this problem by instructing it to
remap any connections destined for 20.20.20.5:80 to really
point to 20.20.20.5:8000. This uses the rdr keyword:
rdr tun0 20.20.20.5/32 port 80 -> 192.168.0.5 port 8000
We can also specify the protocol here, if we wanted to redi-
rect a UDP service, instead of a TCP service (which is the
default). For example, if we had a honeypot on our firewall
to impersonate the popular Back Orifice for Windows, we
could shovel our entire network into this one place with a
simple rule:
rdr tun0 20.20.20.0/24 port 31337 -> 127.0.0.1 port 31337 udp
An extremely important point must be made about rdr: You
cannot easily use this feature as a "reflector". E.g:
rdr tun0 20.20.20.5/32 port 80 -> 20.20.20.6 port 80 tcp
will not work in the situation where .5 and .6 are on the
same LAN segment. The rdr function is applied to packets
that enter the firewall on the specified interface. When a
packet comes in that matches a rdr rule, its destination
address is then rewritten, it is pushed into ipf for filter-
ing, and should it successfully run the gauntlet of filter
rules, it is then sent to the unix routing code. Since this
packet is still inbound on the same interface that it will
need to leave the system on to reach a host, the system gets
confused. Reflectors don't work. Neither does specifying
the address of the interface the packet just came in on.
Always remember that rdr destinations must exit out of the
-----------
Yes. There is a way to do this. It's so convo-
luted that I refuse to use it, though. Smart peo-
ple who require this functionality will transpar-
ently redirect into something like TIS plug-gw on
127.0.0.1. Stupid people will set up a dummy loop
interface pair and double rewrite.
-27-
firewall host on a different interface.
4.5. Transparent Proxy Support; Redirection Made Useful
Since you're installing a firewall, you may have
decided that it is prudent to use a proxy for many of your
outgoing connections so that you can further tighten your
filter rules protecting your internal network, or you may
have run into a situation that the NAT mapping process does
not currently handle properly. This can also be accom-
plished with a redirection statement:
rdr xl0 0.0.0.0/0 port 21 -> 127.0.0.1 port 21
This statement says that any packet coming in on the xl0
interface destined for any address (0.0.0.0/0) on the ftp
port should be rewritten to connect it with a proxy that is
running on the NAT system on port 21.
This specific example of FTP proxying does lead to some
complications when used with web browsers or other auto-
matic-login type clients that are unaware of the require-
ments of communicating with the proxy. There are patches
for TIS Firewall Toolkit'sftp-gw to mate it with the nat
process so that it can determine where you were trying to go
and automatically send you there. Many proxy packages now
work in a transparent proxy environment (Squid for example,
located at http://squid.nlanr.net, works fine.)
This application of the rdr keyword is often more use-
ful when you wish to force users to authenticate themselves
with the proxy. (For example, you desire your engineers to
be able to surf the web, but you would rather not have your
call-center staff doing so.)
4.6. Magic Hidden Within NAT; Application Proxies
Since ipnat provides a method to rewrite packets as
they traverse the firewall, it becomes a convenient place to
build in some application level proxies to make up for well
known deficiencies of that application and typical fire-
walls. For example; FTP. We can make our firewall pay
attention to the packets going across it and when it notices
that it's dealing with an Active FTP session, it can write
itself some temporary rules, much like what happens with
keep state, so that the FTP data connection works. To do
this, we use a rule like so:
map tun0 192.168.1.0/24 -> 20.20.20.1/32 proxy port ftp ftp/tcp
-----------
This includes 127.0.0.1, by the way. That's on
lo0. Neat, huh?
-28-
You must always remember to place this proxy rule before any
portmap rules, otherwise when portmap comes along and
matches the packet and rewrites it before the proxy gets a
chance to work on it. Remember that ipnat rules are first-
match.
There also exist proxies for "rcmd" (which we suspect
is berkeley r-* commands which should be forbidden anyway,
thus we haven't looked at what this proxy does) and "raudio"
for Real Audio PNM streams. Likewise, both of these rules
should be put before any portmap rules, if you're doing NAT.
5. Loading and Manipulating Filter Rules; The ipf Utility
IP Filter rules are loaded by using the ipf utility.
The filter rules can be stored in any file on the system,
but typically these rules are stored in /etc/ipf.rules,
/usr/local/etc/ipf.rules, or /etc/opt/ipf/ipf.rules.
IP Filter has two sets of rules, the active set and the
inactive set. By default, all operations are performed on
the active set. You can manipulate the inactive set by
adding -I to the ipf command line. The two sets can be
toggled by using the -s command line option. This is very
useful for testing new rule sets without wiping out the old
rule set.
Rules can also be removed from the list instead of
added by using the -r command line option, but it is gener-
ally a safer idea to flush the rule set that you're working
on with -F and completely reload it when making changes.
In summary, the easiest way to load a rule set is ipf
-Fa -f /etc/ipf.rules. For more complicated manipulations
of the rule set, please see the ipf(1) man page.
6. Loading and Manipulating NAT Rules; The ipnat Utility
NAT rules are loaded by using the ipnat utility. The
NAT rules can be stored in any file on the system, but typi-
cally these rules are stored in /etc/ipnat.rules,
/usr/local/etc/ipnat.rules, or /etc/opt/ipf/ipnat.rules.
Rules can also be removed from the list instead of
added by using the -r command line option, but it is gener-
ally a safer idea to flush the rule set that you're working
on with -C and completely reload it when making changes.
Any active mappings are not affected by -C, and can be
removed with -F.
NAT rules and active mappings can be examined with the
-l command line option.
-29-
In summary, the easiest way to load a NAT rule set is
ipnat -CF -f /etc/ipnat.rules.
7. Monitoring and Debugging
There will come a time when you are interested in what
your firewall is actually doing, and ipfilter would be
incomplete if it didn't have a full suite of status monitor-
ing tools.
7.1. The ipfstat utility
In its simplest form, ipfstat displays a table of
interesting data about how your firewall is performing, such
as how many packets have been passed or blocked, if they
were logged or not, how many state entries have been made,
and so on. Here's an example of something you might see
from running the tool:
# ipfstat
input packets: blocked 99286 passed 1255609 nomatch 14686 counted 0
output packets: blocked 4200 passed 1284345 nomatch 14687 counted 0
input packets logged: blocked 99286 passed 0
output packets logged: blocked 0 passed 0
packets logged: input 0 output 0
log failures: input 3898 output 0
fragment state(in): kept 0 lost 0
fragment state(out): kept 0 lost 0
packet state(in): kept 169364 lost 0
packet state(out): kept 431395 lost 0
ICMP replies: 0 TCP RSTs sent: 0
Result cache hits(in): 1215208 (out): 1098963
IN Pullups succeeded: 2 failed: 0
OUT Pullups succeeded: 0 failed: 0
Fastroute successes: 0 failures: 0
TCP cksum fails(in): 0 (out): 0
Packet log flags set: (0)
none
ipfstat is also capable of showing you your current rule
list. Using the -i or the -o flag will show the currently
loaded rules for in or out, respectively. Adding a -h to
this will provide more useful information at the same time
by showing you a "hit count" on each rule. For example:
# ipfstat -ho
2451423 pass out on xl0 from any to any
354727 block out on ppp0 from any to any
430918 pass out quick on ppp0 proto tcp/udp from 20.20.20.0/24 to any keep
state keep frags
From this, we can see that perhaps there's something abnor-
mal going on, since we've got a lot of blocked packets out-
bound, even with a very permissive pass out rule. Something
here may warrant further investigation, or it may be
-30-
functioning perfectly by design. ipfstat can't tell you if
your rules are right or wrong, it can only tell you what is
happening because of your rules.
To further debug your rules, you may want to use the -n
flag, which will show the rule number next to each rule.
# ipfstat -on
@1 pass out on xl0 from any to any
@2 block out on ppp0 from any to any
@3 pass out quick on ppp0 proto tcp/udp from 20.20.20.0/24 to any keep
state keep frags
The final piece of really interesting information that ipfs-
tat can provide us is a dump of the state table. This is
done with the -s flag:
# ipfstat -s
281458 TCP
319349 UDP
0 ICMP
19780145 hits
5723648 misses
0 maximum
0 no memory
1 active
319349 expired
281419 closed
100.100.100.1 -> 20.20.20.1 ttl 864000 pass 20490 pr 6 state 4/4
pkts 196 bytes 17394 987 -> 22 585538471:2213225493 16592:16500
pass in log quick keep state
pkt_flags & b = 2, pkt_options & ffffffff = 0
pkt_security & ffff = 0, pkt_auth & ffff = 0
Here we see that we have one state entry for a TCP connec-
tion. The output will vary slightly from version to ver-
sion, but the basic information is the same. We can see in
this connection that we have a fully established connection
(represented by the 4/4 state. Other states are incomplete
and will be documented fully later.) We can see that the
state entry has a time to live of 240 hours, which is an
absurdly long time, but is the default for an established
TCP connection. This TTL counter is decremented every sec-
ond that the state entry is not used, and will finally
result in the connection being purged if it has been left
idle. The TTL is also reset to 864000 whenever the state
IS used, ensuring that the entry will not time out while it
is being actively used. We can also see that we have passed
196 packets consisting of about 17kB worth of data over this
connection. We can see the ports for both endpoints, in
this case 987 and 22; which means that this state entry rep-
resents a connection from 100.100.100.1 port 987 to
20.20.20.1 port 22. The really big numbers in the second
line are the TCP sequence numbers for this connection, which
helps to ensure that someone isn't easily able to inject a
-31-
forged packet into your session. The TCP window is also
shown. The third line is a synopsis of the implicit rule
that was generated by the keep state code, showing that this
connection is an inbound connection.
7.2. The ipmon utility
ipfstat is great for collecting snapshots of what's
going on on the system, but it's often handy to have some
kind of log to look at and watch events as they happen in
time. ipmon is this tool. ipmon is capable of watching
the packet log (as created with the log keyword in your
rules), the state log, or the nat log, or any combination of
the three. This tool can either be run in the foreground,
or as a daemon which logs to syslog or a file. If we wanted
to watch the state table in action, ipmon -o S would show
this:
# ipmon -o S
01/08/1999 15:58:57.836053 STATE:NEW 100.100.100.1,53 -> 20.20.20.15,53 PR
udp
01/08/1999 15:58:58.030815 STATE:NEW 20.20.20.15,123 -> 128.167.1.69,123 PR
udp
01/08/1999 15:59:18.032174 STATE:NEW 20.20.20.15,123 -> 128.173.14.71,123
PR udp
01/08/1999 15:59:24.570107 STATE:EXPIRE 100.100.100.1,53 -> 20.20.20.15,53
PR udp Pkts 4 Bytes 356
01/08/1999 16:03:51.754867 STATE:NEW 20.20.20.13,1019 -> 100.100.100.10,22
PR tcp
01/08/1999 16:04:03.070127 STATE:EXPIRE 20.20.20.13,1019 -> 100.100.100.10,
22 PR tcp Pkts 63 Bytes 4604
Here we see a state entry for an external dns request off
our nameserver, two xntp pings to well-known time servers,
and a very short lived outbound ssh connection.
ipmon is also capable of showing us what packets have
been logged. For example, when using state, you'll often
run into packets like this:
# ipmon -o I
15:57:33.803147 ppp0 @0:2 b 100.100.100.103,443 -> 20.20.20.10,4923 PR tcp
len 20 1488 -A
What does this mean? The first field is obvious, it's a
timestamp. The second field is also pretty obvious, it's
the interface that this event happened on. The third field
@0:2 is something most people miss. This is the rule that
caused the event to happen. Remember ipfstat -in? If you
wanted to know where this came from, you could look there
for rule 2 in rule group 0. The fourth field, the little
"b" says that this packet was blocked, and you'll generally
ignore this unless you're logging passed packets as well,
which would be a little "p" instead. The fifth and sixth
fields are pretty self-explanatory, they say where this
packet came from and where it was going. The seventh ("PR")
and eighth fields tell you the protocol and the ninth field
tells you the size of the packet. The last part, the "-A"
in this case, tells you the flags that were on the packet;
This one was an ACK packet. Why did I mention state ear-
lier? Due to the often laggy nature of the Internet,
-32-
sometimes packets will be regenerated. Sometimes, you'll
get two copies of the same packet, and your state rule which
keeps track of sequence numbers will have already seen this
packet, so it will assume that the packet is part of a dif-
ferent connection. Eventually this packet will run into a
real rule and have to be dealt with. You'll often see the
last packet of a session being closed get logged because the
keep state code has already torn down the connection before
the last packet has had a chance to make it to your fire-
wall. This is normal, do not be alarmed. Another example
packet that might be logged:
12:46:12.470951 xl0 @0:1 S 20.20.20.254 -> 255.255.255.255 PR icmp len 20
9216 icmp 9/0
This is a ICMP router discovery broadcast. We can tell by
the ICMP type 9/0.
Finally, ipmon also lets us look at the NAT table in action.
# ipmon -o N
01/08/1999 05:30:02.466114 @2 NAT:RDR 20.20.20.253,113 <- -> 20.20.20.253,
113 [100.100.100.13,45816]
01/08/1999 05:30:31.990037 @2 NAT:EXPIRE 20.20.20.253,113 <- ->
20.20.20.253,113 [100.100.100.13,45816] Pkts 10 Bytes 455
This would be a redirection to an identd that lies to pro-
vide ident service for the hosts behind our NAT, since they
are typically unable to provide this service for themselves
with ordinary natting.
8. Specific Applications of IP Filter - Things that don't
fit, but should be mentioned anyway.
8.1. Keep State With Servers and Flags.
Keeping state is a good thing, but it's quite easy to
make a mistake in the direction that you want to keep state
in. Generally, you want to have a keep state keyword on
the first rule that interacts with a packet for the connec-
tion. One common mistake that is made when mixing state
tracking with filtering on flags is this:
block in all
pass in quick proto tcp from any to 20.20.20.20/32 port = 23 flags S
pass out all keep state
-----------
For a technical presentation of the IP Filter
stateful inspection engine, please see the white
paper Real Stateful TCP Packet Filtering in IP
Filter, by Guido van Rooij. This paper may be
found at
<http://www.iae.nl/users/guido/papers/tcp_filter-
ing.ps.gz>
-33-
That certainly appears to allow a connection to be created
to the telnet server on 20.20.20.20, and the replies to go
back. If you try using this rule, you'll see that it does
work--Momentarily. Since we're filtering for the SYN flag,
the state entry never fully gets completed, and the default
time to live for an incomplete state is 60 seconds.
We can solve this by rewriting the rules in one of two ways:
1)
block in all
pass in quick proto tcp from any to 20.20.20.20/32 port = 23 keep
state
block out all
or:
2)
block in all
pass in quick proto tcp from any to 20.20.20.20/32 port = 23 flags S
keep state
pass out all keep state
Either of these sets of rules will result in a fully estab-
lished state entry for a connection to your server.
8.2. Coping With FTP
FTP is one of those protocols that you just have to sit
back and ask "What the heck were they thinking?" FTP has
many problems that the firewall administrator needs to deal
with. What's worse, the problems the administrator must
face are different between making ftp clients work and mak-
ing ftp servers work.
Within the FTP protocol, there are two forms of data
transfer, called active and passive. Active transfers are
those where the server connects to an open port on the
client to send data. Conversely, passive transfers are
those where the client connects to the server to recieve
data.
8.2.1. Running an FTP Server
In running an FTP server, handling Active FTP sessions
is easy to setup. At the same time, handling Passive FTP
sessions is a big problem. First we'll cover how to handle
Active FTP, then move on to Passive. Generally, we can han-
dle Active FTP sessions like we would an incoming HTTP or
SMTP connection; just open the ftp port and let keep state
do the rest:
pass in quick proto tcp from any to 20.20.20.20/32 port = 21 flags S keep
state
pass out proto tcp all keep state
-34-
These rules will allow Active FTP sessions, the most common
type, to your ftp server on 20.20.20.20.
The next challenge becomes handling Passive FTP connec-
tions. Web browsers default to this mode, so it's becoming
quite popular and as such it should be supported. The prob-
lem with passive connections are that for every passive con-
nection, the server starts listening on a new port (usually
above 1023). This is essentially like creating a new
unknown service on the server. Assuming we have a good
firewall with a default-deny policy, that new service will
be blocked, and thus Active FTP sessions are broken. Don't
despair! There's hope yet to be had.
A person's first inclination to solving this problem
might be to just open up all ports above 1023. In truth,
this will work:
pass in quick proto tcp from any to 20.20.20.20/32 port > 1023 flags S
keep state
pass out proto tcp all keep state
This is somewhat unsatisfactory, though. By letting every-
thing above 1023 in, we actually open ourselves up for a
number of potential problems. While 1-1023 is the desig-
nated area for server services to run, numerous programs
decided to use numbers higher than 1023, such as nfsd and X.
The good news is that your FTP server gets to decide
which ports get assigned to active sessions. This means
that instead of opening all ports above 1023, you can allo-
cate ports 15001-19999 as ftp ports and only open that range
of your firewall up. In wu-ftpd, this is done with the pas-
sive ports option in ftpaccess. Please see the man page on
ftpaccess for details in wu-ftpd configuration. On the
ipfilter side, all we need do is setup corresponding rules:
pass in quick proto tcp from any to 20.20.20.20/32 port 15000 >< 20000
flags S keep state
pass out proto tcp all keep state
If even this solution doesn't satisfy you, you can always
hack IPF support into your FTP server, or FTP server support
into IPF.
8.2.2. Running an FTP Client
While FTP server support is still less than perfect in
IPF, FTP client support has been working well since 3.3.3.
As with FTP servers, there are two types of ftp client
transfers: passive and active.
The simplest type of client transfer from the fire-
wall's standpoint is the passive transfer. Assuming you're
keeping state on all outbound tcp sessions, passive trans-
fers will work already. If you're not doing this already,
-35-
please consider the following:
pass out proto tcp all keep state
The second type of client transfer, active, is a bit more
troublesome, but nonetheless a solved problem. Active
transfers cause the server to open up a second connection
back to the client for data to flow through. This is nor-
mally a problem when there's a firewall in the middle, stop-
ping outside connections from coming back in. To solve
this, ipfilter includes an ipnat proxy which temporarily
opens up a hole in the firewall just for the FTP server to
get back to the client. Even if you're not using ipnat to
do nat, the proxy is still effective. The following rules
is the bare minimum to add to the ipnat configuration file
(ep0 should be the interface name of the outbound network
connection):
map ep0 0/0 -> 0/32 proxy port 21 ftp/tcp
For more details on ipfilter's internal proxies, see section
3.6
8.3. Assorted Kernel Variables
There are some useful kernel tunes that either need to
be set for ipf to function, or are just generally handy to
know about for building firewalls. The first major one you
must set is to enable IP Forwarding, otherwise ipf will do
very little, as the underlying ip stack won't actually route
packets.
IP Forwarding:
openbsd:
net.inet.ip.forwarding=1
freebsd:
net.inet.ip.forwarding=1
solaris:
ndd -set /dev/ip ip_forwarding 1
Ephemeral Port Adjustment:
openbsd:
net.inet.ip.portfirst = 25000
freebsd:
net.inet.ip.portrange.first = 25000 net.inet.ip.por-
trange.last = 49151
-36-
solaris:
ndd -set /dev/tcp tcp_smallest_anon_port 25000
ndd -set /dev/tcp tcp_largest_anon_port 65535
Other Useful Values:
openbsd:
net.inet.ip.sourceroute = 0
net.inet.ip.directed-broadcast = 0
freebsd:
net.inet.ip.sourceroute=0
net.ip.accept_sourceroute=0
solaris:
ndd -set /dev/ip ip_forward_directed_broadcasts 0
ndd -set /dev/ip ip_forward_src_routed 0
ndd -set /dev/ip ip_respond_to_echo_broadcast 0
In addition, freebsd has some ipf specific sysctl variables.
net.inet.ipf.fr_flags: 0
net.inet.ipf.fr_pass: 514
net.inet.ipf.fr_active: 0
net.inet.ipf.fr_tcpidletimeout: 864000
net.inet.ipf.fr_tcpclosewait: 60
net.inet.ipf.fr_tcplastack: 20
net.inet.ipf.fr_tcptimeout: 120
net.inet.ipf.fr_tcpclosed: 1
net.inet.ipf.fr_udptimeout: 120
net.inet.ipf.fr_icmptimeout: 120
net.inet.ipf.fr_defnatage: 1200
net.inet.ipf.fr_ipfrttl: 120
net.inet.ipf.ipl_unreach: 13
net.inet.ipf.ipl_inited: 1
net.inet.ipf.fr_authsize: 32
net.inet.ipf.fr_authused: 0
net.inet.ipf.fr_defaultauthage: 600
9. Fun with ipf!
This section doesn't necessarily teach you anything new
about ipf, but it may raise an issue or two that you haven't
yet thought up on your own, or tickle your brain in a way
that you invent something interesting that we haven't
thought of.
--
※ 来源:·BBS 水木清华站 smth.org·[FROM: 202.199.66.62]
--
※ 转载:·BBS 荔园晨风站 bbs.szu.edu.cn·[FROM: 192.168.1.115]
[回到开始]
[上一篇][下一篇]
荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店