Bootstrap Checklist: From Current State to Remote Server¶
Prerequisites (already done)¶
- Windows 11 installed on remote PC
- Tailscale installed as Windows app, authenticated
- WSL2 Ubuntu installed, user
admincreated -
wsl.exeshell works interactively on the PC
Phase 1: Configure on the PC (interactive, one-time)¶
These steps must be done while physically at the PC (or via remote desktop).
Step 1.1: Configure WSL2 settings¶
Inside WSL2 -- edit /etc/wsl.conf:
sudo tee /etc/wsl.conf <<'EOF'
[boot]
systemd = true
command = service ssh start
[network]
generateResolvConf = false
EOF
Create static DNS:
sudo rm -f /etc/resolv.conf
sudo tee /etc/resolv.conf <<'EOF'
nameserver 1.1.1.1
nameserver 8.8.8.8
EOF
Step 1.2: Configure .wslconfig¶
On Windows -- create/edit %UserProfile%\.wslconfig:
[general]
instanceIdleTimeout = -1
[wsl2]
vmIdleTimeout = -1
networkingMode = mirrored
[experimental]
autoMemoryReclaim = disabled
Apply: wsl --shutdown from PowerShell, then restart WSL.
Step 1.3: Install and configure SSH¶
sudo apt update && sudo apt install -y openssh-server
sudo systemctl enable ssh
sudo systemctl start ssh
Edit /etc/ssh/sshd_config:
Port 22
ListenAddress 0.0.0.0
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication yes # temporarily, for key deployment
Restart: sudo systemctl restart ssh
Step 1.4: Deploy SSH public key¶
Generate on your home machine:
Copy ~/.ssh/wsl_ubuntu.pub content to the PC (USB, email, whatever), then
on the WSL2 instance:
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo "<paste pubkey here>" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
Step 1.5: Configure firewalls¶
From PowerShell (admin):
# Windows Firewall
New-NetFirewallRule -DisplayName "WSL2 SSH via Tailscale" `
-Direction Inbound -Protocol TCP -LocalPort 22 `
-Action Allow -RemoteAddress 100.64.0.0/10
# Hyper-V Firewall (mirrored mode)
New-NetFirewallHyperVRule -Name "WSL-SSH" -Direction Inbound `
-VMCreatorId '{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}' `
-Protocol TCP -LocalPorts 22 -Action Allow
Disable Windows OpenSSH server if present:
Stop-Service sshd -ErrorAction SilentlyContinue
Set-Service -Name sshd -StartupType Disabled -ErrorAction SilentlyContinue
Step 1.6: Set up auto-start¶
Task Scheduler at logon (PowerShell admin):
$action = New-ScheduledTaskAction -Execute "C:\Windows\System32\wsl.exe" `
-Argument "-d Ubuntu"
$trigger = New-ScheduledTaskTrigger -AtLogOn
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries `
-DontStopIfGoingOnBatteries -ExecutionTimeLimit ([TimeSpan]::Zero)
Register-ScheduledTask -TaskName "WSL2-AutoStart" -Action $action `
-Trigger $trigger -Settings $settings -RunLevel Highest
Optionally configure Windows auto-login (so WSL starts after unattended reboots).
Step 1.7: Test from home (before leaving)¶
From your home machine:
If it works, harden SSH:
# On WSL2:
sudo sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo systemctl restart ssh
Test again with key auth to confirm lockdown.
Phase 2: Remote provisioning (over SSH from home)¶
Once SSH works, everything below can be done remotely.
Step 2.1: Passwordless sudo¶
echo "admin ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/admin
sudo chmod 440 /etc/sudoers.d/admin
Step 2.2: System updates¶
Step 2.3: CUDA toolkit (if needed)¶
See cuda-setup.md.
Step 2.4: Python / ML environment (if needed)¶
See ml-workloads.md.
Step 2.5: Docker (if needed)¶
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker admin
# Re-login for group membership
For GPU containers, see ml-workloads.md Docker section.
Phase 3: Verify everything survives reboot¶
Ask someone at the PC to reboot Windows (or use Tailscale + RDP if available). After reboot:
- Confirm Tailscale reconnects (check admin console).
- Confirm WSL2 starts (Task Scheduler + auto-login).
- Confirm SSH works:
ssh wsl-dev. - Confirm GPU:
nvidia-smi.
Fallback: If Mirrored Mode Fails¶
If SSH is unreachable after Step 1.2, switch to NAT mode + portproxy:
- Remove
networkingMode = mirroredfrom.wslconfig. wsl --shutdownand restart.- Set up portproxy -- see port-forwarding.md.