Nat! bio photo

Nat!

Senior Mull.

Twitter RSS

Github

Bridging a wireless and an ethernet network with OS X 10.8, updated again

I made a modification to the script, because the proxy_all sysctl isn't really needed in my setup.

Below in the drawing is my current home setup. My DSL router 192.168.0.1 ("fritz.box") creates a WIFI network 192.168.0.0/24. I then have another ethernet based network 192.168.1.0/24, with machines, that have no wireless capabilities.

This used to work fine, if one machine with an ethernet card (192.168.1.2) and a wireless card (192.168.0.2) running OS X, provided internet sharing for the wired net. But when I recently added a wireless only machine 192.168.0.3 it became apparent, that this machine was not able to talk to the 192.168.1.0/24 network.

It took me quite a while to figure out how to do it, although the information is available, if you know which keywords to google for.

First things first. Apple's "Internet Sharing" is doing NAT, which in this case is harmful. NAT and bridging can not be used reliably together (says the OpenBSD pf documentation). But I need to use "real" ethernet bridging, which can be done in OS X since 10.8 apparently.

So "Internet Sharing" has to be turned off. This could change the wired interface IP address!

Create a permanent ethernet bridge on OS X

I put this shell script into /usr/local/sbin as mulle-ethernet-bridge.sh (on the machine with the interfaces 192.168.1.2 and 192.168.0.2):

#! /bin/sh
# ######################################
#  coded by Nat!
#  2013 Mulle kybernetiK
#  GPL

command=${1:-start}
shift
proxyarp=${1:-no}
shift

start()
{
        sysctl -w net.inet.ip.forwarding=1
        sysctl -w net.inet.ip.fw.enable=1
        if [ "$proxyarp" != "no" ]
        then
                sysctl -w net.link.ether.inet.proxyall=1
        fi

        ifconfig bridge0 create
        ifconfig bridge0 addm en0
        ifconfig bridge0 addm en1
        ifconfig bridge0 up
        if [ $? -eq 0 ]
        then
                syslog -s "Mulle Ethernet Bridge is up"
        else
                syslog -s "Mulle Ethernet Bridge failure"
        fi
}


stop()
{
        ifconfig bridge0 destroy

        sysctl -w net.inet.ip.forwarding=0
        sysctl -w net.inet.ip.fw.enable=0
        sysctl -w net.link.ether.inet.proxyall=0

        syslog -s "Mulle Ethernet Bridge is down"
}



case "$command" in
        start*) start
                ;;
        
        stop*)  stop
                ;;
esac
and configured it for executability
chmod 755 /usr/local/sbin/mulle-ethernet-bridge.sh
Then I put the following XML into /Library/LaunchDaemons as com.mulle-kybernetik.admin.ethernet-bridge.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>com.mulle-kybernetik.admin.ethernet-bridge</string>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/local/sbin/mulle-ethernet-bridge.sh</string>
        </array>
        <key>UserName</key>
        <string>root</string>
        <key>GroupName</key>
        <string>wheel</string>
        <key>RunAtLoad</key>
        <true/>
        <key>LaunchOnlyOnce</key>
        <true/>   
    </dict>
</plist>
and added it to launchd thusly

sudo chmod 644 /Library/LaunchDaemons/com.mulle-kybernetik.admin.ethernet-bridge.plist
sudo chown root:wheel /Library/LaunchDaemons/com.mulle-kybernetik.admin.ethernet-bridge.plist
sudo launchctl load /Library/LaunchDaemons/com.mulle-kybernetik.admin.ethernet-bridge.plist
Check with ifconfig that the bridge0 device has appeared now:
bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        ether ac:dc:18:48:20:13 
        Configuration:
                priority 0 hellotime 0 fwddelay 0 maxage 0
                ipfilter disabled flags 0x2
        member: en0 flags=3
                 port 4 priority 0 path cost 0
        member: en1 flags=3
                 port 5 priority 0 path cost 0

Configuring a wired box

I have a manually configured wired box with the address 192.168.1.4. It's network settings are now like this:
IP192.168.1.4
Router(Gateway)192.168.1.2
DNS192.168.0.1

