How to stop InternetSharing 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 >bootpd <<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 >bootpd.plist.src <<eof
<?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>allow</key>
<array>
<string>00:00:00:00:00:00</string>
<string>...
</array>
<key>deny</key>
<array>
<string>...
</array>
<key>Subnets</key>
<array>
<dict>
<key>_creator</key>
<string>dan</string>
<key>allocate</key>
<true/>
<key>dhcp_router</key>
<string>10.0.2.1</string>
<key>lease_max</key>
<integer>86400</integer>
<key>lease_min</key>
<integer>86400</integer>
<key>name</key>
<string>10.0.2/24</string>
<key>net_address</key>
<string>10.0.2.0</string>
<key>net_mask</key>
<string>255.255.255.0</string>
<key>net_range</key>
<array>
<string>10.0.2.2</string>
<string>10.0.2.31</string>
</array>
</dict>
</array>
<key>bootp_enabled</key>
<false/>
<key>detect_other_dhcp_server</key>
<true/>
<key>dhcp_enabled</key>
<array>
<string>en1</string>
</array>
<key>use_server_config_for_dhcp_options</key>
<false/>
</dict>
</plist>
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 "$@"
I tried the script replacement trick above and found it very useful! Many thanks!
At my configuration the only additional requirement was to change the bootpd.plist from:
<key>use_server_config_for_dhcp_options</key>
<false/>
to:
<key>use_server_config_for_dhcp_options</key>
<true/>
what instantly opens DNS support to my DHCP clients.
I guess one should remark that any later change of the Internet Sharing configuration will require additional change of the "/etc/bootpd.plist.src" by copying from the current "/etc/bootpd.plist".
In any way the for longer existing conflict between Internet Sharing and Server.app related to DHCP service shall be urgently solved at later Mountain Lion Server versions!