[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

EXT/INT/DMZ topology with small subnet from ISP: SOLVED

I recently posted a question about implementing the "Serious Example"
(http://www.linuxdoc.org/HOWTO/IPCHAINS-HOWTO-7.html) while using the 5
static ip addresses that come with the "enhanced DSL" package from
PacBell. Many thanks to all who responded! Since this situation is
common to the many PacBell users out there as well as anyone else who
gets a small subnet from their ISP, here's what worked for me.

The problem was to implement this topology from the Example:

   External Network (BAD)
      ||             Server Network (DMZ)
      |             |eth0
      |             |----------------------------------------------
      |             | |             |              |
      |             |               |             |              |
      ||               |             |              |
      ---------------         --------       -------        -------
             | eth1           | SMTP |       | DNS |        | WWW |
             |                --------       -------        -------
     Internal Network (GOOD)

In the case of a small subnet from the ISP, things are slightly
different. Since PPP isn't used, the BAD network interface has an ip
address within the range of the DMZ network. This actually matches the
diagram from the example, but this diagram is misleading, since the ip
address assigned to ppp0 comes from the ISP dynamically and so *isn't* (Actually, as I think about it, I don't understand this
diagram, since it shows static, public ip addresses in the DMZ yet uses
PPP to connect to the ISP.)

Anyway, the problem is the ambiguity of having the ip addresses given by
the ISP in both the BAD and the DMZ networks. The result is that while
GOOD and BAD can connect and GOOD and DMZ can connect, DMZ can't get to
BAD and vice versa. Searching through the debian archives, I found a
number of postings reporting this same problem.

So here is the topology I wanted to implement (assuming that the subnet
from the ISP is the first n/29 subnet so its addresses run from x.y.z.0
to x.y.z.7):

   External Network (BAD) -> ISP gateway x.y.z.1/29
             |                   network x.y.z.0/29
             |                   broadcast x.y.z.7/29
      | x.y.z.2/29  |             Server Network (DMZ)
      |             |eth1
      |             |----------------------------------------------
      |             |x.y.z.3/29     |             |              |
      |             |               |             |              |
      | |               |             |              |
      ---------------         --------       -------        -------
             | eth2           | box 1|       | box 2|      | box 3 |
             |                --------       -------        -------
             |               x.y.z.4/29     x.y.z.5/29     x.y.z.6/29
     Internal Network (GOOD) []

Stepping back a bit first, though, there are several possible
alternatives worth considering:

1. Just IPMASQ the DMZ (like GOOD) and portforward the services you want
to run in the DMZ. 

This sidesteps the problem and may be the preferred solution; I'm
interested in hearing how many people out there host their servers in
this way. However, it fails to use the extra ip addresses (unless you
alias them to the firewall box and statically translate them into the
DMZ, but it's unclear to me how this is superior to the simple IPMASQ

2. Subnet the subnet from the ISP to get separate ranges for BAD and

This would work fine, though not with the small n/29 subnet PacBell (and
presumably other ISPs) provides. As it is, of the 8 ip addresses in my
n/29 slice, one is the network address, one is the broadcast address,
and one is the gateway address -- leaving 5. To subnet this into two
would remove 4 more (a network and a broadcast address for each
sub-subnet) leaving only a single address to actually assign to a NIC.
But this topology needs one each for the EXT NIC, the DMZ NIC on the
firewall box, and one for each DMZ host NIC. So this obviously won't

3. Forget this topology and just expose the web/mail/etc hosts in EXT.

Very simple and certainly a fallback. By running IPCHAINS on each
exposed host, you get basically the same result as the DMZ filtering
from the target topology. I suspect a lot (most?) people do this. If I
hadn't managed to get things to work, I would have done this. Perhaps
this is the preferred solution. Still, I wasn't happy giving up without
figuring this out ;-)

4. Bridge+firewall.

There is an interesting Mini-HOW-TO
(http://www.linuxdoc.org/HOWTO/mini/Bridge+Firewall+DSL.html) that
sounded appropriate to this problem. This might be a superior solution,
too, though it seemed more complex than necessary. It would be
interesting to hear from someone who knows more about this than I do as
to its merits vs the other alternatives.

5. Proxy ARP

This finally was the solution that most people reported had worked for
them, and this is what I did. There is a helpful Mini-HOW-TO
(http://www.linuxdoc.org/HOWTO/mini/Proxy-ARP-Subnet/index.html) that
discusses Proxy ARP with subnetting. For the reasons discussed in 2,
subnetting isn't an option here. But using Proxy ARP without subnetting
is a simple solution.

Basically, the idea is to set up the subnet from the ISP so that it
"belongs" to EXT (since it does) but then to use Proxy ARP to tell the
firewall box kernel that specific addresses from that subnet actually
"belong" in the DMZ. (Sorry for the colloquial terminology, though if
you've read this far, it's likely that you are more of an learner like
me than a TCP/IP expert who would be offended by this!) How this happens
is nicely described in the Mini-HOW-TO; it's complex and I won't repeat
it here.

Anyway, to accomplish this is remarkably simple. First you use arp for
each host you want in the DMZ:

	arp -v -i eth0 -Ds x.y.z.4 eth0 pub

This puts arp in verbose mode while it publishes a static entry for the
x.y.z.4 host to the cache for the EXT interface eth0 (the D flag spares
us from looking up and entering the MAC (hardware) address for eth0).
The Mini-HOW-TO proxy ARPs a subnet; here we have to arp each host
separately since we're *not* doing a subnet.

Then you create the correct routes:

	route add -net x.y.z.0 netmask dev eth0

for the subnet from the ISP, and

	route add -host x.y.z.4 dev eth1

for each of the host boxes in the DMZ.

At the end of all this, the routing table for the firewall box should
look like this (after the first DMZ host is added):

# netstat -nr
Kernel IP routing table
Destination  Gateway  Genmask          Flags  MSS Window irtt Iface
x.y.z.4  UH     0   0      0    eth1
x.y.z.0  U      0   0      0    eth0    U      0   0      0    eth2      x.y.z.0          UG     0   0      0    eth0

And the output of arp will show (in addition to lines from other hosts
depending on whether there has been traffic to/from them) a line from
our arp command:

# arp -an
...other stuff deleted...
? (x.y.z.4) at * PERM PUP on eth0

Anyway, hope this summary is useful to anyone else trying to set up this
kind of arrangement. If I've made some errors here (or if there are
reasons to prefer one of the other alternatives) I'd like to hear about

Thanks again to the debian community that provides such amazing help!



Reply to: