9front - general discussion about 9front
 help / color / mirror / Atom feed
From: cinap_lenrek@felloff.net
To: 9front@9front.org
Subject: Using Plan 9 (9front) as a NAT router.
Date: Sat, 27 Jun 2020 17:56:16 +0200	[thread overview]
Message-ID: <7AEE26C1A5214C0FB0014A04A715EB28@felloff.net> (raw)

In my home network, i'v been using 9front as my router
for (both v4 and v6) for a while.

In a pure Plan 9 network, not having NAT is not an issue
as we can import the gateways ip stack over 9p to share
a single ip address with multiple machines.

But with non-plan9 machines in the network, we need something
different.

For that, i have been using a unix machine to do the v4
NAT translation. Recently, that machine failed and i had
to come up with a work around, which i want to share here.

We can actuallly use 9front as a transparent proxy, that
looks almost the same as a NAT router from the outside.

The key mechanism is that if we can add the magic address
0.0.0.0/0.0.0.0 to an interface, the ip stack will accept
any connection as if it was destined to itself.

This mechanism is normally only used for the dhcp client and
it makes the ip stack useless for outgoing connections as
it will put 0.0.0.0 as the source ip address.

But if we combine multiple ip stacks, routing and
aux/trampoline we can build us a transparent proxy.

A script that demonstrates this trick follows:

# fist, we need to get us a separate ip stack that we use
# *only* for incoming connections. lets bind it to /n/nat:

bind -a '#I2' /n/nat

# now, we add a packet interface to the /n/nat stack
# and hook it up to our primay ip stack on /net
< /n/nat/ipifc/clone {
	nifc=/n/nat/ipifc/`{read}
	> $nifc/ctl {
		echo bind pkt

		# here, we add the magic null address so this stack
		# will accept any incoming connection. the nexthop
		# is 0.0.0.1, which will be the interface on the
		# /net side.
		echo add 0.0.0.0 0.0.0.0 0.0.0.1
		echo iprouting 0

		# now, create a new interface on /net that connects
		# the two ip stacks.
		< /net/ipifc/clone {
			oifc=/net/ipifc/`{read}
			> $oifc/ctl {
				echo bind netdev $nifc/data
				echo add 0.0.0.1 255.255.255.255 0.0.0.0
				echo iprouting 1
			}
		}
	}
}

# now, we can listen on /n/nat ip stack for incoming connections
# and relay them to their original destination, but with the source
# ip of the router itself.
# aux/listen1 sets $net to the new incoming network connection directory.
# note that the original destination is found from $net/local:

aux/listen1 -t -p 500 '/n/nat/tcp!*!*' /bin/rc -c 'exec aux/trampoline /net/tcp!`{cat $net/local}' &
aux/listen1 -t -p 100 '/n/nat/udp!*!*' /bin/rc -c 'exec aux/trampoline -t 5000 /net/udp!`{cat $net/local}' &

# the -p flag limits the number of connections active at a time, and
# the aux/trampoline -t flag sets a inactivity timeout for udp.

# finally we can add a source specific default route with gateway
# address of 0.0.0.0 to route traffic from our local network
# (192.168.1.0/24) towards our proxy:

echo add 0.0.0.0 0.0.0.0 0.0.0.0 192.168.1.0 255.255.255.0 > /net/iproute

# end

Implementing 464XLAT is left as an exercise to the reader.

--
cinap


                 reply	other threads:[~2020-06-27 15:56 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7AEE26C1A5214C0FB0014A04A715EB28@felloff.net \
    --to=cinap_lenrek@felloff.net \
    --cc=9front@9front.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).