But for ease of use I also run a DHCP server on the bridging machine (192.168.1.2). Jacques Fortier has the neccessary information to set one up on Mac OS X, without having to install any packages.

Adding routes to the wireless boxes

The wired boxes will be able to send pings to the wireless boxes, but the wireless boxes will send the return packets to the fritz.box, because NAT is disabled and any address 192.168.1.0/24 doesn't mean anything for them yet. Conceivably the fritz.box sends those replies then out to the interwebs, because it doesn't know the 192.168.1.0/24 network eiher and the interwebs are the default route.

This information needs to be added to the static routing tables of the router. Thankfully the fritz box allows this in its expert settings. So I added:

NetworkNetmaskGateway
192.168.1.0255.255.255.0192.168.0.2

With that the setup worked albeit not perfectly. I could now ping from the windows box 192.168.0.3 to the debian box 192.168.1.5, but the packets would actually be running through both 192.168.0.1 and 192.168.0.2: one hop too much. This is especially bad, since the extra hop is wireless. Fortunately you can also add static routes in windows (using -p for a permanent route):
route -p add 192.168.1.0 mask 255.255.255.0 192.168.0.2 metric 1

7 Comments

A photo of David Marr (Test)

From: David Marr (Test)

Hey thanks for publishing your results. I am trying to do something similar with my home network.

I have a router (airport extreme) and i ran a long ethernet cable from it to another room. I tried connecting it directly to my other mac mini and I was hoping to run this script there to act like a sort of bridge/extender.

The problem is how do I have my clients connect to that machine that has the bridge?

A photo of Nat!

From: Nat!

The question is too broad. What's specifically the problem ? Is the problem that the Mini only has one ethernet interface ? Can't you ping the Mini anymore ? Is it not routing ?

A photo of plus.google.com/113228768728804517743

From: plus.google.com/113228768728804517743

Hi Nat!

I am trying to do a similar thing, but using Internet Sharing

http://stackoverflow.com/questions/18985965/redirect-port-forwarding-from-en0-to-bridge0-shared-connection-on-mac-10-8-5

Is the en1 the wireless interface?

I followed your instructions but now I Sharing the wireless conection is dissabled.

Do you use an external Wireless router attached to the mac instead of the "Internet Sharing" option?

Do you think is it possible to Share the internet (bridging) from the Mac without using the System preferences?

Thanks!

A photo of Nat!

From: Nat!

Hi

to quote myself

First things first. Apple's "Internet Sharing" is doing NAT, which in this case is harmful. NAT and bridging can not be used reliably together (says the OpenBSD pf documentation). But I need to use "real" ethernet bridging, which can be done in OS X since 10.8 apparently.

So "Internet Sharing" has to be turned off. This could change the wired interface IP address!

You can not do "Internet Sharing" but you shouldn't have to, since that's the point of the bridge.

en1 is whatever the second ethernet like interface in your system is. It could be either.

I will make a few edits to the text, to make it a bit easier to execute.

A photo of Nat!

From: Nat!

One thing that I could have made a bit more clearer is, that inthe bridging script, it doesn't really matter if en0 is thewired or the wireless interface. We are bridging after all.

A photo of Berque

From: Berque

How do I do the reverse?
I mean, I have a static IP and internet over the ethernet, and i cannot share it over wifi using standart internet sharing. It just creates a wifi network with no internet.
Any ideas?
Think about you had a cable-router and connected to the OSX (with an static IP) , and you want to share it over wifi..

A photo of Nat!

From: Nat!

That should be simpler in theory.

Your boxes on the WIFI should recognize your OS X box as the gateway. Your OS X box then needs to be setup as a router/gateway to forward the packages to the cable router with NAT.

But that is just what internet sharing does and it actually should just work IMO.

I would try to figure out the problem with tcpdump and netstat. Obvious fails to look for:

* packets not emitted on the right interface
* clients not receiving the correct default gateway
* packets not NATed (check return address)

Post a comment

All comments are held for moderation; basic HTML formatting accepted.

Name:
E-mail: (not published)
Website: