What we’re not doing
I found many posts online that covered setting up “Internet Sharing” with a Mac. Some of those referred to this as ‘bridging’ which it is not. At least, in it’s simplest form it is little more than Network Address Translation (NAT) with packets being forwarded from one interface to another. The problem with that approach is that only IP Traffic is passed and even that is adulterated such that clients on one side (the inside) of the link are not directly addressable by hosts on the other side (the outside) of the link.It’s great for letting multiple machines browse the web but not good for having multiple machines talk to each other whether they’re plugged in at the switch or connecting over Wifi and pulling from a common DHCP pool of addresses.
Configure Primary Interface
Primary is conceptual here. I’m taking about the interface that I’ll use to configure the host from over the network. The IP address for this interface will be the (main) address for this host. For me the primary interface is the ethernet port on the back of the Mini. Yours could be any of USB, BlueTooth, USB, FireWire, etc.We want to make sure that the interface is properly setup on the network. For you that may mean DHCP configuration, manually IP-ing it, or something else. I’m not going to spend time telling you how to do this. You’ll know it’s working when you can ping something external to the box (preferably external to the network).
In my case I set a static lease in my DHCP server so that every time the mac address for the Mini shows up it gets the same IP. The interface happens to be en0.
Reboot and make sure it works on start up.
Turn on Internet Sharing
Yes, I know what I said before. We’re using this to make sure that we can actually connect to the WIFI access point and get packets out on the network.
Go to System Preferences -> Sharing
On the left-hand side under Service click on Internet Sharing but make sure you do not click the ‘on’ checkbox next to it.
Share your connection from: should be set to Ethernet (at least for me).
To computers using: should have (only) Wi-Fi selected (the checkbox to the left).
Click on Wi-Fi Options and setup the SSID, password, and channel you plan to use in the end. You can use test values if you want, just remember to set them appropriately before you’re done with the final step.
When you’re sure everything is setup as you desire, click the checkbox next to Internet Sharing to enable it and click OK or Start if prompted by a subsequent dialog box to (re)start Internet Sharing.
Now configure a wireless client to connect to your Mac’s wireless network. Try to ping something to make sure it works.
Reboot and make sure it works on startup.
Bridge the interfaces
Internet Sharing is going to interfere with binding the two interfaces together into a bridge. So the first thing we have to do is open a terminal window and type:
sudo launchctl unload -w\
/System/Library/LaunchDaemons/com.apple.InternetSharing.plist
That disables Internet Sharing. The actual command to create the bridge is remarkably simple. At the command line type in:
sudo ifconfig bridge create
The output of this command depends on what other bridge devices may exist already. If you get something like bridgeX where X is a number then that is your new bridge device and you now only have to add interfaces to it:
sudo ifconfig bridge0 addm en0 addm en1 up
For me en0 is my ethernet port, en1 is the Wi-Fi device, and bridge0 is the name of the device returned by the previous command. Your device names/numbers may be different. Use ifconfig to help figure it out.
Once you’re done with the above you need to re-enable Internet Sharing:
sudo launchctl load -w\
/System/Library/LaunchDaemons/com.apple.InternetSharing.plist
/System/Library/LaunchDaemons/com.apple.InternetSharing.plist
Connect your devices and test to make sure that you can get a proper LAN IP address.
Making it last
You’ll want to run the command line steps every time the system starts. I do this with a cronjob for the root user. I store it in ~root/bin/ (/var/root/bin) and invoke it with the line:
@reboot /var/root/bin/bridge.sh
The script contains:
@reboot /var/root/bin/bridge.sh
The script contains:
#!/bin/sh -x #Name: bridge.sh #Purpose: To create a layer 2 bridge between two interfaces allowing Ethernet # frames to pass between them. PATH=/sbin:/bin if1=${1:="en0"} # If no primary interface is passed assume en0 if2=${2:="en1"} # if no secondary interface is passed assume en1 ifconfig >> /tmp/ifconfig.out echo "#############################################################################" runas_root(){ #Helper funciton to insert "sudo" if succeeding command is invoked a non-root user case ${UID} in 0) echo "" ;; *) echo "sudo " ;; esac } $(runas_root) launchctl unload -w /System/Library/LaunchDaemons/com.apple.InternetSharing.plist bridge_if=$( $(runas_root) ifconfig bridge create) $(runas_root) ifconfig ${bridge_if} addm ${if1} addm ${if2} up $(runas_root) launchctl load -w /System/Library/LaunchDaemons/com.apple.InternetSharing.plist echo "#############################################################################" ifconfig >> /tmp/ifconfig.out
Reboot and make sure it all works on start up
Happy hacking...
Hi there,
ReplyDeletethanks for the writeup. I was able to establish the bridge using the internal wired Ethernet en0 and an external USB-to-Ethernet adapter en4. en0 is the main connection to the network and en4 connects a single other device (Elgato Netstream 4Sat).
The part that is working: The Netstream behind en4 gets a proper DHCP IP through the bridge. I can ping and access the Netstream from other devices in the network (e.g. iPad in the Wifi).
The part that is not working: I cannot ping or access the Netstream behind en4 from the Mac Mini itself that has the bridge configured on it. I assume this is related to the routes on the Mac. Do you have any idea on this?
Thanks,
Torben
Hard to say. If it’s bridged properly your routes shouldn’t matter provided that you have them pulling from addresses on the same subnet. Feel free to email me your configs and the output of ifconfig -a and netstat -nr
DeleteMany, many thanks for your help! I have been looking for this solution for a few years and yours seems to be the only place it exists.
ReplyDeleteI do have a problem, though: I am using a mid-2007 iMac running Mavericks (10.9.4) and have implemented the steps above to create the bridge (but not the startup script.) My iPhone gets the same address as my iPad (10.0.1.2) using DHCP. I have set the en0 to static 10.0.1.6) and the Network Pref panel shows en1 with an IP of 169.254.186.16 - self-assigned. I can not see my iMac from my iPhone but can see my Apple TV (both via an airport attached to my cable modem and on the 10.0.1.x net.) I'm not a net expert by any means so I am stumped. Any help would be appreciated. I don't have your email address or I would attach the outputs mentioned above.
Also, where would I put the start-up script?
Many thanks
Tried this repeatedly and can't get it to work. The only thing I get up and running is regular Internet Sharing (i.e. a network that can't be reached from the outside unless you setup routing to that network). Seems from the other commenters they have similar problems. I am yet to find a solution to setting up a bridge on a Mac between two networks.
ReplyDeleteTo follow up on my original comment further up. I got it to work with these three commands. The Internet Sharing is disabled all the time:
Deletesudo ifconfig bridge create
sudo ifconfig bridge0 addm en0 addm en3 up
sudo ipconfig set bridge0 DHCP
Hope this helps,
Torben
Cant get it working, the bridge interface appears with the 2 physical interfaces allocated.. but there is no connectivity inbetween (on DHCP or IP)
ReplyDelete0: flags=8963 mtu 1500
options=27
ether 00:25:4b:b4:1c:5e
nd6 options=1
media: autoselect (1000baseT )
status: active
en1: flags=8963 mtu 1500
ether 00:25:00:f6:a3:12
inet6 fe80::225:ff:fef6:a312%en1 prefixlen 64 scopeid 0x5
inet 192.168.1.79 netmask 0xffffff00 broadcast 192.168.1.255
nd6 options=1
media: autoselect
status: active
fw0: flags=8863 mtu 4078
lladdr 00:25:4b:ff:fe:b4:1c:5e
nd6 options=1
media: autoselect
status: inactive
bridge0: flags=8863 mtu 1500
options=3
ether 02:25:4b:4b:9f:00
Configuration:
id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
ipfilter disabled flags 0x2
member: en1 flags=3
ifmaxaddr 0 port 5 priority 0 path cost 0
member: en0 flags=3
ifmaxaddr 0 port 4 priority 0 path cost 0
media: autoselect
status: active
Any help would be greatly appreciated!!!
Apparently Apple within OS X 10.10.x somewhere change the code for wi-fi so that this no longer works. Is there any possibility that you could update this so it would work in that environment?
ReplyDeleteMany thanks-
Thanks for the post! I looked for some more background on having a Raspberry Pi connecting trough my Macbook to the internet. In fact, I was just looking for "internet sharing" which I did not know. But the idea of creating a bridge from the command line sounds interesting. I saw some new entry in the output of "ifconfig" after I enabled internet sharing. It would be interesting to drill down even more to the concepts one day (e.g. questions: Why do I see 2 subnets 192.168.2.X and 192.168.3.X? How are routes added? What output to see when pinging the broadcast address ?)
ReplyDelete