A Cheat Sheet For Using pf in OS X Lion and Up

I’ve done plenty of writing on the Application Layer Firewall (ALF) and the IP FireWall (IPFW) in OS X over the years. There will be more on ALF coming in “July” but in the meantime, there’s something I hadn’t written much about in Lion and that’s the pf implementation. To get started, let’s look at the /etc/pf.conf configuration file that comprises pf: scrub-anchor "com.apple/*" nat-anchor "com.apple/*" rdr-anchor "com.apple/*" dummynet-anchor "com.apple/*" anchor "com.apple/*" load anchor "com.apple" from "/etc/pf.anchors/com.apple" Here, you can see that pf is configured with a number of anchors. An anchor is a collection of rules and tables. Basically, the anchor file being loaded is /etc/pf.anchors/com.apple. In here, we see some rules (without comments): scrub-anchor "100.InternetSharing/*" scrub-anchor "300.NetworkLinkConditioner/*" nat-anchor "100.InternetSharing/*" rdr-anchor "100.InternetSharing/*" anchor "100.InternetSharing/*" anchor "200.AirDrop/*" anchor "250.ApplicationFirewall/*" dummynet-anchor "300.NetworkLinkConditioner/*" anchor "300.NetworkLinkConditioner/*" anchor "400.AdaptiveFirewall/*" load anchor "400.AdaptiveFirewall/" from "/Applications/Server.app/Contents/ServerRoot/private/etc/pf.anchors/400.AdaptiveFirewall" These are mostly just allowing the Apple services to work with services enabled in the Sharing system preference pane, etc. The scrub options are pretty cool as it cleans dirty packets prior to passing them to their destination. To see how the rules are interpreted, let’s run pfctl with the -sa option, which shows all information/stats: sudo pfctl -sa Here we see information like stats on timeouts, limits to rules, etc. Let’s look at the rules specifically: sudo pfctl -sr Now let’s load a line below the previously called anchors in the first file: pass in quick on lo0 all pass out quick on lo0 all This is going to always allow local traffic, which we need for a few internal processes. Then let’s block some stuff (after all, if we’re not filtering, why use a packet filter). First add the following to the pf.conf file to block all otherwise allowed incoming sockets: block in all And this one for outbound traffic: block out all Or to knock the two above lines out with one: block all Then to do something pretty straight forward, like allow incoming icmp traffic for en0: pass in quick on en0 proto icmp One more rule, to show how we’re going to pass and log data for data coming into en0 for both tcp and udp from anyone to the IP on that interface running for port 548: pass in log quick on en0 proto { tcp, udp } from any to port 548 keep state Of the above, tables allow you to define ranges and basically alias IPs. Anything in this section of pf.conf in angled (<>) brackets is a table that has been defined. You can also build a list, which allows multiple criteria to be defined for a given rule and macros, which are essentially arrays of IPs, ports, etc, designed to reduce the amount of typing you have to do if you’re building out a big configuration file. Once we’ve edited our configuration file, let’s run a quick sanity check on it: sudo pfctl -v -n -f /etc/pf.conf Now, provided we don’t get any crazy errors, let’s load pf with our rules (which also loads the anchors): sudo pfctl -f /etc/pf.conf Then let’s set pf to be verbose while we’re testing (we’ll turn it off later): sudo pfctl -v Then let’s enable pf: sudo pfctl -e The return code should be something along the lines of the following: pf enabled You can also add information on the fly. For example, to add a table of call localsub: sudo pfctl -t localsub -T add If you want to flush your rules later: sudo pfctl -Fa -f /etc/pf.conf To clear your stats: sudo pfctl -z ; pfctl -si Once we feel good about the pf configuration, set it to be quiet to keep the logs small and make it a little quicker: sudo pfctl -q And to disable pfctl when you’re done tinkeratin’: sudo pfctl -d And to watch what it’s doing: ifconfig pflog0 Followed by sudo tcpdump -v -n -e -ttt -i pflog0 Overall, pfctl is pretty straight forward to use. There is a really good post (thanks to @sacrilicious for pointing it out) at http://ikawnoclast.com/2012/04/using-the-lion-pf-firewall-with-the-emerging-threats-list.html for syncing the Emerging Threats anchor from emergingthreats.net. And of course, OpenBSDs pf page is the best source of information on the project, available here. There are a few limitations. The pf command is limited to one processor, so running a dedicated pf host on an 8 core machine is pretty much overkill. RAM is important as pf doesn’t use swap space. The more you pay for a card, the better a card you get, for the most part. Check out the Small Tree cards as they’re pretty efficient… A few things I haven’t gotten working, the logging is kinda’ wonky. The antispoof protection seems odd (see the antispoof docs on the pf page), osfp (which might be other devices in my walled garden) and dummynet integration (which I have working w/ ipfw)… If I can get them working I’ll put together another post for that in my infinite amounts of free time. I also didn’t end up figuring out the upper limit for packets/rule lookups/table lookups per second… As I write more efficient tables I do more lookups and can therefore process packets faster. It’s annoying when I realize ***I*** am the bottleneck…

