Skip to content

Instantly share code, notes, and snippets.

@joeblackwaslike
Last active April 7, 2022 14:52
Show Gist options
  • Save joeblackwaslike/51e3986da7d3cb51fb29dd396c4a5580 to your computer and use it in GitHub Desktop.
Save joeblackwaslike/51e3986da7d3cb51fb29dd396c4a5580 to your computer and use it in GitHub Desktop.
MacOS LaunchDaemon plist for TCP service thats launched on demand when socket is connected to

MacOS LaunchDaemon plist for TCP service thats launched on demand when socket is connected to

This service isn't started at launch, which is by design. The command being launched establishes a tunnel to a virtual machine running on the host using UTM.app. I created a LoginItem that launches the virtual machine at startup using UTM's registered URI handlers. By starting these tunnels lazily, we are able to connect at a time after the virtual machine has already booted and able to be reached on the network. Trying to do this at startup would result in a failure to connect.

Instructions

  1. Ensure ssh is configured on the remote machine, you've generated an ssh key and you've copied that ssh key to the remote host.
  2. Replace {{ path_to_public_key }} with the full path to the ssh key you generated in step 1.
  3. Replace {{ remote_user }} with your username on the remote machine.
  4. Replace {{ remote_host }} with the remote hostname or ip address (for virtual machines this will probably be an ip address reachable by your local machine).
  5. Replace {{ your_username }} with your username, ex: $ whoami
  6. Replace {{ your_groupname }} with an appropriate group name, select from groups returned by $ id -Gn $(whoami), ex: staff.
  7. Replace {{ port }} with the remote port you'd like to tunnel locally.
  8. Rename the template to remove the prefix and replace template with the port number you want to tunnel: $ mv 2-com.ssh.tunnel.port.template.plist com.ssh.tunnel.port.8080.plist
  9. Install the plist: $ sudo install -o root -g wheel -m 644 com.ssh.tunnel.port.8080.plist /Library/LaunchDaemons
  10. Load the plist to activate it: $ sudo launchd load -w /Library/LaunchDaemons/com.ssh.tunnel.port.8080.plist
<?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>Label</key>
<string>com.ssh.tunnel.port.{{ port }}</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/ssh</string>
<string>-C</string>
<string>-i</string>
<string>{{ path_to_public_key }}</string>
<string>-o</string>
<string>ControlMaster=auto</string>
<string>-o</string>
<string>ControlPersist=16</string>
<string>-o</string>
<string>ServerAliveCountMax=2</string>
<string>-o</string>
<string>ServerAliveInterval=5</string>
<string>-W</string>
<string>localhost:{{ port }}</string>
<string>{{ remote_user }}@{{ remote_host }}</string>
</array>
<key>OnDemand</key>
<true/>
<key>UserName</key>
<string>{{ your_username }}</string>
<key>GroupName</key>
<string>{{ your_groupname }}</string>
<key>inetdCompatibility</key>
<dict>
<key>Wait</key>
<false/>
</dict>
<key>Sockets</key>
<dict>
<key>Listeners</key>
<dict>
<key>SockServiceName</key>
<string>{{ port }}</string>
</dict>
</dict>
</dict>
</plist>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment