Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save shxdow/f611fbfb0d672e03ccb055c9aa29df6b to your computer and use it in GitHub Desktop.
Save shxdow/f611fbfb0d672e03ccb055c9aa29df6b to your computer and use it in GitHub Desktop.
MacOS ScreenSharing on localhost only

Force recent MacOS to listen for screen sharing on localhost only, keeping SIP on

All the following has been validated on MacOS Mojave 10.14.6

Problems

While there is a command line preference to accept only local VNC connections, that setting still doesn't prevent the daemon from listening to the wildcard address, and advertise the service on Bonjour. I haven't actually tried to see if it restricted anything in modern versions of the operating system, but here it is for reference:

sudo defaults write /Library/Preferences/com.apple.RemoteManagement.plist VNCOnlyLocalConnections -bool yes

The LaunchDaemon located at /System/Library/LaunchDaemons/com.apple.screensharing.plist is responsible for both offences:

  <key>Sockets</key>
  <dict>
    <key>Listener</key>
    <dict>
      <key>Bonjour</key>
      <string>rfb</string>
      <key>SockServiceName</key>
      <string>vnc-server</string>
    </dict>
  </dict>

Unfortunately editing that file in not possible because System Integrity Protection prevents modifying any files in /System.

The alternative is to create a new LaunchDaemon in /Library. Unfortunately the screen sharing agent will not work properly when assigned a different label. That means the daemon has to be "shadowing" the original using the same name. That causes it's own problems because on reboot, the system will load the original in /System and ignore the modified version in /Library.

Solution

The solution is to disable the LaunchDaemon and use a "launcher" daemon that will forcibly load the modified LaunchDaemon. However care must be taken to still activate Screen Sharing through the preferences orelse it will endup in observe only mode.

Step by step

  1. Activate Screen Sharing in the System Preferences
  2. sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.screensharing.plist
  3. sudo cp /System/Library/LaunchDaemons/com.apple.screensharing.plist /Library/LaunchDaemons/com.apple.screensharing.plist
  4. In /Library/LaunchDaemons/com.apple.screensharing.plist, edit the Sockets section to look like:
  <key>Sockets</key>
  <dict>
    <key>Listener</key>
    <dict>
      <key>SockNodeName</key>
      <string>localhost</string>
      <key>SockServiceName</key>
      <string>vnc-server</string>
    </dict>
  </dict>
  1. Create /Library/LaunchDaemons/com.apple.screensharing.launcher.plist with the following content:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.apple.screensharing.launcher</string>
  <key>LaunchOnlyOnce</key>
  <true/>
  <key>RunAtLoad</key>
  <true/>
  <key>KeepAlive</key>
  <false/>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/launchctl</string>
    <string>load</string>
    <string>-F</string>
    <string>/Library/LaunchDaemons/com.apple.screensharing.plist</string>
  </array>
</dict>
</plist>
  1. sudo launchctl load -w /Library/LaunchDaemons/com.apple.screensharing.launcher.plist

Bonus: Allow direct connections from localhost

The Screen Sharing client prevents connecting to localhost. It's probably to avoid screen sharing recursion. However, MacOS screen sharing is capable of accessing the screen of a user not logged in on the console, but by default we can't take advantage of this to show the loginwindow of another local user, for example on a second monitor.

The solution is to make the agent listen on a different port than the default.

  1. Replace vnc-server by a port number different from the default in SockServiceName:
      <key>SockServiceName</key>
      <string>5901</string>
  1. Open a connection to vnc://otheruser@localhost:5901
  2. After entering your password, select Login as yourself
  3. Run GUI applications for 2 users at once without switching.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment