erride default ICMP (and other protocols) default replies.

Christopher Cowart ccowart at rescomp.berkeley.edu
Thu Aug 21 18:53:11 UTC 2008


Javier Ubillos wrote:
> Hi freebsd-net.
> (Sorry for cross posting. This time I think I found the right forum for
> my question)
> 
> I'm implementing a NAT (1 ip - 1 ip) like router. (it's not actually
> NAT, but it's a good analogy for this case).
> 
> I have chosen to use pcaplib to pick up the packets. I have an
> implementation which picks up the packets, inspects them, rewrites the
> destination/source ip-addresses and sends them out on the repective
> interface.
> 
> The problem I'm facing however is that my interfaces are answering to
> e.g. icmp-echo (ping) automatically, and I don't know how to turn this
> behaviour off.
> 
> What I want to happen is that if A pings C, my router B in between
> should simply forward the packets w/o any automatic reactions.
> 
> A --> B --> C
> 
> So that if e.g. C is down, no echo-reply is sent back (or if C is up,
> that C is actually sending the echo-reply.
> 
> Does any one know how to turn off the automatic replies (ICMP and
> whatever else I haven't forseen yet) or does any one know where I can
> find out more about the issue?

I'm using ipfw(8), ng_ipfw(4), ng_nat(4), and arp(8) to acheive these
results. I have a transparent HTTP proxy via squid that dynamically runs
code to setup 1-to-1 NAT rules for users who authenticate to our
wireless network. I have a clean 7.0 build, except I patched ng_nat to
7-STABLE to get the functionality of the 'redirectaddr' message.

Some relevant code snippets from the system:

$onatid and $inatid are deterministic identifiers for numbering the
netgraph nodes (they're a function of the public IP assigned). 

On setup:
| ngctl mkpeer ipfw: nat $onatid out
| ngctl name ipfw:$onatid $name
| ngctl connect ipfw: ${name}: $inatid in
| ngctl msg ${name}: setaliasaddr $public_ip
| ngctl msg ${name}: redirectaddr '{' \
|     "local_addr=$private_ip" \
|     "alias_addr=$public_ip" \
|     'description="Static NAT"' \
| '}'
|
| # Clear any arp entries for this IP that might be in the table, just
| # to keep things consistent
| arp -d "$public_ip" >/dev/null 2>&1
|
| # Use arp(8) to claim this public IP address
| arp -s $public_ip $aux_mac pub 2>&1 | nac_log
|
| ipfw table $private_table add $private_ip $onatid
| ipfw table $public_table  add $public_ip  $inatid

On teardown:
| arp -d "$public_ip"
| ngctl shutdown ipfw:${onatid}
| for table in $PRIVATE_TABLES ; do
|     ipfw -q table $table delete $private_ip $onatid
| done
| for table in $PUBLIC_TABLES ; do
|     ipfw -q table $table  delete $public_ip  $inatid
| done

This corresponds with the following in ipfw.rules (note by this point in
the ruleset, all "management" traffic has been dealt with):
| # NAT all traffic coming in from authenticated users
| $cmd netgraph tablearg all from "table($TABLE_WIFI_PRIV_AUTH)" to any in
| for net in $NAC_PUBLIC_NETS ; do
| 
|     # NAT all traffic coming in to authenticated users
|     $cmd netgraph tablearg all from any to "table($TABLE_WIFI_PUB_AUTH)" \
|         in via $(nac_if "$net")
| 
|     # We must set interface and direction on these fwd rules. If not, they
|     # will match traffic from any other hosts on these subnets (including
|     # the router) and deflect traffic in the wrong direction.
|     for privnet in $NAC_PRIVATE_NETS ; do
|         $cmd fwd $(nac_router "$net") ip from $(nac_subnet "$net") to not \
|             $(nac_subnet "$net") in via $(nac_if "$privnet")
|     done
| done
| $cmd allow all from any to "table($TABLE_WIFI_PRIV_AUTH)"
| $cmd allow all from "table($TABLE_WIFI_PUB_AUTH)" to any

For each subnet I'm using, I assign an IP to this FreeBSD box so that it
knows how to get to the gateway. The published arp entries take care of
"claiming" the addresses that are in-use and getting the IP traffic
passed up the stack. ipfw intercepts, does the packet-munging, and
forwards the results.

The hosts behind this box (dubbed an "aux-router" internally) see all IP
traffic destined for them -- incoming ICMP or TCP or UDP all gets where
it's supposed to go. There is no state across reboots.

You may be able to get things working the way you want by *not* using
ifconfig to assign address, but instead using this arp(8) trick. You may
find the use of ng_nat suits your needs though. Let me know if any of
this is unclear.

-- 
Chris Cowart
Network Technical Lead
Network & Infrastructure Services, RSSP-IT
UC Berkeley
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-net/attachments/20080821/40072368/attachment.pgp


More information about the freebsd-net mailing list