Skip to content

Conversation

@olistrik
Copy link
Contributor

@olistrik olistrik commented Nov 21, 2025

I needed to do a few things to get this to work, they're in separate commits so if you'd prefer I split them into seperate PRs I can do that quite easily.

  • 457f2bd adds a --unix-socket flag, which when provided a path will create a socket there and listen on it. This acts much like the localhost loopback, but does not elevate the permissions of incoming connections.
  • 4b4fd93 adds a --disable-tcp flag, this prevents the creation of a TCP listener on either tsnet or tailscaled, but does not otherwise interfere with the creation of the local client.
  • 73650f6 adds a --server-url flag, which takes precedence over the FQDN of the node. This is used to provide the domain name that the reverse proxy is behind.
  • 0e573bb adds support for listening on a systemd socket, when LISTEN_FDS is provided.

I believe this resolves #84, there may be others.

I fully expect this is going to need some discussion, I've tested this on my own server with the following configuration:

{ config, ... }:
let
  cfg = config.services.tsidp;
  unixSocket = "/run/tsidp.sock";
in
{
  services.tsidp = {
    enable = true;

    settings = {
      serverURL = "idp.olii.nl";
      useLocalTailscaled = true;
      disableTCP = true;
    };
  };

  services.caddy.virtualHosts = {
    ${cfg.settings.serverURL} = {
      extraConfig = ''
        reverse_proxy unix/${unixSocket}
      '';
    };
  };

  users.groups.tsidp-sock = { };

  systemd = {
    sockets = {
      tsidp = {
        description = "TSIDP Socket";
        partOf = [ "tsidp.service" ];
        wantedBy = [ "sockets.target" ];
        listenStreams = [ unixSocket ];
        socketConfig = {
          SocketMode = "0660";
          SocketGroup = "tsidp-sock";
        };
      };
    };

    services = {
      tsidp = {
        requires = [ "tsidp.socket" ];
        after = [ "tsidp.socket" ];
        serviceConfig = {
          SupplementaryGroups = [ "tsidp-sock" ];
        };
      };
      caddy = {
        wants = [ "tsidp.socket" ];
        after = [ "tsidp.socket" ];
        serviceConfig = {
          SupplementaryGroups = [ "tsidp-sock" ];
        };
      };
    };
  };
}

I'm not actually using the --unix-socket flag here, it's not used by the systemd socket listener so it can be dropped if it's deemed unnecessary.

os.Exit(1)
}
defer func() {
ln.Close() // TODO: the other listeners are not closed?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also found this somewhat strange, I'm fairly sure that unix sockets must be closed, but I noticed that none of the tcp listeners are being closed. Are they cleaned up automatically by go when the program exits?


srv.SetServerURL(strings.TrimSuffix(st.Self.DNSName, "."), *flagPort)
if *flagServerURL != "" {
srv.SetServerURL(*flagServerURL, *flagPort)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be smarter to provide a list of additional TrustedOrigins, that way all the listeners can be supported simultaneously. I'm not very familiar with OAuth2 though, so I didn't want to touch the server.go file in this PR.

if err := ipn.CheckFunnelAccess(uint16(*flagPort), st.Self); err != nil {
slog.Error("funnel access denied", slog.Any("error", err))

if !*flagDisableTCP {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As it stands, I don't really see much of a use-case for --unix-socket without --use-local-tailscaled. The nginx server will never be able to listen on the same domain as tsnet and there will have to be a local tailscaled session for ingress through nginx to be tagged correctly.

I added the disable flag here mostly for completeness.

@olistrik olistrik force-pushed the unix-socket-pr branch 2 times, most recently from 0b01e40 to 92b2b2d Compare December 4, 2025 13:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Bring Your Own Domain

1 participant