Chapter 2: Remote Access
Your Server is Useless If You Can't Reach It
You have a GPU server. Maybe it's sitting in a university lab, maybe it's a cloud instance, maybe it's a box under someone's desk that your advisor bought three years ago. It has GPUs. It can train models.
But you can only use it when you're sitting at your desk, SSH'd in from your laptop, on the campus network.
Your server is useless for 16 hours a day. Not because it's off — because you can't reach it.
That ends now.
By the end of this chapter, you'll SSH into your server from your phone, from anywhere in the world. Coffee shop. Airport. Your bed at midnight when you get a notification that training crashed. You'll open an app, tap your server, and you're in.
This is the foundation everything else builds on. No remote access, no autonomous research. Get this right first.
SSH Keys: Stop Typing Passwords
Every time you type a password to log into your server, you're doing it wrong. Passwords are slow, they're a security risk (shoulder surfing, keyloggers, reuse), and they make automation impossible. Claude Code can't type your password for you.
SSH keys fix all of this. You generate a key pair: a private key (stays on your machine, never shared) and a public key (goes on the server). When you connect, the math checks out, and you're in. No password prompt. Ever.
Generate your key pair
On your local machine (laptop/desktop):
ssh-keygen -t ed25519 -C "your-email@example.com"When it asks for a file location, press Enter to accept the default (~/.ssh/id_ed25519). When it asks for a passphrase, press Enter for no passphrase. Yes, no passphrase. You need unattended SSH for automation later — a passphrase-protected key will block every automated connection.
This creates two files:
~/.ssh/id_ed25519— your private key. Guard this with your life. Never copy it to a server. Never email it. Never commit it to git.~/.ssh/id_ed25519.pub— your public key. This one goes to the server.
Copy your public key to the server
ssh-copy-id your-username@your-serverThis is the last time you'll type your password. ssh-copy-id appends your public key to the server's ~/.ssh/authorized_keys file. From now on, the server recognizes your key and lets you in without a password.
Test it
ssh your-username@your-serverNo password prompt. You're in. If it still asks for a password, something went wrong — check that ~/.ssh/authorized_keys on the server has the right permissions (chmod 600) and that the ~/.ssh directory is chmod 700.
SSH Config: Never Type the Full Command Again
You just logged in with ssh your-username@your-server. That's already better than typing a password. But your server probably has a non-standard port, a long hostname, and a username you keep forgetting. Something like:
ssh jsmith@compute-node-7.cs.university.edu -p 2222 -i ~/.ssh/id_ed25519You are not typing that every time. You are not memorizing it. You are writing it down once and never thinking about it again.
Create your SSH config
Open ~/.ssh/config (create it if it doesn't exist):
nano ~/.ssh/configAdd your server:
Host lab-server
HostName your.server.ip
User your-username
Port 22
IdentityFile ~/.ssh/id_ed25519Save and close. Now test:
ssh lab-serverThat's it. Two words. ssh lab-server. This is what you'll type for the rest of your research career. The config handles the hostname, username, port, and key file.
What each line means
- Host — the alias you'll use. Pick something short.
lab,gpu1,cluster— whatever makes sense to you. - HostName — the actual IP address or domain name of the server.
- User — your username on the server.
- Port — the SSH port. Default is 22. Your server might use something different (common for shared clusters).
- IdentityFile — which private key to use. If you only have one key, SSH finds it automatically, but being explicit avoids confusion later.
Multiple servers
If you have multiple servers, add a block for each:
Host lab-server
HostName your.server.ip
User your-username
Port 22
IdentityFile ~/.ssh/id_ed25519
Host cloud-gpu
HostName another.server.ip
User ubuntu
Port 22
IdentityFile ~/.ssh/id_ed25519Now ssh lab-server and ssh cloud-gpu both work. No ambiguity, no typos, no forgotten port numbers.
Tailscale: Access Your Server from Anywhere
SSH keys and config are great — but they only work when you can reach the server's IP address. If your server is behind a university firewall, NAT, or VPN, you can't connect from outside the campus network. You're back to being chained to your desk.
Tailscale fixes this. It's a mesh VPN — think of it as a private network that connects all your devices, regardless of where they physically are. Your laptop at home, your server in the lab, your phone at a coffee shop — they all see each other as if they were on the same local network.
The key insight: Tailscale gives every device a stable IP address that works from anywhere. Your server gets a Tailscale IP (something like 100.x.y.z) that you can reach from any network in the world. No port forwarding, no firewall rules, no VPN client that drops every 30 minutes.
Install Tailscale on your local machine
Follow the instructions for your OS at https://tailscale.com/download. On Ubuntu:
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale upIt opens a browser for authentication. Log in with your Google/GitHub/Microsoft account. Done.
Install Tailscale on your server
SSH into your server and run the same commands:
ssh lab-server
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale upImportant: This requires sudo access on the server. If you're on a shared university cluster where you don't have root, you can't install Tailscale on the server side. Skip to the Termius section — you'll still be able to SSH from your phone through your local machine. But if you have a dedicated server or a cloud instance, install Tailscale. It's worth it.
Tailscale is free for personal use (up to 100 devices). You don't need a paid plan.
Verify the connection
On your local machine:
tailscale statusYou should see both your local machine and your server listed, each with a Tailscale IP. Test the connection:
ssh your-username@100.x.y.zReplace 100.x.y.z with your server's Tailscale IP from the status output.
Update your SSH config
Add the Tailscale IP as another Host entry (or replace your existing one):
Host lab-tailscale
HostName 100.x.y.z
User your-username
Port 22
IdentityFile ~/.ssh/id_ed25519Now you have two ways to reach your server: ssh lab-server (direct, for when you're on the same network) and ssh lab-tailscale (through Tailscale, for when you're anywhere else).
Why this matters for the phone
Look at the architecture diagram in the README again. See the bottom arrow — the one that goes directly from the phone to the GPU server, labeled "Tailscale mesh"?
That's what you just set up. Your phone can install Tailscale too. Which means your phone can directly SSH to the server, bypassing the local machine entirely. You don't need your laptop to be on, you don't need a relay. Phone to server, direct.
Install the Tailscale app on your phone (iOS App Store / Google Play Store). Log in with the same account. Your phone is now on the same mesh network as your server.
This becomes critical later when Claude Code is running on your local machine and you want to check on the server independently.
Termius: Your Server in Your Pocket
You can reach your server from anywhere now. But you're not going to open a laptop every time you want to check on training. You need SSH on your phone.
Termius is a mobile SSH client. It's clean, it's fast, and it handles SSH keys properly. Install it:
- iOS: App Store
- Android: Google Play
Free tier vs Pro
The free tier handles basic SSH connections. That's enough to follow this guide.
If you're a student: GitHub Education gives you Termius Premium for free. This adds SFTP, port forwarding, and synced SSH keys across devices. Apply with your university email — it takes a few days to verify, but it's worth it. Do it now and continue with the free tier while you wait.
Set up your server in Termius
- Open Termius. Tap Hosts → + (add new host).
- Set Alias to something memorable:
lab-server. - Set Hostname to your server's Tailscale IP (
100.x.y.z). If you don't have Tailscale, use your server's direct IP (this will only work on the same network). - Set Username to your server username.
- Under Keys, tap + to create or import a key:
- Option A (recommended): Generate a new key pair in Termius and copy the public key to your server's
~/.ssh/authorized_keys. - Option B: If you have Termius Premium, you can sync keys across devices.
- Option A (recommended): Generate a new key pair in Termius and copy the public key to your server's
- Save the host.
Connect
Tap your server. You're in.
You're looking at a terminal. On your phone. Connected to your GPU server. Run a command:
nvidia-smiThere are your GPUs. From your phone.
The Moment of Truth
You started this chapter able to reach your server only from your desk. Now you can reach it from anywhere on the planet.
Let's prove it. Put your laptop away. Pick up your phone.
- Open Termius.
- Tap your server.
- Wait for the connection.
- Type
nvidia-smiand hit Enter.
You should see something like:
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 550.xx.xx Driver Version: 550.xx.xx CUDA Version: 12.x |
|---------------------------------------+------------------------+------------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
|=======================================+========================+========================|
| 0 NVIDIA GeForce RTX ... On | 00000000:01:00.0 Off | N/A |
| 30% 35C P8 20W / 350W | 0MiB / 24564MiB | 0% Default |
+---------------------------------------+------------------------+------------------------+Those are your GPUs. Listed on your phone. From wherever you are right now.
Checkpoint
Open Termius on your phone. SSH into your server. Run
nvidia-smi. If you see your GPUs listed, you've unlocked remote access. You can now reach your server from anywhere in the world.
This is the foundation. Every chapter after this assumes you can reach your server from your phone. In the next chapter, you'll make sure your training sessions survive disconnection — because your phone's SSH session won't stay open forever, and it doesn't need to.