Workflow and scope
This tutorial runs Sunshine on Ubuntu 24.04 Desktop so a Mac can control the existing desktop through official Moonlight. Validate streaming on the same LAN first, then add Tailscale if access across networks is needed.
The baseline assumes a single user who can already log into Ubuntu's graphical desktop, an available display output and someone at the host to approve initial pairing. Sunshine's user service does not create a graphical login session. Headless operation or access after a reboot before login needs a separate design.
| Main task | Recommended approach |
|---|---|
| Animated GUIs, browsers, 3D or the full desktop | Sunshine + Moonlight; validate the existing GPU and desktop first |
| Coding Agent commands and file access | Use SSH for execution and recovery, with Moonlight for viewing the GUI |
| Editing on Mac and running programs on Ubuntu | SSH + VS Code Remote SSH can be the primary workflow |
| Remote login immediately after boot | Evaluate Ubuntu 24.04 Remote Login separately |
Seven implementation corrections
The source report checked the original article. These corrections affect installation, pairing and validation.
| Item | Finding | Action |
|---|---|---|
| Old DEB filename | sunshine-ubuntu-24.04-amd64.deb does not match this release's naming | Use the pinned asset containing the version, Ubuntu version and architecture; verify SHA-256 |
| PIN direction | Moonlight displays the PIN | Enter those digits on Sunshine's PIN page |
| Built-in VNC on Ubuntu 24.04 | Ubuntu removed built-in VNC in 22.10 | The native GNOME remote desktop path needs an RDP client; Mac VNC Screen Sharing cannot connect directly |
| RDP performance comparison | No tests use identical hardware, networks and workloads, so there is no basis for claiming Sunshine is universally faster | Choose according to motion or office work; GNOME RDP hardware acceleration improvements in Ubuntu 26.04 do not automatically apply to 24.04 |
| NVIDIA assessment | A successful nvidia-smi only shows communication with the driver | Use the existing GPU and check capture, hardware encoding logs and Mac decoding before buying a graphics card |
| Tailscale path | Connections can use direct, DERP relay or peer-relay paths | Check the actual path with tailscale ping and tailscale status |
| Automatic startup | Enabling a service does not provide an unattended desktop | Validate logged-in use, reconnection and operation after reboot before login separately |
Version and maintenance snapshot
Release dates use the official UTC dates. The verification date uses Asia/Taipei.
| Component | Pinned baseline | Release date | Selection and limits |
|---|---|---|---|
| Sunshine | v2026.914.233613 | 2026-09-15 | Official Ubuntu 24.04 amd64 / arm64 DEB, including the Linux security fix |
| Moonlight PC / Qt | v6.2.0 | 2026-10-04 | Official macOS Universal build; adds AV1 hardware decoding on M3 and newer Macs; both ends must support the selected codec |
| Tailscale | v1.104.1 | 2026-10-07 | GitHub stable snapshot; macOS release channels may differ, so record the actual installed version |
Do not downgrade a newer installation. Check the official release, Ubuntu 24.04 assets, migration notes and security advisories before updating the version record. New packages require their matching filenames and hashes.
Recent Sunshine changes address Portal capture, Linux encoding and network bind addresses. Moonlight 6.2 changes the default renderer on Mac. Recent commits show maintenance activity, but do not guarantee compatibility with every GPU.
The Moonlight macOS Enhanced release API returned v1.3.9-rc.5, released on 2026-10-13, at verification time. GitHub did not mark it as a prerelease, but its version contains RC and its release notes explicitly describe a prerelease and an architecture rebuild, so it is only a candidate for testing. The latest five commits share an author, which is insufficient to determine how many people maintain the project.
Capture, encoding and latency
| Stage | Location and function |
|---|---|
| Desktop capture | Ubuntu captures the screen through backends such as Portal or KMS |
| Video encoding | Ubuntu encodes through backends such as NVENC, VAAPI or Vulkan |
| Network transport | Video and audio travel to the Mac; keyboard and mouse input returns to Ubuntu |
| Decoding and display | The Mac decodes and displays the stream; applications still run on Ubuntu |
capture = portal and encoder = nvenc can be used together because capture and encoding are separate layers. GNOME and KDE have different capture options, so do not copy a kwin setting without checking or treat NvFBC as a general Wayland capture method. Older configuration documentation omitted Portal; see the official documentation correction PR.
Interactive latency includes input, host processing and capture, encoding, networking, decoding and display. A frame at 60 FPS takes about 16.7 ms; this is not the full click-to-display latency. Moonlight's component statistics are not an end-to-end measurement either.
Alternatives and selection criteria
| Tool | Suitable tasks | Limits to check first |
|---|---|---|
| Sunshine + Moonlight | A single GPU desktop with continuous motion | Needs a capturable desktop and display output; does not provide file synchronization or independent desktops for multiple users |
| GNOME Remote Desktop + RDP | Office work and native Remote Login | Distinguish Desktop Sharing from Remote Login and check the actual ports; use an RDP client on Mac |
| RustDesk | Remote support | 1.5.0 includes Wayland, input and login-screen fixes; test login-screen and package compatibility in the actual environment |
| OpenSSH + VS Code Remote SSH | Editing on Mac and running programs and tools on Ubuntu | Does not provide a full desktop |
Tailscale is the networking layer and cannot replace a remote desktop tool. Do not rank these tools by performance without measurements under the same conditions.
Prerequisites
- Not completed:
Ubuntu 24.04 Desktop supports normal login, and the single desktop user has the required installation permissions.
- Not completed:
The host has an available display output, and someone can approve Portal access during initial setup.
- Not completed:
Both computers are initially on the same LAN, and the correct Ubuntu IP is known.
- Not completed:
The Mac model, macOS version and CPU architecture are recorded; Homebrew cask 6.2.0 requires macOS 13 or later.
- Not completed:
Ubuntu has
curl, valid CA certificates andapt; install only missing required tools. - Not completed:
Existing Sunshine settings and service overrides are backed up; pairing keys must not enter public documents or Git.
- Not completed:
Local login or an existing SSH recovery path is available, and active work can be saved before a restart.
Ubuntu environment inventory
Connect and turn on a display, then run these commands in the Ubuntu graphical desktop's terminal. An SSH session type does not identify the graphical desktop type. When inventorying over SSH, use loginctl to find the actual graphical session.
cat /etc/os-release
dpkg --print-architecture
uname -r
printf 'Session=%s Desktop=%s\n' "$XDG_SESSION_TYPE" "$XDG_CURRENT_DESKTOP"
lspci -nnk
hostname -IFor NVIDIA, you can also run nvidia-smi to record the GPU and driver. For Intel / AMD, you can install and run vainfo:
sudo apt install vainfo
vainfoVAEntrypointEncSlice or VAEntrypointEncSliceLP indicates encoding capability, which still needs confirmation through Sunshine logs and an actual stream. If an NVIDIA driver is missing, check Ubuntu Software & Updates > Additional Drivers first and assess compatibility and restart requirements.
Pinned version installation
Check the existing version with dpkg-query -W sunshine; the query may report no package if Sunshine is not installed. If a newer stable version is already installed, do not run the older pinned installation block below. Check the installed version against official documentation instead.
This block applies only to Ubuntu 24.04. It selects the official amd64 / arm64 DEB and passes it to apt only after checksum verification succeeds.
(
set -eu
. /etc/os-release
if [ "$ID" != ubuntu ] || [ "$VERSION_ID" != 24.04 ]; then
echo '此段只適用 Ubuntu 24.04,請改用對應發行版套件。' >&2
exit 1
fi
SUN_ARCH="$(dpkg --print-architecture)"
case "$SUN_ARCH" in
amd64) SUN_SHA='c38e9c705f650f8705f61702717e99bec34044c5028fcb8f23a08fe041292c21' ;;
arm64) SUN_SHA='5751c22cf0b9253b459d7f42103f1c422594363a5881e21bd1ce845218226888' ;;
*) echo "未涵蓋的架構:$SUN_ARCH" >&2; exit 1 ;;
esac
SUN_WORK="$(mktemp -d)"
cd "$SUN_WORK"
curl --fail --location --proto '=https' --tlsv1.2 \
-o sunshine.deb \
"https://github.com/LizardByte/Sunshine/releases/download/v2026.914.233613/sunshine_2026.914.233613-1%2Bubuntu24.04_${SUN_ARCH}.deb"
printf '%s sunshine.deb\n' "$SUN_SHA" | sha256sum --check -
sudo apt update
sudo apt install ./sunshine.deb
)Record the package version after installation:
dpkg-query -W sunshinePrefer the native package when an official matching DEB is available. Flatpak and AppImage handle capture and permissions differently; do not mix installations. Official prebuilt packages usually do not require a separate CUDA Toolkit installation.
User service and desktop capture
Run as the Ubuntu desktop user. Do not launch the long-running service from a sudo shell:
systemctl --user start app-dev.lizardbyte.app.Sunshine
systemctl --user status app-dev.lizardbyte.app.Sunshine --no-pager
journalctl --user -u app-dev.lizardbyte.app.Sunshine -b -n 100 --no-pagerOpen https://localhost:47990 in Ubuntu's browser and create separate management credentials. The default certificate is self-signed; confirm that the destination is the local Sunshine instance before continuing.
On GNOME Wayland, observe the automatic capture selection first; if needed, select Portal in the Web UI and approve screen sharing or Remote Desktop on the host. Leave encoding on automatic initially and check the actual backend in the logs. An active service confirms only that its process is running.
If the Mac can already connect to Ubuntu through SSH, create this tunnel on the Mac. Replace the account and IP first, keep the terminal connection open, then open the same localhost URL in the Mac browser.
ssh -N -o ExitOnForwardFailure=yes -L 127.0.0.1:47990:127.0.0.1:47990 ubuntu_user@UBUNTU_IPThe Mac's localhost normally refers to the Mac. The SSH tunnel above forwards that port to Ubuntu. If the host is headless and no one can approve Portal, first choose Remote Login, a virtual display or another headless arrangement.
Mac installation and pairing
Download the macOS Universal DMG from the official v6.2.0 release and move Moonlight.app into Applications. If Homebrew is already installed, its cask is an option; check the current macOS requirement and version before installation:
brew install --cask moonlightManually add Ubuntu's LAN IP in Moonlight.
When Moonlight displays a PIN, enter those digits on the Sunshine Web UI PIN page.
Open Desktop. If it is absent, create a Desktop entry in Sunshine Applications with no launch command to stream the existing desktop.
Check the picture, keyboard, mouse, scrolling, Traditional Chinese input and audio.
Mac Command differs from Ubuntu Ctrl / Super. Record how shortcuts and the host input method behave.
Streaming performance baseline
| Setting | Initial value |
|---|---|
| Resolution | 1920×1080 |
| Frame rate | 60 FPS |
| Codec | H.264 |
| Bitrate | 20 Mbps |
| Color | SDR |
| Other options | Keep defaults |
20 Mbps is an engineering test starting point, not the best value for every network. The host display resolution must match or be compatible. Changing Moonlight's resolution does not necessarily change Ubuntu's actual display output.
Use the desktop continuously for 10 minutes and record Moonlight statistics, usually available through Ctrl + Alt / Option + Shift + S. After the baseline passes, change one setting at a time, such as 1440p, HEVC, bitrate, V-sync, renderer or frame rate.
For blurry text, check resolution, scaling, chroma subsampling and codec before increasing bitrate. Do not assume Macs older than M3 support the newly added AV1 hardware decoding. Test the actual workload separately when AI computation also uses the GPU.
Tailscale access across networks
Complete LAN validation before adding Tailscale as needed. On Ubuntu, download and read the official installer first:
curl --fail --location https://tailscale.com/install.sh -o /tmp/tailscale-install.sh
less /tmp/tailscale-install.shAfter review, press q to exit less, then install and log in:
sh /tmp/tailscale-install.sh
sudo tailscale up
tailscale version
tailscale ip -4On Mac, follow the official macOS installation guide. Join both computers to the same authorized tailnet, with the user completing login, MFA and system network extension approval. Record the actual version at each end.
Manually add Ubuntu's Tailscale IPv4 in Moonlight. Run the following on Ubuntu to check the path to the Mac, replacing the peer name or IP first:
tailscale ping MAC_TAILNET_NAME_OR_IP
tailscale status| Path | Meaning |
|---|---|
| direct | A direct connection between endpoints |
| relay / DERP | Traffic passes through a Tailscale relay |
| peer-relay | Traffic passes through a peer relay within the tailnet |
The initial packets may travel through DERP before the connection becomes direct. If it stays relayed and performance is poor, lower the bitrate first and check the network, host upload capacity and dropped frames.
Disable Sunshine UPnP, do not enable Tailscale Funnel, and do not forward streaming ports or management port 47990 to the public internet. If a connection is blocked, check tailnet grants / ACLs, service listening addresses and the host firewall separately.
Automatic startup and login
Enable automatic startup of the user service only after the preceding tests pass:
systemctl --user enable app-dev.lizardbyte.app.SunshineTest reconnection after a disconnect, reconnection after a service restart, then logout and login. Before testing a host reboot, save active work and confirm local login or an SSH recovery path. Do not run a separate manual Sunshine process at the same time.
A user service does not create a graphical desktop before login. loginctl enable-linger does not replace graphical login either. Do not automatically enable autologin, disable the lock screen or modify GRUB to make the test pass.
Moonlight-compatible ports and firewall
| Function | Protocol and ports | Scope |
|---|---|---|
| Streaming control | TCP 47984, 47989, 48010 | Required client sources |
| Streaming data | UDP 47998, 47999, 48000, 48002, 48010 | Required client sources |
| LAN discovery | UDP 5353 | LAN; manually entering an IP avoids discovery |
| Sunshine Web UI | TCP 47990 | localhost or an existing SSH tunnel |
Check these Moonlight-compatible ports against Sunshine's actual listeners and any custom base port setting; not every UDP port necessarily listens continuously. The Tailscale baseline uses manually entered IPs and does not require mDNS across networks. Do not expose the Web UI directly to the entire network.
Use the following example only when UFW is already enabled and confirmed to be blocking the connection. Review existing rules first, then replace MAC_LAN_IP with the Mac's actual LAN IP:
sudo ufw status numbered
MAC_IP="MAC_LAN_IP"After replacing the value, add rules that allow only that source:
sudo ufw allow from "$MAC_IP" to any port 47984,47989,48010 proto tcp
sudo ufw allow from "$MAC_IP" to any port 47998,47999,48000,48002,48010 proto udpDo not reset or disable the existing firewall, or enable UFW on a remote host without checking the consequences. Verify Tailscale netfilter behavior and grants / ACLs separately; do not assume UFW covers all tailnet traffic. Roll back only the rules added in this setup.
Troubleshooting and permission limits
| Symptom | Evidence to check first | Corrective action |
|---|---|---|
| Audio without video | Graphical session, display, Portal and encoder logs | Restore capture prerequisites before changing drivers or GRUB |
| Portal fails after changing the display | Saved token or missing-stream logs | Confirm the cause, use Web UI → Troubleshooting → Reset XDG Portal Capture, then approve access again on the host |
| Video without working input | uinput and the package's udev rules | Follow official documentation to repair or reload rules, or log in again; do not make the device writable by every user |
| High CPU use or persistent dropped frames | Whether a software encoder is actually in use | Check hardware encoding logs for NVENC / VAAPI or the selected backend |
| LAN works but remote performance is poor | Tailscale path, upload bandwidth and network frame drops | Compare direct / relay state before adjusting bitrate |
| Cannot connect after reboot | Sleep, login, display output and approval state | Recover through existing SSH or locally; design unattended operation separately |
| Blurry text | Resolution, scaling, chroma subsampling and codec | Match display settings first; coding work can use a Mac editor + SSH |
Completion checks
These are this tutorial's engineering thresholds, not vendor performance guarantees. Leave untested items unchecked and record pass, fail, blocked or not-tested in the deliverables.
- Not completed:
Record Ubuntu / Mac versions, CPU architecture, GPU / driver and graphical session.
- Not completed:
LAN pairing succeeds, with picture, keyboard, mouse, Traditional Chinese input and audio checked.
- Not completed:
Logs confirm hardware encoding; software-only encoding does not pass the target performance acceptance.
- Not completed:
Operate at 1080p60 continuously for 10 minutes without a black screen, a recovery restart or persistent dropped frames.
- Not completed:
FPS during motion testing is close to the configured rate; target network frame drops below 1%, or mark unmeasured when there is no counter.
- Not completed:
Reconnection, service restart and login each have a separate result.
- Not completed:
If access across networks is in scope, record direct / peer-relay / relay and subjective observations from a different network.
- Not completed:
No public port forwarding, UPnP or Funnel is enabled; recovery remains available and changes can be rolled back.
Community reports and trial conditions
| Report | Available information | Limits on conclusions |
|---|---|---|
| Moonlight #1929, 2026-07 | macOS mouse latency discussion, including subjective improvements with Enhanced and maintainer replies on input and display paths | Not a general benchmark; compare on identical hardware, network and resolution when testing |
| Sunshine #5020, 2026-04 to 2026-08 | Vulkan artifact reports include Ubuntu 24.04 | Closure as stale does not establish a fix; retain an NVENC / VAAPI baseline |
| RustDesk #15417 and 1.5.0 | DRM / KMS, unattended operation, Wayland and login-screen improvements | Actual hardware, package and login state still need testing |
The source report did not recommend an official skill dedicated to maintaining this combination. The Agent Action below includes inventory, execution, acceptance and rollback requirements; no additional MCP or third-party skill is needed first.
Agent Action specification
Use this copyable specification after the user authorizes an Agent to configure the target computers. Reading the tutorial does not execute system commands.
Verification date: 2026-10-16 (Asia/Taipei). This specification can be used independently.
Goal and context
Deploy Sunshine on an Ubuntu 24.04 Desktop host so a Mac can control its existing desktop with Moonlight. First validate 1080p / 60 FPS / SDR streaming on the same LAN, then add Tailscale for access across networks if needed. If the primary workload is a Coding Agent, retain SSH for task execution and recovery, and use Moonlight to view the GUI.
The user has not yet supplied the GPU model, Ubuntu IP, login account, Mac model, macOS version or headless status. Inventory what is available from the authorized target environment first; do not treat the Agent's cloud work container as the user's Ubuntu host. Without a target connection, complete the installation plan and pending scripts, mark the task blocked and ask the user for a target connection method without claiming deployment is complete.
The baseline assumes a single user, an Ubuntu graphical desktop that already supports normal login, an available display output and someone at the host to approve initial pairing. If operation must begin after reboot before login, unattended and without a display, redesign the login and display arrangement first. The standard desktop workflow does not resolve that requirement.
Selected tools and versions
Release dates below use the official UTC dates; the verification date uses Asia/Taipei.
| Component | Verified baseline | Execution rule |
|---|---|---|
| Ubuntu | 24.04 Desktop | Keep the existing OS; do not upgrade the distribution for streaming |
| Sunshine | v2026.914.233613, released 2026-09-15 | Official native DEB, selected for amd64 / arm64 |
| Moonlight PC / Qt | v6.2.0, released 2026-10-04 | Official macOS Universal DMG |
| Tailscale | GitHub stable v1.104.1, released 2026-10-07 | Install when access across networks is needed; record the actual versions on both ends, since platform releases may differ |
| GPU driver | No assumed version | Check the actual GPU, Ubuntu package and Sunshine logs; successful nvidia-smi does not pass NVENC validation |
Recheck official stable releases and security advisories before execution. If a newer stable release exists, verify its Ubuntu 24.04 assets, migration notes and checksums before use, and update versions.md; do not apply the old checksums below to new files. Do not automatically downgrade a newer existing installation.
Do not use nightly builds, beta releases or forks of unknown origin. This Sunshine baseline fixes GHSA-fp6g-27w5-489j.
Execution order
Inventory and backup
Read the management rules that apply to the target project or machine. Confirm where each step runs on Ubuntu or Mac and which permissions it needs.
In the Ubuntu graphical user's terminal, collect the OS, architecture, GPU, driver, Wayland/X11, display output, current network and firewall. XDG_SESSION_TYPE in an SSH session does not identify the graphical desktop type; use loginctl to find the actual graphical session.
On Mac, collect
sw_vers,uname -mand existing Moonlight/Tailscale versions.If Sunshine is installed, identify its source, version, systemd user unit, configuration directory and capture backend. Back up the configuration and required service overrides. Backups contain pairing keys: restrict permissions and keep them out of public reports and Git.
List missing prerequisites. Do not install an entire desktop, change the display manager or blindly install NVIDIA drivers on an unidentified GPU.
For NVIDIA CUDA / NVFBC capture or direct GPU-memory NVENC, check the pinned CUDA compatibility table: the verified documentation lists CUDA 13.1.1 and minimum driver 590.48.01. If the driver is older, identify a supported path first. A successful nvidia-smi is not proof of compatibility; do not upgrade the driver automatically.
Install Sunshine
Use the official DEB by default. Check that the target has curl, CA certificates and apt; install required tools only if missing.
The following block installs the report's baseline version reproducibly. Confirm that no newer version is already installed before running it.
(
set -eu
. /etc/os-release
if [ "$ID" != ubuntu ] || [ "$VERSION_ID" != 24.04 ]; then
echo '此段只適用 Ubuntu 24.04,請改用對應發行版套件。' >&2
exit 1
fi
SUN_ARCH="$(dpkg --print-architecture)"
case "$SUN_ARCH" in
amd64) SUN_SHA='c38e9c705f650f8705f61702717e99bec34044c5028fcb8f23a08fe041292c21' ;;
arm64) SUN_SHA='5751c22cf0b9253b459d7f42103f1c422594363a5881e21bd1ce845218226888' ;;
*) echo "未涵蓋的架構:$SUN_ARCH" >&2; exit 1 ;;
esac
SUN_WORK="$(mktemp -d)"
cd "$SUN_WORK"
curl --fail --location --proto '=https' --tlsv1.2 \
-o sunshine.deb \
"https://github.com/LizardByte/Sunshine/releases/download/v2026.914.233613/sunshine_2026.914.233613-1%2Bubuntu24.04_${SUN_ARCH}.deb"
printf '%s sunshine.deb\n' "$SUN_SHA" | sha256sum --check -
sudo apt update
sudo apt install ./sunshine.deb
)Record the version with
dpkg-query -W sunshine. Official prebuilt packages usually do not require a separate CUDA Toolkit installation; investigate GPU issues through actual logs.
Graphical session, service and capture
Start the user service as the Ubuntu desktop user:
systemctl --user start app-dev.lizardbyte.app.Sunshine
systemctl --user status app-dev.lizardbyte.app.Sunshine --no-pager
journalctl --user -u app-dev.lizardbyte.app.Sunshine -b -n 100 --no-pagerOn GNOME Wayland, observe automatic selection first. If needed, select XDG Portal capture in the Web UI and approve Remote Desktop / screen sharing on the host. Keep the backend roles distinct:
portalhandles capture, whilenvenc/vaapi/vulkanhandle encoding.Let the application choose the initial encoder. If it selects software or encounters compatibility issues, try NVENC or VAAPI according to the GPU. Do not force Vulkan merely because it is newer.
Confirm hardware encoding in the actual logs. An active service proves only that the process exists, not that streaming works.
Do not run Sunshine as root long term, use
chmod 666 /dev/uinput, or copy an old tutorial to add cap_sys_admin manually. The official DEB installation script itself sets cap_sys_admin,cap_sys_nice+p; that differs from adding permissions manually. For input failures, check the package's udev rules first; repair permissions according to official documentation only when evidence shows the need, and record changes.
Mac installation and LAN pairing
Download the official v6.2.0 macOS Universal DMG and move Moonlight.app into Applications. If Homebrew is already available, its cask is an option, but check the installed version and current macOS requirements.
Open
https://localhost:47990on Ubuntu and create separate management credentials. For management from Mac, use an existing SSH connection to forward to Ubuntu localhost. Mac localhost does not refer to Ubuntu.Manually add Ubuntu's LAN IP in Moonlight. Moonlight displays the PIN; enter it on the Sunshine Web UI PIN page. Do not include management passwords or pairing-state files in the deliverables.
Test the Desktop entry. If absent, create a Desktop application with no launch command to stream the existing desktop.
Start with 1920×1080, 60 FPS, H.264, 20 Mbps and SDR, leaving other defaults unchanged. These are test starting values, not official optimum settings.
Test the mouse, English and Traditional Chinese input, scrolling and audio. Record differences between the host input method and Mac shortcuts.
Networking and Tailscale when access across networks is needed
Pass LAN validation first. Install official Tailscale on both ends and join the same authorized tailnet. The user completes login, MFA and system network extension approval.
Use the official Linux installation method on Ubuntu and the official macOS package on Mac. Record versions and the Ubuntu Tailscale IPv4.
Manually add Ubuntu's Tailscale IP in Moonlight. Use
tailscale ping <對端名稱或IP>andtailscale statusto confirm whether the eventual path is direct, peer-relay or DERP relay. Initial packets over DERP do not establish that the connection remains relayed.Do not enable Tailscale Funnel or Sunshine UPnP, or forward management or streaming ports to the public internet. Keep the existing firewall running.
If a connection is blocked, check tailnet grants/ACL, the OS firewall and service addresses first. Use the current official compatible port table, actual listeners and custom base port setting to add only the minimum rules for required sources. Do not rewrite the entire tailnet policy or assume UFW rules cover all Tailscale netfilter behavior.
For Sunshine management from Mac, prefer localhost port forwarding through existing SSH. Do not change origin_web_ui_allowed to wan to expose the management UI.
Tuning, reconnection and restarts
Save the 1080p60 baseline, then change only one setting at a time: resolution, bitrate, codec or frame rate. Measure the real workload, particularly when AI computation also occupies the GPU.
Use Moonlight statistics to record FPS, network frame drops, decoding time and jitter when displayed. These values do not measure full click-to-display end-to-end latency.
Enable
systemctl --user enable app-dev.lizardbyte.app.Sunshineonly after validation passes. Avoid a second process from a separate manual sunshine launch.Before a restart test, confirm that the user's work is saved and a login or recovery path exists. Test reconnection after a service restart, availability after logging in again and availability after host reboot before login separately. The last case is outside the baseline commitment by default.
Neither enable nor loginctl enable-linger creates a graphical desktop. Do not automatically enable autologin, disable the lock screen or modify GRUB.
Acceptance criteria
- Not completed:
Record the target OS, CPU architecture, GPU/driver, Mac model and versions at both ends.
- Not completed:
LAN pairing works, Desktop displays a picture, mouse and keyboard work, and Chinese input and audio are checked.
- Not completed:
Logs confirm hardware encoding. If only software encoding is available, mark target performance acceptance as failed.
- Not completed:
Operate at 1080p60 continuously for 10 minutes without a black screen, a recovery restart or persistent dropped frames, and record actual statistics and network conditions. The 10 minutes and following figures are engineering thresholds for this task, not official performance promises: FPS should stay close to the configured rate during smooth motion testing, with a target of network frame drops below 1%. Mark unmeasured if the relevant counter is unavailable.
- Not completed:
Reconnection succeeds after a disconnect and after a service restart. Document login-state and display-state limits.
- Not completed:
If access across networks is in scope, test from a different network and record direct / peer-relay / relay. A relayed connection can pass functional acceptance, but needs separate performance acceptance.
- Not completed:
Public port forwarding and UPnP/Funnel are disabled. Keep existing SSH / recovery access, and make configuration changes reversible.
Required deliverables
environment.md: Actual environment and missing prerequisites; exclude sensitive IPs and accounts from the public version.versions.md: Versions, official download URLs, SHA-256 and verification date.setup-log.md: Executed steps, changed files and service state; do not record passwords, keys or authorization tokens.validation.md: Per-item pass/fail/blocked/not-tested, measured values, test date and session state. Do not mark untested items successful.rollback.md: Reverse only this setup's changes: stop or disable the service introduced here, restore settings and remove added rules. Do not remove preexisting software or tailnet settings, or downgrade to a version with known vulnerabilities.
Proceed with authorized inventory, installation and reversible fixes. Pause only for actions that would interrupt work, change core login or security arrangements, or require user interaction, and explain the specific reason. This specification authorizes remote desktop setup, not hardware purchases, changes to account privileges or a full OS upgrade.
Official and verification sources
Pinned Sunshine release: https://github.com/LizardByte/Sunshine/releases/tag/v2026.914.233613
Sunshine installation: https://docs.lizardbyte.dev/projects/sunshine/latest/md_docs_2getting__started.html
Sunshine troubleshooting: https://docs.lizardbyte.dev/projects/sunshine/latest/md_docs_2troubleshooting.html
Linux security fix: https://github.com/LizardByte/Sunshine/security/advisories/GHSA-fp6g-27w5-489j
Moonlight pairing and ports: https://github.com/moonlight-stream/moonlight-docs/wiki/Setup-Guide
Tailscale connection types: https://tailscale.com/docs/reference/connection-types
Remote SSH: https://code.visualstudio.com/docs/remote/ssh
Sources and verification limits
This page adapts the complete source report, retaining the seven corrections, seven setup steps, troubleshooting and full Agent Action. Verification date: 2026-10-16 (Asia/Taipei). Pinned versions, asset hashes, service names, pairing and ports were also checked against official sources.
Official releases and APIs determine versions; community reports describe only their reported environments. The reader's GPU, network, display and Mac have not been tested. Example thresholds are not measured performance results.
References
- Moonlight macOS Enhanced
- Sunshine
- Moonlight
- GNOME Remote Desktop
- RustDesk
- OpenSSH
- VS Code Remote SSH
- Moonlight v6.2.0 release
- Tailscale macOS installation
- Original article published 2026-10-16
- Sunshine v2026.914.233613 release
- Sunshine installation and service setup
- Sunshine troubleshooting: Portal, input, encoding and networking
- Ubuntu Remote Desktop test plan
- Tailscale connection types and diagnostics
- Sunshine Linux security advisory GHSA-fp6g-27w5-489j
- Sunshine release API: Ubuntu 24.04 assets and SHA-256
- Moonlight Setup Guide: pairing and ports
- Homebrew Moonlight cask: version and macOS requirements
- Tailscale Linux installation
- Tailscale v1.104.1
- RustDesk v1.5.0 release
- RustDesk DRM/KMS discussion #15417
- Enhanced release API: v1.3.9-rc.5 snapshot
- Moonlight macOS mouse latency issue #1929
- Sunshine Vulkan artifacts issue #5020
- Sunshine Portal documentation PR #5938
- Ubuntu 26.04 LTS: GNOME remote desktop hardware acceleration
- Recent Sunshine commits
- Recent Moonlight commits
- Recent Enhanced commits
- Sunshine pinned CUDA compatibility and installation guide