HEADSCALE_VERSION="0.28.0" HEADSCALE_ARCH="amd64" DOMAIN_URL="https://vpn.excloud.in" wget --output-document=headscale.deb \ "https://github.com/juanfont/headscale/releases/download/v${HEADSCALE_VERSION}/headscale_${HEADSCALE_VERSION}_linux_${HEADSCALE_ARCH}.deb" apt install ./headscale.deb systemctl enable --now headscale PREAUTH_KEY=$(headscale preauthkeys create --tags tag:headscale-agent) apt-get install caddy -y mkdir -p /var/lib/headplane chown -R $(whoami):$(whoami) /var/lib/headplane mkdir -p /etc/headplane touch /etc/headplane/config.yaml wget https://go.dev/dl/go1.26.0.linux-amd64.tar.gz tar -C /usr/local -xzf go1.26.0.linux-amd64.tar.gz echo 'export PATH=$PATH:/usr/local/go/bin' >> /etc/profile rm go1.26.0.linux-amd64.tar.gz curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash \. "$HOME/.nvm/nvm.sh" source ~/.bashrc nvm install 24 git clone https://github.com/tale/headplane.git cd headplane COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack enable pnpm COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack install pnpm install pnpm build cat > "/etc/caddy/Caddyfile" < "/etc/headplane/config.yaml" <" # Headscale specific settings to allow Headplane to talk # to Headscale and access deep integration features headscale: # The URL to your Headscale instance # (All API requests are routed through this URL) # (THIS IS NOT the gRPC endpoint, but the HTTP endpoint) # # IMPORTANT: If you are using TLS this MUST be set to 'https://' url: "http://127.0.0.1:8080" # If you use the TLS configuration in Headscale, and you are not using # Let's Encrypt for your certificate, pass in the path to the certificate. # (This has no effect if 'url' does not start with 'https://') # tls_cert_path: "/var/lib/headplane/tls.crt" # Optional, public URL if its different from the 'headscale.url' # This affects certain parts of the web UI which shows Headscale's URL public_url: "${DOMAIN_URL}" # Path to the Headscale configuration file # This is optional, but HIGHLY recommended for the best experience # If this is read only, Headplane will show your configuration settings # in the Web UI, but they cannot be changed. config_path: "/etc/headscale/config.yaml" # Whether the Headscale configuration should be strictly validated # when reading from 'config_path'. If true, Headplane will not interact # with Headscale if there are any issues with the configuration file. # # This is recommended to be true for production deployments to, however it # may not work if you are using a version of Headscale that has configuration # options unknown to Headplane. config_strict: true # If you are using 'dns.extra_records_path' in your Headscale # configuration, you need to set this to the path for Headplane # to be able to read the DNS records. # # Pass it in if using Docker and ensure that the file is both # readable and writable to the Headplane process. # When using this, Headplane will no longer need to automatically # restart Headscale for DNS record changes. # dns_records_path: "/var/lib/headscale/extra_records.json" # Integration configurations for Headplane to interact with Headscale integration: # The Headplane agent allows retrieving information about nodes # This allows the UI to display version, OS, and connectivity data # You will see the Headplane agent in your Tailnet as a node when # it connects. agent: enabled: true # To connect to your Tailnet, you need to generate a pre-auth key # This can be done via the web UI or through the 'headscale' CLI. pre_authkey: "${PREAUTH_KEY}" # Optionally change the name of the agent in the Tailnet. host_name: "headplane-agent" # Configure different caching settings. By default, the agent will store # caches in the path below for a maximum of 1 minute. If you want data # to update faster, reduce the TTL, but this will increase the frequency # of requests to Headscale. # cache_ttl: 60 # cache_path: /var/lib/headplane/agent_cache.json # The work_dir represents where the agent will store its data to be able # to automatically reauthenticate with your Tailnet. It needs to be # writable by the user running the Headplane process. # # If using Docker, it is best to leave this as the default. # work_dir: "/var/lib/headplane/agent" # Only one of these should be enabled at a time or you will get errors # This does not include the agent integration (above), which can be enabled # at the same time as any of these and is recommended for the best experience. docker: enabled: false # By default we check for the presence of a container label (see the docs) # to determine the container to signal when changes are made to DNS settings. container_label: "me.tale.headplane.target=headscale" # HOWEVER, you can fallback to a container name if you desire, but this is # not recommended as its brittle and doesn't work with orchestrators that # automatically assign container names. # # If 'container_name' is set, it will override any label checks. # container_name: "headscale" # The path to the Docker socket (do not change this if you are unsure) # Docker socket paths must start with unix:// or tcp:// and at the moment # https connections are not supported. socket: "unix:///var/run/docker.sock" # Please refer to docs/integration/Kubernetes.md for more information # on how to configure the Kubernetes integration. There are requirements in # order to allow Headscale to be controlled by Headplane in a cluster. kubernetes: enabled: false # Validates the manifest for the Pod to ensure all of the criteria # are set correctly. Turn this off if you are having issues with # shareProcessNamespace not being validated correctly. validate_manifest: true # This should be the name of the Pod running Headscale and Headplane. # If this isn't static you should be using the Kubernetes Downward API # to set this value (refer to docs/Integrated-Mode.md for more info). pod_name: "headscale" # Proc is the "Native" integration that only works when Headscale and # Headplane are running outside of a container. There is no configuration, # but you need to ensure that the Headplane process can terminate the # Headscale process. # # (If they are both running under systemd as sudo, this will work). proc: enabled: false # OIDC Configuration for simpler authentication # (This is optional, but recommended for the best experience) # oidc: # Set to false to define OIDC config without enabling it. # Useful for Helm charts or generating docs from config files. # enabled: true # The OIDC issuer URL # issuer: "https://accounts.google.com" # If you are using OIDC, you need to generate an API key # that can be used to authenticate other sessions when signing in. # # This can be done with 'headscale apikeys create --expiration 999d' # headscale_api_key: "" # If your OIDC provider does not support discovery (does not have the URL at # '/.well-known/openid-configuration'), you need to manually set endpoints. # This also works to override endpoints if you so desire or if your OIDC # discovery is missing certain endpoints (ie GitHub). # For some typical providers, see https://headplane.net/features/sso. # authorization_endpoint: "" # token_endpoint: "" # userinfo_endpoint: "" # The authentication method to use when communicating with the token endpoint. # This is fully optional and Headplane will attempt to auto-detect the best # method and fall back to 'client_secret_basic' if unsure. # token_endpoint_auth_method: "client_secret_post" # The client ID for the OIDC client # For the best experience please ensure this is *identical* to the client_id # you are using for Headscale. because # client_id: "your-client-id" # The client secret for the OIDC client # You may also provide 'client_secret_path' instead to read a value from disk. # See https://headplane.net/configuration/#sensitive-values # client_secret: "" # Whether to use PKCE when authenticating users. This is recommended as it # adds an extra layer of security to the authentication process. Enabling this # means your OIDC provider must support PKCE and it must be enabled on the # client. # use_pkce: true # If you want to disable traditional login via Headscale API keys # disable_api_key_login: false # By default profile pictures are pulled from the OIDC provider when # we go to fetch the userinfo endpoint. Optionally, this can be set to # "oidc" or "gravatar" as of 0.6.1. # profile_picture_source: "gravatar" # The scopes to request when authenticating users. The default is below. # scope: "openid email profile" # Extra query parameters can be passed to the authorization endpoint # by setting them here. This is useful for providers that require any kind # of custom hinting. # extra_params: # prompt: "select_account" # Example: force account selection on Google EOF NODE_PATH=$(nvm which current) cat > "/etc/systemd/system/headplane.service" <