Set up an auto-start internet sharing service

Oct 14, '02 08:26:04AM

Contributed by: hagbard

After lots of trial and error I've managed to have osx actually BE a network server that starts automagically. Indeed, as many of us have discovered, in order to share one's internet connexion with a LAN, one has to click the "start" internet sharing after each restart. Bummer... but no longer !

This tip may be a bit complicated, and it requires a couple of scripts, but I believe that it's still quite straightforward. Be prepared to part from the InternetSharing prefs pane, though (RIP).

In the following instructions, I'm assuming that you have a dynamic connection to your ISP (ie through DHCP) that uses an Ethernet modem. I believe this hint should work as well with a static IP, but I haven't tested it this way.

[Editor's note: This is a long and fairly complex hint, and I have not tested it myself. Please make sure you have good backups prior to doing anything such as the following on your machine ... it's just common sense!]

STEP ONE:
We're going to create a new IP address for our LAN. This address must exist as early as possible, or named won't be able to bind to it (cf supra). Open the Network prefs pane, and select "Network Port Configurations" from the "Show:" menu. Click New... and call it whatever you want, but select "Built-in Ethernet" (if your primary net access is throught ethernet, or course). Now select your new configuration from the "Show" popup menu. Select configure "Manually". Set the values as follows:

Now click "Apply Now". What we've done is we created an alias on the en0 (built-in Ethernet) interface.

STEP TWO:
Now, let's get NAT working. Here's a script that you have to install inside /Library/StartupItems/ (you must have root privileges, so you can either sudo each command or use 'su'). Go into /Library/StartupItems/ and type:
 % mkdir NAT
% chmod 755 NAT
% chown root:wheel NAT
% cd NAT
And now for the script itself; use your favorite editor (vi, emacs etc) and call it NAT and enter the following text:
 #!/bin/sh

. /etc/rc.common

ConsoleMessage "Starting NAT"

wrongorder=$(/sbin/ifconfig en0 | sed -n '/inet/p' | head -n 1
| sed -n '/192/p' | awk '{print $2}'| wc -l)
# Enter the above as ONE LINE! #

if [ "${wrongorder}" -gt 0 ]; then
ConsoleMessage "swapping DHCP and unregistered alias"
ifconfig en0 -alias 192.168.0.1
ifconfig en0 alias 192.168.0.1
fi

/usr/sbin/natd -f /etc/natd.conf

/sbin/ipfw add 20000 divert natd all from any to any via en0
/sbin/ipfw add 20050 divert natd all from any to any via en1
Save the file, exit your editor and type chmod 4754 NAT.

Let's explain what the script does. The wrongorder part is actually a kludge. What is advertised in the Network prefs pane, is that the order in which you see your network interfaces is the order in which they're supposed to be created. But if your primary interface uses DHCP, it will most of the time be created AFTER your local interface (192.168.0.1). And this is bad, because NAT will bind to the latter and therefore won't work. So what we're simply doing is swapping the order of the aliased IP address. (You can check for this with the command "ifconfig en0").

The two lines at the end ask your firewall to divert packets that go through your interfaces to natd so that masquerading can take place. If you don't want to route traffic from airport, simply remove the line that says:
/sbin/ipfw add 20050 divert natd all from any to any via en1
STEP THREE:
Because of the way startup scripts are loaded by SystemStarter, we need to create a StartupParameters.plist file that informs of the dependencies of this script. While still in the /Library/StartupItems/NAT/ folder, create a file called StartupParameters.plist and enter the following text:
 {
Description = "NAT";
Provides = ("NAT");
Requires = ("Network",
"Resolver");
OrderPreference = "Late";
Messages =
{
start = "Starting NAT";
stop = "Stopping NAT";
};
}
Save and exit, and, just to make sure, do (as root):
 % chown root:admin StartupParameters.plist
% chmod 644 StartupParameters.plist
STEP FOUR:Alright, now let's make sure that everything is fine in the hostconfig file (which carries global values for things like ip forwarding etc). Open /etc/hostconfig as root in a text editor, and make sure that you have the following saying "-YES-":
 IPFORWARDING=-YES-
DNSSERVER=-YES-
The last line is if you want a local DNS/named server)

STEP FIVE:
Now let's edit a couple of config files, namely for natd and for named. Edit as root /etc/named.conf. In the "options" section, you should see a line that looks like:
 // query-source address * port 53;
After it is a line that starts with "listen-on". Make sure that the listen-on line is not commented (doesn't have any // at the beginning), and replace it with the following:
 listen-on { 192.168.0.1; };
Save and exit. What we've just done is we asked named to only reply to internal DNS querries. Unless you want to have a public DNS server (in which case you probably would know how to set it up by yourself ^_^), you'll want to keep your DNS private.

STEP SIX:
Edit as root /etc/natd.conf, and replace the content with the following:
 interface en0
dynamic yes
same_ports yes
log_denied no
use_sockets yes
unregistered_only yes
Save and exit.

STEP SEVEN:
There is no step seven! ;-) Oh yes, restart your Mac, cross your fingers, do a voodoo dance around your desk, etc. Remember, don't start internet sharing from the system's preference panes, since we bypassed everything manually. If you put the line about diverting en1 (AirPort), then your machine should route AirPort as soon as it is turned on (even if you switch it on later on). Piece o' cake, wasn't it ? ^_^

Comments (10)


Mac OS X Hints
http://hints.macworld.com/article.php?story=20021014052604432