Skip to content

Commit

Permalink
Merge pull request #42 from byjg/issue/41
Browse files Browse the repository at this point in the history
Issue #41
  • Loading branch information
byjg authored Jul 4, 2023
2 parents b52c413 + f0057fb commit 5d03751
Show file tree
Hide file tree
Showing 60 changed files with 1,301 additions and 612 deletions.
23 changes: 21 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,23 @@ EasyHAProxy can detect and configure HAProxy automatically on the following plat
- Docker Swarm
- Kubernetes

## Who is using?

EasyHAProxy is part of some projects:
- Dokku
- MicroK8s

See detailed instructions on how to install below.

## EasyHAProxy Mission

Easy to set up and low configuration to numerous features.

## Features

EasyHAProxy will discover the services based on the Docker Tags of the containers running on a Docker host or Docker Swarm cluster and dynamically set up the `haproxy.cfg`. Below, EasyHAProxy main features:

- Use Letsencrypt with HAProxy.
- Support Automatic Certificate Management Environment (ACME) protocol compatible with Let's encrypt and others CA.
- Set your custom SSL certificates
- Balance traffic between multiple replicas
- Set SSL with three different levels of validations and according to the most recent definitions.
Expand All @@ -34,7 +46,7 @@ EasyHAProxy will discover the services based on the Docker Tags of the container

Also, it is possible to set up HAProxy from a simple Yaml file instead of creating `haproxy.cfg` file.

## How Does It Works?
## How Does It Work?

You don't need to change your current infrastructure and don't need to learn the HAProxy configuration.

Expand All @@ -59,6 +71,13 @@ Or you can install using tools:
[![MicroK8s](docs/easyhaproxy_microk8s.png)](docs/microk8s.md)
[![Dokku](docs/easyhaproxy_dokku.png)](docs/dokku.md)

## Special Topics

If you already set up the EasyHAProxy, is time to go deeper:

- [Custom SSL](docs/ssl.md)
- [Automatic Certificate Issuing](docs/acme.md) (e.g. Letsencrypt)

## See EasyHAProxy in action

Click on the image to see the videos (use HD for better visualization)
Expand Down
3 changes: 1 addition & 2 deletions build/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM alpine:3.16
FROM alpine:3.18

ARG RELEASE_VERSION_ARG

Expand All @@ -11,7 +11,6 @@ COPY src/ /scripts/
COPY build/assets /

RUN apk add --no-cache haproxy bash python3 py3-pip py-yaml certbot openssl \
&& ln -s /usr/bin/python3 /usr/bin/python \
&& pip3 install --upgrade pip \
&& pip install -r requirements.txt \
&& pytest -s -vv tests/ \
Expand Down
6 changes: 3 additions & 3 deletions deploy/docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ services:
image: byjg/easy-haproxy:4.3.1-rc1
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- certs_letsencrypt:/certs/letsencrypt
- certs_certbot:/certs/certbot
- certs_haproxy:/certs/haproxy

environment:
EASYHAPROXY_DISCOVER: docker
EASYHAPROXY_LABEL_PREFIX: easyhaproxy
EASYHAPROXY_LETSENCRYPT_EMAIL: [email protected]
EASYHAPROXY_CERTBOT_EMAIL: [email protected]
EASYHAPROXY_SSL_MODE: "default"
HAPROXY_CUSTOMERRORS: "true"
HAPROXY_USERNAME: admin
Expand All @@ -27,7 +27,7 @@ services:
- easyhaproxy

volumes:
certs_letsencrypt:
certs_certbot:
external: true
certs_haproxy:
external: true
Expand Down
2 changes: 1 addition & 1 deletion deploy/docker/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
ASSETS_DIR="$(dirname "${BASH_SOURCE[0]}")"/../../build/assets/certs/haproxy

docker network create easyhaproxy
docker volume create certs_letsencrypt
docker volume create certs_certbot
docker volume create certs_haproxy

docker run -d --rm --name easyhaproxy_install -v certs_haproxy:/certs alpine tail -f /dev/null
Expand Down
99 changes: 99 additions & 0 deletions docs/acme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# SSL - Automatic Certificate Management Environment (ACME)

The Automatic Certificate Management Environment (ACME) protocol
allow automating interactions between certificate authorities and their users' servers,
allowing the automated deployment of public key infrastructure.

Most of the issuers offers Automatic Issuing free of cost.

## Environment Variables

To enable the ACME protocol we need to enable Certbot in EasyHAProxy by setting up to 4 environment variables:

