3.22.2012

Mac OS X "SOE" Day 3

Page Redirection > continued from day 2...

Ready to copy my scripts over, as previously mentioned I am thinking of having 3 phases;
  1. build - preps the image for dmg capture.
  2. firstboot - runs anything I can't do in build ie, writing to byhost files etc that require UUID or Macaddress. Basically machine/model specific settings.
  3. localise - runs localisation scripts such as language, locale etc etc. Basically a set of dynamic scripts in case you are an admin for multiple offices, multiple countries.

So what's the minimum we need in the "build" phase?
  1. Disable the Setup Wizard.
  2. Disable the Registration Wizard.
  3. Create a local admin user(s) and set autologin for the firstboot phase.
  4. Enable root (set the password).
  5. Enable SSH Access
  6. Enable VNC Access
  7. Enable ARD Access
  8. Disable softwareupdate automatic updates "schedule"
  9. Cleanup/Minimise the dmg where possible.
  10. Set a firstboot loginhook for the second phase.

What are some other nice things you may want? (I'm doing the following)
  1. Enable Access for Assistive Devices (maybe some stuff can't be script nicely so use Applescript instead).
  2. Modify default prefs in /System/Library/User Templates (you may want to do this prior to creating your local admin users so they get the defaults too...)
  3. Add a link to often used Directory Utility.
  4. Add a link to often used Printer Utility.

Now lets begin, starting from the previous step (booted in single user mode) run these. (I'll leave it up to you how you want to package them, I like to keep things non-proprietary so I don't roll them into PKG files, instead keep them as shell scripts).

Mount the disk first so you can make changes to the filesystem.
/sbin/mount -uw /

Disable Setup Wizard
sudo /usr/bin/touch "/private/var/db/.AppleSetupDone"
sudo /usr/sbin/chown root:wheel "/private/var/db/.AppleSetupDone"

Disable Registration Wizard
sudo /usr/bin/touch "/Library/Receipts/.SetupRegComplete"
sudo /usr/sbin/chown root:wheel "/Library/Receipts/.SetupRegComplete"

Create a local admin user account (run this as many times as you need if you want more than one). I am doing it via single user but you could use InstaDMG's CreateLionUser pkg file to target a booted volume. I just prefer this way as I know exactly whats happening and don't have to worry about bugs.
# For 10.7 load open directory
launchctl load /System/Library/LaunchDaemons/com.apple.opendirectoryd.plist

# Create a user (replacing the SHORTNAME and PASSWORD vars)
# NOTE : I redirect NFSHomeDirectory to /var so local admins are less visible to end users.
# NOTE : UniqueID less than 500
sudo /usr/bin/dscl . -create /Users/${SHORTNAME}
sudo /usr/bin/dscl . -create /Users/${SHORTNAME} UserShell /bin/bash
sudo /usr/bin/dscl . -create /Users/${SHORTNAME} RealName "${SHORTNAME}"
sudo /usr/bin/dscl . -create /Users/${SHORTNAME} UniqueID 444
sudo /usr/bin/dscl . -create /Users/${SHORTNAME} PrimaryGroupID 80
sudo /usr/bin/dscl . -create /Users/${SHORTNAME} NFSHomeDirectory "/var/${SHORTNAME}"
sudo /usr/bin/dscl . -passwd /Users/${SHORTNAME} "${PASSWORD}"
sudo /usr/bin/dscl . -append /Groups/admin GroupMembership ${SHORTNAME}
sudo /bin/cp -Rfv /System/Library/User\ Template/English.lproj "/var/${SHORTNAME}"
sudo /usr/sbin/chown -R ${SHORTNAME}:admin "/var/${SHORTNAME}"

# Hide the user from the loginwindow
sudo defaults write /Library/Preferences/com.apple.loginwindow HiddenUsersList -array-add "${SHORTNAME}"

# Hide the < UniqueID 500 users.
sudo defaults write /Library/Preferences/com.apple.loginwindow Hide500Users -bool TRUE

# Prevent "Other" from appearing in the loginwindow.
sudo defaults write /Library/Preferences/com.apple.loginwindow SHOWOTHERUSERS_MANAGED -bool FALSE

# Enable autoLoginUser for this user.
sudo /usr/bin/defaults write "/Library/Preferences/com.apple.loginwindow" autoLoginUser -string "${SHORTNAME}"

# Set autologin password
# NOTE : Can't script this :( just manually create a user and generate one then deliver it via paylaod.
sudo /bin/cp -Rfv kcpassword" "/etc/kcpassword"
sudo /bin/rm -Rf "/etc/kcpassword.disabled"

# Note the special permissions for kcpassword.
sudo /usr/sbin/chown root:wheel "/etc/kcpassword"
sudo /bin/chmod 600 "/etc/kcpassword"

Enable root by simply setting the password.
passwd

Enable ssh for remote support.
# Enable the daemon.
sudo /usr/bin/defaults delete "/System/Library/LaunchDaemons/ssh" "Disabled"

# Note the special permissions for LaunchDaemons.
sudo /usr/sbin/chown root:wheel "/System/Library/LaunchDaemons/ssh.plist"
sudo /bin/chmod 644 "/System/Library/LaunchDaemons/ssh.plist"

# MOTD banner.
sudo /bin/echo "Unauthorized access to these resources is prohibited." > "/etc/motd"

# Note the special permissions for motdsudo /bin/chmod 755 "/etc/motd"
sudo /usr/sbin/chown root:wheel "/etc/motd"

Set a VNC password then enable VNC.
# Set encrypted VNC password string (replacing the PASSWORD var)
ENCVNCPASSWD=$(echo "${PASSWORD}" | perl -we 'BEGIN { @k = unpack "C*", pack "H*", "1734516E8BA8C5E2FF1C39567390ADCA"}; $_ = <>; chomp; s/^(.{8}).*/$1/; @p = unpack "C*", $_; foreach (@k) { printf "%02X", $_ ^ (shift @p || 0) }; print "\n"')
sudo /bin/echo "${ENCVNCPASSWD}" > "/Library/Preferences/com.apple.VNCSettings.txt"

# com.apple.VNCSettings.txt special permissions.
sudo /usr/sbin/chown -R root:wheel "/Library/Preferences/com.apple.VNCSettings.txt"
sudo /bin/chmod -R 600 "/Library/Preferences/com.apple.VNCSettings.txt"

# Enable VNC
/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -activate -access -on -clientopts -setvnclegacy -vnclegacy yes -restart -agent

Enable ARD.
# Enable ARD with options. Up to you what options you want. Consult MAN.
/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate -configure -access -on -users ${SHORTNAME} -privs -all -clientopts -setvnclegacy -vnclegacy yes

Disable softwareupdate "scheduled" updates using a LaunchDaemon. I am using a launch daemon as the plist file is a little awkward to deal with using the defaults command.
# Disable softwareupdate schedule via a daemon
sudo /usr/bin/defaults write /Library/LaunchDaemons/org.softwareupdate Label org.softwareupdate
sudo /usr/bin/defaults write /Library/LaunchDaemons/org.softwareupdate LaunchOnlyOnce -bool TRUE
sudo /usr/bin/defaults write /Library/LaunchDaemons/org.softwareupdate Program "/usr/sbin/softwareupdate"
sudo /usr/bin/defaults write /Library/LaunchDaemons/org.softwareupdate RunAtLoad -bool TRUE
sudo /usr/bin/defaults write /Library/LaunchDaemons/org.softwareupdate ProgramArguments -array "/usr/sbin/softwareupdate" "--schedule" "off"

# Note the special permissions for LaunchDaemons.
sudo /usr/sbin/chown root:wheel "/Library/LaunchDaemons/org.softwareupdate.plist"sudo /bin/chmod 644 "/Library/LaunchDaemons/org.softwareupdate.plist"

Cleanup and minimise.
# Remove Alex Voice and save 450mb in DMG size, I've tried it in 10.5 and 10.6 and never had a problem.
sudo /bin/rm -Rf "/System/Library/Speech/Voices/Alex.SpeechVoice"

# Remove the sleepimage
# NOTE : You can disable this completely by running "pmset -a hibernatemode 0" if you know what your are doing ;)
sudo /bin/rm -Rf "/private/var/vm/sleepimage"

# Remove caches and swap just-in-case they exist
sudo /bin/rm -Rf "/private/var/vm/swapfile0"
sudo /bin/rm -Rf ~/Library/Caches/*
sudo /bin/rm -Rf /Library/Caches/*
sudo /bin/rm -Rf /System/Library/Caches/*

Setup firstboot loginhook
# Create a loginhook to run scripts that cannot be added to the build. ie, scripts that write byhost info.
sudo /usr/bin/defaults write "/var/root/Library/Preferences/com.apple.loginwindow" LoginHook -string "/var/root/firstboot.sh"

Stay tuned...