荔园在线
荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀
[回到开始]
[上一篇][下一篇]
发信人: georgehill (清风浮云 人生), 信区: Linux
标 题: ipfilter-howto(7-15)(转寄)
发信站: BBS 荔园晨风站 (Thu Nov 2 23:07:31 2000), 站内信件
【 以下文字转载自 georgehill 的信箱 】
【 原文由 georgehill.bbs@smth.org 所发表 】
发信人: snofe ([听潮阁主人]), 信区: FreeBSD
标 题: ipfilter-howto(7-15)(转寄)
发信站: BBS 水木清华站 (Tue Oct 31 13:45:20 2000)
-7-
Compare this to our previous rule:
block in quick from 192.168.0.0/16 to any
pass in all
The old way, all traffic from 192.168.0.0/16, regardless of
interface, was completely blocked. The new way, using on
tun0 means that it's only blocked if it comes in on the tun0
interface. If a packet arrived on the xl0 interface from
192.168.0.0/16, it would be passed.
At this point you can build a fairly extensive set of
definitive addresses which are passed or blocked. Since
we've already started blocking private address space from
entering tun0, lets take care of the rest of it:
block in quick on tun0 from 192.168.0.0/16 to any
block in quick on tun0 from 172.16.0.0/12 to any
block in quick on tun0 from 10.0.0.0/8 to any
block in quick on tun0 from 127.0.0.0/8 to any
pass in all
You've already seen the first 3 blocks, but not the fourth.
The fourth is a largely wasted class-A network used for
loopback. Much software communicates with itself on
127.0.0.1 so blocking it from an external source is a good
idea.
There's a very important principle in packet filtering
which has only been alluded to with the private network
blocking and that is this: When you know there's certain
types of data that only comes from certain places, you setup
the system to only allow that kind of data from those
places. In the case of the unroutable addresses, you know
that nothing from 10.0.0.0/8 should be arriving on tun0
because you have no way to reply to it. It's an illegiti-
mate packet. The same goes for the other unroutables as
well as 127.0.0.0/8.
Many pieces of software do all their authentication
based upon the packet's originating IP address. When you
have an internal network, say 20.20.20.0/24, you know that
the only traffic for that internal network is going to come
off the local ethernet. Should a packet from 20.20.20.0/24
arrive over a PPP dialup, it's perfectly reasonable to drop
it on the floor, or put it in a dark room for interrogation.
It should by no means be allowed to get to its final desti-
nation. You can accomplish this particularly easily with
what you already know of IPF. The new ruleset would be:
block in quick on tun0 from 192.168.0.0/16 to any
block in quick on tun0 from 172.16.0.0/12 to any
block in quick on tun0 from 10.0.0.0/8 to any
block in quick on tun0 from 127.0.0.0/8 to any
-8-
block in quick on tun0 from 20.20.20.0/24 to any
pass in all
2.7. Bi-Directional Filtering; The "out" Keyword
Up until now, we've been passing or blocking inbound
traffic. To clarify, inbound traffic is all traffic that
enters the firewall on any interface. Conversely, outbound
traffic is all traffic that leaves on any interface (whether
locally generated or simply passing through). This means
that all packets coming in are not only filtered as they
enter the firewall, they're also filtered as they exit.
Thusfar there's been an implied pass out all that may or may
not be desirable. Just as you may pass and block incoming
traffic, you may do the same with outgoing traffic.
Now that we know there's a way to filter outbound pack-
ets just like inbound, it's up to us to find a concievable
use for such a thing. One possible use of this idea is to
keep spoofed packets from exiting your own network. Instead
of passing any traffic out the router, you could instead
limit permitted traffic to packets originating at
20.20.20.0/24. You might do it like this:
pass out quick on tun0 from 20.20.20.0/24 to any
block out quick on tun0 from any to any
If a packet comes from 20.20.20.1/32, it gets sent out by
the first rule. If a packet comes from 1.2.3.4/32 it gets
blocked by the second.
You can also make similar rules for the unroutable
addresses. If some machine tries to route a packet through
IPF with a destination in 192.168.0.0/16, why not drop it?
The worst that can happen is that you'll spare yourself some
bandwidth:
block out quick on tun0 from any to 192.168.0.0/16
block out quick on tun0 from any to 172.16.0.0/12
block out quick on tun0 from any to 10.0.0.0/8
In the narrowest viewpoint, this doesn't enhance your secu-
rity. It enhances everybody else's security, and that's a
nice thing to do. As another viewpoint, one might suppose
that because nobody can send spoofed packets from your site,
that your site has less value as a relay for crackers, and
as such is less of a target.
You'll likely find a number of uses for blocking out-
bound packets. One thing to always keep in mind is that in
-----------
This can, of course, be changed by using -DIPFIL-
TER_DEFAULT_BLOCK when compiling ipfilter on your
system.
-9-
and out directions are in reference to your firewall, never
any other machine.
2.8. Logging What Happens; The "log" Keyword
Up to this point, all blocked and passed packets have
been silently blocked and silently passed. Usually you want
to know if you're being attacked rather than wonder if that
firewall is really buying you any added benefits. While I
wouldn't want to log every passed packet, and in some cases
every blocked packet, I would want to know about the blocked
packets from 20.20.20.0/24. To do this, we add the log key-
word:
block in quick on tun0 from 192.168.0.0/16 to any
block in quick on tun0 from 172.16.0.0/12 to any
block in quick on tun0 from 10.0.0.0/8 to any
block in quick on tun0 from 127.0.0.0/8 to any
block in log quick on tun0 from 20.20.20.0/24 to any
pass in all
So far, our firewall is pretty good at blocking packets com-
ing to it from suspect places, but there's still more to be
done. For one thing, we're accepting packets destined any-
where. One thing we ought to do is make sure packets to
20.20.20.0/32 and 20.20.20.255/32 get dropped on the floor.
To do otherwise opens the internal network for a smurf
attack. These two lines would prevent our hypothetical net-
work from being used as a smurf relay:
block in log quick on tun0 from any to 20.20.20.0/32
block in log quick on tun0 from any to 20.20.20.255/32
This brings our total ruleset to look something like this:
block in quick on tun0 from 192.168.0.0/16 to any
block in quick on tun0 from 172.16.0.0/12 to any
block in quick on tun0 from 10.0.0.0/8 to any
block in quick on tun0 from 127.0.0.0/8 to any
block in log quick on tun0 from 20.20.20.0/24 to any
block in log quick on tun0 from any to 20.20.20.0/32
block in log quick on tun0 from any to 20.20.20.255/32
pass in all
2.9. Complete Bi-Directional Filtering By Interface
So far we have only presented fragments of a complete
ruleset. When you're actually creating your ruleset, you
should setup rules for every direction and every interface.
The default state of ipfilter is to pass packets. It is as
though there were an invisible rule at the beginning which
states pass in all and pass out all. Rather than rely on
some default behaviour, make everything as specific as pos-
sible, interface by interface, until every base is covered.
-10-
First we'll start with the lo0 interface, which wants
to run wild and free. Since these are programs talking to
other on the local system, go ahead and keep it unre-
stricted:
pass out quick on lo0
pass in quick on lo0
Next, there's the xl0 interface. Later on we'll begin plac-
ing restrictions on the xl0 interface, but to start with,
we'll act as though everything on our local network is
trustworthy and give it much the same treatment as lo0:
pass out quick on xl0
pass in quick on xl0
Finally, there's the tun0 interface, which we've been half-
filtering with up until now:
block out quick on tun0 from any to 192.168.0.0/16
block out quick on tun0 from any to 172.16.0.0/12
block out quick on tun0 from any to 10.0.0.0/8
pass out quick on tun0 from 20.20.20.0/24 to any
block out quick on tun0 from any to any
block in quick on tun0 from 192.168.0.0/16 to any
block in quick on tun0 from 172.16.0.0/12 to any
block in quick on tun0 from 10.0.0.0/8 to any
block in quick on tun0 from 127.0.0.0/8 to any
block in log quick on tun0 from 20.20.20.0/24 to any
block in log quick on tun0 from any to 20.20.20.0/32
block in log quick on tun0 from any to 20.20.20.255/32
pass in all
This is a pretty significant amount of filtering already,
protecting 20.20.20.0/24 from being spoofed or being used
for spoofing. Future examples will continue to show one-
sideness, but keep in mind that it's for brevity's sake, and
when setting up your own ruleset, adding rules for every
direction and every interface is necessary.
2.10. Controlling Specific Protocols; The "proto" Keyword
Denial of Service attacks are as rampant as buffer
overflow exploits. Many denial of service attacks rely on
glitches in the OS's TCP/IP stack. Frequently, this has
come in the form of ICMP packets. Why not block them
entirely?
block in log quick on tun0 proto icmp from any to any
Now any ICMP traffic coming in from tun0 will be logged and
discarded.
-11-
2.11. Filtering ICMP with the "icmp-type" Keyword; Merging
Rulesets
Of course, dropping all ICMP isn't really an ideal sit-
uation. Why not drop all ICMP? Well, because it's useful
to have partially enabled. So maybe you want to keep some
types of ICMP traffic and drop other kinds. If you want
ping and traceroute to work, you need to let in ICMP types 0
and 11. Strictly speaking, this might not be a good idea,
but if you need to weigh security against convenience, IPF
lets you do it.
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
Remember that ruleset order is important. Since we're doing
everything quick we must have our passes before our blocks,
so we really want the last three rules in this order:
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
block in log quick on tun0 proto icmp from any to any
Adding these 3 rules to the anti-spoofing rules is a bit
tricky. One error might be to put the new ICMP rules at the
beginning:
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
block in log quick on tun0 proto icmp from any to any
block in quick on tun0 from 192.168.0.0/16 to any
block in quick on tun0 from 172.16.0.0/12 to any
block in quick on tun0 from 10.0.0.0/8 to any
block in quick on tun0 from 127.0.0.0/8 to any
block in log quick on tun0 from 20.20.20.0/24 to any
block in log quick on tun0 from any to 20.20.20.0/32
block in log quick on tun0 from any to 20.20.20.255/32
pass in all
The problem with this is that an ICMP type 0 packet from
192.168.0.0/16 will get passed by the first rule, and never
blocked by the fourth rule. Also, since we quickly pass an
ICMP ECHO_REPLY (type 0) to 20.20.20.0/24, we've just opened
ourselves back up to a nasty smurf attack and nullified
those last two block rules. Oops. To avoid this, we place
the ICMP rules after the anti-spoofing rules:
block in quick on tun0 from 192.168.0.0/16 to any
block in quick on tun0 from 172.16.0.0/12 to any
block in quick on tun0 from 10.0.0.0/8 to any
block in quick on tun0 from 127.0.0.0/8 to any
block in log quick on tun0 from 20.20.20.0/24 to any
block in log quick on tun0 from any to 20.20.20.0/32
block in log quick on tun0 from any to 20.20.20.255/32
-12-
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
block in log quick on tun0 proto icmp from any to any
pass in all
Because we block spoofed traffic before the ICMP rules are
processed, a spoofed packet never makes it to the ICMP rule-
set. It's very important to keep such situations in mind
when merging rules.
2.12. TCP and UDP Ports; The "port" Keyword
Now that we've started blocking packets based on proto-
col, we can start blocking packets based on specific aspects
of each protocol. The most frequently used of these aspects
is the port number. Services such as rsh, rlogin, and tel-
net are all very convenient to have, but also hideously
insecure against network sniffing and spoofing. One great
compromise is to only allow the services to run internally,
then block them externally. This is easy to do because
rlogin, rsh, and telnet use specific TCP ports (513, 514,
and 23 respectively). As such, creating rules to block them
is easy:
block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 513
block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 514
block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 23
Make sure all 3 are before the pass in all and they'll be
closed off from the outside (leaving out spoofing for
brevity's sake):
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0
pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11
block in log quick on tun0 proto icmp from any to any
block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 513
block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 514
block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 23
pass in all
You might also want to block 514/udp (syslog), 111/tcp &
111/udp (portmap), 515/tcp (lpd), 2049/tcp and 2049/udp
(NFS), 6000/tcp (X11) and so on and so forth. You can get a
complete listing of the ports being listened to by using
netstat -a (or lsof -i, if you have it installed).
Blocking UDP instead of TCP only requires replacing
proto tcp with proto udp. The rule for syslog would be:
block in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 514
IPF also has a shorthand way to write rules that apply to
both proto tcp and proto udp at the same time, such as
portmap or NFS. The rule for portmap would be:
-13-
block in log quick on tun0 proto tcp/udp from any to 20.20.20.0/24 port =
111
3. Advanced Firewalling Introduction
This section is designed as an immediate followup to
the basic section. Contained below are both concepts for
advanced firewall design, and advanced features contained
only within ipfilter. Once you are comfortable with this
section, you should be able to build a very strong firewall.
3.1. Rampant Paranoia; or The Default-Deny Stance
There's a big problem with blocking services by the
port: sometimes they move. RPC based programs are terrible
about this, lockd, statd, even nfsd listens places other
than 2049. It's awfully hard to predict, and even worse to
automate adjusting all the time. What if you miss a ser-
vice? Instead of dealing with all that hassle, lets start
over with a clean slate. The current ruleset looks like
this:
Yes, we really are starting over. The first rule we're
going to use is this:
block in all
No network traffic gets through. None. Not a peep. You're
rather secure with this setup. Not terribly useful, but
quite secure. The great thing is that it doesn't take much
more to make your box rather secure, yet useful too. Lets
say the machine this is running on is a web server, nothing
more, nothing less. It doesn't even do DNS lookups. It
just wants to take connections on 80/tcp and that's it. We
can do that. We can do that with a second rule, and you
already know how:
block in on tun0 all
pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80
This machine will pass in port 80 traffic for 20.20.20.1,
and deny everything else. For basic firewalling, this is
all one needs.
3.2. Implicit Allow; The "keep state" Rule
The job of your firewall is to prevent unwanted traffic
getting to point B from point A. We have general rules
which say "as long as this packet is to port 23, it's okay."
-14-
We have general rules which say "as long as this packet has
its FIN flag set, it's okay." Our firewalls don't know the
beginning, middle, or end of any TCP/UDP/ICMP session. They
merely have vague rules that are applied to all packets.
We're left to hope that the packet with its FIN flag set
isn't really a FIN scan, mapping our services. We hope that
the packet to port 23 isn't an attempted hijack of our tel-
net session. What if there was a way to identify and autho-
rize individual TCP/UDP/ICMP sessions and distinguish them
from port scanners and DoS attacks? There is a way, it's
called keeping state.
We want convenience and security in one. Lots of peo-
ple do, that's why Ciscos have an "established" clause that
lets established tcp sessions go through. Ipfw has estab-
lished. Ipfwadm has setup/established. They all have this
feature, but the name is very misleading. When we first saw
it, we thought it meant our packet filter was keeping track
of what was going on, that it knew if a connection was
really established or not. The fact is, they're all taking
the packet's word for it from a part of the packet anybody
can lie about. They read the TCP packet's flags section and
there's the reason UDP/ICMP don't work with it, they have no
such thing. Anybody who can create a packet with bogus
flags can get by a firewall with this setup.
Where does IPF come in to play here, you ask? Well,
unlike the other firewalls, IPF really can keep track of
whether or not a connection is established. And it'll do it
with TCP, UDP and ICMP, not just TCP. Ipf calls it keeping
state. The keyword for the ruleset is keep state.
Up until now, we've told you that packets come in, then
the ruleset gets checked; packets go out, then the ruleset
gets checked. Actually, what happens is packets come in,
the state table gets checked, then *maybe* the inbound rule-
set gets checked; packets go out, the state table gets
checked, then *maybe* the outbound ruleset gets checked.
The state table is a list of TCP/UDP/ICMP sessions that are
unquestionadely passed through the firewall, circumventing
the entire ruleset. Sound like a serious security hole?
Hang on, it's the best thing that ever happened to your
firewall.
All TCP/IP sessions have a start, a middle, and an end
(even though they're sometimes all in the same packet). You
can't have an end without a middle and you can't have a mid-
dle without a start. This means that all you really need to
filter on is the beginning of a TCP/UDP/ICMP session. If
the beginning of the session is allowed by your firewall
rules, you really want the middle and end to be allowed too
(lest your IP stack should overflow and your machines become
useless). Keeping state allows you to ignore the middle and
end and simply focus on blocking/passing new sessions. If
-15-
the new session is passed, all its subsequent packets will
be allowed through. If it's blocked, none of its subsequent
packets will be allowed through. Here's an example for run-
ning an ssh server (and nothing but an ssh server):
block out quick on tun0 all
pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 22 keep
state
The first thing you might notice is that there's no "pass
out" provision. In fact, there's only an all-inclusive
"block out" rule. Despite this, the ruleset is complete.
This is because by keeping state, the entire ruleset is cir-
cumvented. Once the first SYN packet hits the ssh server,
state is created and the remainder of the ssh session is
allowed to take place without interference from the fire-
wall. Here's another example:
block in quick on tun0 all
pass out quick on tun0 proto tcp from 20.20.20.1/32 to any keep state
In this case, the server is running no services. Infact,
it's not a server, it's a client. And this client doesn't
want unauthorized packets entering its IP stack at all.
However, the client wants full access to the internet and
the reply packets that such privledge entails. This simple
ruleset creates state entries for every new outgoing TCP
session. Again, since a state entry is created, these new
TCP sessions are free to talk back and forth as they please
without the hinderance or inspection of the firewall rule-
set. We mentioned that this also works for UDP and ICMP:
block in quick on tun0 all
pass out quick on tun0 proto tcp from 20.20.20.1/32 to any keep state
pass out quick on tun0 proto udp from 20.20.20.1/32 to any keep state
pass out quick on tun0 proto icmp from 20.20.20.1/32 to any keep state
Yes Virginia, we can ping. Now we're keeping state on TCP,
UDP, ICMP. Now we can make outgoing connections as though
there's no firewall at all, yet would-be attackers can't get
back in. This is very handy because there's no need to
track down what ports we're listening to, only the ports we
want people to be able to get to.
State is pretty handy, but it's also a bit tricky. You
can shoot yourself in the foot in strange and mysterious
ways. Consider the following ruleset:
pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23
pass out quick on tun0 proto tcp from any to any keep state
block in quick all
block out quick all
At first glance, this seems to be a good setup. We allow
incoming sessions to port 23, and outgoing sessions
--
※ 来源:·BBS 水木清华站 smth.org·[FROM: 202.199.66.62]
--
※ 转载:·BBS 荔园晨风站 bbs.szu.edu.cn·[FROM: 192.168.1.115]
[回到开始]
[上一篇][下一篇]
荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店