Deck 09 ยท the remote-control rig
Your desk, in your pocket.
Your phone becomes a real screen + keyboard + mouse for your Mac and Ubuntu box โ on the home WiFi, or from a coffee shop three cities away. Built from what the OS already ships, one free app, and (only off the home network) one mesh VPN. $0, no cloud in the control path, no ports opened to the internet.
macOS Screen Sharing
x11vnc
RealVNC Viewer
Tailscale / WireGuard
verified live
02 ยท the itch
Why would you want this? Four moments.
Not a workstation replacement โ occasional, light touches on real work, from wherever you already are.
๐๏ธ Mid-rest, an agent needs a nudge
Tap the phone, type "looks good, continue" โ it lands as a real keypress in the real terminal.
๐จ A build is running upstairs
Glance at the mirrored terminal. No SSH session to remember, no monitoring app.
๐ฌ A reply is worth sending now
Your normal phone keyboard โ glide typing, autocorrect, clipboard โ typing into Slack, email, a commit message.
โ๏ธ Another city entirely
The same saved entry still reaches home, through an encrypted tunnel. Zero router ports opened.
2
servers, mostly pre-installed
1
phone app, both machines
1
mesh VPN โ only off the LAN
03 ยท the route
Three parts. Each removes exactly one constraint.
Set up in order โ everything after Part 1 builds on Part 1 and never rebuilds it.
๐ถ
PART 1 ยท SAME NETWORK
Phone drives the desktop over home WiFi. Running today.
โโโบ
๐
PART 2 ยท THE INTERNET
Same rig from anywhere โ a re-addressing, not a rebuild.
โโโบ
โ๏ธ
PART 3 ยท DEEP DIVE
What's on the wire โ for when you want the why.
The one habit worth forming: one phone app โ RealVNC Viewer โ drives both machines. One saved entry per box (<ip>:5900), each with its own password. Two entries, one muscle memory.
04 ยท part 1 โ why VNC
"Why not just SSH?" SSH can't do this job.
SSH โ a parallel door into the basement
Drops you into a new text shell. Can't see the desktop you left running, can't click, can't type into open apps, can't fire shortcuts.
VNC โ a mirror plus a hand
Phone sees your apps, exactly as left. Every tap and keystroke is injected as a real input event โ indistinguishable from sitting at the keyboard.
the property everything rests onReal input events โ every app and every hotkey listener responds. That's why a phone can fire Super+A or dictate a commit message โ and why this rig is VNC-based, not SSH-based. (The gears, slide 18.)
05 ยท part 1 โ the Mac
The Mac half: the server is already installed.
- System Settings โ General โ Sharing โ Screen Sharing โ on. Keep it plain Screen Sharing, not Remote Management (RM serves the login window and typing into it drops focus).
- โ โ "VNC viewers may control screen with password" โ set that password. Without it, most phone clients fail to connect at all.
- Connect from the phone to <mac-ip>:5900 โ the VNC password, username blank. (Tested live.)
The macOS control path โ one toggle + a VNC password and every app responds as if you typed it. Click to zoom.
06 ยท part 1 โ Ubuntu
The Ubuntu half: one package, one command.
$ sudo apt install -y x11vnc
# find the real display number first: who โ "<user> :N <date>"
$ x11vnc -display :<N> -auth guess -usepw -shared -repeat -forever
The Ubuntu control path โ x11vnc turns the session you're already logged into into the server. Click to zoom.
the two flags that bite-shared (default off): without it, one stale half-open connection blocks every reconnect. -repeat (default off): without it, held keys repeat never โ one character per touch. Both earned by real failure.
07 ยท part 1 โ the phone
The phone half: one app, no account.
RealVNC Viewer, free. Standardized on for one reason that beats any feature list: it speaks the classic VNC auth both servers serve โ same app, same gestures, same saved list for the Mac and the Ubuntu box.
Verified live: a dual-monitor desktop, both screens in one session โ swipe to pan between them, pinch to zoom. Same story on the Mac and Ubuntu. Click to zoom.
read this before signing inRealVNC the company sells a cloud ecosystem โ accounts, device lists, "connect from anywhere". None of it is needed. The Viewer connects direct, machine-to-machine. Don't sign in; add an address, connect: <ip>:5900 + its VNC password.
08 ยท part 1 โ first drive
First drive: it feels like sitting down.
The moment it clicks โ you're on the couch, the desktop is upstairs, and neither of you notices the distance:
โจ๏ธ The nudge
Terminal mirrored on the phone. You type "looks good, continue" โ it lands as a real keypress in the real terminal, same as if you'd walked over.
๐ The glance
A build's mid-run upstairs? Pull up the phone, read the tail of the output, put it away. Nothing to reconnect, nothing to remember.
verified liveWindow switching, multi-key shortcuts, the full keyboard โ all from the phone, exactly as from the desk. The next four slides are the technique that makes it fewer taps, every time.
09 ยท part 1 โ gestures
Your fingers are the mouse: taps are clicks.
- One finger = left click. Two fingers at once = right-click. Three = middle click; double-tap-hold-drag = select text.
- Scroll = two-finger swipe โ a real wheel event. Pages, lists, editors scroll natively on both OSes; terminal scrollback works out of the box.
- Modifier keys are toggles, not holds. A touchscreen can't chord. Tap Ctrl in the toolbar (stays armed) โ tap the key โ the combo fires and releases. Stack Ctrl, Shift, then the key.
- Switch apps via the hot corner first. Tap the top-left pixel (GNOME) or a macOS hot corner โ window overview โ tap. One tap, no modifier.
- Right-click-heavy session? Pair a Bluetooth mouse โ its real right button just works. Gesture reference โ. Same plays in bVNC; its right-click is hold + second-finger tap.
10 ยท part 1 โ everyday moves
The moves you'll use every single day.
- Reopen a closed tab: arm Ctrl + Shift, tap T.
- Stop a runaway command: Ctrl toggle + c. Ctrl+C stops the program; Ctrl+D ends the shell โ neither touches the VNC session.
- Fix a line without arrows: Ctrl+A / Ctrl+E start/end, Ctrl+W delete word โ readline bindings work over VNC exactly like locally.
- Done? Just disconnect. The desktop keeps running; your session waits. Close a shell with exit when you actually mean it.
Switch terminals by keystroke โ use the desktop's window overview (hot corner or Alt+Tab) instead of hunting window thumbnails.
11 ยท part 1 โ personas
Same three mechanics, whoever you are.
Gestures, modifier toggles, the hot corner โ everything above reduces to those three. What changes is what you do with them:
๐ฉโ๐ป if you live in terminalsThe dev
Ctrl+Shift+C/V to copy-paste in terminals (the Shift is the tell), Ctrl+R history search, โ+Enter to rerun.
๐งญ if you're browsing, not buildingThe explorer
Pinch = client-side zoom on dense pages, three-finger tap = middle-click paste, Esc kills dialogs.
๐ฌ if it's media and messagesEveryone else
Keyboard autofill fills desktop passwords, the emoji panel sends real keystrokes, Space plays and pauses.
12 ยท part 1 โ cautions
Two cautions, both learned the annoying way.
caution 1 โ autocorrectAutocorrect + terminals don't mix. It will "fix" flags, paths, and git subcommands โ and keystrokes arrive already corrected, with no desktop-side guard to catch it. Disable it for the VNC app, or proofread before Enter.
caution 2 โ the cursorVoice typing lands wherever the cursor is. Check the focused window before you speak โ dictation commits instantly into whatever app owns the cursor.
One honesty note on voice: phone keyboards dictate through their maker's cloud speech service โ free and zero-setup, but not offline. Know which way that cuts before dictating anything sensitive.
13 ยท part 1 โ when it breaks
When it breaks: three symptoms cover most of it.
- Mac loops on "enter credentials" โ answer the VNC door: password only, username blank โ and the first 8 characters are the real password. (Why 8: slide 20.)
- Ubuntu says "connection refused" โ nothing is listening: pgrep -af x11vnc, then re-run and read the output โ usually the wrong display number.
- Worked yesterday, dead today โ DHCP re-leased the LAN IP: hostname -I / ipconfig getifaddr en0, update the saved entry โ or set a router reservation.
The full symptom โ fix table โ including the timeout-vs-refused tell and the Mac's three auth behaviors โ lives in the post's Reference section.
Read it here โ
the security line, in one breathKeep 5900 LAN-scoped, treat the VNC password as 8 characters effective, and never port-forward 5900 โ needing in from outside is Part 2's job.
14 ยท part 2 โ off the LAN
"Wait โ this only works on my WiFi." Fixable. Not by port-forwarding.
The 2010 advice fails silently on a large share of modern connections. Five minutes tells you which side you're on:
# 1 โ router admin panel: note its WAN IP
# 2 โ ask the internet what IP your desktop is seen as
$ curl ifconfig.me
# 3 โ compare: same โ real public IP, forwarding possible
# different, or WAN IP inside 100.64.0.0/10
# โ CGNAT: your ISP's shared NAT drops inbound, forever
CGNAT is standard now on many fiber and 5G connections โ your router's "public" side is itself private, inside the ISP's NAT layer. Everything on your side can be perfect and the packets still never arrive.
And even with a clean check โ don't, not raw VNC: classic VNC auth is a single shared 8-character password, and a correct guess drives your desktop. The real goal: put phone and desktop on one private network, wherever both physically are.
15 ยท part 2 โ the mesh VPN
Tailscale: your private network that follows the devices.
A mesh VPN built on WireGuard encryption. Install it, log in once โ every device gets a permanent private 100.x.y.z address (the "tailnet") that never changes when the device moves. The phone just dials that instead of the LAN IP.
Part 2 in one picture โ a networking-layer swap; the rig's software never learns a VPN exists. Click to zoom.
What actually changes: the address the phone dials (LAN IP โ tailnet IP), one ufw rule (100.64.0.0/10 instead of your subnet), and two small installs. x11vnc, Screen Sharing, the port, the password, the app โ all unchanged. A re-addressing, not a rebuild.
16 ยท part 2 โ trust
"Can I trust some company's VPN?" Here's the case.
the cryptoWireGuard's, not home-rolled
Formally verified primitives, end-to-end between your two devices only. The coordination server exchanges public keys โ relays carry ciphertext by construction.
the codeData-touching parts are open
Every client and even the relay code are on GitHub. The closed piece โ coordination โ sees metadata, never payloads.
the exitAudited, and exit-able
Recurring third-party audits, millions of daily users. If the trade-off ever stops being acceptable: Headscale, a self-hosted control plane, same clients.
E2E
encryption device-to-device
17 ยท part 2 โ the receipts
Not a diagram โ a live session.
mobile data
WiFi off, live session
direct
WireGuard path โ no relay
verified from cellularScreen updated, taps and keystrokes landed, every Part 1 skill carried over โ on a carrier network. Verify the interaction, not the connection: connect, hit the hot corner, open a terminal, type a line, fire a Ctrl+key combo. Anything stuttery โ tailscale status will say relay โ that's transport, not the rig.
The Mac's route ran live too โ through the DERP relay, the encrypted fallback (~125 ms, fully usable VNC): the one carrier round where no direct path was punchable. Honest edge: the escape hatches (SSH reverse tunnel, Headscale, Cloudflare Tunnel) remain untested on this rig.
18 ยท part 3 โ hotkeys
The deep dive's best trick: why shortcuts fire.
XTEST โ the X11 extension built for test automation, injecting at the server level, upstream of every app. Click to zoom.
- VNC keystrokes enter the X server's input stream โ dispatched exactly like the physical keyboard's: same keycodes, same grabs, same hotkey listeners.
- So terminals, the window manager, and every launcher see a real key event โ Super-shaped shortcuts included, all from the phone.
- SSH bytes go to one process's stdin โ nothing about them is a keyboard event as far as the OS is concerned.
19 ยท part 3 โ finding each other
Your phone and your desktop sit behind two different firewalls. How do they meet?
The rendezvous trick: both sides send at each other simultaneously โ each outbound packet opens a pinhole in its own firewall. Click to zoom.
the envelopeWireGuard
Each device pair shares keys; traffic is a sealed UDP envelope no relay can open.
the usual outcomeDirect path
Coordination tells each side the other's address; the simultaneous handshake connects them directly.
the fallbackDERP relay
When no direct path is punchable: encrypted packets relayed through Tailscale's servers. Slower by a hop, still ciphertext โ a post office, not a listener.
20 ยท part 3 โ the protocol
RFB โ the conversation every VNC session opens with.
RFC 6143 โ step 3 is where the 8-character cap lives. Click to zoom.
why 8 characters, mechanicallyClassic VNC auth is a DES challenge-response: the server sends a challenge; the client encrypts it with DES using the password itself as the key โ and DES keys are 8 bytes. Whatever you type past character 8 never enters the computation. Every classic-auth implementation inherits it โ macOS and x11vnc alike. Not a bug: the protocol wearing its age on its sleeve.
21 ยท after setup โ the daily loop
After the weekend: nothing to type.
The VPN runs as a service, the servers autostart, the firewall rule persists across reboots. What's left in a normal week:
start ยท only if you unloaded itMac server on
sudo launchctl load -w โฆ/screensharing.plist โ confirm with the port check. Phone: VPN toggle โ saved entry.
check ยท ten secondsMe or the rig?
tailscale status โ online? direct or relay? Then nc -vz <ip> 5900: refused = server off ยท timeout = path ยท succeeded = go.
stop ยท done for the dayClose things down
Phone: disconnect, VPN off (battery). Mac: the matching unload โ one line each direction, both survive reboots.
Ubuntu has no daily anything โ server, VPN, and firewall all persist on their own. The Mac's launchctl pair is the only on/off in the whole internet rig.
22 ยท the bill
What it actually costs: see for yourself.
2
OSes, served by built-ins
- No subscription โ free tiers throughout, nothing expires.
- No cloud in the control path โ connections are direct device-to-device, encrypted with your own keys.
- No ports opened to the internet โ the firewall rules only ever narrow.
- Honest edges โ escape hatches untested; relay rounds are usable but laggier (~125 ms).
23 ยท where this landed
Where this landed: a full second seat at the desk.
- Mac, on the LAN: RealVNC Viewer end to end โ window switching, multi-key shortcuts, voice typing โ through reboots and IP re-leases.
- Ubuntu, on the LAN: same standard handshake against x11vnc โ one app, two entries.
- Off the LAN, direct: phone on mobile data, ~66 ms, every Part 1 skill carried over unchanged.
- Off the LAN, relayed: the Mac driven over the DERP fallback โ observed live, not just diagrammed.
- Deliberately small: 2 servers you mostly already have + 1 phone app + 1 mesh VPN only off the LAN.
24 ยท build it
The couch is a valid place to get something done. So is another city.
Part 1 alone takes an evening and works on your home network today. The internet comes along later as one small install.