portable-sftp

command module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 29, 2026 License: MIT Imports: 25 Imported by: 0

README

portable-sftp

A single-binary SFTP server for ad-hoc file transfers on a trusted network.

Run it in a directory, connect with any SFTP client, stop it when you're done. No daemon, no system configuration, no root privileges, no config file.

$ portable-sftp

portable-sftp v1.0.0

  serving    /home/you/Pictures  (read-write)
  listening  [::]:2222
  user       sftp
  password   cAds-L29c-W88E-KWce
             (generated for this run; set -password or $SFTP_PASSWORD to choose your own)
  host key   SHA256:PAbgL0iubsiG2h4YN1Fp9REmEGy2ai4L6q91JOvKTa4

  connect with:
    sftp -P 2222 sftp@192.168.50.241

  Ctrl-C to stop.

Why

Moving a few files between a laptop and a phone, or between two machines on the same network, is a solved problem with about six unsatisfying solutions. This is one binary you can drop anywhere and delete afterwards.

Install

Download a binary from Releases, or:

go install github.com/H7O/portable-sftp@latest

Build it yourself:

git clone https://github.com/H7O/portable-sftp
cd portable-sftp
CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o portable-sftp .

CGO_ENABLED=0 produces a static binary that runs on any Linux of the same architecture. Cross-compile with GOOS/GOARCH:

GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o portable-sftp-arm64 .

Requires Go 1.25 or newer to build (it uses os.Root for path confinement).

Usage

portable-sftp [flags]
Flag Default Meaning
-root . Directory to serve
-user sftp Username clients must log in as
-password generated Password to require
-keyfile authorized_keys file to accept instead of a password
-port 2222 Port to listen on (0 picks a free one)
-bind all Address to bind; 127.0.0.1 for local only
-read-only false Refuse writes, renames, and deletions
-max-conns 10 Maximum concurrent connections
-hostkey ~/.config/portable-sftp/host_key Host key path
-stats-interval 0 Log a summary at this interval
-verbose false Log every request, including rejected ones
-version Print the version and exit
Examples

Share a folder read-only:

portable-sftp -root ~/Pictures -read-only

Use a password you choose, without putting it in your shell history or in ps:

SFTP_PASSWORD='the one you want' portable-sftp

Use key authentication:

portable-sftp -keyfile ~/.ssh/authorized_keys

Accept connections from this machine only:

portable-sftp -bind 127.0.0.1
Authentication

If you give neither -password nor -keyfile, a strong password is generated and printed once at startup. There is no default password.

-password and -keyfile are mutually exclusive, and only the corresponding authentication method is offered to clients. -keyfile accepts a normal OpenSSH authorized_keys file, so multiple keys and comments work as expected.

Host key

A persistent Ed25519 host key is generated on first run and stored in ~/.config/portable-sftp/host_key, so your client won't warn about a changed fingerprint every time you start the server. The fingerprint is printed at startup — check it against what your client shows on first connection.

The key is deliberately kept outside the served directory, and the server refuses to start if -hostkey points inside -root, since a client could otherwise download it and impersonate the server.

Security

This is a tool for trusted local networks. Do not expose it to the internet.

What it does
  • Serves exactly one directory. Paths are confined with os.Root, which resolves every path component through the kernel (openat2 with RESOLVE_BENEATH where available). .., absolute paths, and symlinks pointing outside the root are all rejected, with no window between checking a path and opening it.
  • Never creates symlinks or hard links on the client's behalf.
  • Offers only the authentication method you configured.
  • Compares credentials in constant time.
  • Caps concurrent connections and bounds the pre-authentication handshake.
  • Recovers from panics in a session without taking down the server.
What it does not do
  • No rate limiting on failed passwords. SSH caps attempts per connection, but nothing stops a client from reconnecting. Use the generated password or a key; don't pick a short one.
  • No encryption at rest, no auditing, no multi-user support. One user, one directory, one password or key set.
  • No protection against whoever runs it. The server has your filesystem permissions. -root is a boundary for the client, not a sandbox for you.
  • Not hardened for hostile networks. It has not been audited, and it is not a replacement for OpenSSH.

If you need a real SFTP server, use OpenSSH with ChrootDirectory.

Found a security problem? See SECURITY.md.

Development

go test ./...            # unit and end-to-end tests
go test -race ./...      # the end-to-end tests are concurrent
go vet ./...
govulncheck ./...        # go install golang.org/x/vuln/cmd/govulncheck@latest
gofmt -l .

The test suite starts real servers on ephemeral ports and drives them with a real SFTP client, including regression tests for path escapes, authentication bypasses, malformed protocol messages, and connection-limit enforcement.

License

MIT

Documentation

Overview

Command portable-sftp is a single-binary SFTP server for ad-hoc file transfers on a trusted network.

Run it in a directory and connect with any SFTP client. It serves exactly one directory, confined with os.Root, and needs no system configuration, no daemon, and no root privileges.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL