Mobile clients #15

Closed
opened 2025-12-29 01:19:59 +01:00 by adam · 21 comments
Owner

Originally created by @ptman on GitHub (Jul 20, 2021).

Tailscale has clients for linux, Windows, macOS, Android and iOS. Linux, Windows and macOS can be told to connect to a headscale server. I'm not aware of a way to do that on Android or iOS.

Can the (open source) android client be compiled with another server or be patched to allow server selection? What about iOS?

Originally created by @ptman on GitHub (Jul 20, 2021). Tailscale has clients for linux, Windows, macOS, Android and iOS. Linux, Windows and macOS can be told to connect to a headscale server. I'm not aware of a way to do that on Android or iOS. Can the (open source) android client be compiled with another server or be patched to allow server selection? What about iOS?
adam closed this issue 2025-12-29 01:19:59 +01:00
Author
Owner

@outbackdingo commented on GitHub (Jul 22, 2021):

sounds more like a tailscale question then headscale

@outbackdingo commented on GitHub (Jul 22, 2021): sounds more like a tailscale question then headscale
Author
Owner

@ptman commented on GitHub (Jul 22, 2021):

Sort of, but it doesn't affect users of tailscale that don't use headscale.

@ptman commented on GitHub (Jul 22, 2021): Sort of, but it doesn't affect users of tailscale that don't use headscale.
Author
Owner

@juanfont commented on GitHub (Jul 22, 2021):

