How to stop InternetSharing overwriting /etc/bootpd.plist I set up a /etc/bootpd.plist so as to protect my wireless network,
and to manage statically attributed IP addresses.

Unfortunatly, when I start InternetSharing, this file is overwritten
by a plist which I didn't find the source of.



How may I avoid InternetSharing overwriting this file?

Where is the source of this file overwriting /etc/bootpd.plist?
Source of the problem

By studying the processes spawned by InternetSharing (with the help of opensnoop and debugging shell scripts) I finally build a
way to circumvent this systematic and stupid overwriting of /etc/bootpd.plist.

InternetSharing creates a minimal /etc/bootpd.plist and then
spawns 2 processes:

/usr/libexec/bootpd
/usr/libexec/natpmpd


Solution

I replaced the original bootpd by a simple shell script in charge of
putting my source of /etc/bootpd.plist in place before firing the
original bootpd code. Of course most of these commands have to be
ran as root.

/usr/bin/sudo -s    
cd /usr/libexec

# make a backup copy of the original binary bootpd
mv bootpd bootpd.orig

# create the shell script which will first install the wanted
# bootpd.plist and then fire the original bootpd with the
# correctly quoted original list of arguments "$@"
cat &gt;bootpd &lt;&lt;eof
#!/bin/sh
cp /etc/bootpd.plist.src /etc/bootpd.plist
exec /usr/libexec/bootpd.orig "$@"
eof

# make this shell script executable
chmod 755 bootpd

cd /etc

# create the "source" bootpd.plist.src which will be copied every
# time by the above shell script and will cancel the copy made by
# "InternetSharing"
cat &gt;bootpd.plist.src &lt;&lt;eof
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
    &lt;key&gt;allow&lt;/key&gt;
    &lt;array&gt;
            &lt;string&gt;00:00:00:00:00:00&lt;/string&gt;
            &lt;string&gt;...
    &lt;/array&gt;
    &lt;key&gt;deny&lt;/key&gt;
    &lt;array&gt;
            &lt;string&gt;...
    &lt;/array&gt;
    &lt;key&gt;Subnets&lt;/key&gt;
    &lt;array&gt;
            &lt;dict&gt;
                    &lt;key&gt;_creator&lt;/key&gt;
                    &lt;string&gt;dan&lt;/string&gt;
                    &lt;key&gt;allocate&lt;/key&gt;
                    &lt;true/&gt;
                    &lt;key&gt;dhcp_router&lt;/key&gt;
                    &lt;string&gt;10.0.2.1&lt;/string&gt;
                    &lt;key&gt;lease_max&lt;/key&gt;
                    &lt;integer&gt;86400&lt;/integer&gt;
                    &lt;key&gt;lease_min&lt;/key&gt;
                    &lt;integer&gt;86400&lt;/integer&gt;
                    &lt;key&gt;name&lt;/key&gt;
                    &lt;string&gt;10.0.2/24&lt;/string&gt;
                    &lt;key&gt;net_address&lt;/key&gt;
                    &lt;string&gt;10.0.2.0&lt;/string&gt;
                    &lt;key&gt;net_mask&lt;/key&gt;
                    &lt;string&gt;255.255.255.0&lt;/string&gt;
                    &lt;key&gt;net_range&lt;/key&gt;
                    &lt;array&gt;
                            &lt;string&gt;10.0.2.2&lt;/string&gt;
                            &lt;string&gt;10.0.2.31&lt;/string&gt;
                    &lt;/array&gt;
            &lt;/dict&gt;
    &lt;/array&gt;
    &lt;key&gt;bootp_enabled&lt;/key&gt;
    &lt;false/&gt;
    &lt;key&gt;detect_other_dhcp_server&lt;/key&gt;
    &lt;true/&gt;
    &lt;key&gt;dhcp_enabled&lt;/key&gt;
    &lt;array&gt;
            &lt;string&gt;en1&lt;/string&gt;
    &lt;/array&gt;
    &lt;key&gt;use_server_config_for_dhcp_options&lt;/key&gt;
    &lt;false/&gt;
&lt;/dict&gt;
&lt;/plist&gt;
eof


The 2 arrays allow and deny let me define exactly which MAC
addresses I will accept within my shared network and which one I
will banish.

This protection is far from bullet proof, but is better than the
total lack of protection provided by InternetSharing on a WEP Fi-fi
network :).



Compatibility with OS upgrades

To avoid any trouble with any OS upgrade which might fix /usr/libexec/bootpd, here is the shell script I run before any OS upgrade:

/usr/bin/sudo -s    
cd /usr/libexec

# reset into place the backup copy of the original binary bootpd
mv bootpd.orig bootpd

# go back to a safe working uid
exit


Compatibility with OS versions

This shell script is working on:


Lion
Mountain Lion
Mavericks
Yosemite


Attack survey

With the option -v passed to bootpd, I have a logging of MAC addresses
which attempted to request an IP address but were rejected.

To pass this option -v to bootpd I inserted it in my bootpd wrapper:

#!/bin/sh
cp /etc/bootpd.plist.src /etc/bootpd.plist
exec /usr/libexec/bootpd.orig -v "$@"