github.com/parquery/revproxyry
go get github.com/parquery/revproxyry

github.com/parquery/revproxyry

a reverse proxy with integrated Let's encrypt client

by Parquery

v1.0.7 (see all)License:MIT
go get github.com/parquery/revproxyry
Readme

revproxyry

revproxyry is a reverse proxy with integrated Let's encrypt client that automatically renews SSL certificates.

Story

We needed to deploy web servers to hundreds of machines that should support SSL.

Each instance had individual and pre-defined reverse proxying to static files and ports on the local host automatically generated from separate meta-configuration files. We picked Nginx as our first choice. Unfortunately, the task turned out to be quiet complex. The code to modify the Nginx configuration became clumsy fast.

To provide encryption, we considered buying SSL certificates for this many hosts. It became soon clear that bought certificates were too costly. They would be a pain to manage and renew automatically. No one of our users needed high security, the basic encryption was enough. We turned to Let's encrypt. But managing the automatic renewal of Let's encrypt's certificates proved messy as well. The provided tools, while easy to install manually, were difficult to add to our pipeline and lead to yet another messy part in the deployment script.

This lead us to the conclusion: there must be a simpler way. We didn't want any of the Nginx more advanced features. Just a reverse proxy to either a path or a microservice. And we wanted dumb-simple configuration files, a single flag to give us Let's encrypt's SSL certificates and basic authentication, if possible.

That's why we implemented revproxyry. We decided to use Go as it already provided all the ingredients we needed: a simple handler for reverse proxying and an easy to use ACME client needed for the communication with Let's encrypt.

Installation

Pre-compiled Binaries

We provide the pre-compiled binaries of the revproxyry. Please see the release page.

To install the release, just unpack it somewhere, add bin/ directory to your PATH and you are ready to go.

Debian Packages

We also provide a Debian package. Please also see the release page.

For example, to download the package and install it, call:

wget https://github.com/Parquery/revproxyry/releases/download/v1.0.3//revproxyry_1.0.3_amd64.deb
sudo dpkg -i revproxyry_1.0.3_amd64.deb

Compile From Source

Assuming you have a working Go environment, you can install the revproxyry from the source by running:

go get -U github.com/Parquery/revproxyry

Usage

You start the revproxyry by pointing it to the configuration file (see Section Configuration):

revproxyry --config_path /path/to/some/configuration.json

If you want to make it quiet, use --quiet:

revproxyry \
    --config_path /path/to/some/configuration.json \
    --quiet

To terminate revproxyry, send SIGTERM to the process.

You can generate the password hashes either by using revproxyhashry, a hashing tool developed by us with a very simple interface in mind, or a more complex Apache's htpasswd.

Configuration

The configuration file is written in JSON format as a JSON object.

The configuration file specifies the access and the routes of the reverse proxying. If you want to start straight with an example, please jump to Section Example Configuration. Otherwise, here is a detailed list of the configuration properties:

  • domain: specifies the domain name of the machine.

  • lets_encrypt_dir: points to where the Let's encrypt data is stored.

    If empty or undefined, Let's encrypt will not be used.

  • ssl_key_path: points to the SSL key path, if you don't want to use Let's encrypt, but want to provide an SSL key instead.

    Leave this field empty or undefined if you don't want to use SSL key.

  • ssl_cert_path: points to the SSL certificate, if you don't want to use Let's encrypt's certificates.

    Analogous to ssl_key_path, leave this field empty or unspecified if you don't want to use your own SSL certificate.

  • http_address: specifies the address on which to listen to HTTP requests, usually :80.

  • https_address: specifies the address on which to listen to HTTPS requests, usually :443.

  • auths: defines the authorization as a pair (user name, password hash).

    Each authorization is identified by its key in auths and specifies:

    • username: of the authorized user

    • password_hash: either Apr1 MD5 hash or bcrypt hash.

      You can generate hashes either with revproxyhashry or with Apache's htpasswd.

      If the username is empty, everybody is authorized.

  • routes: lists the routes of the reverse proxy.

    Each route is a JSON object which specifies:

    • auths: the list of authorization identifiers as defined in auths.

      If auths is an empty list or undefined, everybody is granted access.

    • target: path to a directory, path to a file or URL.

    • prefix: path prefix of the reversed path.

      Mind that the prefix is stripped from the request.

      If the target is a path, the remainder of the requested path is appended to it to resolve the actual path to the directory or file on the disk.

      If the target is an URL, the remainder of the requested path is appended to the path part of the URL.

If revproxyry is configured to use HTTPS, whenever the user goes to an HTTP URL, s/he will be automatically redirected to an HTTPS URL.

Example Configuration

We demonstrate here an example configuration. It instruct the reverse proxy to use Let's encrypt and authorizes two users, somebody and somebody_else to access different routes to local directories and URLs.

The password of the user somebody was generated using Apache's htpasswd and the password of the user somebody_else was generated using revproxyhashry, respectively.

{
  "domain": "some-subdomain.example.com",
  "letsencrypt_dir": "/some/dir/to/lets/encrypt",
  "ssl_key_path": "",
  "ssl_cert_path": "",
  "http_address": ":80",
  "https_address": ":443",
  "auths": {
    "everybody": {
      "username": "",
      "password_hash": ""
    },
    "somebody": {
      "username": "somebody",
      "password_hash": "$apr1$TBUT11YV$MKTEAeq9GU731f4ZanSuE/"
    },
    "somebody_else": {
      "username": "somebody_else",
      "password_hash": "$2a$14$5OzUXHawpYze7RZVpkNZSe09iFd6jNLIIh/KENNfg.uLsSOfcVj2y"
    }
  },
  "routes": [
    {
      "auths": [
        "everybody"
      ],
      "target": "/some/directory",
      "prefix": "/some-public-directory/"
    },
    {
      "auths": [],
      "target": "/another/directory/file.txt",
      "prefix": "/public-file.txt"
    },
    {
      "auths": [
        "somebody"
      ],
      "target": "http://127.0.0.1:11080/",
      "prefix": "/somebody/service"
    },
    {
      "auths": [
        "somebody_else"
      ],
      "target": "http://127.0.0.1:8055/",
      "prefix": "/somebody_else/another-service"
    }
  ]
}

Development

  • Clone the repository beneath your GOPATH:
go get github.com/Parquery/revproxyry
  • Change to the revproxyry directory:
cd $GOPATH/src/github.com/Parquery/revproxyry
  • If you want to build everything in the project:
go build ./...
  • If you want to build and install everything to $GOPATH/bin:
go install ./...
  • Create a pull request and send it for review :)

Versioning

We follow Semantic Versioning. The version X.Y.Z indicates:

  • X is the major version (backward-incompatible),
  • Y is the minor version (backward-compatible) and
  • Z is the patch version (backward-compatible bug fix).

GitHub Stars

12

LAST COMMIT

2yrs ago

MAINTAINERS

0

CONTRIBUTORS

4

OPEN ISSUES

0

OPEN PRs

0
VersionTagPublished
v1.0.3
1yr ago
v1.0.6
1yr ago
v1.0.4
1yr ago
v1.0.7
1yr ago
No alternatives found
No tutorials found
Add a tutorial