MCPcopy Index your code
hub / github.com/bolcom/libunftp

github.com/bolcom/libunftp @libunftp-0.23.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release libunftp-0.23.0 ↗ · + Follow
785 symbols 1,689 edges 124 files 154 documented · 20%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

libunftp

Crate Version API Docs Build Status Crate License Follow on Telegram

When you need to FTP, but don't want to.

logo

Website | API Docs | unFTP

The libunftp library drives unFTP. It's an extensible, async, cloud orientated FTP(S) server implementation in Rust brought to you by the bol.com techlab.

Because of its plug-able authentication (e.g. PAM, JSON File, Generic REST) and storage backends (e.g. local filesystem, Google Cloud Storage) it's more flexible than traditional FTP servers and a perfect match for the cloud.

It runs on top of the Tokio asynchronous run-time and tries to make use of Async IO as much as possible.

Feature highlights:

  • 42 Supported FTP commands (see commands directory) and growing
  • Ability to implement own storage back-ends
  • Ability to implement own authentication back-ends
  • Explicit FTPS (TLS)
  • Mutual TLS (Client certificates)
  • TLS session resumption
  • Prometheus integration (enabled by default, can be disabled)
  • Structured Logging
  • Proxy Protocol support (enabled by default, can be disabled)
  • Automatic session timeouts
  • Per user IP allow lists
  • Configurable cryptographic providers (ring or aws-lc-rs)

Known storage back-ends:

  • unftp-sbe-fatfs - Provides read-only access to FAT filesystem images
  • unftp-sbe-fs - Stores files on the local filesystem
  • unftp-sbe-gcs - Stores files in Google Cloud Storage
  • unftp-sbe-iso - Provides FTP access to ISO 9660 files
  • unftp-sbe-opendal - Provides access to various storage services through Apache OpenDAL (supports S3, Azure Blob Storage, and more)
  • unftp-sbe-restrict - Wraps another storage back-end in order to restrict the FTP operations a user can do i.e. provide authorization.
  • unftp-sbe-rooter - Wraps another storage back-end in order to root a user to a specific home directory.
  • unftp-sbe-webdav - A WebDAV storage back-end providing translation between FTP & WebDAV

Known authentication back-ends:

Cryptographic Providers

These two feature flags can be used to select the cryptographic provider:

  • aws_lc_rs (default): Uses AWS-LC through rustls for cryptographic operations
  • ring: Uses the ring crate for cryptographic operations

To use a specific provider, enable the corresponding feature in your Cargo.toml:

[dependencies]
libunftp = { version = "0.23.0", features = ["ring"] }  # Use ring
# or
libunftp = { version = "0.23.0", features = ["aws_lc_rs"] }  # Use aws-lc-rs (default)

The default provider is aws-lc-rs for backward compatibility. Choose the provider that best fits your needs:

  • ring: More widely used, good for general-purpose applications
  • aws-lc-rs: Optimized for AWS environments, good for cloud deployments

Optional Features

The following feature flags are included in the default features but can be disabled to reduce dependencies:

  • prometheus: Enables Prometheus metrics integration. When enabled, you can collect metrics about FTP operations, sessions, and transfers using the .metrics() method on the server builder. Enabled by default.

  • proxy_protocol: Enables Proxy Protocol support. This allows the server to receive client connection information (IP address and port) when behind a proxy or load balancer. * Enabled by default.*

To disable these features and reduce dependencies, use default-features = false and explicitly enable only what you need:

[dependencies]
libunftp = { version = "0.22.0", default-features = false, features = ["aws_lc_rs"] }

Or enable all features explicitly:

[dependencies]
libunftp = { version = "0.22.0", features = ["all"] }

Prerequisites

You'll need Rust 1.85.0 or higher to build libunftp.

Getting started

If you've got Rust and cargo installed, create your project with

cargo new myftp

Add the libunftp and tokio crates to your project's dependencies in Cargo.toml. Then also choose a storage back-end implementation to add. Here we choose the file system back-end:

[dependencies]
libunftp = "0.23.0"
unftp-sbe-fs = "0.4.0"
tokio = { version = "1", features = ["full"] }

Now you're ready to develop your server! Add the following to src/main.rs:

use libunftp::ServerBuilder;
use unftp_sbe_fs::Filesystem;

#[tokio::main]
pub async fn main() {
    let ftp_home = std::env::temp_dir();
    let server = ServerBuilder::new(Box::new(move || Filesystem::new(ftp_home.clone()).unwrap()))
        .greeting("Welcome to my FTP server")
        .passive_ports(50000..=65535)
        .build()
        .unwrap();

    server.listen("127.0.0.1:2121").await;
}

You can now run your server with cargo run and connect to localhost:2121 with your favourite FTP client e.g.:

lftp -p 2121 localhost

For more help refer to:

Getting help and staying informed

Support is given on a best effort basis. You are welcome to engage us on the discussions page or create a Github issue.

You can also follow news and talk to us on Telegram

Contributing

Thank you for your interest in contributing to libunftp!

Please feel free to create a Github issue if you encounter any problems.

Want to submit a feature request or develop your own storage or authentication back-end? Then head over to our contribution guide (CONTRIBUTING.md).

License

You're free to use, modify and distribute this software under the terms of the Apache License v2.0.

Extension points exported contracts — how you extend this code

ControlChanMiddleware (Interface)
(no doc) [9 implementers]
src/server/controlchan/middleware.rs
Authenticator (Interface)
(no doc) [7 implementers]
crates/unftp-core/src/auth/authenticator.rs
DataListener (Interface)
(no doc) [3 implementers]
src/notification/event.rs
TrimQuotes (Interface)
(no doc) [1 implementers]
crates/unftp-auth-rest/src/lib.rs
CommandHandler (Interface)
(no doc) [42 implementers]
src/server/controlchan/handler.rs
Metadata (Interface)
Represents the metadata of a _FTP File_ [4 implementers]
crates/unftp-core/src/storage/storage_backend.rs
PresenceListener (Interface)
(no doc) [3 implementers]
src/notification/event.rs
LegacyReplyProducer (Interface)
(no doc) [2 implementers]
src/server/controlchan/commands/passive_common.rs

Core symbols most depended-on inside this repo

send_to_server
called by 46
tests/common.rs
parse_to_eol
called by 39
src/server/controlchan/line_parser/parser.rs
as_ref
called by 39
crates/unftp-core/src/auth/authenticator.rs
spawn
called by 35
src/server/controlchan/control_loop.rs
as_ref
called by 34
src/server/password.rs
build
called by 27
crates/unftp-auth-rest/src/lib.rs
path
called by 21
src/server/chancomms.rs
take
called by 19
src/server/tls.rs

Shape

Method 393
Function 210
Class 128
Enum 41
Interface 13

Languages

Rust100%

Modules by API surface

src/server/controlchan/line_parser/tests.rs53 symbols
crates/unftp-sbe-gcs/src/gcs_client.rs37 symbols
src/server/ftpserver.rs36 symbols
crates/unftp-sbe-fs/tests/main.rs36 symbols
src/server/controlchan/commands/user.rs32 symbols
src/server/datachan.rs28 symbols
crates/unftp-sbe-fs/src/lib.rs25 symbols
crates/unftp-sbe-fs/src/tests.rs20 symbols
crates/unftp-core/src/storage/storage_backend.rs18 symbols
crates/unftp-auth-rest/src/lib.rs18 symbols
crates/unftp-auth-jsonfile/src/lib.rs17 symbols
crates/unftp-sbe-gcs/src/lib.rs16 symbols

For agents

$ claude mcp add libunftp \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact