Skip to content

rguziy/ndrop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

10 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

ndrop

πŸš€ ndrop is a self-hosted data transfer utility for text, files, and folders, built in Go. It uses a self-hosted HTTP server accessible locally or remotely, with end-to-end encryption so the server stores only ciphertext.

Similar in spirit to AirDrop-style sharing, but uses HTTP and E2E encryption instead of OS-specific peer-to-peer discovery.

Use cases

  • Run ndropd on your laptop for local quick transfers.
  • Deploy ndropd on a VPS or remote machine for internet-based drops.
  • Use ndrop from any network-capable client to push/pull text, files, and folders over HTTPS.

Features

  • πŸ” End-to-end encrypted content transfer
  • πŸ“€ Push text, files, folders, or clipboard contents from the CLI
  • πŸ“₯ Pull shared content to stdout, system clipboard, saved file, or extracted folder
  • 🧩 API-key-based isolation per shared buffer
  • βš™οΈ Configurable with TOML, CLI flags, and environment variables
  • πŸ–₯️ ndropd CLI with init, start, stop, and help

Quick Start

1. Initialize client config

./ndrop init

This creates ~/.config/ndrop/ndrop.toml with:

[server]
url = "http://localhost:8080"
api_key = "your-api-key"
timeout_seconds = 120

[pull]
default_save_dir = "~/Downloads"

2. Initialize server config

./ndropd init

This creates ~/.config/ndrop/ndropd.toml with:

port = "8080"
max_size_mb = 10
ttl_hours = 1
allow_any_api_key = true
allowed_api_keys = []

3. Start the server

./ndropd start

4. Push and pull

# Push inline text
./ndrop push "Hello World!"

# Push a file
./ndrop push ./archive.tar.gz

# Push a folder
./ndrop push ./my-folder

# Push clipboard contents
./ndrop push --clipboard

# Push command output
./ndrop push -c "date"

# Pull text to stdout (default)
./ndrop pull

# Pull text to system clipboard
./ndrop pull --clipboard

# Pull a file or folder to a directory
./ndrop pull --save ./downloads/

# Pull raw bytes to stdout
./ndrop pull --stdout

CLI Usage

Client commands

  • ndrop init β€” create default client config
  • ndrop push [text|file|folder] β€” push text, a file, or a folder
  • ndrop pull β€” pull the latest entry

Push options

  • --clipboard β€” push text from the system clipboard
  • -c, --cmd <command> β€” execute a command and push its output

Pull options

  • --clipboard β€” write text to the system clipboard
  • --save <dir> β€” save a file or extract a folder to a directory
  • --stdout β€” write raw bytes to stdout

Server commands

  • ndropd init β€” create server config
  • ndropd start β€” run server in the foreground
  • ndropd stop β€” stop the running server
  • ndropd help β€” show help

Web UI

ndropd serves an embedded web UI at /.

Open the server URL in a browser, enter the same API key used by the CLI, and use the page to:

  • pull and decrypt the latest text, file, or folder transfer locally in the browser
  • copy pulled text to the system clipboard
  • download pulled files and folders; folders are downloaded as zip files
  • push text or a file

The web UI uses the browser WebCrypto API for AES-GCM encryption and decryption, so the server still stores only ciphertext. WebCrypto requires a secure browser context: use https:// for remote deployments or http://localhost for local testing.

How encryption works

ndrop uses the configured API key for two separate purposes:

  • It derives a stable bucket_id, which selects the shared buffer on the server.
  • It derives an AES-256-GCM encryption key, which encrypts and decrypts the payload.

When you run ndrop push, the client encrypts the text, file, or zipped folder before uploading it. The server stores only:

  • the derived bucket_id
  • encrypted data
  • the nonce needed to decrypt that encrypted payload
  • metadata such as device name, MIME type, and payload name

The nonce is a random 12-byte value generated for every push. It is not secret, but it must be unique for each encryption with the same API key. The pull client receives data and nonce, then decrypts locally using the same API key.

The raw API key is sent to the server in the Authorization: Bearer <api-key> header so the server can route the request and optionally enforce allowed_api_keys. The server does not store the raw API key, but deployments should still use HTTPS when the server is accessed over a network.

Configuration

Client config

File: ~/.config/ndrop/ndrop.toml

[server]
url = "http://localhost:8080"
api_key = "my-secret-api-key"

# Client-side HTTP request timeout in seconds (0 uses default 120s)
timeout_seconds = 120

