fuckssh

June 16, 2026 · View on GitHub

English | 中文

CI Go Report Card Release

Cross-platform CLI for VPS SSH — from IP + password to ssh my-vps in minutes, using only standard ~/.ssh/config.

About

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.

Table of contents

Features

  • One-stop setupadd password mode: generate Ed25519 key, deploy public key, write config; key mode: write config for an existing private key
  • Script-friendlyadd -H <ip> -P <pass> for non-interactive setup; tests connectivity before writing any files
  • Manage hostslist / search / edit / delete for the full host lifecycle
  • Encrypted migrationexport / import to 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_LANG or language selection on first run)
  • Terminal-nativeBubble Tea TUI wizard and table output

Use cases

New VPS — passwordless login in one session

fuckssh add
ssh myserver

Script or automation — non-interactive add

fuckssh add -H 1.2.3.4 -u root -P mypass -a myserver
ssh myserver

Migrate 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.enc

Find a host quickly

fuckssh search prod
fuckssh search --user root --port 2222 web

Prerequisites

  • OpenSSH client (ssh in PATH) — required for add and connectivity tests
  • Writable ~/.ssh/ directory
  • Go 1.22+ — only if building from source

Installation

macOS / Linux (requires curl, installs to ~/.local/bin):

curl -fsSL https://raw.githubusercontent.com/hczs/fuckssh/master/scripts/install.sh | sh

Pin 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 | iex

The 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 prod

Pre-built binaries

Download from GitHub Releases and put fuckssh in your PATH.

PlatformExample artifact
Linux x86_64 / arm64fuckssh_linux_x86_64.tar.gz, fuckssh_linux_arm64.tar.gz
macOS Intelfuckssh_macos_x86_64.tar.gz
macOS Apple Siliconfuckssh_macos_arm64.tar.gz
macOS Universalfuckssh_macos_all.tar.gz (Intel + Apple Silicon)
Windowsfuckssh_windows_x86_64.zip

Go install

Requires Go 1.22+:

go install github.com/fuckssh/fuckssh@latest

Build from source

See Development.

Quick start

fuckssh add
ssh <your-alias>

For more scenarios, see Use cases.

Command reference

CommandShortDescription
fuckssh addaInteractive 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 listlsParse and display all Hosts in a table; multiple aliases shown comma-separated
fuckssh search <query>sMulti-keyword OR search; --user/--host/--port filters; highlighted results in TTY
fuckssh edit <alias>eInteractive edit of an existing Host (pre-filled, supports "go back and revise" retry)
fuckssh delete <alias>dDelete 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 versionvShow version, commit, and build date (injected via ldflags in release builds)

Global options

OptionDescription
-h, --helpHelp (English and Chinese supported)
--versionPrint version information

Command options

OptionCommandsDescription
-H, --hostaddTarget host address (triggers non-interactive mode)
-u, --useraddLogin user (default: root)
-p, --portaddSSH port (default: 22)
-P, --passwordaddSSH password (triggers password mode)
-i, --identity-fileaddPrivate key path (triggers key mode)
-a, --aliasaddHost alias (auto-generated from address if omitted)
-r, --remarkaddRemark / note
--usersearchFilter by username
--hostsearchFilter by host address
--portsearchFilter by port
-f, --forcedeleteSkip confirmation prompt

Examples

add — Interactive VPS setup

$ 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

add — Non-interactive mode

$ 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

list — Show all Hosts

$ 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
└──────────────┴───────────────┴──────┴────────┴──────────────┘

search — Find hosts

$ fuckssh s prod

Search: prod 1 match

┌──────────────┬───────────────┬──────┬────────┬──────────────┐
 Alias Address Port User Remark
├──────────────┼───────────────┼──────┼────────┼──────────────┤
 myserver 1.2.3.4   22 root Production
└──────────────┴───────────────┴──────┴────────┴──────────────┘

edit — Modify an existing Host

$ 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

delete — Remove a Host

$ 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

export — Encrypted backup

$ fuckssh export ~/Desktop

请设置主密码(至少 6 位,不能纯数字):
主密码: ********
确认密码: ********
正在导出...
 导出成功
  文件: /home/user/Desktop/fuckssh-backup-20260616-102739.tar.enc
  大小: 4096 字节
  包含: 3 Host 配置, 2 个私钥

请将此文件拷贝到目标机器,然后运行:
  fuckssh import fuckssh-backup-20260616-102739.tar.enc

import — Restore on another machine

No 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)

version

$ fuckssh v

v0.6.0 (abc1234, 2026-06-16)

Design principles

  1. Standard-first — Reads and writes OpenSSH conventions. Uninstall fuckssh and your config still works.
  2. Recoverable — Backs up config before every write (~/.ssh/backup/); import also backs up existing config before merging.
  3. CLI-native — Built for developers who live in the terminal and VS Code Remote SSH. Complements GUI clients, doesn't replace them.
  4. Portableexport / import for moving hosts and keys to a new machine. Backup files are written with mode 0600; keep them safe if you store them on a sync drive.

Roadmap

PhaseCapabilities
Shippedadd (interactive + non-interactive) / list / search / edit / delete / export / import / version / short aliases
NextInclude directive expansion, --json output, custom config path

Development

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.

TriggerWorkflowDescription
push / PR → main / masterCITest, lint, cross-platform build check

Documentation

DocDescription
PRDProduct requirements & scenarios
Tech SelectionTech stack & module breakdown
ArchitectureSystem architecture (HTML)
Command flowSequence diagrams for add, list, search, export, import
AGENTS.mdContributor & AI collaboration conventions

Contributing

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

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.