Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 Jan 2007 01:50:49 +1100 (EST)
From:      Ian Smith <smithi@nimnet.asn.au>
To:        "Dan Mahoney, System Admin" <danm@prime.gushi.org>
Cc:        freebsd-questions@freebsd.org
Subject:   Re: Problem with "ipfw flush"
Message-ID:  <Pine.BSF.3.96.1070126000614.29489A-100000@gaia.nimnet.asn.au>
In-Reply-To: <20070125032203.9986C16A47B@hub.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
 Re: freebsd-questions Digest, Vol 162, Issue 11
 > Message: 31

On Wed, 24 Jan 2007 19:20:47 -0500 (EST), Dan Mahoney wrote:

 > On Wed, 24 Jan 2007, Kevin Kinsey wrote:
 > 
 > > Dan Mahoney, System Admin wrote:
 > >> Hey all.
 > >> 
 > >> In trying to tweak my firewall setup I'm using a file called 
 > >> /etc/ipfw.rules
 > >> 
 > >> However, it seems even though I copy my rules perfectly to that file, the 
 > >> system freezes up and locks me out when I do:
 > >
 > > /usr/share/examples/ipfw/change_rules.sh?
 > 
 > That is a very cool script, however, it appears as though it calls 
 > firewall_script on line 131 with "sh", not with ipfw.
 > 
 > nohup sh ${firewall_script} ${firewall_type}.new
 > 
 > Whereas, etc/rc.firewall calls ipfw on line 299 via the "ipfw" command:
 > 
 > ${fwcmd} ${firewall_flags} ${firewall_type}
 > 
 > The difference is that the resulting rules file would not be parseable by 
 > "sh" since the lines in the file would not contain the "ipfw" command but 
 > only the arguments.  As one's in "examples" and the other's in a live 
 > startup script, I'd assume the latter to be the correct method.

Either.  Check /etc/defaults/rc.conf and you'll notice that the default
for firewall_script="/etc/rc.firewall" so 'sh ${firewall_script}' runs
'sh /etc/rc.firewall' which runs ipfw -f flush, denying all connections,
then later, in your case with a given filename, ipfw $flags $pathname

Do you have firewall_quiet="YES" ?  This will help a lot, otherwise ipfw
writes to the terminal, which after the flush, it can't.  From ipfw(8):

     o   If you are logged in over a network, loading the kld(4) version of
         ipfw is probably not as straightforward as you would think.  I recom-
         mend the following command line:

               kldload ipfw && \
               ipfw add 32000 allow ip from any to any

         Along the same lines, doing an

               ipfw flush

         in similar surroundings is also a bad idea.

 > That said, this still does not tell me why a subsequent flush-and-rerun 
 > isn't working via ssh.  It works totally fine via the command line, but 
 > over ssh it gives:
 > 
 > Jan 24 19:10:55 ads-bsh-fwa4 sshd[845]: fatal: Write failed: Permission 
 > denied on the console (but by that point my connection's already dropped).

Exactly.

 > However, this shouldn't actually stop an already-typed command, should it?

Yes, if it's trying to write to the terminal.  The bottom line is that
if you want to run it from a command line over ssh, the command must say
nothing to the terminal until finished.  Even then, if your ssh session
was being permitted by a keep-state rule you'll still lose your session,
but as someone else (sorry) mentioned, you can log straight back in.

 > Additionally, it doesn't appear that /etc/rc.firewall has the smarts to do 

I think you mean /etc/rc.d/ipfw here?

 > this, as the "stop" command it lists only disables the kernel firewall 
 > structure via sysctl, but does NOT flush the rules, pipes, counts, or the 
 > like, so it's not a true "restart".  (the idea being that otherwise, every 
 > rule will be added twice -- the flush is a necessary step there).

It is necessary, and it's done on (re)start.  If you're using
rc.firewall, as it seems you are, then in /etc/rc.d/ipfw: 

  ipfw_start()
  {
        # set the firewall rules script if none was specified
        [ -z "${firewall_script}" ] && firewall_script=/etc/rc.firewall

Right?  Then:

        if [ -r "${firewall_script}" ]; then
                  # .. nat stuff ..

                . "${firewall_script}"

which runs /etc/rc.firewall (in the current shell), starting with a) 
setting firewall_type - in your case, to your rules file, b) setting
fwcmd='ipfw -q' if firewall_quiet=yes (you do want this!) and then does
the '${fwcmd} -f flush' then (if not wedged) your rules.

 > Even if I add the "flush" command directly to /etc/ipfw.rules, and run 
 > ipfw -f /etc/ipfw.rules right from the command line, my connection gets 
 > dropped and the rest of the commands do not run.

Try with -q instead (this also implies -f)  RTFM on -q, until grokked.

 > In experimenting a bit more, I've found that I can do:
 > 
 > nohup ipfw -f /etc/ipfw.rules
 > 
 > This allows the rest of the ipfw command to run, but the HUP-on-disconnect 
 > still doesn't explain why the command doesn't even finish running.

I think it will IFF you use ipfw_quiet="yes" - and perhaps add a static
allow rule for your ssh access, before using any stateful rules, as any
existing dynamic connections will get clobbered on a flush, of course. 

Cheers, Ian




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.96.1070126000614.29489A-100000>