#reverse-proxy #pingora #proxy

app vicarian

Vicarian is a reverse proxy server with ACME support

13 releases

Uses new Rust 2024

new 0.1.12 Dec 23, 2025
0.1.11 Dec 22, 2025

#125 in Network programming

Apache-2.0

87KB
2K SLoC

Vicarian

Vicarian is a reverse proxy server with built-in ACME support. It is currently targeted at self-hosting and SOHO installations; in particular it supports provisioning TLS certificates behind-the-firewall via ACME DNS-01 and the zone-update library.

Project Status

This software should be consider pre-alpha; the feature-set is MVP and is still in active development. It should not be considered production-ready and no warranty is expressed or implied.

Features

Current features

  • Reverse Proxy: Route traffic to multiple backend services based on URL contexts
  • Dynamic Certificate Loading: Externally provided TLS certificates are monitored and reloaded on update.
  • ACME Support: Automatic certificate issuance and renewal via ACME protocol; both HTTP and DNS types are supported.
  • Multiple DNS Providers: Multiple DNS providers for ACME are supported via the zone-update project. See that project for a list of supported providers.

Possible Future Features

The following may be implemented at some point depending on interest and resources.

  • Static file serving.
  • TLS-ALPN-01 ACME support.
  • Virtual host support.
  • Prometheus stats.

Installation

Install from crates.io

cargo install vicarian

The binary will be available at ~/.crates/bin/vicarian.

Building from Source

git clone https://github.com/tarka/vicarian.git
cd vicarian
cargo build --release

The binary will be available at target/release/vicarian.

Running

Systemd Service

An example systemd service in provided in systemd/vicarian.service. The systemd service sets the CAP_NET_BIND_SERVICE flag which allows binding to ports 80/443 without root.

Configuration

Vicarian currently uses the corn configuration language. The default configuration file is located at /etc/vicarian/vicarian.corn, but can be changed with the --config flag.

Basic Configuration Structure

The full configuration structure is documented in CONFIGURATION.md, and additional examples are available in the examples directory, but a basic working configuration with HTTP-based Let's Encrypt TLS would look like:

{
  hostname = "your-domain.com"
  listen = "[::]"  // Listen on all interfaces (IPv4 & IPv6)

  insecure = {
      port = 80    // HTTP port (default)
      redirect = true  // Redirect HTTP to HTTPS
  }

  tls = {
    port = 443  // HTTPS port (default)
    config = {
      acme = {
        acme_provider = "letsencrypt"
        contact = "admin@your-domain.com"
        challenge = {
          type = "http-01"
        }
      }
    }
  }

  backends = [
    {
      context = "/"
      url = "http://localhost:8443"
      // This service enforces TLS with a self-signed cert, so
      // we need to disable certificate verification.
      trust = true
    }
    {
      context = "/copyparty"
      url = "http://localhost:9090"
    }
  ]
}

ACME Configuration (Automatic Certificate Management)

To use automatic certificate management with Let's Encrypt:

{
  hostname = "your-domain.com"
  listen = "[::]"

  insecure = {
      port = 80
      redirect = true
  }

  tls = {
    port = 443
    config = {
      acme = {
        acme_provider = "letsencrypt"
        contact = "admin@your-domain.com"
        challenge = {
          type = "dns-01"
          domain = "your-domain.com"
          dns_provider = {
            name = "porkbun"  // Or other supported providers
            // Corn supports reading variables from the environment
            key = $env_PORKBUN_KEY
            secret = $env_PORKBUN_SECRET
          }
        }
      }
    }
  }

  backends = [
    {
      context = "/api"
      url = "http://localhost:3000"
    }
  ]
}

Development

Contributing

At this point the most useful contributions would be to add additional DNS provider APIs to the zone-update project. However contributions to this project are welcome.

AI Contribution Policy

LLM and related 'AI' technologies can be useful for software development, but best-practices on their usage are still evolving. For this reason this project will not accept runtime code generated by AI. Generation of draft documentation and test code is acceptable, but should be reviewed by the submitter before raising a PR. After all, if you can't be bothered to review it why should anybody else?

Security Notes

  • Vicarian binds to ports 80 and 443 by default, requiring appropriate permissions
  • The systemd service uses CAP_NET_BIND_SERVICE to bind to privileged ports without full root privileges
  • Private keys are stored in PEM format and should be properly secured
  • When using ACME with DNS-01 challenges, ensure DNS provider API credentials are stored securely

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Dependencies

~160MB
~4M SLoC