Setup secure web-based terminal access to WSL2 from mobile/tablet via ttyd + ngrok/Cloudflare/Tailscale. One-command install, start, stop, status. Use when you need remote terminal access, web terminal, browser-based shell, or mobile access to WSL2 environment.
66
80%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Fix and improve this skill with Tessl
tessl review fix ./.claude/skills/ttyd-remote-terminal-wsl2/SKILL.mdThe canonical home for this skill is ttyd-remote-terminal-wsl2 in fernandezbaptiste/Skrillz
Access your WSL2 terminal from any device (phone, tablet, remote computer) via secure web-based terminal using ttyd with ngrok, Cloudflare Tunnel, or Tailscale.
What This Skill Does:
When to Use This Skill:
When NOT to Use This Skill:
What You'll Get:
System Requirements:
User Requirements:
Not Required:
Get remote terminal access in <10 minutes:
cd ~/.claude/skills/ttyd-remote-terminal-wsl2/scripts
./install.shFollow prompts to:
./configure-auth.shThis generates a strong password and configures secure access.
./ttyd-start.shThis will:
Copy the URL and open in any browser (phone, tablet, etc.)
Open the displayed URL in browser → Login with displayed password → You now have terminal access!
./ttyd-stop.shDone! You now have working remote terminal access.
For detailed setup, troubleshooting, and advanced configuration, see the full workflow below.
This step installs ttyd and your chosen tunnel service. You only need to do this once.
cd ~/.claude/skills/ttyd-remote-terminal-wsl2/scripts
./install.shThe installer will:
ngrok - Best for beginners:
Cloudflare Tunnel - Best for production:
Tailscale - Best for private access:
Recommendation: Start with ngrok (easiest), migrate to Cloudflare Tunnel if you need more bandwidth.
After choosing tunnel service, you'll need to create free account and get auth token:
For ngrok:
ngrok config add-authtoken YOUR_TOKEN_HEREFor Cloudflare Tunnel:
cloudflared tunnel login)For Tailscale:
sudo tailscale up# Check ttyd installed
ttyd --version
# Check tunnel tool installed
ngrok version # or: cloudflared --version # or: tailscale versionTroubleshooting Installation:
Configure secure access with strong password. You only need to do this once.
cd ~/.claude/skills/ttyd-remote-terminal-wsl2/scripts
./configure-auth.shThis will:
~/.ttyd/.env with 600 permissionsThe script will display:
==================================================
ttyd Remote Terminal Credentials
==================================================
Username: myusername
Password: aB3$xK9#mL2@pQ7!
Store these credentials securely!
==================================================Save these credentials - you'll need them to login from browser.
Security Notes:
~/.ttyd/.env with restricted permissions (only you can read).env file to git./configure-auth.shTroubleshooting Authentication:
./configure-auth.sh to generate new one./configure-auth.sh --custom-passwordStart ttyd and tunnel, get connection URL. Do this each time you want remote access.
cd ~/.claude/skills/ttyd-remote-terminal-wsl2/scripts
./ttyd-start.shThe script will:
~/.ttyd/.envYou'll see output like this:
==================================================
ttyd Remote Terminal - CONNECTION READY
==================================================
🌐 Connection URL:
https://abc123.ngrok-free.app
🔐 Login Credentials:
Username: myusername
Password: aB3$xK9#mL2@pQ7!
📱 To connect from phone/tablet/browser:
1. Open the URL above in any browser
2. Login with username and password
3. You'll see your WSL2 terminal
⚠️ Security Warnings:
- Only share URL with trusted people
- URL is HTTPS encrypted
- Session is active until you stop it
- Remember to stop when done (saves data)
==================================================
Session running. Press Ctrl+C to stop (or use ./ttyd-stop.sh)Option 1: Keep terminal open (simplest)
Option 2: Run in background (advanced)
./ttyd-start.sh &
disownNow you can close terminal and ttyd keeps running.
Troubleshooting Start:
lsof -i :7681Use the connection URL from any device with browser.
On your phone, tablet, or remote computer:
You'll see HTTP Basic Auth prompt:
Click "Sign In" or "Login"
You now see your WSL2 terminal in browser!
What You Can Do:
Tips:
Example Commands to Try:
# Check you're in WSL2
uname -a
# Navigate your projects
cd ~/projects
ls -la
# Check resource usage
htop
# Run your development commands
npm run dev
python manage.py runserverTo disconnect (without stopping ttyd):
To fully stop (free up resources, data usage):
Stop ttyd and tunnel when you're done. This frees up resources and saves data (ngrok).
cd ~/.claude/skills/ttyd-remote-terminal-wsl2/scripts
./ttyd-stop.shThis will:
The script will show:
Stopping ttyd remote terminal session...
✓ Tunnel stopped
✓ ttyd stopped
Session ended successfully.Verify Nothing Running:
./ttyd-status.shShould show: ttyd is not running
Why Stop?:
Troubleshooting Stop:
ps aux | grep ttydpkill -9 ttyd && pkill -9 ngrokCheck if ttyd session is running and get connection info.
cd ~/.claude/skills/ttyd-remote-terminal-wsl2/scripts
./ttyd-status.shIf Running, you'll see:
==================================================
ttyd Remote Terminal - STATUS
==================================================
Status: RUNNING ✓
🌐 Connection URL:
https://abc123.ngrok-free.app
🔐 Login Credentials:
Username: myusername
Password: aB3$xK9#mL2@pQ7!
⏱️ Session Duration: 1 hour 23 minutes
📊 Resource Usage:
ttyd process: 15 MB
Tunnel process: 24 MB
To stop session: ./ttyd-stop.sh
==================================================If Stopped, you'll see:
==================================================
ttyd Remote Terminal - STATUS
==================================================
Status: NOT RUNNING
To start session: ./ttyd-start.sh
==================================================Check before starting: Avoid starting duplicate sessions
./ttyd-status.sh && ./ttyd-start.shGet URL when you forgot it: Status shows current URL
./ttyd-status.sh # Copy URL from outputCheck if forgotten session running: See if you left it running
./ttyd-status.sh # If running, consider stoppingMonitor session duration: See how long it's been running
watch -n 60 './ttyd-status.sh' # Update every minuteSecurity-First Design: This skill implements defense-in-depth security to protect your WSL2 environment.
✅ Authentication Required
✅ HTTPS Encryption
✅ Localhost Binding
✅ Secure Credential Storage
~/.ttyd/.env with 600 permissions✅ No Hardcoded Secrets
Do:
./ttyd-status.sh)Don't:
Protected Against:
Not Protected Against (out of scope):
⚠️ ngrok Free Tier Warning: ngrok free tier URLs are public (anyone with URL can access). However:
abc123xyz.ngrok-free.app)⚠️ WSL2 Firewall: If you have Windows Firewall enabled (you should), ttyd running on localhost is protected. If you modify scripts to bind to 0.0.0.0, ensure Windows Firewall blocks port 7681.
⚠️ Session Hijacking: If someone gets your URL + password, they can access your terminal. Treat these like SSH credentials.
For enhanced security, see Security Guide:
Error: ttyd: command not found
Fix:
# Reinstall ttyd
./install.shError: Address already in use (port 7681)
Fix:
# Find what's using port
lsof -i :7681
# Kill the process
kill <PID>
# Or use different port
TTYD_PORT=7682 ./ttyd-start.shngrok Error: authtoken not configured
Fix:
# Add your ngrok authtoken
ngrok config add-authtoken YOUR_TOKEN_HEREngrok Error: Bandwidth limit exceeded
Fix:
./install.sh # Choose Cloudflare TunnelCloudflare Error: not logged in
Fix:
cloudflared tunnel loginTailscale Error: not authenticated
Fix:
sudo tailscale upIssue: URL opens but shows "Unable to connect" Fix:
./ttyd-status.shpgrep ngrok (or cloudflared, tailscale)./ttyd-stop.sh && ./ttyd-start.shIssue: Authentication not working (wrong password) Fix:
# Reset password
./configure-auth.sh
# Get new credentials
./ttyd-status.shIssue: ngrok warning page (free tier) Fix:
Error in browser console: WebSocket connection failed
Fix:
./ttyd-status.sh./ttyd-start.shIssue: Commands feel laggy Fixes:
htop # Check CPU/memory not maxed outIssue: Terminal displays but keyboard input doesn't work
Cause: ttyd runs in readonly mode by default (security feature)
Fix: The ttyd-start.sh script now includes the --writable flag automatically.
If you're running ttyd manually, you MUST use the -W or --writable flag:
ttyd --writable --credential user:pass bashReferences:
-W to enable inputError: ./ttyd-start.sh: Permission denied
Fix:
# Make scripts executable
chmod +x ~/.claude/skills/ttyd-remote-terminal-wsl2/scripts/*.shDetailed Troubleshooting: See Troubleshooting Guide
Community Help:
Comprehensive guides for deeper understanding:
All automation scripts are in scripts/ directory:
./install.sh # Interactive installer for ttyd + tunnel
./install.sh --ngrok # Non-interactive: install with ngrok
./install.sh --cloudflare # Non-interactive: install with Cloudflare
./install.sh --tailscale # Non-interactive: install with Tailscale./configure-auth.sh # Interactive: generate password
./configure-auth.sh --custom-password # Interactive: use your password./ttyd-start.sh # Start ttyd + tunnel, display URL
./ttyd-stop.sh # Stop both gracefully
./ttyd-status.sh # Check status, show URL if running./health-check.sh # Verify installation and configurationConfiguration templates for advanced users:
File: templates/ttyd.service
For auto-start on WSL2 boot (requires systemd support):
# Copy template
cp templates/ttyd.service ~/.config/systemd/user/
# Enable auto-start
systemctl --user enable ttyd
systemctl --user start ttydFile: templates/.env.template
Example .env configuration (created automatically by configure-auth.sh):
TTYD_USER=myusername
TTYD_PASSWORD=strongpassword
TUNNEL_TYPE=ngrok
NGROK_AUTH_TOKEN=your_token_hereiOS: Save URL as Home Screen bookmark
Android: Save URL as Chrome shortcut
Want terminal AND web server accessible?
Use different ports:
# Terminal on 7681
TTYD_PORT=7681 ./ttyd-start.sh
# Another service on different port
ngrok http 8080 # Your web server# View ngrok dashboard
ngrok http 7681 --log stdout | grep -i "bytes"# One-liner restart
./ttyd-stop.sh && ./ttyd-start.sh# Use port 8080 instead of 7681
TTYD_PORT=8080 ./ttyd-start.shUnlike ngrok (URLs change each restart), Cloudflare Tunnel URLs persist:
# First time: creates persistent URL
cloudflared tunnel create ttyd-terminal
cloudflared tunnel route dns ttyd-terminal terminal.yourdomain.com
# Now this URL never changes
# https://terminal.yourdomain.comSee Tunneling Options Guide for details.
Resource Usage:
Network Latency (typical):
Bandwidth Usage (approximate):
ngrok Free Tier Data Budget:
When to use ttyd (this skill):
When to use code-server:
Can use both: Install both skills, use ttyd for quick tasks, code-server for serious coding.
After Setup:
Advanced Setup:
Explore More:
You've successfully setup remote terminal access when:
./ttyd-start.sh)./ttyd-stop.sh)./ttyd-status.sh)Congratulations! You now have secure remote terminal access to WSL2 from any device.
ttyd-remote-terminal-wsl2 - Secure web-based terminal access made simple.
Issue: Terminal shows "reconnect" button after being idle or switching apps on mobile
Cause: Mobile browsers suspend background tabs to save battery (by design)
Fix Applied: Aggressive 3-second ping interval (--ping-interval 3)
Understanding the Behavior:
Best Practices:
tmux new -s workReferences:
cat ~/.ttyd/CONNECTION-KEEPALIVE-GUIDE.mdNEW: ttyd now uses a persistent tmux session by default!
What this means:
How it works:
# The magic command (in ttyd-start.sh line 102)
tmux new -As ttyd-mobileThis creates a session called "ttyd-mobile" on first connection, and every subsequent connection attaches to the same session.
Example:
# Connection 1 (mobile):
cd /mnt/c/projects
echo "Working on project" > status.txt
# <close browser, go to sleep>
# Connection 2 (desktop, next morning):
pwd # Shows: /mnt/c/projects
cat status.txt # Shows: Working on project
# Exactly where you left off!Complete guide: cat ~/.ttyd/PERSISTENT-SESSION-GUIDE.md
93ed392
Canonical home
since Sep 12, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.