荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: 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软件 网络书店