Internet Sharing in macOS is (internally) done by creating a bridge device containing two or more interfaces, activating a DHCP server, setting up various pf rules and enabling pf.
To print all rules the following shell script has to be executed:
pfdump.sh:
#!/bin/bash
function pfprint() {
if [ -n "$1" ];then
sudo pfctl -a "$2" -s"$1" 2>/dev/null
else
sudo pfctl -s"$1" 2>/dev/null
fi
}
function print_all() {
local p=$(printf "%-40s" $1)
(
pfprint r "$1" | sed "s,^,r ,"
pfprint n "$1" | sed "s,^,n ,"
pfprint A "$1" | sed "s,^,A ,"
) | sed "s,^,$p,"
for a in `pfprint A "$1"`; do
print_all "$a"
done
}
print_all
By default pf is disabled with the following pf dump:
r scrub-anchor "com.apple/*" all fragment reassemble
r anchor "com.apple/*" all
n nat-anchor "com.apple/*" all
n rdr-anchor "com.apple/*" all
A com.apple
com.apple r anchor "200.AirDrop/*" all
com.apple r anchor "250.ApplicationFirewall/*" all
com.apple A com.apple/200.AirDrop
com.apple A com.apple/250.ApplicationFirewall
After activating Internet Sharing pf is enabled and a dump looks like this:
r scrub-anchor "com.apple/*" all fragment reassemble
r scrub-anchor "com.apple.internet-sharing" all fragment reassemble
r anchor "com.apple/*" all
r anchor "com.apple.internet-sharing" all
n nat-anchor "com.apple/*" all
n nat-anchor "com.apple.internet-sharing" all
n rdr-anchor "com.apple/*" all
n rdr-anchor "com.apple.internet-sharing" all
A com.apple
A com.apple.internet-sharing
com.apple r anchor "200.AirDrop/*" all
com.apple r anchor "250.ApplicationFirewall/*" all
com.apple A com.apple/200.AirDrop
com.apple A com.apple/250.ApplicationFirewall
com.apple.internet-sharing r scrub-anchor "base_v4" all fragment reassemble
com.apple.internet-sharing r anchor "base_v4" all
com.apple.internet-sharing n nat-anchor "base_v4" all
com.apple.internet-sharing n rdr-anchor "base_v4" all
com.apple.internet-sharing A com.apple.internet-sharing/base_v4
com.apple.internet-sharing/base_v4 r scrub on en1 all no-df fragment reassemble
com.apple.internet-sharing/base_v4 r scrub on bridge100 all no-df max-mss 1460 fragment reassemble
com.apple.internet-sharing/base_v4 r scrub on bridge100 proto esp all no-df fragment reassemble
com.apple.internet-sharing/base_v4 r pass on en1 all flags any keep state
com.apple.internet-sharing/base_v4 r pass on en1 proto esp all no state
com.apple.internet-sharing/base_v4 r pass on bridge100 all flags any keep state rtable 6
com.apple.internet-sharing/base_v4 n nat on en1 inet from 192.168.2.0/24 to any -> (en1:0) extfilter ei
com.apple.internet-sharing/base_v4 n no nat on bridge100 inet from 192.168.2.1 to 192.168.2.0/24
com.apple.internet-sharing/base_v4 n rdr on bridge100 inet proto tcp from 192.168.2.0/24 to any port = 21 -> 127.0.0.1 port 8021
Here en1 is the external interface (the one sharing to your internal network) and 192.168.2.0/24 the internal network provided by the DHCP server. Both could differ in your environment.
To expose an internal server to the public with Internet Sharing enabled, you have to forward a port of the external interface to the IP and the service port of the server:
Create rdr rule on the router (your Mac Pro) by entering in Terminal.app:
sudo nano /private/etc/pf-rdr.rule
and the content:
rdr on en1 inet proto tcp from any to 152.1.2.3 port = 9999 -> 192.168.2.3 port 80
assuming en1 is the external interface, 152.1.2.3:9999 its IP:port and 192.168.2.3:80 the IP:port of the internal server. To get the device identifier (and IP) of your external interface enter ifconfig
on your Mac Pro.
Then create a launch daemon:
sudo nano /Library/LaunchDaemons/org.user.pfrdr.plist
with the content:
<?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>Disabled</key>
<false/>
<key>Label</key>
<string>org.user.pfrdr</string>
<key>ProgramArguments</key>
<array>
<string>/sbin/pfctl</string>
<string>-a</string>
<string>com.apple/portforwarding</string>
<string>-f</string>
<string>/private/etc/pf-rdr.rule</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/Library/Logs/org.usr.pfrdr.log</string>
<key>StandardOutPath</key>
<string>/Library/Logs/org.usr.pfrdr.log</string>
</dict>
</plist>
Launch the daemon with:
sudo launchctl load /Library/LaunchDaemons/org.user.pfrdr.plist
This will add a second rdr rule in the com.apple anchor to pf and forward the external port to the internal host.
Since DHCP assigns IP addresses dynamically it's also useful to define a fixed IP for the internal server:
Create a file bootptab on the router (your Mac Pro):
sudo nano /etc/bootptab
with the content:
# Bootptab file
# Section 1 -- ignored
%%
# Section 2 -- used
# Hardware types: 1=Ethernet, 6=Wireless
# See http://www.ietf.org/rfc/rfc1700.txt
#
# machine entries have the following format:
#
# hostname hwtype hwaddr ipaddr bootfile
your-nas-ethernet 1 c4:2c:03:3a:7f:65 192.168.2.3 boot
a-wireless-machine 6 60:33:4b:27:6c:62 192.168.2.4 boot
another-ethernet 1 00:0d:93:72:e7:96 192.168.2.2 boot
Replace the MAC addresses (hwaddr) and the hardware types (hwtype) by the proper ones found in your environment here. You can get the MAC addresses by entering ifconfig
on the respective host. Reboot your router (Mac Pro) afterwards.
Security implications:
By using your Mac Pro as a router it is exposed to the Internet and vulnerable as such. Pf as it runs after enabling Internet Sharing has absolutely no blocking rule. You have to add a whole bunch of additional rules to make it more secure (and working).
The IP you have published belongs to 152.1.0.0/16 - an IP block assigned to the North Carolina State University (NCSU). Your university may have applied security measures in this network which will prevent access from other networks (or the "whole" Internet).