$npx -y skills add Dicklesworthstone/agent_flywheel_clawdbot_skills_and_integrations --skill sshSSH remote access patterns and utilities. Connect to servers, manage keys, tunnels, and transfers.
| 1 | # SSH Skill |
| 2 | |
| 3 | Use SSH for secure remote access, file transfers, and tunneling. |
| 4 | |
| 5 | ## Basic Connection |
| 6 | |
| 7 | Connect to server: |
| 8 | ```bash |
| 9 | ssh user@hostname |
| 10 | ``` |
| 11 | |
| 12 | Connect on specific port: |
| 13 | ```bash |
| 14 | ssh -p 2222 user@hostname |
| 15 | ``` |
| 16 | |
| 17 | Connect with specific identity: |
| 18 | ```bash |
| 19 | ssh -i ~/.ssh/my_key user@hostname |
| 20 | ``` |
| 21 | |
| 22 | ## SSH Config |
| 23 | |
| 24 | Config file location: |
| 25 | ``` |
| 26 | ~/.ssh/config |
| 27 | ``` |
| 28 | |
| 29 | Example config entry: |
| 30 | ``` |
| 31 | Host myserver |
| 32 | HostName 192.168.1.100 |
| 33 | User deploy |
| 34 | Port 22 |
| 35 | IdentityFile ~/.ssh/myserver_key |
| 36 | ForwardAgent yes |
| 37 | ``` |
| 38 | |
| 39 | Then connect with just: |
| 40 | ```bash |
| 41 | ssh myserver |
| 42 | ``` |
| 43 | |
| 44 | ## Running Remote Commands |
| 45 | |
| 46 | Execute single command: |
| 47 | ```bash |
| 48 | ssh user@host "ls -la /var/log" |
| 49 | ``` |
| 50 | |
| 51 | Execute multiple commands: |
| 52 | ```bash |
| 53 | ssh user@host "cd /app && git pull && pm2 restart all" |
| 54 | ``` |
| 55 | |
| 56 | Run with pseudo-terminal (for interactive): |
| 57 | ```bash |
| 58 | ssh -t user@host "htop" |
| 59 | ``` |
| 60 | |
| 61 | ## File Transfer with SCP |
| 62 | |
| 63 | Copy file to remote: |
| 64 | ```bash |
| 65 | scp local.txt user@host:/remote/path/ |
| 66 | ``` |
| 67 | |
| 68 | Copy file from remote: |
| 69 | ```bash |
| 70 | scp user@host:/remote/file.txt ./local/ |
| 71 | ``` |
| 72 | |
| 73 | Copy directory recursively: |
| 74 | ```bash |
| 75 | scp -r ./local_dir user@host:/remote/path/ |
| 76 | ``` |
| 77 | |
| 78 | ## File Transfer with rsync (preferred) |
| 79 | |
| 80 | Sync directory to remote: |
| 81 | ```bash |
| 82 | rsync -avz ./local/ user@host:/remote/path/ |
| 83 | ``` |
| 84 | |
| 85 | Sync from remote: |
| 86 | ```bash |
| 87 | rsync -avz user@host:/remote/path/ ./local/ |
| 88 | ``` |
| 89 | |
| 90 | With progress and compression: |
| 91 | ```bash |
| 92 | rsync -avzP ./local/ user@host:/remote/path/ |
| 93 | ``` |
| 94 | |
| 95 | Dry run first: |
| 96 | ```bash |
| 97 | rsync -avzn ./local/ user@host:/remote/path/ |
| 98 | ``` |
| 99 | |
| 100 | ## Port Forwarding (Tunnels) |
| 101 | |
| 102 | Local forward (access remote service locally): |
| 103 | ```bash |
| 104 | ssh -L 8080:localhost:80 user@host |
| 105 | # Now localhost:8080 connects to host's port 80 |
| 106 | ``` |
| 107 | |
| 108 | Local forward to another host: |
| 109 | ```bash |
| 110 | ssh -L 5432:db-server:5432 user@jumphost |
| 111 | # Access db-server:5432 via localhost:5432 |
| 112 | ``` |
| 113 | |
| 114 | Remote forward (expose local service to remote): |
| 115 | ```bash |
| 116 | ssh -R 9000:localhost:3000 user@host |
| 117 | # Remote's port 9000 connects to your local 3000 |
| 118 | ``` |
| 119 | |
| 120 | Dynamic SOCKS proxy: |
| 121 | ```bash |
| 122 | ssh -D 1080 user@host |
| 123 | # Use localhost:1080 as SOCKS5 proxy |
| 124 | ``` |
| 125 | |
| 126 | ## Jump Hosts / Bastion |
| 127 | |
| 128 | Connect through jump host: |
| 129 | ```bash |
| 130 | ssh -J jumphost user@internal-server |
| 131 | ``` |
| 132 | |
| 133 | Multiple jumps: |
| 134 | ```bash |
| 135 | ssh -J jump1,jump2 user@internal-server |
| 136 | ``` |
| 137 | |
| 138 | In config file: |
| 139 | ``` |
| 140 | Host internal |
| 141 | HostName 10.0.0.50 |
| 142 | User deploy |
| 143 | ProxyJump bastion |
| 144 | ``` |
| 145 | |
| 146 | ## Key Management |
| 147 | |
| 148 | Generate new key (Ed25519, recommended): |
| 149 | ```bash |
| 150 | ssh-keygen -t ed25519 -C "your_email@example.com" |
| 151 | ``` |
| 152 | |
| 153 | Generate RSA key (legacy compatibility): |
| 154 | ```bash |
| 155 | ssh-keygen -t rsa -b 4096 -C "your_email@example.com" |
| 156 | ``` |
| 157 | |
| 158 | Copy public key to server: |
| 159 | ```bash |
| 160 | ssh-copy-id user@host |
| 161 | ``` |
| 162 | |
| 163 | Copy specific key: |
| 164 | ```bash |
| 165 | ssh-copy-id -i ~/.ssh/mykey.pub user@host |
| 166 | ``` |
| 167 | |
| 168 | ## SSH Agent |
| 169 | |
| 170 | Start agent: |
| 171 | ```bash |
| 172 | eval "$(ssh-agent -s)" |
| 173 | ``` |
| 174 | |
| 175 | Add key to agent: |
| 176 | ```bash |
| 177 | ssh-add ~/.ssh/id_ed25519 |
| 178 | ``` |
| 179 | |
| 180 | Add with macOS keychain: |
| 181 | ```bash |
| 182 | ssh-add --apple-use-keychain ~/.ssh/id_ed25519 |
| 183 | ``` |
| 184 | |
| 185 | List loaded keys: |
| 186 | ```bash |
| 187 | ssh-add -l |
| 188 | ``` |
| 189 | |
| 190 | ## Multiplexing (Connection Sharing) |
| 191 | |
| 192 | In ~/.ssh/config: |
| 193 | ``` |
| 194 | Host * |
| 195 | ControlMaster auto |
| 196 | ControlPath ~/.ssh/sockets/%r@%h-%p |
| 197 | ControlPersist 600 |
| 198 | ``` |
| 199 | |
| 200 | Create socket directory: |
| 201 | ```bash |
| 202 | mkdir -p ~/.ssh/sockets |
| 203 | ``` |
| 204 | |
| 205 | ## Known Hosts |
| 206 | |
| 207 | Remove old host key: |
| 208 | ```bash |
| 209 | ssh-keygen -R hostname |
| 210 | ``` |
| 211 | |
| 212 | Scan and add host key: |
| 213 | ```bash |
| 214 | ssh-keyscan hostname >> ~/.ssh/known_hosts |
| 215 | ``` |
| 216 | |
| 217 | ## Debugging |
| 218 | |
| 219 | Verbose output: |
| 220 | ```bash |
| 221 | ssh -v user@host |
| 222 | ``` |
| 223 | |
| 224 | Very verbose: |
| 225 | ```bash |
| 226 | ssh -vv user@host |
| 227 | ``` |
| 228 | |
| 229 | Maximum verbosity: |
| 230 | ```bash |
| 231 | ssh -vvv user@host |
| 232 | ``` |
| 233 | |
| 234 | ## Security Tips |
| 235 | |
| 236 | - Use Ed25519 keys (faster, more secure than RSA) |
| 237 | - Set `PasswordAuthentication no` on servers |
| 238 | - Use `fail2ban` on servers to block brute force |
| 239 | - Keep keys encrypted with passphrases |
| 240 | - Use `ssh-agent` to avoid typing passphrase repeatedly |
| 241 | - Restrict key usage with `command=` in authorized_keys |