Tailscale for Samsung Tizen TV (Experiment)
May 8, 2026 · View on GitHub
A Tailscale exit-node app for Samsung Smart TVs running Tizen.
The TV joins your tailnet and (optionally) advertises itself as an exit node, so other devices on the tailnet can route traffic through it. The TV's own apps continue to use the local network -- this app does not provide VPN coverage for the TV itself.
Tracking Issue
See https://github.com/tailscale/tailscale/issues/10955
How it works
┌────────────────── Tizen TV ──────────────────┐
│ │
│ .NET (NUI) UI ──── localapi/v0 ────┐ │
│ com.tailscale.tailscale │ │
│ Unix sock │
│ │ │
│ tailscaled (Go, --tun=userspace)───┘ │
│ │ │
│ └── magicsock / DERP / WireGuard │
│ │
└──────────────────────────────────────────────┘
The .NET app launches a cross-compiled tailscaled binary as a
subprocess, then drives the IPN state machine over the Unix-socket
LocalAPI. tailscaled runs in --tun=userspace-networking mode and
uses gVisor netstack to terminate/redial peer traffic. No TUN device
is required.
Build prerequisites
- Tizen Studio 5.x or newer with the TV CLI tools.
See Installing TV SDK.
We use
tools/tizen-core/tz(the newer Go-based CLI) andtools/sdb. - .NET 8 SDK with the Tizen workload.
Install the SDK from your distro or
microsoft.com, then the workload:
(See the Tizen.NET wiki for details and platform-specific notes.)curl -sSL https://raw.githubusercontent.com/Samsung/Tizen.NET/main/workload/scripts/workload-install.sh | bash - Go (any recent version). The build cross-compiles
tailscaledfrom the public source at the version pinned ingo.mod; you do not need a separate tailscale.com checkout. - (Linux only) gnome-keyring + dbus-run-session, used by
make packbecause Tizen'stzCLI stashes PKCS#12 passwords via libsecret. On macOS the system Keychain handles this; nothing extra to install.sudo apt-get install gnome-keyring libsecret-tools
The Samsung certificate dance
Samsung TVs reject unsigned, generically-signed, or tizen-public-distributor-signed
apps. You need a Samsung-issued distributor certificate bound to the TV's
DUID before any installable tpk will load. This is a one-time setup per
TV.
- Enable Developer Mode on the TV. See Samsung's instructions.
- Connect to the TV with sdb so you can read its DUID:
Save that DUID -- it goes into the cert.~/tizen-studio/tools/sdb connect <TV_IP> ~/tizen-studio/tools/sdb shell 0 getduid - Open Tizen Studio's Certificate Manager (or the VS Code Tizen
Extension, "Create Certificate" pane). Pick Samsung (not
Tizen), profile name e.g.
tailscale-tv, privilege level Public, and paste the DUID when prompted. You'll be asked to sign in with a Samsung account. - The output lands at
~/SamsungCertificate/<profile_name>/:author.p12 distributor.p12 author.crt distributor.crt author.csr distributor.csr author.pri distributor.pri device-profile.xml - Copy the two
.p12files somewhere stable and remember the password(s) you set during creation. The Makefile defaults assume:~/tizen-studio-data/keystore/tv-samsung/author.p12 ~/tizen-studio-data/keystore/tv-samsung/distributor.p12
Building and installing
Configure the build with environment variables (or a gitignored
.env.local file at the repo root):
cat > .env.local <<EOF
TS_AUTHOR_PW=<your author p12 password>
TS_DIST_PW=<your distributor p12 password>
EOF
Other variables you can override (defaults in Makefile):
TIZEN_STUDIO-- path to Tizen Studio (default~/tizen-studio).DOTNET-- path todotnetwith the Tizen workload installed.SIGN_PROFILE-- security profile name to (re-)create at pack time.DEVICE-- sdb serial of the target TV (sdb devices). Defaultemulator-26101.TS_AUTHOR_P12/TS_DIST_P12-- paths to your Samsung-issued certs.
Then:
make check-deps # verify Tizen Studio, .NET workload, certs, sdb device, etc.
make tailscaled # cross-compiles tailscaled for ARMv7 into Tailscale/lib/
make build # dotnet build → unsigned tpk
make pack # signs with the Samsung profile → Tailscale.signed.tpk
make install # sdb-installs onto $DEVICE
make run # launches the app
make install chains the previous steps, so make install run from
a clean checkout does everything end-to-end. Run make check-deps
first if you're not sure whether your environment is set up.
Connecting to the TV
~/tizen-studio/tools/sdb connect <TV_IP>
~/tizen-studio/tools/sdb devices
# emulator-26101 device UN65xxxxxxxx
sdb prints "failed to connect" even on a successful connection; ignore it and check
sdb devicesinstead.
If the TV is on a separate network and only reachable through some
tunnel, you'll need to terminate the tunnel locally and sdb connect
to a local port.
Using the app
Once installed, launch from the TV's Apps screen.
- Logged out view: pick Log in.
- The app asks tailscaled for a login URL, generates a QR code, and shows it. Scan with your phone (or open the URL on a laptop) to authenticate against your tailnet.
- Connected view: hostname, IPv4/IPv6, plus buttons for Disconnect, Advertise as exit node, Sign out, About.
Once "Advertise as exit node" is on, peers on your tailnet can pick the TV under their Exit nodes menu and route their traffic through it.
Privileges
The app requests:
http://tizen.org/privilege/internet-- to dial DERP and any exit-node-routed destinations.http://tizen.org/privilege/network.get-- to query interface info.
No raw sockets, no TUN, no root.
Repo layout
Tailscale/ .NET (NUI) Tizen TV app
├── Tailscale.csproj net6.0-tizen8.0
├── tizen-manifest.xml package id, privileges, app type
├── Program.cs UI, tailscaled subprocess, view transitions
├── LocalApi.cs HTTP-over-AF_UNIX client for tailscaled
├── lib/ cross-compiled tailscaled lands here at build (gitignored)
└── shared/res/ logo + icon assets
Makefile
NOTES.md
Limitations
- The app advertises the TV as an exit node but does not route the TV's apps' traffic through Tailscale. (Tizen's app sandbox doesn't grant the privileges that would require.)
- The app icon and login screen are minimal -- this is a starter version.
- Tested on a 32" Samsung Full HD F6000F TV running Tizen 8.0 (ARMv7). Other Samsung TV models in dev mode should work but are unverified.