agentleFS
FrankieeWFrankieeW/agent-skills/ssh/SKILL.md

ssh

Skill0 starsChanged 8 months agoMITView on GitHub

SSH remote access patterns and utilities for connecting to servers, managing keys, configuring connections, creating tunnels, and transferring files.

  • Reads credentials

8 other projects use a version of this, 1 of them edited.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

13 rules. 0 are common, 10 are distinctive, and 3 are very specific to this project.

  • 0

    Common

    Most of the 5 edited versions we read keep these.

  • 10

    Distinctive

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Create or edit for easier connections:

    line 31
  2. Distinctive:

    Add key to agent:

    line 93
  3. Distinctive:

    Add with macOS keychain:

    line 98
  4. Distinctive:

    Run with pseudo-terminal (for interactive):

    line 120
  5. Distinctive:

    Remove old host key:

    line 234
  6. Distinctive:

    Test SSH config syntax:

    line 274
  7. Distinctive:

    Check SSH service status:

    line 279
  8. Distinctive:

    Use Ed25519 keys (faster, more secure than RSA)

    line 362
  9. Very specific:

    Use fail2ban to block brute force attempts

    line 364
  10. Distinctive:

    Keep keys encrypted with passphrases

    line 365
  11. Very specific:

    Use ssh-agent to avoid typing passphrase repeatedly

    line 366
  12. Distinctive:

    Always test new SSH config before restarting (keep session open)

    line 368
  13. Very specific:

    Use AllowUsers or AllowGroups to limit access

    line 369

“Common” is measured: kept by at least 6 in 10 of the 5 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

SSH Skill

Comprehensive SSH for secure remote access, file transfers, tunneling, and server hardening.

Basic Connection

Connect to server:

ssh user@hostname

Connect on specific port:

ssh -p 2222 user@hostname

Connect with specific identity:

ssh -i ~/.ssh/my_key user@hostname

SSH Config

Config file location: ~/.ssh/config

Create or edit for easier connections:

mkdir -p ~/.ssh
chmod 700 ~/.ssh
cat > ~/.ssh/config << 'EOF'
Host myserver
    HostName 192.168.1.100
    User deploy
    Port 22
    IdentityFile ~/.ssh/myserver_key
    ForwardAgent yes
    ServerAliveInterval 60
EOF
chmod 600 ~/.ssh/config

Then connect with just:

ssh myserver

Key Management

Generate new key (Ed25519, recommended):

ssh-keygen -t ed25519 -C "your_email@example.com"

Generate RSA key (legacy compatibility):

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

Copy public key to server:

ssh-copy-id user@host

Copy specific key:

ssh-copy-id -i ~/.ssh/mykey.pub user@host

Manual key copy:

# Display public key
cat ~/.ssh/id_ed25519.pub

# On server, as the user
mkdir -p ~/.ssh
chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys  # Paste public key
chmod 600 ~/.ssh/authorized_keys

SSH Agent

Start agent:

eval "$(ssh-agent -s)"

Add key to agent:

ssh-add ~/.ssh/id_ed25519

Add with macOS keychain:

ssh-add --apple-use-keychain ~/.ssh/id_ed25519

List loaded keys:

ssh-add -l

Running Remote Commands

Execute single command:

ssh user@host "ls -la /var/log"

Execute multiple commands:

ssh user@host "cd /app && git pull && pm2 restart all"

Run with pseudo-terminal (for interactive):

ssh -t user@host "htop"

File Transfer

SCP

Copy file to remote:

scp local.txt user@host:/remote/path/

Copy file from remote:

scp user@host:/remote/file.txt ./local/

Copy directory recursively:

scp -r ./local_dir user@host:/remote/path/

rsync (preferred)

Sync directory to remote:

rsync -avz ./local/ user@host:/remote/path/

Sync from remote:

rsync -avz user@host:/remote/path/ ./local/

With progress and compression:

rsync -avzP ./local/ user@host:/remote/path/

Dry run first:

rsync -avzn ./local/ user@host:/remote/path/

Port Forwarding (Tunnels)

Local Forward

Access remote service locally:

