[plug] masq cameron tony

Cameron Patrick cameron at patrick.wattle.id.au
Tue Dec 16 19:00:43 WST 2003


On Tue, Dec 16, 2003 at 06:18:17PM +0800, smclevie wrote:

| Have twiddled and fiddled Camerons script.  I have picked up a number of 
| <carriage-returns>... in amongst the commands  (That is ONE reason for 
| using WORD ..!  I can see the hidden characters ...)

Those extra line breaks are bad, you don't want them there.  If you are
using vim as your editor, :set textwidth=0 will stop it from
automatically inserting line breaks after a certain length of line... or
the -w command-line option if you're using nano.  (The nano in recent
versions of Debian has been patched so that this is the default when
you're running it as root, but I'm not sure whether that'll be the case
in yours.)

| Could I have a Pauline Hanson on the first 3 commands?  (Please explain...)

(I believe that we are in danger of being swamped by shell scripts... :-P)

The first one (LAN_NET) sets the IP range which isn't visible to the
"real" internet.  Any request that comes from there but is heading
somewhere else masqueraded.

The second one (INET_IP) finds your Internet-visible IP address.  I can't
remember why I had to use this rather than doing it by specifying an
interface with -i/-o - it was something related to the quirky stuff that
my particular set-up does but yours doesn't have to.  (Possibly because
sometimes I have two public IP addresses?)

The third (TRUSTED_IFACE) lists network interfaces that you trust
completely; any packets from them will be accepted.  You always want to
list "lo" here (which is the loopback interface, for connection from
your computer to itself), because otherwise things fail mysteriously.
The other entry is eth0, your internal network.  (In my case, there is
another interface listed too.)

An explanation of how this line works:
	INET_IP="`ip addr show dev ppp0 | grep ' inet ' | awk '{print$2}' | cut -d/  -f1`"
The stuff between the backticks `...` is executed as a shell command,
and the output placed into the ${INET_IP} variable.  In this case, we
run 'ip addr show dev ppp0' and pipe its output to a bunch of other
command to extract the IP address from it.

The output of ip addr show [blah] looks something like this:
3: eth0: <BROADCAST,MULTICAST,NOTRAILERS,UP> mtu 1500 qdisc pfifo_fast qlen 100
    link/ether 00:40:f4:87:a1:ae brd ff:ff:ff:ff:ff:ff
    inet 10.0.1.2/24 brd 10.0.1.255 scope global eth0
    inet6 fec0::240:f4ff:fe87:a1ae/64 scope site dynamic 
       valid_lft 2591972sec preferred_lft 604772sec
    inet6 fe80::240:f4ff:fe87:a1ae/64 scope link 

The bit we want is "10.0.1.2", so we use grep to only list lines
containing the string ' inet ', awk to extract the second
space-separated field (in this case, 10.0.1.2/24) and cut to remove the
first field ("-f1") delimited by /'s ("-d/") - leaving us with the IP
address 10.0.1.2.

(This is where someone else tells me it can all be done in one command
and/or line of perl code, without any magic shell scripting.)

| I have no idea as to whether it actually 'works' but I do know when
| the machine is rebooted it hangs on stopping 'named' and the XP
| machine loses Samba access to Debian.

I don't believe it would, those for loops that you killed were where the
important stuff happened, i.e. allowing access to/from the outside world :-)

| My preference is to have a more 'static' implementation if possible (ie. 
| avoid for - do loops).

I'll explain how to do that below, but they're there to make things
easier to change so you might not want to.

The stuff below it appears James has already answered, but...

| INET_IP="`ip addr show dev ppp0 | grep ' inet ' | awk '{print$2}' | cut -d/ 
| -f1`"

(Hopefully this wasn't wrapped in your original script)

| #for chain in FORWARD INPUT OUTPUT do iptables -A ${chain} -m state --state 
| ESTABLISHED,RELATED -j ACCEPT done

There was a reason that each bit was on a separate line on the original:
it makes it easier to read, and also lets bash know where one command
starts and another ends.  Otherwise, you need semicolons.  (Insert pun
about syntax errors and semicolon cancer here :-P)  Incidentally,
you've even removed the ';' between OUTPUT and do - it's necessary
unless you put the 'do' on a line of its own.

If you want to 'unroll' this loop, you'd want something like:
        iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
        iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
        iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Doing it with for is IMHO neater :-)

(In your case, the OUTPUT bit is actually unnecessary, as you don't have
any rules which deny outgoing traffic later on.  I do, which is why it
was there.)

| #for iface in $TRUSTED_IFACE do iptables -A FORWARD -i $iface -j ACCEPT 
| iptables -A INPUT -p ALL -i $iface -j ACCEPT done

(What I said about semicolons and line breaks applies here too.)

And the unrolled version:

        iptables -A FORWARD -i lo -j ACCEPT
        iptables -A INPUT -p ALL -i lo -j ACCEPT
        iptables -A FORWARD -i eth0 -j ACCEPT
        iptables -A INPUT -p ALL -i eth0 -j ACCEPT

Cheers,

Cameron.




More information about the plug mailing list