Man Pages Made Easy

Ever since upgrading to Lion I’ve been making a few slight changes in workflow. One such change, which I’m still on the fence about, is to switch from reading man pages in a tiled Terminal screen, to reading them in a browser window. It seems like a small thing, but I spend a lot of time switching between terminal screens or using screen to switch between sessions. Bwana allows you to read a man page from within a browser. Simply load download the Bwana app into your /Applications directory and wait a few seconds. Then open a browser window and look for a man page. For example:
Now, you may notice that you can’t actually click on the link above and have the link open as it would if you typed the information into the browser manually. You could also use man://dsconfigad to access a man page, but you still cannot refer to those from other sites. You can open those urls using terminal: open man://dsconfigad To see an index of all pages, enter the following in Safari:
To reindex:

RAMdisk on MacBook Air

I can’t remember where I picked up how to get a RAM Disk mounted in OS X, but it’s a great way to get some unbelievable speeds on your Mac for those minor IO intensive processes that don’t need persistent data. It should be mentioned that the contents of RAM disks are erased, once ejected, but the speed of processes while they’re running can be pretty phenomenal on systems with fast RAM. The best example is a MacBook Air, where the memory is surface-mounted QFP and so really fast. Let’s say you have 4GB of memory and you want to run a process that isn’t going to take more than a gig of memory. You have 3GB of memory you can then use as a RAM Disk. To mount up the RAM disk, I usually create a .command file with the following contents: diskutil erasevolume HFS+ "rdisk" `hdiutil attach -nomount ram://6144000` I usually call that file mountrdisk.command Then I create another .command file called unmountrdisk.command with the following: hdiutil detach /dev/disk1 These allow me to mount and unmount the RAM disk, quickly. I then add a line at the top of the second command file to backup the contents to a folder on my local computer, since anything in there doesn’t get saved once detached: cp -R /Volumes/rdisk ~/rdiskbackup Running the first .command file will create the rdisk with the following output: Started erase on disk1 Unmounting disk Erasing Initialized /dev/rdisk1 as a 3 GB HFS Plus volume Mounting disk Finished erase on disk1 rdisk You can then cd into it and treat it as you would any other volume. Once you’re done, run the backup command file and then the unmount command file to back it up and trash it. Speed tests show anywhere from 325 MB/s to well over a thousand according to what you are doing. The performance can degrade quickly in some cases, but when used properly it’s a great little tool.

Hosting afp on Linux

