English | 中文
Cross-platform CLI for VPS SSH — from IP + password to
ssh my-vpsin minutes, using only standard~/.ssh/config.
Setting up passwordless SSH on a new VPS usually means juggling ssh-keygen, uploading public keys, and hand-editing ~/.ssh/config. fuckssh walks you through that in an interactive wizard — or in one non-interactive command for scripts.
It reads and writes standard OpenSSH files only. No proprietary formats, no lock-in. Uninstall fuckssh and everything still works with ssh, VS Code Remote SSH, Tabby, and any OpenSSH-compatible tool.
- About
- Features
- Use cases
- Prerequisites
- Installation
- Quick start
- Command reference
- Examples
- Design principles
- Roadmap
- Development
- Documentation
- Contributing
- License
- One-stop setup —
addpassword mode: generate Ed25519 key, deploy public key, write config; key mode: write config for an existing private key - Script-friendly —
add -H <ip> -P <pass>for non-interactive setup; tests connectivity before writing any files - Manage hosts —
list/search/edit/deletefor the full host lifecycle - Encrypted migration —
export/importto move config and private keys across machines (Argon2id + AES-256-GCM) - Safe by default — auto-backup before every config write; passwords used only for the initial connection, never stored in plaintext
- Standard files only — no proprietary config format; uninstall and your setup still works
- Cross-platform — Windows, macOS, Linux; English and Chinese UI (
FUCKSSH_LANGor language selection on first run) - Terminal-native — Bubble Tea TUI wizard and table output
New VPS — passwordless login in one session
fuckssh add
ssh myserverScript or automation — non-interactive add
fuckssh add -H 1.2.3.4 -u root -P mypass -a myserver
ssh myserverMigrate to a new laptop
# On the old machine
fuckssh export ~/Desktop
# Copy fuckssh-backup-*.tar.enc to the new machine, then:
fuckssh import fuckssh-backup-20260616-102739.tar.encFind a host quickly
fuckssh search prod
fuckssh search --user root --port 2222 web- OpenSSH client (
sshin PATH) — required foraddand connectivity tests - Writable
~/.ssh/directory - Go 1.22+ — only if building from source
macOS / Linux (requires curl, installs to ~/.local/bin):
curl -fsSL https://raw.githubusercontent.com/hczs/fuckssh/master/scripts/install.sh | shPin a version: curl -fsSL .../install.sh | sh -s -- --version v0.6.0
Windows (PowerShell):
irm https://raw.githubusercontent.com/hczs/fuckssh/master/scripts/install.ps1 | iexThe script checks your PATH and guides you if ~/.local/bin (or %USERPROFILE%\.local\bin on Windows) isn't included. After installation, a fs alias is ready:
fs ls # same as fuckssh list
fs a # same as fuckssh add
fs s prod # same as fuckssh search prodDownload from GitHub Releases and put fuckssh in your PATH.
| Platform | Example artifact |
|---|---|
| Linux x86_64 / arm64 | fuckssh_linux_x86_64.tar.gz, fuckssh_linux_arm64.tar.gz |
| macOS Intel | fuckssh_macos_x86_64.tar.gz |
| macOS Apple Silicon | fuckssh_macos_arm64.tar.gz |
| macOS Universal | fuckssh_macos_all.tar.gz (Intel + Apple Silicon) |
| Windows | fuckssh_windows_x86_64.zip |
Requires Go 1.22+:
go install github.com/fuckssh/fuckssh@latestSee Development.
fuckssh add
ssh <your-alias>For more scenarios, see Use cases.
| Command | Short | Description |
|---|---|---|
fuckssh add |
a |
Interactive wizard: password mode (generate key + deploy pubkey + write config) or key mode (write config only) |
fuckssh add -H <ip> -P <pass> |
— | Non-interactive: one-line setup (-H triggers; -u user, -p port, -a alias, -i identity file, -r remark) |
fuckssh list |
ls |
Parse and display all Hosts in a table; multiple aliases shown comma-separated |
fuckssh search <query> |
s |
Multi-keyword OR search; --user/--host/--port filters; highlighted results in TTY |
fuckssh edit <alias> |
e |
Interactive edit of an existing Host (pre-filled, supports "go back and revise" retry) |
fuckssh delete <alias> |
d |
Delete Host with confirmation; removes managed IdentityFile keys too |
fuckssh export [dir] |
— | Pack ~/.ssh/config and private keys into an encrypted .tar.enc backup |
fuckssh import <file> |
— | Decrypt and merge backup; interactive conflict resolution (overwrite / skip / rename) |
fuckssh version |
v |
Show version, commit, and build date (injected via ldflags in release builds) |
Global options
| Option | Description |
|---|---|
-h, --help |
Help (English and Chinese supported) |
--version |
Print version information |
Command options
| Option | Commands | Description |
|---|---|---|
-H, --host |
add | Target host address (triggers non-interactive mode) |
-u, --user |
add | Login user (default: root) |
-p, --port |
add | SSH port (default: 22) |
-P, --password |
add | SSH password (triggers password mode) |
-i, --identity-file |
add | Private key path (triggers key mode) |
-a, --alias |
add | Host alias (auto-generated from address if omitted) |
-r, --remark |
add | Remark / note |
--user |
search | Filter by username |
--host |
search | Filter by host address |
--port |
search | Filter by port |
-f, --force |
delete | Skip confirmation prompt |
$ fuckssh add
Enter VPS details:
> Address: 1.2.3.4
Port: 22
User: root
Alias: myserver
✓ Key pair generated
✓ Public key deployed to 1.2.3.4
✓ Written to ~/.ssh/config
ssh myserver$ fuckssh add -H 1.2.3.4 -u root -P mypass -a myserver
✓ Connection test passed
✓ Key pair generated
✓ Public key deployed to 1.2.3.4
✓ Written to ~/.ssh/config
ssh myserver
Completed in 3.2s$ fuckssh ls
Reading: /home/user/.ssh/config
3 hosts found
┌──────────────┬───────────────┬──────┬────────┬──────────────┐
│ Alias │ Address │ Port │ User │ Remark │
├──────────────┼───────────────┼──────┼────────┼──────────────┤
│ myserver │ 1.2.3.4 │ 22 │ root │ Production │
│ dev │ 10.0.0.1 │ 22 │ ubuntu │ Dev machine │
│ staging │ 172.16.0.5 │ 2222 │ admin │ Staging │
└──────────────┴───────────────┴──────┴────────┴──────────────┘$ fuckssh s prod
Search: prod — 1 match
┌──────────────┬───────────────┬──────┬────────┬──────────────┐
│ Alias │ Address │ Port │ User │ Remark │
├──────────────┼───────────────┼──────┼────────┼──────────────┤
│ myserver │ 1.2.3.4 │ 22 │ root │ Production │
└──────────────┴───────────────┴──────┴────────┴──────────────┘$ fuckssh e myserver
Edit VPS details (Enter to keep current value):
> Alias: myserver
Address: 1.2.3.4
Port: 2222 ← changed
User: root
✓ ~/.ssh/config updated
ssh myserver$ fuckssh d myserver
Delete myserver (root@1.2.3.4)? [y/N] y
✓ Deleted myserver
✓ Removed managed key /home/user/.ssh/keys/id_ed25519_myserver$ fuckssh export ~/Desktop
请设置主密码(至少 6 位,不能纯数字):
主密码: ********
确认密码: ********
正在导出...
✓ 导出成功
文件: /home/user/Desktop/fuckssh-backup-20260616-102739.tar.enc
大小: 4096 字节
包含: 3 个 Host 配置, 2 个私钥
请将此文件拷贝到目标机器,然后运行:
fuckssh import fuckssh-backup-20260616-102739.tar.encNo conflicts:
$ fuckssh import fuckssh-backup-20260616-102739.tar.enc
请输入主密码: ********
正在解密...
✓ 发现 3 个 Host 配置,无冲突
✓ 导入完成With conflicts:
$ fuckssh import fuckssh-backup-20260616-102739.tar.enc
请输入主密码: ********
正在解密...
✓ 发现 3 个 Host 配置,其中 1 个与现有配置冲突:
[myserver] root@1.2.3.4:22
[1] 覆盖 [2] 跳过 [3] 重命名
> 3
新别名: myserver-new
✓ 导入完成(新增 2,覆盖 0,重命名 1,跳过 0)$ fuckssh v
v0.6.0 (abc1234, 2026-06-16)- Standard-first — Reads and writes OpenSSH conventions. Uninstall fuckssh and your config still works.
- Recoverable — Backs up config before every write (
~/.ssh/backup/); import also backs up existing config before merging. - CLI-native — Built for developers who live in the terminal and VS Code Remote SSH. Complements GUI clients, doesn't replace them.
- Portable —
export/importfor moving hosts and keys to a new machine. Backup files are written with mode0600; keep them safe if you store them on a sync drive.
| Phase | Capabilities |
|---|---|
| Shipped | add (interactive + non-interactive) / list / search / edit / delete / export / import / version / short aliases |
| Next | Include directive expansion, --json output, custom config path |
Prerequisites:
- Go 1.22+
- golangci-lint (for local linting and pre-commit)
goimports:go install golang.org/x/tools/cmd/goimports@latest
git clone https://github.com/hczs/fuckssh.git
cd fuckssh
make build # compile to bin/fuckssh
make test # go test ./...
make lint # golangci-lint
make fmt # gofmt + goimports
make run # go run ./cmd/fuckssh
make hooks # enable pre-commit (auto fmt + lint on staged .go files)After cloning, run make hooks once. Every git commit will then auto-format and lint staged .go files.
Push a v* tag (e.g. v0.6.0) to trigger the Release workflow — GoReleaser builds and publishes to GitHub Releases. Dry run locally: make release-dry.
| Trigger | Workflow | Description |
|---|---|---|
push / PR → main / master |
CI | Test, lint, cross-platform build check |
| Doc | Description |
|---|---|
| PRD | Product requirements & scenarios |
| Tech Selection | Tech stack & module breakdown |
| Architecture | System architecture (HTML) |
| Command flow | Sequence diagrams for add, list, search, export, import |
| AGENTS.md | Contributor & AI collaboration conventions |
Issues and pull requests are welcome. Please ensure make test passes before submitting. With make hooks enabled, commits are auto-formatted and linted. For larger changes, open an Issue first to discuss direction.
License to be determined. Until then, please do not use this project for commercial redistribution that requires an explicit open-source license. Watch this repo for updates.