ssh -L 8080:localhost:80 user@host
# Now localhost:8080 connects to host's port 80

Forward to another host:

ssh -L 5432:db-server:5432 user@jumphost
# Access db-server:5432 via localhost:5432

Remote Forward

Expose local service to remote:

ssh -R 9000:localhost:3000 user@host
# Remote's port 9000 connects to your local 3000

Dynamic SOCKS Proxy

ssh -D 1080 user@host
# Use localhost:1080 as SOCKS5 proxy for network pivoting

Jump Hosts / Bastion

Connect through jump host:

ssh -J jumphost user@internal-server

Multiple jumps:

ssh -J jump1,jump2 user@internal-server

In config file:

Host internal
    HostName 10.0.0.50
    User deploy
    ProxyJump bastion

Multiplexing (Connection Sharing)

In ~/.ssh/config:

Host *
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 600

Create socket directory:

mkdir -p ~/.ssh/sockets

Known Hosts

Remove old host key:

ssh-keygen -R hostname

Scan and add host key:

ssh-keyscan hostname >> ~/.ssh/known_hosts

Common SSH Options

OptionDescription
-p PORTConnect to specific port
-XEnable X11 forwarding
-L local:remote:portLocal port forwarding
-R remote:local:portRemote port forwarding
-D portDynamic SOCKS proxy
-NDon't execute remote command (for tunnels)
-fRun in background
-vVerbose mode (use -vv, -vvv for more)

Debugging

Verbose output:

ssh -v user@host

Very verbose:

ssh -vv user@host

Maximum verbosity:

ssh -vvv user@host

Test SSH config syntax:

sudo sshd -t

Check SSH service status:

sudo systemctl status sshd

SSH Hardening (Server Side)

Create Non-Root User

# Create user
sudo adduser deployer

# Add to sudo group
sudo usermod -aG sudo deployer

# Test sudo access
su - deployer
sudo whoami  # Should output: root

Hardened sshd_config

Edit /etc/ssh/sshd_config:

# Disable root login
PermitRootLogin no

# Disable password authentication
PasswordAuthentication no

# Disable empty passwords
PermitEmptyPasswords no

# Limit authentication attempts
MaxAuthTries 3

# Allow specific users
AllowUsers deployer

# Use only SSH protocol 2
Protocol 2

# Disable X11 forwarding (unless needed)
X11Forwarding no

# Set login grace time
LoginGraceTime 60

# Disable host-based authentication
HostbasedAuthentication no

Optional Advanced Settings

# Change default port (reduces automated scanner noise)
Port 2222

# Disable agent forwarding
AllowAgentForwarding no

# Disable TCP forwarding (if not needed)
AllowTcpForwarding no

# Set idle timeout
ClientAliveInterval 300
ClientAliveCountMax 2

Test and Restart

# Test configuration
sudo sshd -t

# Restart SSH service
sudo systemctl restart sshd

Security Best Practices

  • Use Ed25519 keys (faster, more secure than RSA)
  • Set PasswordAuthentication no on production servers
  • Use fail2ban to block brute force attempts
  • Keep keys encrypted with passphrases
  • Use ssh-agent to avoid typing passphrase repeatedly
  • Restrict key usage with command= in authorized_keys
  • Always test new SSH config before restarting (keep session open)
  • Use AllowUsers or AllowGroups to limit access
  • Monitor authentication logs: /var/log/auth.log
  • Rotate SSH keys periodically

File Permissions

# Private key (MUST be 600)
chmod 600 ~/.ssh/id_ed25519

# Public key (can be 644)
chmod 644 ~/.ssh/id_ed25519.pub

# SSH directory
chmod 700 ~/.ssh

# Authorized keys
chmod 600 ~/.ssh/authorized_keys

# SSH config
chmod 600 ~/.ssh/config

Troubleshooting

IssueSolution
Connection refusedVerify SSH running; check firewall; confirm port
Auth failedCheck key permissions (600); verify authorized_keys format
Host key changedRemove old entry: ssh-keygen -R hostname
Tunnel not workingCheck GatewayPorts in sshd_config; verify firewall
Permission deniedCheck file permissions; verify user has access

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.