Add functionality by copy-pasting pre-generated certs to vm and update README.md

This commit includes the pre-generated certs in the files/certs
directory. README.md was thoroughly updated to include an example of
using certbot with this role and how to import the root.crt to Firefox.
This commit is contained in:
Santeri Kainulainen 2025-12-01 15:51:30 +02:00
parent b3204eb4da
commit 733c3ed250
8 changed files with 130 additions and 12 deletions

View file

@ -1,15 +1,44 @@
# Kifi Caddy
Installs and configures Caddy for use as a local ACME CA server allowing certificates to be issued in testing
Installs and configures Caddy for use as a local ACME CA server allowing certificates to be issued in testing.
This role should function as of now, but for example certificate lifetime changes don't work (defaults to 12h).
## Example usage
In your playbook, define the role and config paths. Most likely the defaults are fine, so you can just simply add the role. Remember to add this before any certbot role. The ACME server is hosted at port 8443. You can also change the `templates/Caddyfile.j2` to fit your own needs.
Example:
Example for tilastot.kirjastot.fi.local:
```
- role: caddy
- role: kifi.caddy
caddy_config_path: /etc/caddy/Caddyfile
caddy_root: /var/www/caddy
caddy_service_name: caddy
```
```
Another example of how to use this in combination with the kifi.certbot role:
```
tasks:
- name: Run Certbot role
include_role:
name: kifi.certbot
vars:
certbot_disable_certbot_cron: yes
certbot_host_with_certs: tilastot.kirjastot.fi.local
certbot_create_if_missing: yes
certbot_admin_email: tekniikka@kirjastot.fi
certbot_certs:
- domains:
- tilastot.kirjastot.fi.local
certbot_create_command: >
sudo -E REQUESTS_CA_BUNDLE=/var/lib/caddy/.local/share/caddy/pki/authorities/local/root.crt
certbot certonly --server https://localhost:8443/acme/local/directory
--standalone
--email {{ certbot_admin_email }}
--agree-tos
--non-interactive
-d {{ certbot_certs | map(attribute='domains') | flatten | join(' -d ') }}
tags: certbot, ssl
```
Note that the domains get looped over, so you can have multiple of them.
Certificates for domains can be found in the folder /etc/letsencrypt/live/domainname though it might be wise to change this

View file

@ -2,4 +2,27 @@
caddy_root: /usr/share/caddy
caddy_config_path: /etc/caddy/Caddyfile
caddy_service_name: caddy
caddy_service_name: caddy
caddy_trust_local_ca: false
# system user/group for Caddy runtime files
caddy_user: caddy
caddy_group: caddy
# path where role will deploy Caddy authority certs
caddy_authorities_path: /var/lib/caddy/.local/share/caddy/pki/authorities/local
caddy_authorities_mode: '0700'
# templates subdirectory that contains the cert files (role/templates/<dir>/...)
caddy_certs_template_dir: certs
# ownership/mode for deployed cert files
caddy_cert_owner: "{{ caddy_user }}"
caddy_cert_group: "{{ caddy_group }}"
caddy_cert_mode: '0600'
# ownership/mode for caddy_root
caddy_root_owner: www-data
caddy_root_group: www-data
caddy_root_mode: '0755'

View file

@ -0,0 +1,12 @@
-----BEGIN CERTIFICATE-----
MIIBtDCCAVqgAwIBAgIRAMHp+q/ddqH+S9fE5V7QhhkwCgYIKoZIzj0EAwIwJjEk
MCIGA1UEAxMbTXkgTG9jYWwgQ0EgLSAyMDI1IEVDQyBSb290MB4XDTI1MTIwMTEz
MTg1M1oXDTI1MTIwODEzMTg1M1owKTEnMCUGA1UEAxMeTXkgTG9jYWwgQ0EgLSBF
Q0MgSW50ZXJtZWRpYXRlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZL83Hyar
iIsBkRtRNxRtHoiW7KEUuxq4gVyNrJjtdYZwlfZE+qOCYo5I6E99zZiVD2SZNe1x
uVXYV6mcERDnC6NmMGQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8C
AQAwHQYDVR0OBBYEFJII7wjwySNFSJWt700GYE1JfsGxMB8GA1UdIwQYMBaAFHCv
EafSET7wyiMUOd3eZrQx3lw8MAoGCCqGSM49BAMCA0gAMEUCIQCCj54nwceSHHJ+
RCN2CyEByqMh/RdDd/FijJ800x3J6gIgemnp9J3CrKN/Fzy3JOhetVCRkVqjDNLc
ZH4K1pYnDBA=
-----END CERTIFICATE-----

View file

@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIDLfKjCXLIseInlVmkL1dx6K/Iv6uxjhJjRmI4xr9kXNoAoGCCqGSM49
AwEHoUQDQgAEZL83HyariIsBkRtRNxRtHoiW7KEUuxq4gVyNrJjtdYZwlfZE+qOC
Yo5I6E99zZiVD2SZNe1xuVXYV6mcERDnCw==
-----END EC PRIVATE KEY-----

11
files/certs/root.crt Normal file
View file

@ -0,0 +1,11 @@
-----BEGIN CERTIFICATE-----
MIIBjzCCATWgAwIBAgIQMNAFWqphrzOxuSOWVbSr4jAKBggqhkjOPQQDAjAmMSQw
IgYDVQQDExtNeSBMb2NhbCBDQSAtIDIwMjUgRUNDIFJvb3QwHhcNMjUxMjAxMTMx
ODUzWhcNMzUxMDEwMTMxODUzWjAmMSQwIgYDVQQDExtNeSBMb2NhbCBDQSAtIDIw
MjUgRUNDIFJvb3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASD2byYNpauRUOg
LggkyrY/ZRMZIQMT+rXlQMctxnV77VOdaXccTC2vfpOS2tqwcwySyP1NYg1DqvD0
L4VjUb/To0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBATAd
BgNVHQ4EFgQUcK8Rp9IRPvDKIxQ53d5mtDHeXDwwCgYIKoZIzj0EAwIDSAAwRQIh
AI4rOGX/GNjlUnwixzcXM1FFrBrarzRZd/6+z99I+1yhAiAqxxK69h4ae0nylgVO
pKlmiO5bk38ZfwjN6qAIqMaCcg==
-----END CERTIFICATE-----

5
files/certs/root.key Normal file
View file

@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEICFWtuowkCW/82uhRaJUuisuQFQ3kQc6WH2xopi6aID8oAoGCCqGSM49
AwEHoUQDQgAEg9m8mDaWrkVDoC4IJMq2P2UTGSEDE/q15UDHLcZ1e+1TnWl3HEwt
r36TktrasHMMksj9TWINQ6rw9C+FY1G/0w==
-----END EC PRIVATE KEY-----

View file

@ -4,6 +4,7 @@
state: present
- name: Create Caddy configuration directory
become: yes
ansible.builtin.file:
path: /etc/caddy
state: directory
@ -12,15 +13,40 @@
mode: '0755'
- name: Deploy Caddyfile
become: yes
ansible.builtin.template:
src: Caddyfile.j2
dest: "{{ caddy_config_path }}"
owner: root
group: root
mode: '0644'
notify: Restart Caddy
- name: Ensure Caddy authorities directory exists
become: yes
ansible.builtin.file:
path: /var/lib/caddy/.local/share/caddy/pki/authorities/local
state: directory
owner: caddy
group: caddy
mode: '0700'
# Copy the pre-generated certs from files/certs folder to Caddy,
# so that you only need to import the root.crt once for all .local domains
- name: Deploy Caddy root certificates
become: yes
vars:
cert_list: "{{ lookup('fileglob', role_path + '/files/certs/*', wantlist=True) | map('basename') | list }}"
ansible.builtin.copy:
src: "certs/{{ item }}"
dest: "{{ caddy_authorities_path }}/{{ item }}"
owner: caddy
group: caddy
mode: '0600'
force: yes
loop: "{{ cert_list }}"
- name: Ensure Caddy root directory exists
become: yes
ansible.builtin.file:
path: "{{ caddy_root }}"
state: directory
@ -29,14 +55,24 @@
mode: '0755'
- name: Start and enable Caddy service
become: yes
ansible.builtin.service:
name: "{{ caddy_service_name }}"
state: started
enabled: true
- name: Restart Caddy
become: yes
ansible.builtin.service:
name: "{{ caddy_service_name }}"
state: restarted
# By default don't trust as its not usually needed
- name: Trust Caddy local CA
become: yes
copy:
src: /var/lib/caddy/.local/share/caddy/pki/authorities/local/root.crt
dest: /usr/local/share/ca-certificates/caddy-local.crt
remote_src: yes
notify: Update CA trust
notify: Update CA trust
when: caddy_trust_local_ca | default(false) | bool

View file

@ -11,9 +11,6 @@
localhost:8443 {
acme_server {
ca local
lifetime 720h
}
}
# Refer to the Caddy docs for more information:
# https://caddyserver.com/docs/caddyfile
}