Creating a Bridged Network Connection in Terminal

Networkterminal

Okay, I'm struggling a bit here. I'm not all that good with Terminal and sorting out network issues using it but I've managed to scrape by so far.

Without using Internet Sharing (because controlling that via Terminal as per my question here doesn't actually seem to work in Yosemite) how can I share my internet connection from one interface (lets say en0) to another (again, lets say en1)?

I kind of understand that Internet Sharing creates a bridge (usually called bridge100) and then uses bootpd (I think) to establish a DHCP server and NAT to route all traffic from 192.168.2.xxx (which is the bridged network) through to your primary network.

How can I get the same result without using the Sharing pref pane?

Best Answer

Here is an interesting solution to share internet with a layer-2 bridge but without using NAT/DHCP (not required)/Internet Sharing Pref Panel at all:

Create a shell script ethernet-bridge.sh in /usr/local/sbin with the following content:

#! /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 "Ethernet Bridge is up"
        else
                syslog -s "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 "Ethernet Bridge is down"
}



case "$command" in
        start*) start
                ;;

        stop*)  stop
                ;;
esac

and make it executable:

chmod 755 /usr/local/sbin/ethernet-bridge.sh

Then put the following XML into /Library/LaunchDaemons as com.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.ethernet-bridge.plist</string>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/local/sbin/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>

Then modify the file and load it:

sudo chmod 644 /Library/LaunchDaemons/com.ethernet-bridge.plist
sudo chown root:wheel /Library/LaunchDaemons/com.ethernet-bridge.plist
sudo launchctl load /Library/LaunchDaemons/com.ethernet-bridge.plist

The plist will enable the bridge mode while booting.

Check with ifconfig -a if the bridge is visible.

To stop the bridge mode just enter:

sudo /usr/local/sbin/ethernet-bridge.sh stop

To restart the bridge mode just enter:

sudo /usr/local/sbin/ethernet-bridge.sh start

Now set up the clients with a fixed IP/netmask/Gateway (the internal IP-address of the briding machine)/DNS or properly set up a DHCP server on the bridging machine.

Additionally you have to set up a static route on your router to the network you provide Internet Sharing to (in your example (en1)).

Until now the syslog messages don't work - I'll try to improve the script pertinently.


A similar approach is outlined here, but I didn't get it to work in Yosemite