One of the main reasons people get a server is to share files. Mac OS X Server is one of the more common devices used to share files to Mac OS X clients, using afp, the default file sharing protocol for Mac OS X. But you don’t have to use Mac OS X Server. You can use Linux as well. We’re going to look at using an open source project called netatalk to do so. If you find that after reading this that you’d like to find out more about netatalk then check out the open source project page at http://netatalk.sourceforge.net. The netatalk installer can be installed through most of the package installers for Linux. However, due to licensing issues with many versions of Linux, some of what you need might not come with the source, namely that Mac OS X 10.5 and above will not be able to authenticate to the netatalk daemon due to the lack of uams so files for dhx. Therefore, we’re going to look at building netatalk from source using apt-get in Ubuntu or Debian (for Redhat, use yum). To get started let’s get our dependencies (everything in this article needs to be run with elevated privileges):
apt-get install dpkg-dev devscripts libssl-dev fakeroot cracklib2-dev
Now let’s grab the netatalk source:
apt-get source netatalk
Now let’s get any other dependencies we might not have noticed already:
apt-get build-dep netatalk
Now cd into the netatalk directory (current version is 2.0.3):
cd netatalk-2.0.3
Now let’s tell it to build with SSL enabled:
And to finally run the built package:
dpkg -i ../netatalk_*.deb
Next, let’s choose which authentication mechanisms we want to support. I practically always enable the pam modules so that netatalk can pass authentication back through my directory service and it’s very important that for Mac OS X 10.5 and above support that you make sure to go ahead and enable dhx as well. For most environments I’ll also disable cleartext passwords at this time. This is all done in the /etc/netatalk/afpd.conf file. At the bottom, by default you will see a list of authentication modules. Add the following line, adding any additional uams modules you’d like to support and removing any you would not like to support:
– -transall -uamlist uams_guest.so,uams_dhx_pam.so,uams_dhx_passwd.so,uams_dhx.so
We can also go ahead and restrict users from being able to save their password using the -nosavepassword option, meaning the line would instead appear as follows:
– -transall -uamlist uams_guest.so,uams_dhx_pam.so,uams_dhx_passwd.so,uams_dhx.so -nosavepassword
Note: The afpd.conf man page and the project documentation will lay out more about what each of these does. Once you have updated afpd.conf you will want to edit the /etc/netatalk/AppleVolumes.default file, which is where you create your shares. At the bottom of this file you’ll want to add a line that adds each new share (home directories are automatically shared by default). Here, you’ll specify the path to the share, followed by how you want the share to appear in the connect to server dialog, followed by an allow statement of who is able to access the share and then the options for the share (options are indicated in the man page and have commented descriptions in the actual file):
/SHARED/Accounting “Accounting” allow:accounting,root options:crlf,noadouble,mswindows,nodots,usehex dbpath:/tmp
The above file is also where you would make changes to the method used to store authentication database used (ie – using CNID In order to have different daemons or more likely to kill off the AppleTalk daemon) you’ll need to customize the /etc/default/netatalk file. Here, you can choose whether AppleTalk will run (ATALKD_RUN, whether to use bdb (CNID_METAD_RUN) and whether or not AFP will run (AFPD_RUN). You can also choose a maximum number of users to hit the server (AFPD_MAX_CLIENTS) and set AppleTalk names and zones if you’re running AppleTalk (ATALK_NAME and ATALK_ZONE respectively). And by default, AFP guests (AFPD_GUEST) are mapped to nobody (for permissions)… Once you’ve made your changes, save and then let’s restart the daemon and test connectivity:
/etc/init.d/netatalk restart
While testing, I usually like to run a tail of syslog to see if any errors pop up:
tail -f /var/log/syslog
When new versions come out, you will then be able to perform an update using apt-get as well:
apt-get update && apt-get install netatalk
If you find that through this you installed some things that you’d like to get rid of or that you’d like to start over, you can get rid of netatalk using the apt-get autoremove option:
apt-get autoremove netatalk
And if you don’t want the dependencies either, check out deborphan to clean those up as well!

AFP and Cleartext Passwords

AFP can be persnickety about you doing something as painfully silly as authenticating into a host using a password sent in cleartext (completely unencrypted). But when you’re troubleshooting it can be useful to disable this behavior, if only to test and then re-enable again. To do so:
defaults write com.Apple.AppleShareClient afp_cleartext_allow -bool YES
And to disable the warning:
defaults write com.Apple.AppleShareClient afp_cleartext_warn -bool NO

Peachpit Books

Now that all of the Peachpit books are available for 10.6 Certification purposes I thought it might be a good time to post a link to all of them. Here goes: Or for ACMA (the Final Cut below could be swapped out with Support Essentials, Directory Services or Deployment):

Adding DHCP Options in Mac OS X Server

Mac OS X Server comes with a number of DHCP options available; most notably the options available in the GUI. But what about options that aren’t available in the GUI, such as NTP. Well, using /etc/bootpd.plist, the same file we used to define servers allowed to relay, you can also define other options. These begin with the following keys that can be added into your property list:
  • dhcp_time_offset (option 2)
  • dhcp_router (option 3)
  • dhcp_domain_name_server (option 6)
  • dhcp_domain_name (option 15)
  • dhcp_network_time_protocol_servers (option 42)
  • dhcp_nb_over_tcpip_name_server (option 44)
  • dhcp_nb__over_tcpip_dgram_dist_server (option 45)
  • dhcp_nb_over_tcpip_node_type (option 46)
  • dhcp_nb_over_tcpip_scope (option 47)
  • dhcp_smtp_server (option 69)
  • dhcp_pop3_server (option 70)
  • dhcp_nntp_server (option 71)
  • dhcp_ldap_url (option 95)
  • dhcp_netinfo_server_address (option 112)
  • dhcp_netinfo_server_tag (option 113)
  • dhcp_url (option 114)
  • dhcp_domain_search (option 119)
  • dhcp_proxy_auto_discovery_url (option 252)
But you can also add options by their numerical identifier. To add them, add the following into your /etc/bootpd.plist file and then restart the DHCP service: <string>dhcp_option_120</string> <data> </data>
In the above, you’d replace the option 120 (SIP) with the option you wish to use. Numbers correspond to options as follows:
0 – Pad
1 – Subnet Mask
3 – Router
4 – Time Server
5 – Name Server
6 – Domain Name Server
7 – Log Server
8 Quote Server
9 – LPR Server
10 – Impress Server
11 – Resource Location Server
12 – Host Name
13 – Boot File Size
14 – Merit Dump File
15 – Domain Name
16 – Swap Server
17 – Root Path
18 – Extensions Path
19 – IP Forwarding
20 – WAN Source Routing
21 – Policy Filter
22 – Maximum Datagram Reassembly Size
23 – Default IP Time-to-live
24 – Path MTU Aging Timeout
25 – Path MTU Plateau Table
26 – Interface MTU
27 – All Subnets are Local
28 – Broadcast Address
29 – Perform Mask Discovery
30 – Mask supplier
31 – Perform router discovery
32 – Router solicitation address
33 – Static routing table
34 – Trailer encapsulation.
35 – ARP cache timeout
36 – Ethernet encapsulation
37 – Default TCP TTL
38 – TCP keep alive interval
39 – TCP keep alive garbage
40 – Network Information Service Domain
41 – Network Information Servers
42 – NTP servers
43 – Vendor specific information
44 – NetBIOS over TCP/IP name server
45 – NetBIOS over TCP/IP Datagram Distribution Server
46 – NetBIOS over TCP/IP Node Type
47 – NetBIOS over TCP/IP Scope
48 – X Window System Font Server
49 – X Window System Display Manager
50 – Requested IP Address
51 – IP address lease time
52 – Option overload
53 – DHCP message type
54 – Server identifier
55 – Parameter request list
56 – Message
57 – Maximum DHCP message size
58 – Renew time value
59 – Rebinding time value
60 – Class-identifier
61 – Client-identifier
62 – NetWare over IP Domain Name
63 – NetWare over IP information
64 – Network Information Service Domain
65 – Network Information Service Servers
66 – TFTP server name
67 – Bootfile name
68 – Mobile IP Home Agent
69 – Simple Mail Transport Protocol Server
70 – Post Office Protocol Server
71 – Network News Transport Protocol Server
72 – Default World Wide Web Server
73 – Default Finger Server
74 – Default Internet Relay Chat Server
77 – User Class Information
78 – SLP Directory Agent
79 – SLP Service Scope
80 – Rapid Commit
81 – Fully Qualified Domain Name
82 – Relay Agent Information
83 – Internet Storage Name Service
85 – NDS servers
86 – NDS tree name
87 – NDS context
88 – BCMCS Controller Domain Name list
89 – BCMCS Controller IPv4 address list
90 – Authentication
91 – Client Last Transaction Time
92 – Associated IP
93 – Client System Architecture Type
94 – Client Network Interface Identifier
95 – LDAP, Lightweight Directory Access Protocol
97 – Client Machine Identifier
98 – Open Group User Authentication
100 – IEEE 1003.1 TZ String
101 – Reference to the TZ Database
112 – NetInfo Parent Server Address
113 – NetInfo Parent Server Tag
114- URL
116 – Auto-Configure
117 – Name Service Search
118 – Subnet Selection
119 – DNS domain search list
120 – SIP Servers DHCP Option
121 – Classless Static Route Option
123 – GeoConfiguration
124 – Vendor-Identifying Vendor Class
125 – Vendor-Identifying Vendor Specific
128 – TFPT Server IP address
129 – Call Server IP address
130 – Discrimination string
131 – Remote statistics server IP address
132 – 802.1P VLAN ID
133 – 802.1Q L2 Priority
134 – Diffserv Code Point
135 – HTTP Proxy for phone-specific applications
136 – PANA Authentication Agent
139 – IPv4 MoS
140 – IPv4 Fully Qualified Domain Name MoS
150 – TFTP server address
176 – IP Telephone
220 – Subnet Allocation
221 – Virtual Subnet Selection
252 – Proxy auto-discovery
254 – Private use
255 – End

Snow Leopard & Malware

An article on ZDNet that states that Snow Leopard has anti-malware built into it (thanks Dee-Ann): http://blogs.zdnet.com/security/?p=4104&tag=nl.e589 Side note: I wonder whether or not they read the EULA for their pre-released software? I realize that release date is really just a few days from now, but come on guys… Just wait a couple of days to post these things…

Foundations of Mac Snow Leopard Security

I’ve been asked by a number of people whether or not we will be updating the Mac OS X security book I did a couple of years ago for Apress to Snow Leopard.  The answer is yes.  We are currently working on the updates and hope to have it available by December.  The book will undergo a number of changes/improvements, as all second editions should.  I’ll update when it’s available on Amazon & of course, in stores.