Disable all network traffic on a Mac VM

I needed to create a sandbox for a new user to look at some code. There are many API calls and hooks to the outside world I needed to protect from this person so created a VM and blocked all network traffic. I accomplished this using the packet filter ( PF ) built into macOS. I ran all commands in terminal as root to make life easier. It’s a VM so, YOLO.

su
Password: password
nano /etc/pf.conf

Add block all to the end of the config file for pf.

#
# Default PF configuration file.
#
# This file contains the main ruleset, which gets automatically loaded
# at startup.  PF will not be automatically enabled, however.  Instead,
# each component which utilizes PF is responsible for enabling and disabling
# PF via -E and -X as documented in pfctl(8).  That will ensure that PF
# is disabled only when the last enable reference is released.
#
# Care must be taken to ensure that the main ruleset does not get flushed,
# as the nested anchors rely on the anchor point defined here. In addition,
# to the anchors loaded by this file, some system services would dynamically
# insert anchors into the main ruleset. These anchors will be added only when
# the system service is used and would removed on termination of the service.
#
# See pf.conf(5) for syntax.
#
#
# com.apple anchor point
#
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"

block all

You need to disable System Integrity Protection to set up pf to enable at boot. This can only be done from recovery mode.

Set the nvram to boot to recovery mode.

sudo nvram "recovery-boot-mode=unused"

reboot to recovery

sudo reboot recovery

Using terminal in recovery mode

csrutil disable
reboot

Your system should now be booted as normal and you can check if System Integrity Protection is disabled

csrutil status

You should expect it to say: System Integrity Protection status: disabled.

Now edit the plist to look like below. Specifically adding the <string>-e</string> which enables it on boot.

sudo nano /System/Library/LaunchDaemons/com.apple.pfctl.plist
&lt;?xml version="1.0" encoding="UTF-8"?>
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
&lt;plist version="1.0">
&lt;dict>
        &lt;key>Disabled&lt;/key>
        &lt;false/>
        &lt;key>Label&lt;/key>
        &lt;string>com.apple.pfctl&lt;/string>
        &lt;key>WorkingDirectory&lt;/key>
        &lt;string>/var/run&lt;/string>
        &lt;key>Program&lt;/key>
        &lt;string>/sbin/pfctl&lt;/string>
        &lt;key>ProgramArguments&lt;/key>
        &lt;array>
                &lt;string>pfctl&lt;/string>
                &lt;string>-e&lt;/string>
                &lt;string>-f&lt;/string>
                &lt;string>/etc/pf.conf&lt;/string>
        &lt;/array>
        &lt;key>RunAtLoad&lt;/key>
        &lt;true/>
&lt;/dict>
&lt;/plist

Now clean up after yourself and turn System Integrity Protection back on.

sudo nvram "recovery-boot-mode=unused"
sudo reboot recovery
csrutil enable
reboot

macOS 10.13.2 supplement update disaster and recovery story

This is going to be a quick, poorly written post. I want to get this information out there since this might only be a short lived problem for mac users.

I have a 2017 iMac with a SSD.

I was running 10.13.2.

I did the supplemental update for meltdown and spectre.

The iMac would not boot.

I booted into recovery mode to run “First aid”. It exited with error 11.

I booted into single user mode and ran fsck_afps. Same error 11.

I made a disk image of my drive as a secondary backup to my time machine backup.

I did a reinstall of the OS. It still would not boot.

I tried with disk utility to erase the Macintosh HD. This is when things really went sideways.

I thought I would do a network restore of the OS, it would not work!

I downloaded the full 5+ gb installer of High Sierra. I created a bootable USB installer. That would not work. I could get the installer to boot, but not install.

It gets a little fuzzy in my memory at this point. While booted to the USB installer, the iMac would shutdown to a black screen and just generally thrashed as I tried to create a new Macintosh HD volume with the Disk Utility application. I could not truly clear the ssd.

I had to resort to terminal diskutil to really blow away everything.

With diskutil I created the new volume.

Now I was able to install the OS.

I tried to used to migration assistant, and the computer would shutdown just like earlier. I did this twice.

I tried to restore my DMG, that failed when i tried to scan for restore.

I wiped and installed the OS again. This time I created a new admin user and completed setup without migration assistant.

I go to do software update, and find out that the new download of High Sierra did not include the supplemental update.

I download that and restart. The supplemental install took about 20 minutes.

With all updates done, and a fresh admin user. I was finally able to use migration assistant and bring the user accounts back from my time machine backup.

WHAT A RIDE!

How to be the fmserver user

If you are ever trying to troubleshoot a system script that will be run by the fmserver user on OS X you can do the following to replicate what the server is doing with terminal.

1. Type su

2. Enter the root user password

3. Type su fmserver

