Launchd won’t load plists at boot

launchd

I have a set of scripts that need to run on system boot and stay alive. I have the plist saved as /Library/LaunchAgents/net.vps.tunnel.plist and it has the proper permissions:

-rw-r--r--  1 root  wheel  516 Nov  6 22:03 net.vps.tunnel.plist

The script is stored in the root /Library/LaunchAgents, NOT the user ~/Library/LaunchAgents directory, so it's supposed to run on boot as the superuser. If I manually run the script via sudo launchctl load /Library/LaunchAgents/net.vps.tunnel.plist it runs fine. But despite the fact that it is supposed to run on boot, it doesn't. When I check launchctl list immediately after boot, I see that it has not been loaded. Trying to start via sudo launchctl start net.vps.tunnel fails with the error "launchctl start error: No such process".

If I log in via the GUI, suddenly launchd loads all of the scripts. However, they run with my user permissions and some of them do not work properly. In the plists, I have specified the UserName key as a daemon user, but they all run under my user credentials.

Here's the plist file in question, located at /Library/LaunchAgents/net.vps.tunnel.plist and with -rw-r–r– permissions for root:wheel:

<?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>net.vps.tunnel</string>
        <key>ProgramArguments</key>
                <array>
                        <string>/Users/_tunnel/tunnel.sh</string>
                </array>
        <key>RunAtLoad</key>
                <true/>
        <key>WorkingDirectory</key>
                <string>/Users/_tunnel</string>
        <key>UserName</key>
                <string>_tunnel</string>
        <key>KeepAlive</key>
                <true/>
</dict>
</plist>

And here's the tunnel script, with permissions -rwxr-x— for _tunnel:_tunnel:

#/bin/bash

logger "Opening VPS tunnel..."

ssh -i ./.ssh/id_rsa -gnN tunnel@********.com &
PID=$!
logger "VPS tunnel is now open."

wait $PID
logger "VPS tunnel is now closed."
exit 0

Best Answer

Try moving the plist to /Library/LaunchDaemons/. Agents (other than pre-login agents) are run only after a user logs in and they are owned by the user. Also the UserName key has no effect for agents.

See the Daemons and Agents tech note.