|
20 | 20 |
|
21 | 21 | SSHC transforms your `~/.ssh/config` into a searchable, navigable interface — letting you connect to servers, transfer files, and manage hosts without memorizing hostnames or typing lengthy commands. |
22 | 22 |
|
23 | | -Built with Go and the [Charm](https://charm.sh) ecosystem for a fast, responsive experience that feels native to the terminal. |
| 23 | +Built with Go and the [Charm](https://charm.sh) ecosystem. Continuation of [sshm](https://github.com/Gu1llaum-3/sshm). |
24 | 24 |
|
25 | 25 | --- |
26 | 26 |
|
@@ -175,8 +175,242 @@ sshc update Check for and install updates |
175 | 175 |
|
176 | 176 | --- |
177 | 177 |
|
178 | | -## Cross-Platform |
| 178 | +## Usage |
179 | 179 |
|
180 | | -- macOS, Linux, Windows support |
| 180 | +### Interactive Mode |
| 181 | + |
| 182 | +Launch without arguments to enter the TUI: |
| 183 | + |
| 184 | +```bash |
| 185 | +sshc |
| 186 | +``` |
| 187 | + |
| 188 | +### Navigation |
| 189 | + |
| 190 | +``` |
| 191 | +up/down, j/k Navigate hosts |
| 192 | +enter Connect to selected host |
| 193 | +a Add new host |
| 194 | +e Edit selected host |
| 195 | +d Delete selected host |
| 196 | +m Move host to another config file |
| 197 | +f Port forwarding setup |
| 198 | +t File transfer |
| 199 | +/ Search/filter hosts |
| 200 | +s Switch sort mode (name/recent) |
| 201 | +n Sort by name |
| 202 | +r Sort by recent |
| 203 | +tab Cycle filter modes |
| 204 | +q Quit |
| 205 | +``` |
| 206 | + |
| 207 | +### Status Indicators |
| 208 | + |
| 209 | +- Green — host is reachable via SSH |
| 210 | +- Yellow — currently checking connectivity |
| 211 | +- Red — host is unreachable or connection failed |
| 212 | +- Gray — status not yet determined |
| 213 | + |
| 214 | +### Direct Connection |
| 215 | + |
| 216 | +Connect to any configured host without entering the TUI: |
| 217 | + |
| 218 | +```bash |
| 219 | +sshc production-server |
| 220 | +sshc db-staging |
| 221 | +sshc web-01 |
| 222 | +``` |
| 223 | + |
| 224 | +All direct connections are tracked in history. Use `-c` for custom config files: |
| 225 | + |
| 226 | +```bash |
| 227 | +sshc my-server -c /path/to/custom/ssh_config |
| 228 | +``` |
| 229 | + |
| 230 | +--- |
| 231 | + |
| 232 | +## Port Forwarding |
| 233 | + |
| 234 | +Press `f` while a host is selected to open the port forwarding interface. |
| 235 | + |
| 236 | +### Forward Types |
| 237 | + |
| 238 | +**Local (-L)** — forward a local port to a remote host through the SSH connection |
| 239 | + |
| 240 | +``` |
| 241 | +ssh -L 15432:localhost:5432 server |
| 242 | +# Database on remote localhost:5432 becomes accessible at localhost:15432 |
| 243 | +``` |
| 244 | + |
| 245 | +**Remote (-R)** — forward a remote port back to a local service |
| 246 | + |
| 247 | +``` |
| 248 | +ssh -R 8080:localhost:3000 server |
| 249 | +# Local app on port 3000 becomes accessible from remote host's port 8080 |
| 250 | +``` |
| 251 | + |
| 252 | +Requirements for external access: |
| 253 | +- SSH server config: `GatewayPorts yes` in `/etc/ssh/sshd_config` |
| 254 | +- Firewall: open the remote port |
| 255 | +- Bind address: use `0.0.0.0` for external, `127.0.0.1` for local-only |
| 256 | + |
| 257 | +**Dynamic (-D)** — create a SOCKS proxy |
| 258 | + |
| 259 | +``` |
| 260 | +ssh -D 1080 server |
| 261 | +# Configure browser to use localhost:1080 as SOCKS5 proxy |
| 262 | +``` |
| 263 | + |
| 264 | +### Port Forwarding History |
| 265 | + |
| 266 | +SSHC remembers forwarding configurations per host. Previously used setups appear as suggestions for quick reuse. |
| 267 | + |
| 268 | +--- |
| 269 | + |
| 270 | +## Configuration |
| 271 | + |
| 272 | +SSHC works directly with your `~/.ssh/config` file. Custom configs can be specified with `-c`: |
| 273 | + |
| 274 | +```bash |
| 275 | +sshc -c /path/to/config |
| 276 | +``` |
| 277 | + |
| 278 | +### SSH Include Support |
| 279 | + |
| 280 | +Organize configurations across multiple files: |
| 281 | + |
| 282 | +```ssh |
| 283 | +# ~/.ssh/config |
| 284 | +Include ~/.ssh/conf.d/* |
| 285 | +Include work-servers.conf |
| 286 | +
|
| 287 | +Host personal |
| 288 | + HostName personal.example.com |
| 289 | + User me |
| 290 | +``` |
| 291 | + |
| 292 | +The `move` command relocates hosts between included config files. |
| 293 | + |
| 294 | +### Supported SSH Options |
| 295 | + |
| 296 | +Built-in fields: |
| 297 | +- `HostName` — server address |
| 298 | +- `User` — SSH username |
| 299 | +- `Port` — SSH port |
| 300 | +- `IdentityFile` — path to private key |
| 301 | +- `ProxyJump` — jump host for tunneling |
| 302 | +- `Tags` — custom tags (SSHC extension) |
| 303 | + |
| 304 | +Any valid SSH option can be added through the forms. Enter in command-line format: |
| 305 | + |
| 306 | +``` |
| 307 | +-o Compression=yes -o ServerAliveInterval=60 |
| 308 | +``` |
| 309 | + |
| 310 | +This converts to: |
| 311 | + |
| 312 | +```ssh |
| 313 | + Compression yes |
| 314 | + ServerAliveInterval 60 |
| 315 | +``` |
| 316 | + |
| 317 | +Common options: `Compression`, `ServerAliveInterval`, `ServerAliveCountMax`, `StrictHostKeyChecking`, `UserKnownHostsFile`, `BatchMode`, `ConnectTimeout`, `ControlMaster`, `ControlPath`, `ControlPersist`, `ForwardAgent`, `LocalForward`, `RemoteForward`, `DynamicForward`. |
| 318 | + |
| 319 | +### Custom Key Bindings |
| 320 | + |
| 321 | +Configure in `~/.config/sshc/config.json`: |
| 322 | + |
| 323 | +```json |
| 324 | +{ |
| 325 | + "key_bindings": { |
| 326 | + "quit_keys": ["q", "ctrl+c"], |
| 327 | + "disable_esc_quit": true |
| 328 | + } |
| 329 | +} |
| 330 | +``` |
| 331 | + |
| 332 | +Set `disable_esc_quit` to `true` if you use vim and accidentally quit with ESC. |
| 333 | + |
| 334 | +### Data Storage |
| 335 | + |
| 336 | +``` |
| 337 | +~/.config/sshc/ |
| 338 | +├── config.json # preferences, keybindings |
| 339 | +├── history.json # connection history |
| 340 | +├── k8s.yaml # kubernetes hosts |
| 341 | +└── backups/ # automatic config backups |
| 342 | +``` |
| 343 | + |
| 344 | +Backups are created automatically before any configuration change. |
| 345 | + |
| 346 | +--- |
| 347 | + |
| 348 | +## Platform Notes |
| 349 | + |
| 350 | +**macOS / Linux** |
| 351 | +- Standard config: `~/.ssh/config` |
181 | 352 | - XDG Base Directory compliance on Linux |
182 | | -- Proper permissions — enforces 0600 for config, 0700 for directories |
| 353 | +- File permissions enforced (0600 config, 0700 directories) |
| 354 | + |
| 355 | +**Windows** |
| 356 | +- Works with built-in OpenSSH client (Windows 10/11) |
| 357 | +- Config location: `%USERPROFILE%\.ssh\config` |
| 358 | +- Compatible with WSL configurations |
| 359 | + |
| 360 | +--- |
| 361 | + |
| 362 | +## Building from Source |
| 363 | + |
| 364 | +```bash |
| 365 | +git clone https://github.com/xvertile/sshc.git |
| 366 | +cd sshc |
| 367 | +go build -o sshc . |
| 368 | +sudo mv sshc /usr/local/bin/ |
| 369 | +``` |
| 370 | + |
| 371 | +### Dependencies |
| 372 | + |
| 373 | +- [Cobra](https://github.com/spf13/cobra) — CLI framework |
| 374 | +- [Bubble Tea](https://github.com/charmbracelet/bubbletea) — TUI framework |
| 375 | +- [Bubbles](https://github.com/charmbracelet/bubbles) — TUI components |
| 376 | +- [Lip Gloss](https://github.com/charmbracelet/lipgloss) — styling |
| 377 | +- [x/crypto/ssh](https://golang.org/x/crypto/ssh) — SSH connectivity |
| 378 | + |
| 379 | +--- |
| 380 | + |
| 381 | +## Releases |
| 382 | + |
| 383 | +| Platform | Architecture | Download | |
| 384 | +|----------|--------------|----------| |
| 385 | +| Linux | AMD64 | [sshc-linux-amd64.tar.gz](https://github.com/xvertile/sshc/releases/latest/download/sshc-linux-amd64.tar.gz) | |
| 386 | +| Linux | ARM64 | [sshc-linux-arm64.tar.gz](https://github.com/xvertile/sshc/releases/latest/download/sshc-linux-arm64.tar.gz) | |
| 387 | +| macOS | Intel | [sshc-darwin-amd64.tar.gz](https://github.com/xvertile/sshc/releases/latest/download/sshc-darwin-amd64.tar.gz) | |
| 388 | +| macOS | Apple Silicon | [sshc-darwin-arm64.tar.gz](https://github.com/xvertile/sshc/releases/latest/download/sshc-darwin-arm64.tar.gz) | |
| 389 | +| Windows | AMD64 | [sshc-windows-amd64.zip](https://github.com/xvertile/sshc/releases/latest/download/sshc-windows-amd64.zip) | |
| 390 | +| Windows | ARM64 | [sshc-windows-arm64.zip](https://github.com/xvertile/sshc/releases/latest/download/sshc-windows-arm64.zip) | |
| 391 | + |
| 392 | +--- |
| 393 | + |
| 394 | +## Contributing |
| 395 | + |
| 396 | +1. Fork the repository |
| 397 | +2. Create a feature branch (`git checkout -b feature/new-feature`) |
| 398 | +3. Commit changes (`git commit -m 'Add new feature'`) |
| 399 | +4. Push to branch (`git push origin feature/new-feature`) |
| 400 | +5. Open a Pull Request |
| 401 | + |
| 402 | +--- |
| 403 | + |
| 404 | +## License |
| 405 | + |
| 406 | +MIT — see [LICENSE](LICENSE) for details. |
| 407 | + |
| 408 | +--- |
| 409 | + |
| 410 | +## Acknowledgments |
| 411 | + |
| 412 | +- [Charm](https://charm.sh/) for the TUI libraries |
| 413 | +- [Guillaume](https://github.com/Gu1llaum-3) for the original [sshm](https://github.com/Gu1llaum-3/sshm) |
| 414 | +- [yimeng](https://github.com/yimeng) for SSH Include directive support |
| 415 | +- [ldreux](https://github.com/ldreux) for multi-word search |
| 416 | +- [qingfengzxr](https://github.com/qingfengzxr) for custom key bindings |
0 commit comments