4. Type whoami and it should return fmserver. This last step verifies that you are in fact the fmserver user.

This is what it should look like in terminal:

servername:~ currentuser$ su
Password:
sh-3.2# su fmserver
bash-3.2$ whoami
fmserver

An example of what you can do at this point is execute a shell script as fmserver.

sh /Library/FileMaker\ Server/Data/Scripts/example.sh

Preparing FileMaker Server System Script File for Mac OS X

When preparing a system script file for FileMaker server you must place it in the proper folder with proper ownership and privileges.

Step 1: Copy file to proper location

cp example.sh /Volumes/OS_Drive_Name_Example/Library/FileMaker\ Server/Data/Scripts/example.sh

Step 2: Navigate to FileMaker Server scripts folder

cd /Volumes/OS_Drive_Name_Example/Library/FileMaker\ Server/Data/Scripts/

Step 3: Assign FileMaker server owner/group to the file:

sudo chown fmserver:fmsadmin example.sh

Step 4: Assign proper privileges:

sudo chmod 755 example.sh

scp: ambiguous target

I was recently trying to copy a simple bash script from one FileMaker server to another using scp. The standard scp command is:

scp file.ext destination_user@server.address:/Folder/file.ext

This would leave you to think that the scp command for copying a script from one FileMaker server to another would look like this:

scp touch.sh user@123.456.7.8:/Library/FileMaker\ Server/Data/Scripts/touch.sh

 

This however fails with the response from terminal being:

scp: ambiguous target

Since the FileMaker Server folder contains a space this causes the failure, despite placing the backslash before the space. The answer is to put quotes around the entire destination to look like this:

scp touch.sh user@123.456.7.8:"/Library/FileMaker\ Server/Data/Scripts/touch.sh"

CustomList custom function limited to 300 items in list on FileMaker Server

I received a nice email from Agnès who created the CustomList function. I have copied her email below.  The function has been updated.

“I just did the test and saw that the function Evaluate () is the problem ( the same for FileMaker Go )
it is the current limit of FileMaker Serveur internal Evaluate function
FileMaker GO Evaluate () is limited to 400 (+/-)
FMServeur Evaluate () is limited to 300 (test FMServeur v11 )
instead of 1700 (+/-) for FileMaker. ( runtime and IWP )

I update the calc CustomList for this to work correctly on FMSserver
http://www.briandunning.com/cf/868 and http://www.fmfunctions.com/fid/118 )

Do not hesitate to let me know by email if you have a problem with CustomList ()
In this case, I have made test with FMS v11, maybe the limit is different with other versions.

Thank you

Agnès”

——–

Be careful when using the CustomList custom function on FileMaker server. My testing has revealed that the list this function will generate is limited to 300 entries when used on FileMaker Server. The documentation of this functions states that it is limited to 500,000 on FileMaker Pro and 150,000 on FileMaker Go.

CustomList_server_limitation_example.fp7

Bash script to FTP exported files from FileMaker Server

The below bash script can used if you need to FTP an export from FileMaker Server to anywhere.  The script basically looks to see what ever document is in the Documents folder of FileMaker Server and passes that to the cURL command.  It then moves the file to clear it out the directory.  You can /should include error trapping and maybe setup subdirectories but my objetive is to keep this simple to convey the concept after which you can “go nuts” customizing it.

#!/bin/bash
cd /Volumes/Server\ HD/Library/FileMaker\ Server/Data/Documents/
LOCALFILE=$(ls)
curl -T /Volumes/Server\ HD/Library/FileMaker\ Server/Data/Documents/"$LOCALFILE" ftp://123.123.123.123/destinationdirectory/ --user username:password
mv "$LOCALFILE" /Volumes/Drivename/uploads/

FileMaker Server scheduled bash script could not be found or is invalid.

If you are using FileMaker server to execute bash scripts be sure to check the first line to see that is includes the bang after the hash (#!/bin/bash).  I  ( and many others as revealed in a google search ) accidentally erased the bang while commenting a bash script and found out what happens. If you do this, you will see an error in the event.log file on FileMaker server when executed which looks like this.

Schedule “schedule_name” aborted; “scriptname.sh” could not be found or is invalid.

 

Object naming order very important to FileMaker web viewer responding to script step

The FileMaker web viewer can be controlled via the script step Set Web Viewer.  This script step is dependent on you naming the web viewer object and telling the script step that name. I have often found that I like to make the entire web viewer a button for things like downloading a document from SuperContainer.  The absolute key to this working is that your must first name the web viewer BEFORE making it a button. If you do so afterword, only the button has an object name and not the web viewer. Since the web viewer would not have an object name in this case, it would not respond to the script step.

If you have found this information helpful, or if you have any tips or suggestions, please leave a comment.