| Environment Variable | Required? | Description |
|----------------------------------|-----------|----------------------------------------------------------------------------------------------------------------------------------|
| EASYHAPROXY_CERTBOT_EMAIL | YES | Your email in the certificate authority. |
| EASYHAPROXY_CERTBOT_AUTOCONFIG | - | Will use pre-sets for your Certificate Authority (CA). See table below. |
| EASYHAPROXY_CERTBOT_SERVER | - | The ACME Endpoint of your certificate authority. If you use AUTOCONFIG, it is set automatically. See table below. |
| EASYHAPROXY_CERTBOT_EAB_KID | - | External Account Binding (EAB) Key Identifier (KID) provided by your certificate authority. Some CA require it. See table below. |
| EASYHAPROXY_CERTBOT_EAB_HMAC_KEY | - | External Account Binding (EAB) HMAC Key provided by your certificate authority. Some CA require it. See table below. |
| EASYHAPROXY_CERTBOT_RETRY_COUNT | - | Wait 'n' requests before retrying issue invalid requests. Default 60. |

## Auto Config Certificate Authority (CA)

Here are detailed instructions per Certificate Authority (CA). If anyone is missing, please let's know.

| CA | Auto Config | Free? | Account Required? | EAB KID? | EAB HMAC Key? | More Info |
|----------------------|------------------|-------|--------------------|----------|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Let's Encrypt | - | Yes | No | No | No | - |
| Let's Encrypt (Test) | letsencrypt_test | Yes | No | No | No | - |
| ZeroSSL | zerossl | Yes | No | No | No | [Link](https://zerossl.com/documentation/acme/) |
| BuyPass | buypass | Yes | No | No | No | [Link](https://community.buypass.com/t/63d4ay/buypass-go-ssl-endpoints-updated-14-05-2020) |
| BuyPass (test) | buypass_test | Yes | No | No | No | [Link](https://community.buypass.com/t/63d4ay/buypass-go-ssl-endpoints-updated-14-05-2020) |
| Google | google | Yes | Yes | Yes | Yes | [Link](https://cloud.google.com/blog/products/identity-security/automate-public-certificate-lifecycle-management-via--acme-client-api) |
| Google Test | google_test | Yes | Yes | Yes | Yes | [Link](https://cloud.google.com/blog/products/identity-security/automate-public-certificate-lifecycle-management-via--acme-client-api) |
| SSLCOM RCA | sslcom_rca | Trial | EAB Keys by email. | Yes | Yes | [Link](https://www.ssl.com/blogs/sslcom-supports-acme-protocol-ssl-tls-certificate-automation/) |
| SSLCOM ECC | sslcom_ecc | Trial | EAB Keys by email. | Yes | Yes | [Link](https://www.ssl.com/blogs/sslcom-supports-acme-protocol-ssl-tls-certificate-automation/) |
| Digicert | - | No | Yes | Yes | Yes | [Link](https://docs.digicert.com/en/certcentral/certificate-tools/certificate-lifecycle-automation-guides/use-a-third-party-acme-client-for-host-automations.html) |
| Entrust | - | No | Yes | Yes | Yes | [Link](https://www.entrust.com/knowledgebase/ssl/how-to-use-acme-to-install-ssl-tls-certificates-in-entrust-certificate-services-apache) |
| Sectigo | - | No | Yes | Yes | Yes | [Link](https://www.sectigo.com/resource-library/sectigos-acme-automation) |

This configuration is global. After set up ACME properly, is necessary enable for each domain the certificate request.

To do that add the label: `easyhaproxy.<definition>.certbot=true`. See the method of installation you are using to learn how to set up properly.

## Example

### Setting up EasyHAProxy

Run the EasyHAProxy container:

```bash
docker run \
... \
-e EASYHAPROXY_CERTBOT_AUTOCONFIG=zerossl \
-e [email protected] \
-p 80:80 \
-p 443:443 \
-v /path/to/guest/certbot/certs:/certs/certbot \
... \
byjg/easy-haproxy
```

Notes:

- The `EASYHAPROXY_CERTBOT_AUTOCONFIG` is not required for Let's Encrypt. In this example, the certificate will be issued by ZeroSSL.
- If you don't setup `EASYHAPROXY_CERTBOT_EMAIL` environment variable, EasyHAProxy will fail silently and **will not request** a certificate.
- The ports 80 and 443 needs to accessible through the internet as [Let's Encrypt requirement](https://letsencrypt.org/docs/allow-port-80/)

In order to avoid several certificate issuing,
**It is required you to persist the container folder `/certs/certbot` outside the container.**
You cannot delete or change it contents.
If you do not persist, or change/delete the contents, Issue a certificate might not work properly and hit rate limit.

If you are using Let's Encrypt, be aware of it rate limits:

- https://letsencrypt.org/docs/duplicate-certificate-limit/
- https://letsencrypt.org/docs/rate-limits/


## Setting up your container to use the ACME CA

```bash
docker run \
... \
--label easyhaproxy.express.port=80 \
--label easyhaproxy.express.localport=3000 \
--label easyhaproxy.express.host=example.org \
--label easyhaproxy.express.certbot=true \
... \
some/myimage
```

Requirements:

- Your container **must** listen to port 80. The CA will not issue the certificate if `easyhaproxy.<definition>.port` is in another port, and EasyHAProxy will fail silently.
- You cannot set port 443 for the container with the Letsencrypt because EasyHAProxy will create this port automatically once the certificate is issued.

----
[Open source ByJG](http://opensource.byjg.com)
27 changes: 14 additions & 13 deletions docs/container-labels.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@

## Container (Docker or Swarm) labels

| Tag | Description | Default | Example |
|---------------------------------------|-------------------------------------------------------------------------------------------------------|----------------|--------------|
| easyhaproxy.[definition].host | Host(s) HAProxy is listening. More than one host use comma as delimiter | **required** | somehost.com OR host1.com,host2.com |
| easyhaproxy.[definition].mode | (Optional) Is this `http` or `tcp` mode in HAProxy. | http | http or tcp |
| easyhaproxy.[definition].port | (Optional) Port HAProxy will listen for the host. | 80 | 3000 |
| easyhaproxy.[definition].localport | (Optional) Port container is listening. | 80 | 8080 |
| easyhaproxy.[definition].redirect | (Optional) JSON containing key/value pair from host/to URL redirect. | *empty* | {"foo.com":"https://bla.com", "bar.com":"https://bar.org"} |
| easyhaproxy.[definition].sslcert | (Optional) Cert PEM Base64 encoded. Do not use this if `letsencrypt` is enabled. | *empty* | base64 cert + key |
| easyhaproxy.[definition].ssl | (Optional) If `true` you need to provide certificate as a file. See below. Do not use with `sslcert`. | false | true or false |
| easyhaproxy.[definition].health-check | (Optional) `ssl`, enable health check via SSL in `mode tcp` | *empty* | ssl |
| easyhaproxy.[definition].letsencrypt | (Optional) Generate certificate with letsencrypt. Do not use with `sslcert` parameter. | false | true OR false |
| easyhaproxy.[definition].redirect_ssl | (Optional) Redirect all requests to https | false | true OR false |
| easyhaproxy.[definition].clone_to_ssl | (Optional) It copies the configuration to HTTPS(443) and disable SSL from the current config. **Do not use* this with `ssl` or `letsencrypt` parameters | false | true OR false |
| Tag | Description | Default | Example |
|---------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|--------------|------------------------------------------------------------|
| easyhaproxy.[definition].host | Host(s) HAProxy is listening. More than one host use comma as delimiter | **required** | somehost.com OR host1.com,host2.com |
| easyhaproxy.[definition].mode | (Optional) Is this `http` or `tcp` mode in HAProxy. | http | http or tcp |
| easyhaproxy.[definition].port | (Optional) Port HAProxy will listen for the host. | 80 | 3000 |
| easyhaproxy.[definition].localport | (Optional) Port container is listening. | 80 | 8080 |
| easyhaproxy.[definition].redirect | (Optional) JSON containing key/value pair from host/to URL redirect. | *empty* | {"foo.com":"https://bla.com", "bar.com":"https://bar.org"} |
| easyhaproxy.[definition].sslcert | (Optional) Cert PEM Base64 encoded. Do not use this if `certbot` is enabled. | *empty* | base64 cert + key |
| easyhaproxy.[definition].ssl | (Optional) If `true` you need to provide certificate as a file. See below. Do not use with `sslcert`. | false | true or false |
| easyhaproxy.[definition].ssl-check | (Optional) `ssl`, enable health check via SSL in `mode tcp` | *empty* | ssl |
| easyhaproxy.[definition].certbot | (Optional) Generate certificate with certbot. Do not use with `sslcert` parameter. More info [here](acme.md). | false | true OR false |
| easyhaproxy.[definition].redirect_ssl | (Optional) Redirect all requests to https | false | true OR false |
| easyhaproxy.[definition].clone_to_ssl | (Optional) It copies the configuration to HTTPS(443) and disable SSL from the current config. **Do not use* this with `ssl` or `certbot` parameters | false | true OR false |
| easyhaproxy.[definition].balance | (Optional) HAProxy balance algorithm. See [HAProxy documentation](https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4.2-balance) | roundrobin | roundrobin, source, uri, url_param, hdr, rdp-cookie, leastconn, first, static-rr, rdp-cookie, hdr_dom, map-based |

The `definition` is a string that will group all configurations togethers. Different `definition` will create different configurations.

Expand Down
22 changes: 0 additions & 22 deletions docs/docker-environment.md

This file was deleted.

Loading

0 comments on commit 5d03751

Please sign in to comment.