Skip to main content

Setting up golink in my personal tailnet

  • Posted
  • Updated

I created a macOS LaunchAgent to start golink automatically whenever my desktop Mac restarts.

We use golink a lot at work, and I wanted to add it to my personal tailnet.

I decided to run it from my home Mac mini, because it’s always running and golink is a very lightweight service. Writing this, it occurs to me I could have also run it on my Linux web server, which doesn’t have to restart for macOS updates, but it’s set up now.

These are some notes on how I set it up:

  1. Clone the [golink repo] to my Mac.

    $ git clone git@github.com:tailscale/golink.git ~/repos/golink
  2. Authenticate golink with my tailnet. I created an auth key for my tailnet which is tagged with tag:golink, then passed it as the TS_AUTH_KEY environment variable to start golink:

    $ TS_AUTHKEY="tskey-auth-<key>" go run ./cmd/golink -sqlitedb "/Volumes/Media (Speedwell)/golink.db"

    That starts an instance of golink that I could see at http://go/, but it would only last as long as my terminal session – I want it to be an always-running service.

  3. Configure golink to start automatically. I created a macOS LaunchAgent by creating a file at ~/Library/LaunchAgents/net.alexwlchan.golinks.plist with the following contents:

    <?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>net.alexwlchan.golinks</string>
            <key>ProgramArguments</key>
            <array>
                <string>/usr/local/go/bin/go</string>
                <string>run</string>
                <string>./cmd/golink</string>
                <string>-sqlitedb</string>
                <string>/Volumes/Media (Speedwell)/golink.db</string>
            </array>
            <key>WorkingDirectory</key>
            <string>/Users/alexwlchan/repos/golink</string>
            <key>RunAtLoad</key>
            <true/>
            <key>StandardOutPath</key>
            <string>/Users/alexwlchan/Library/Logs/golinks.log</string>
            <key>StandardErrorPath</key>
            <string>/Users/alexwlchan/Library/Logs/golinks.log</string>
        </dict>
    </plist>

    I start the service by running:

    $ launchctl load ~/Library/LaunchAgents/net.alexwlchan.golinks.plist

    Now my golink service is running, and will be automatically started whenever I restart or log into my Mac.

    If I need to stop it, I run:

    $ launchctl unload ~/Library/LaunchAgents/net.alexwlchan.golinks.plist

    I can restart the service by running unload/load, for example if I’ve made changes to the LaunchAgent plist.

  4. Allow my devices to see golink. I added a grant to my policy file which allows every device in my tailnet to look up http://go/ URLs:

    "grants": [
      
      {
        "src": ["autogroup:member"],
        "dst": ["tag:golink"],
        "ip":  ["*"],
      },
    ]

    It’s also possible for me to control who’s allowed to edit links, but I’m the only user in my personal tailnet, so that’s a non-issue.

  5. Add a policy file test to ensure I can reach golinks from my devices.

    "hosts": {
      "phaenna-mac-mini":     "100.76.19.1",
      "go":                   "100.107.83.99",
      
    },
    
    "tests": [
      {
        "src":    "phaenna-mac-mini",
        "accept": ["go:80"],
      },
      
    ],

    I populated the hosts field using the output of tailscale status.

(Disclaimer: At time of writing, I’m employed by Tailscale.)