Selecting the control server will be coming in the future for the official mobile clients (https://twitter.com/dave_universetf/status/1415046381996167170).

For the time being is possible to compile the Android client and change the hardcoded ipn.Prefs when calling the library.

@juanfont commented on GitHub (Jul 22, 2021): Selecting the control server will be coming in the future for the official mobile clients (https://twitter.com/dave_universetf/status/1415046381996167170). For the time being is possible to compile the Android client and change the hardcoded `ipn.Prefs` when calling the library.
Author
Owner

@juanfont commented on GitHub (Jul 22, 2021):

I will close this for the time being...

@juanfont commented on GitHub (Jul 22, 2021): I will close this for the time being...
Author
Owner

@kradalby commented on GitHub (Aug 3, 2021):

For people who wonder how to tell macOS to connect to headscale:

Install from App Store:

/Applications/Tailscale.app/Contents/MacOS/Tailscale up -login-server <YOUR HEADSCALE> --accept-routes
@kradalby commented on GitHub (Aug 3, 2021): For people who wonder how to tell macOS to connect to `headscale`: Install from App Store: ```bash /Applications/Tailscale.app/Contents/MacOS/Tailscale up -login-server <YOUR HEADSCALE> --accept-routes ```
Author
Owner

@tombh commented on GitHub (Oct 2, 2021):

I wonder if it might also be useful to mention in the README that Headscale doesn't yet support mobile clients natively? Just took me a bit of digging to get here and so realise that Headscale wasn't going to be so useful in my case.

@tombh commented on GitHub (Oct 2, 2021): I wonder if it might also be useful to mention in the README that Headscale doesn't yet support mobile clients natively? Just took me a bit of digging to get here and so realise that Headscale wasn't going to be so useful in my case.
Author
Owner

@kradalby commented on GitHub (Oct 2, 2021):

I wonder if it might also be useful to mention in the README that Headscale doesn't yet support mobile clients natively? Just took me a bit of digging to get here and so realise that Headscale wasn't going to be so useful in my case.

Would be a good idea, would you be able to submit a PR?

We could have a table with os, client combos

@kradalby commented on GitHub (Oct 2, 2021): > I wonder if it might also be useful to mention in the README that Headscale doesn't yet support mobile clients natively? Just took me a bit of digging to get here and so realise that Headscale wasn't going to be so useful in my case. Would be a good idea, would you be able to submit a PR? We could have a table with os, client combos
Author
Owner

@crisidev commented on GitHub (Oct 24, 2021):

A little guide on how to hack the Tailscale Android Client.

Patch fe76bef85b/cmd/tailscale/backend.go (L112) to look like this:

func (b *backend) Start(notify func(n ipn.Notify)) error {
    b.backend.SetNotifyCallback(notify)
    prefs := ipn.NewPrefs()
    prefs.ControlURL = "https://myheadscale.example.org"
    opts := ipn.Options{
    StateKey: "ipn-android",
        UpdatePrefs: prefs,
    }
    return b.backend.Start(opts)
}

Compile tailscale-android with make tailscale-debug.apk and adb install -f tailscale-debug.apk

Login on the app without SSO and it should bring you to the headscale page with the instructions to register the new node.

Hope it help others :)

@crisidev commented on GitHub (Oct 24, 2021): A little guide on how to hack the Tailscale Android Client. Patch https://github.com/tailscale/tailscale-android/blob/fe76bef85b8386f1c74edd831d701f312047eed2/cmd/tailscale/backend.go#L112 to look like this: ```go func (b *backend) Start(notify func(n ipn.Notify)) error { b.backend.SetNotifyCallback(notify) prefs := ipn.NewPrefs() prefs.ControlURL = "https://myheadscale.example.org" opts := ipn.Options{ StateKey: "ipn-android", UpdatePrefs: prefs, } return b.backend.Start(opts) } ``` Compile tailscale-android with `make tailscale-debug.apk` and `adb install -f tailscale-debug.apk` Login on the app without SSO and it should bring you to the headscale page with the instructions to register the new node. Hope it help others :)
Author
Owner

@ironicbadger commented on GitHub (Oct 26, 2021):

It is disappointing to see this issue closed without official support in the clients for all mobile platforms.

@ironicbadger commented on GitHub (Oct 26, 2021): It is disappointing to see this issue closed without official support in the clients for all mobile platforms.
Author
Owner

@kradalby commented on GitHub (Oct 26, 2021):

It is for us to support.

We are lucky to be able to use Tailscale's clients that they have put lots of engineering time to in most cases.

@kradalby commented on GitHub (Oct 26, 2021): It is for us to support. We are lucky to be able to use Tailscale's clients that they have put lots of engineering time to in most cases.
Author
Owner

@boehs commented on GitHub (Feb 6, 2022):

Could tailscale android be patched to introduce a configuration option?

@boehs commented on GitHub (Feb 6, 2022): Could tailscale android be patched to introduce a configuration option?
Author
Owner

@Akruidenberg commented on GitHub (Feb 6, 2022):

I have the same question.

@Akruidenberg commented on GitHub (Feb 6, 2022): I have the same question.
Author
Owner

@artemklevtsov commented on GitHub (Apr 1, 2022):

I managed to automate the process using GitLab CI.

.gitlab-ci.yml:

variables:
  GIT_TAG: "1.23.148-t7c7f37342-gb4f8e7f90a4"
  GIT_REPO: "tailscale/tailscale-android"

stages:
  - docker
  - build
  - upload

.fetch-repo: &fetch-repo
  - curl -o tailscale-android.zip https://codeload.github.com/${GIT_REPO}/zip/refs/tags/${GIT_TAG}
  - unzip -q tailscale-android.zip
  - mv -n tailscale-android-${GIT_TAG}/* .
  - rm -rf tailscale-android.zip tailscale-android-${GIT_TAG}

build-image:
  stage: docker
  image: docker:20.10
  services:
    - docker:20.10-dind
  variables:
    DOCKER_DRIVER: overlay2
    DOCKER_TLS_CERTDIR: "/certs"
  script:
    - apk add curl
    - *fetch-repo
    - docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} ${CI_REGISTRY}
    - docker pull ${CI_REGISTRY_IMAGE} || true
    - docker build --cache-from ${CI_REGISTRY_IMAGE} --tag ${CI_REGISTRY_IMAGE} .
    - docker push ${CI_REGISTRY_IMAGE}

build-apk:
  stage: build
  image: ${CI_REGISTRY_IMAGE}
  script:
    - apt-get install -y patch
    - *fetch-repo
    - sed -i "s|@LOGIN_SERVER_URL@|${LOGIN_SERVER_URL}|g" backend.patch
    - patch -p0 < backend.patch
    - make tailscale-fdroid.apk
  artifacts:
    paths:
      - tailscale-fdroid.apk

upload-apk:
  stage: upload
  image: curlimages/curl:latest
  script:
    - export TAILSCALE_APK=tailscale-fdroid.apk
    - export TAILSCALE_VERSION=$(echo ${GIT_TAG} | cut -d - -f 1)
    - 'curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file ${TAILSCALE_APK} ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/tailscale/${TAILSCALE_VERSION}/${TAILSCALE_APK}'

backend.patch:

--- cmd/tailscale/backend-fix.go	2022-04-01 19:34:35.375976556 +0700
+++ cmd/tailscale/backend.go	2022-04-01 19:34:23.224731221 +0700
@@ -136,9 +136,13 @@
 
 func (b *backend) Start(notify func(n ipn.Notify)) error {
 	b.backend.SetNotifyCallback(notify)
-	return b.backend.Start(ipn.Options{
+	prefs := ipn.NewPrefs()
+	prefs.ControlURL = "@LOGIN_SERVER_URL@"
+	opts := ipn.Options{
 		StateKey: "ipn-android",
-	})
+		UpdatePrefs: prefs,
+	}
+	return b.backend.Start(opts)
 }
 
 func (b *backend) LinkChange() {

Note: set LOGIN_SERVER_URL variable in CI settings.

@artemklevtsov commented on GitHub (Apr 1, 2022): I managed to automate the process using GitLab CI. `.gitlab-ci.yml`: ```yaml variables: GIT_TAG: "1.23.148-t7c7f37342-gb4f8e7f90a4" GIT_REPO: "tailscale/tailscale-android" stages: - docker - build - upload .fetch-repo: &fetch-repo - curl -o tailscale-android.zip https://codeload.github.com/${GIT_REPO}/zip/refs/tags/${GIT_TAG} - unzip -q tailscale-android.zip - mv -n tailscale-android-${GIT_TAG}/* . - rm -rf tailscale-android.zip tailscale-android-${GIT_TAG} build-image: stage: docker image: docker:20.10 services: - docker:20.10-dind variables: DOCKER_DRIVER: overlay2 DOCKER_TLS_CERTDIR: "/certs" script: - apk add curl - *fetch-repo - docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} ${CI_REGISTRY} - docker pull ${CI_REGISTRY_IMAGE} || true - docker build --cache-from ${CI_REGISTRY_IMAGE} --tag ${CI_REGISTRY_IMAGE} . - docker push ${CI_REGISTRY_IMAGE} build-apk: stage: build image: ${CI_REGISTRY_IMAGE} script: - apt-get install -y patch - *fetch-repo - sed -i "s|@LOGIN_SERVER_URL@|${LOGIN_SERVER_URL}|g" backend.patch - patch -p0 < backend.patch - make tailscale-fdroid.apk artifacts: paths: - tailscale-fdroid.apk upload-apk: stage: upload image: curlimages/curl:latest script: - export TAILSCALE_APK=tailscale-fdroid.apk - export TAILSCALE_VERSION=$(echo ${GIT_TAG} | cut -d - -f 1) - 'curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file ${TAILSCALE_APK} ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/tailscale/${TAILSCALE_VERSION}/${TAILSCALE_APK}' ``` `backend.patch`: ```diff --- cmd/tailscale/backend-fix.go 2022-04-01 19:34:35.375976556 +0700 +++ cmd/tailscale/backend.go 2022-04-01 19:34:23.224731221 +0700 @@ -136,9 +136,13 @@ func (b *backend) Start(notify func(n ipn.Notify)) error { b.backend.SetNotifyCallback(notify) - return b.backend.Start(ipn.Options{ + prefs := ipn.NewPrefs() + prefs.ControlURL = "@LOGIN_SERVER_URL@" + opts := ipn.Options{ StateKey: "ipn-android", - }) + UpdatePrefs: prefs, + } + return b.backend.Start(opts) } func (b *backend) LinkChange() { ``` Note: set `LOGIN_SERVER_URL` variable in CI settings.
Author
Owner

@half-duplex commented on GitHub (Apr 12, 2022):

I wrote a kinda gross patch that allows you to enter your own server info, here's the APK for anyone who doesn't want to compile their own. Forked from 51fc2e7030 (~v1.23.152)

@half-duplex commented on GitHub (Apr 12, 2022): I wrote a [kinda gross patch](https://github.com/tailscale/tailscale-android/pull/45) that allows you to enter your own server info, [here's the APK](https://github.com/half-duplex/tailscale-android/releases/tag/v1.23.152ish) for anyone who doesn't want to compile their own. Forked from https://github.com/tailscale/tailscale-android/commit/51fc2e7030191d08b434758dbd70a3a90338ef48 (~v1.23.152)
Author
Owner

@GrahamJenkins commented on GitHub (Apr 18, 2022):

Tested and using this gross patch. Seems to be working well, great hack @half-duplex!

I probably should just fork their repo, apply the changes and set up an auto build to make my own apk, but good enough for now. Thanks!

@GrahamJenkins commented on GitHub (Apr 18, 2022): Tested and using this gross patch. Seems to be working well, great hack @half-duplex! I probably should just fork their repo, apply the changes and set up an auto build to make my own apk, but good enough for now. Thanks!
Author
Owner

@FarisZR commented on GitHub (May 6, 2022):

I have set up build on push using GH actions in my repo, and it will upload an artifact(apk file) for each build.
https://github.com/FZR-forks/tailscale-android

It includes @half-duplex patch.

@FarisZR commented on GitHub (May 6, 2022): I have set up build on push using GH actions in my repo, and it will upload an artifact(apk file) for each build. https://github.com/FZR-forks/tailscale-android It includes @half-duplex patch.
Author
Owner

@FarisZR commented on GitHub (May 6, 2022):

It seems that GitHub only allows the repo owner to download the artifact ?

We can side-step that by just creating an F-droid repo which will have the app in it.
But that's for another day 😅

@FarisZR commented on GitHub (May 6, 2022): It seems that GitHub only allows the repo owner to download the artifact ? We can side-step that by just creating an F-droid repo which will have the app in it. But that's for another day :sweat_smile:
Author
Owner

@mrbluecoat commented on GitHub (Jul 3, 2022):

Any chance we can disable the ability to toggle off the VPN? Would love to use an enforced exit node: https://github.com/tailscale/tailscale/issues/1698

@mrbluecoat commented on GitHub (Jul 3, 2022): Any chance we can disable the ability to toggle off the VPN? Would love to use an enforced exit node: https://github.com/tailscale/tailscale/issues/1698
Author
Owner

@half-duplex commented on GitHub (Jul 10, 2022):

@mrbluecoat Please open new issues in the appropriate repo and do not comment on unrelated ones.

@half-duplex commented on GitHub (Jul 10, 2022): @mrbluecoat Please open new issues in the appropriate repo and do not comment on unrelated ones.
Author
Owner

@0x1a8510f2 commented on GitHub (Aug 1, 2022):

Good news y'all :D https://github.com/tailscale/tailscale-android/pull/55

@0x1a8510f2 commented on GitHub (Aug 1, 2022): Good news y'all :D https://github.com/tailscale/tailscale-android/pull/55
Author
Owner

@half-duplex commented on GitHub (Aug 1, 2022):

To put instructions here for easier googling:
In test builds or once v1.30.0 of the official Android Tailscale client is out, you should be able to set a custom control server by opening and closing the login screen's 3-dot menu 6 times then selecting the menu option that appears.

Would be good to add this to the headscale docs, but I don't want to bother before the patch is released.

@half-duplex commented on GitHub (Aug 1, 2022): To put instructions here for easier googling: In [test builds](https://github.com/tailscale/tailscale-android/pull/55#issuecomment-1201870483) or once v1.30.0 of the official Android Tailscale client is out, you should be able to set a custom control server by opening and closing the login screen's 3-dot menu 6 times then selecting the menu option that appears. Would be good to add this to the headscale docs, but I don't want to bother before the patch is released.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/headscale#15