Skip to content

Add support for configuring TLS certificates (bring your own cert) #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ansible.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ jobs:
ansible-lint -x fqcn-builtins,var-spacing -c .ansible-lint

molecule test -s default
molecule test -s tls
132 changes: 126 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,6 @@ Name and group of the user running the minio server.
minio_server_envfile: /etc/default/minio
```

You can specify the location of your existing config using --config-dir (default: ${HOME}/.minio)

```yaml
minio_config_dir: "/etc/minio"
```

Path to the file containing the minio server configuration ENV variables.

```yaml
Expand Down Expand Up @@ -116,6 +110,132 @@ minio_install_server: true
minio_install_client: true
```

### TLS

```yaml
minio_enable_tls: false
```
Turn on or off TLS support. This requires also configuring TLS certificates, but if you just want TLS and don't care about serving multiple domains (SNI) or about proper handling of the private keys, just set `minio_enable_tls: true` and fill out the `minio_tls_public_cert` and `minio_tls_private_key` variables accordingly (you may want to use e.g. [certgen](https://github.com/minio/certgen/) to generate a certificate if you don't have one already).

If you need to serve multiple domains (SNI), you can put the contents of your PEM-encoded certificate files and keys in the Ansible variables documented below, or you can opt to have this role create symlinks to certificate files managed outside of this role. The latter is useful when using automatically renewing certificates such as those from the LetsEncrypt CA.

If you need to specify custom certificate authorities (CAs) you also have a similar choice of storing them in Ansible variables or create symlinks - or both.

It's possible to mix and match these two methods for any combination of certificates/keys/CAs, but keep in mind that for private keys stored in Ansible variables, you should probably use something like [Ansible Vault](https://docs.ansible.com/ansible/latest/cli/ansible-vault.html).

Refer to the MinIO TLS documentation for more information: https://min.io/docs/minio/linux/operations/network-encryption.html

```yaml
minio_certs_dir: "/etc/minio/certs"
```
Directory to store MinIO certificates.

```yaml
minio_certs_dir_basedir_owner: root
```
Owner of the directory above the certs dir (default location /etc/minio)

```yaml
minio_certs_dir_owner: "{{ minio_user }}"
```
Owner of the certs directory. It's recommended to change this to root (or whichever user manages the renewal of certs) in production.

```yaml
minio_certs_owner: "{{ minio_user }}"
```
Owner of the files in the certs directory. It's recommended to change this to root (or whichever user manages the renewal of certs) in production

```yaml
minio_tls_directory_permissions: '0750'
minio_tls_file_permissions: '0640'
```

File and directory permissions for certificates stored under `minio_certs_dir`. There is typically no need to change these and if there is, it is usually to just remove the owner's write permissions on the files.

```yaml
minio_tls_hostnames: []
```
Hostnames to set up for multiple domain-based TLS certificates (SNI). Must match the hostnames in `minio_hostspecific_*` vars (or those part of the paths specified in in externally managed certs)

```yaml
minio_tls_public_cert: ""
```
If you only want to use a single certificate regardless of domain, this is the variable to put the (public) certificate in.
```yaml
minio_tls_private_key: ""
```
If you only want to use a single certificate regardless of domain, this is the variable to put the private key for it it in.

```yaml
minio_tls_hostspecific_public_certs:
- hostname: example1.lan
content: |
-----BEGIN CERTIFICATE-----
.....
-----END CERTIFICATE-----
- hostname: example2.lan
content: |
-----BEGIN CERTIFICATE-----
.....
-----END CERTIFICATE-----
```
If you want MinIO to serve content over TLS to multiple domains (hostnames) and use Server Name Indication to answer with different certificates for different domains, this is the variable to put the (public) certificates in and map them to the correct domain (hostname). Any hostnames specified here must also be present in the `minio_tls_hostnames` list.
```yaml
minio_tls_hostspecific_private_keys:
- hostname: example1.lan
content: |
-----BEGIN PRIVATE KEY-----
.....
-----END PRIVATE KEY-----
- hostname: example2.lan
content: |
-----BEGIN PRIVATE KEY-----
.....
-----END PRIVATE KEY-----
```
If you want MinIO to serve content over TLS to multiple domains (hostnames) and use Server Name Indication to answer with different certificates for different domains, this is the variable to put the (private) keys in and map them to the correct domain (hostname). Any hostnames specified here must also be present in the `minio_tls_hostnames` list.

```yaml
minio_tls_cacerts:
- filename: ca1.crt
content: |
-----BEGIN CERTIFICATE-----
.....
-----END CERTIFICATE-----
- filename: ca2.crt
content: |
-----BEGIN CERTIFICATE-----
.....
-----END CERTIFICATE-----
```

This is for putting CA certs in the `CAs` subdirectory of `minio_certs_dir`. If your certificate(s)
are signed by certificate authorities that the system doesn't already trust, you'll want to put them
here.

```yaml
minio_tls_externally_managed_certs: []
- crt_src: /usr/local/share/minio/certs/example1.lan.crt
key_src: /usr/local/share/minio/private/example1.lan.key
crt_dst: example1.lan/public.crt
key_dst: example1.lan/private.key
- crt_src: /usr/local/share/minio/certs/example2.lan.crt
key_src: /usr/local/share/minio/private/example2.lan.key
crt_dst: example2.lan/public.crt
key_dst: example2.lan/private.key
```

If you want to use certificate files (and corresponding private key files) that are stored outside the `minio_certs_dir` (such as if they are managed by something other than this role), you can use this variable to specify a mapping and the role will then create the appropriate symlinks. Just make sure the source files are accessible to the user/group specified in `minio_user`/`minio_group`.

```yaml
minio_tls_externally_managed_cacerts: []
- ca_src: /usr/local/share/minio/CAs/ca1.crt
ca_dst: ca1.crt
- ca_src: /usr/local/share/minio/CAs/ca2.crt
ca_dst: ca2.crt
```
Like the `minio_tls_externally_managed_certs` variable, this is just for setting up symlinks to externally managed CA certificates located outside the `minio_certs_dir`.

## Dependencies

None.
Expand Down
91 changes: 86 additions & 5 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ minio_group: minio
# Path to the file containing the ENV variables for the MinIO server
minio_server_envfile: /etc/default/minio

# Directory to store minio config. Will default to minio_user/.minio if not defined
minio_config_dir: "/etc/minio"

# Minio server ip/fqdn and port. This makes up the server_addr below
minio_server_ip: ""
minio_server_port: "9000"
Expand Down Expand Up @@ -59,5 +56,89 @@ minio_root_password: "{{ minio_secret_key | default('minioadmin') }}"
minio_install_server: true
minio_install_client: true

# TODO: in future
minio_enable_ssl: false
# Enable TLS
minio_enable_tls: false

# Directory to store minio certificates
minio_certs_dir: "/etc/minio/certs"

# Owner of the directory above the certs dir (default location /etc/minio)
minio_certs_dir_basedir_owner: root

# Owner of the certs dir
minio_certs_dir_owner: "{{ minio_user }}"

# Owner of the files in the certs dir
minio_certs_owner: "{{ minio_user }}"

minio_tls_directory_permissions: '0750'
minio_tls_file_permissions: '0640'

# Hostnames to set up for multiple domain-based TLS certificates (SNI)
# Must match the hostnames in `minio_hostspecific_*` vars (or those part of the paths specified in in externally managed certs)
minio_tls_hostnames: []
# - example1.lan
# - example2.lan

minio_tls_public_cert: "" # |
# -----BEGIN CERTIFICATE-----
# .....
# -----END CERTIFICATE-----

minio_tls_private_key: "" # |
# -----BEGIN PRIVATE KEY-----
# .....
# -----END PRIVATE KEY-----

minio_tls_hostspecific_public_certs: []
# - hostname: example.lan
# content: |
# -----BEGIN CERTIFICATE-----
# .....
# -----END CERTIFICATE-----
# - hostname: example2.lan
# content: |
# -----BEGIN CERTIFICATE-----
# .....
# -----END CERTIFICATE-----

minio_tls_hostspecific_private_keys: []
# - hostname: example.lan
# content: |
# -----BEGIN PRIVATE KEY-----
# .....
# -----END PRIVATE KEY-----
# - hostname: example2.lan
# content: |
# -----BEGIN PRIVATE KEY-----
# .....
# -----END PRIVATE KEY-----

minio_tls_cacerts: []
# - filename: ca1.crt
# content: |
# -----BEGIN CERTIFICATE-----
# .....
# -----END CERTIFICATE-----
# - filename: ca2.crt
# content: |
# -----BEGIN CERTIFICATE-----
# .....
# -----END CERTIFICATE-----


minio_tls_externally_managed_certs: []
# - crt_src: /usr/local/share/minio/certs/example1.crt
# key_src: /usr/local/share/minio/private/example1.key
# crt_dst: example1.lan/public.crt
# key_dst: example1.lan/private.key
# - crt_src: /usr/local/share/minio/certs/example2.crt
# key_src: /usr/local/share/minio/private/example2.key
# crt_dst: example2.lan/public.crt
# key_dst: example2.lan/private.key

minio_tls_externally_managed_cacerts: []
# - ca_src: /usr/local/share/minio/CAs/ca1.crt
# ca_dst: ca1.crt
# - ca_src: /usr/local/share/minio/CAs/ca2.crt
# ca_dst: ca2.crt
25 changes: 25 additions & 0 deletions molecule/resources/tests/verify-tls.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
- name: Verify
hosts: all
tasks:
- name: Populate service facts
service_facts:

- name: Assert that minio service is running
assert:
that: |
"'running' in ansible_facts.services['minio.service'].state"
or
"'running' in ansible_facts.services['minio'].state"

- name: Check MinIO WebUI
ansible.builtin.uri:
url: "https://localhost:9000/minio/login"
status_code: 200
headers:
User-Agent: "Mozilla/5.0"
validate_certs: false
register: login_page
until: login_page.status == 200
retries: 10
delay: 1
6 changes: 6 additions & 0 deletions molecule/tls/converge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---

- hosts: all
any_errors_fatal: true
roles:
- ansible-minio
Loading