[pull]
default_save_dir = "~/Downloads"

Server config

File: ~/.config/ndrop/ndropd.toml

port = "8080"
max_size_mb = 10
ttl_hours = 1
allow_any_api_key = true
allowed_api_keys = []

Set allow_any_api_key = false and list accepted keys to reject unknown clients:

allow_any_api_key = false
allowed_api_keys = ["laptop-key", "phone-key"]

Environment variables

Client config can be overridden with:

  • NDROP_URL
  • NDROP_API_KEY

Server config can be overridden with:

  • PORT
  • MAX_SIZE_MB
  • TTL_HOURS
  • ALLOW_ANY_API_KEY
  • ALLOWED_API_KEYS

Production Deployment & Reverse Proxy (Nginx)

When exposing ndropd to the internet, it is strongly recommended to run it behind a reverse proxy like Nginx with SSL termination.

Because ndrop processes large files via memory/Base64, streaming raw data instantly without proxy buffering is critical to prevent timeouts and connection drops.

Recommended Nginx Configuration

Add the following configuration inside your Nginx server block (handling port 443 with SSL):

location / {
    proxy_pass http://localhost:8080; # or your docker container name

    # 1. Disable all buffering for instant streaming of large payloads
    proxy_buffering off;
    proxy_request_buffering off;
    client_max_body_size 0; # Disables Nginx upload size limits

    # 2. Extend timeouts to handle large multi-megabyte transfers over slow networks
    proxy_connect_timeout 3600s;
    proxy_read_timeout 3600s;
    proxy_send_timeout 3600s;
    send_timeout 3600s; # Crucial: prevents Nginx from cutting off slow pull streams

    # 3. Standard headers for proxying
    proxy_set_header Host \$http_host;
    proxy_set_header X-Real-IP \$remote_addr;
    proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto \$scheme;
}

Docker

A Docker Compose setup is included under docker/docker-compose.yml. Use docker/Dockerfile to build the image and docker/build.sh to run the workflow.

From the repository root:

./docker/build.sh build

This builds the ndropd image only.

./docker/build.sh up

This rebuilds the image and starts the ndropd service in detached mode.

The compose service publishes port 8080 and sets:

  • PORT=8080
  • MAX_SIZE_MB=10
  • TTL_HOURS=1
  • ALLOW_ANY_API_KEY=true

Linux systemd

A sample systemd unit is available at deploy/systemd/ndropd.service.

It assumes:

  • ndropd is installed at /usr/local/bin/ndropd
  • a dedicated Linux user and group named ndrop exist
  • server state is stored under /var/lib/ndrop

Example setup:

sudo useradd --system --home-dir /var/lib/ndrop --create-home --shell /usr/sbin/nologin ndrop
sudo install -m 0755 ndropd /usr/local/bin/ndropd
sudo install -m 0644 deploy/systemd/ndropd.service /etc/systemd/system/ndropd.service
sudo systemctl daemon-reload
sudo systemctl enable --now ndropd

Before starting the service on a public host, edit /etc/systemd/system/ndropd.service and replace:

Environment=ALLOWED_API_KEYS=change-me

For multiple API keys, use a comma-separated value:

Environment=ALLOWED_API_KEYS=laptop-key,phone-key

Build

The canonical project version is defined in internal/version/version.go. Plain go build, Docker builds, and Make-based release builds use that value. Update it there before cutting a new release.

Both binaries can print their version:

ndrop --version
ndropd --version

Local Go build

go build -o ndrop ./cmd/ndrop
go build -o ndropd ./cmd/ndropd

Cross-platform build with Make

The repository includes a Makefile with platform targets. Built artifacts are packaged as ZIP archives in the build/ directory.

make linux-amd64
make windows-amd64
make darwin-amd64
make darwin-arm64

To build all supported targets:

make release

To remove generated build artifacts:

make clean

Supported targets:

  • linux-amd64
  • linux-armv5
  • linux-armv6
  • linux-armv7
  • windows-amd64
  • darwin-amd64
  • darwin-arm64

Each target builds both ndrop and ndropd, then creates a zip package like:

  • build/ndrop-linux-amd64-1.1.0.zip
  • build/ndrop-windows-amd64-1.1.0.zip
  • build/ndrop-darwin-arm64-1.1.0.zip

πŸ“„ License

MIT Β© 2026 Ruslan Huzii