wip: letsencrypt
This commit is contained in:
parent
04df1bd919
commit
5d4d2de910
67
README.md
67
README.md
|
@ -53,7 +53,7 @@ Install myos on a server and manage server config with ansible.
|
||||||
|
|
||||||
* DEBUG
|
* DEBUG
|
||||||
|
|
||||||
Show executed commands
|
Show executed commands.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ make up DEBUG=true
|
$ make up DEBUG=true
|
||||||
|
@ -61,7 +61,7 @@ $ make up DEBUG=true
|
||||||
|
|
||||||
* DRYRUN
|
* DRYRUN
|
||||||
|
|
||||||
Do nothing, show commands instead of executing it
|
Do nothing, show commands instead of executing it.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ make up DRYRUN=true
|
$ make up DRYRUN=true
|
||||||
|
@ -69,7 +69,7 @@ $ make up DRYRUN=true
|
||||||
|
|
||||||
* VERBOSE
|
* VERBOSE
|
||||||
|
|
||||||
Show called functions
|
Show called functions.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ make up VERBOSE=true
|
$ make up VERBOSE=true
|
||||||
|
@ -81,6 +81,67 @@ $ make up VERBOSE=true
|
||||||
$ make print-VARIABLE
|
$ make print-VARIABLE
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Setup
|
||||||
|
|
||||||
|
* SETUP_LETSENCRYPT
|
||||||
|
|
||||||
|
Generate ${DOMAIN} certificate files with letsencrypt.
|
||||||
|
|
||||||
|
By default, myos generates invalid ${DOMAIN} certificate files with openssl.
|
||||||
|
You can use letsencrypt instead, to generate valid wildcard certificate files.
|
||||||
|
|
||||||
|
To achieve this, you must add following DNS entries to domain ${DOMAIN} to prove you own it:
|
||||||
|
|
||||||
|
```
|
||||||
|
_acme-challenge.${DOMAIN} IN CNAME ${DOMAIN}.acme.${DOMAIN}.
|
||||||
|
acme.${DOMAIN}. IN NS certbot.${DOMAIN}.
|
||||||
|
certbot.${DOMAIN}. IN A ${DOCKER_HOST_INET4}
|
||||||
|
```
|
||||||
|
|
||||||
|
In this config, DOCKER_HOST_INET4 should be the external IP address of the server running certbot.
|
||||||
|
Port 53 of this IP address must be reachable from internet and point to this server.
|
||||||
|
|
||||||
|
If you want a simple DNS configuration to host all your services on the same server, you can setup following DNS config:
|
||||||
|
|
||||||
|
```
|
||||||
|
@ IN A ${DOCKER_HOST_INET4}
|
||||||
|
*.${DOMAIN}. IN CNAME ${DOMAIN}.
|
||||||
|
_acme-challenge.${DOMAIN} IN CNAME ${DOMAIN}.acme.${DOMAIN}.
|
||||||
|
acme.${DOMAIN}. IN NS ${DOMAIN}.
|
||||||
|
```
|
||||||
|
|
||||||
|
This will point domain ${DOMAIN} to the IP address ${DOCKER_HOST_INET4} of this server, and point all subdomains *.{DOMAIN} to the ip address pointed by ${DOMAIN}.
|
||||||
|
|
||||||
|
At this point, you should be able to generate a valid certificate for *.${DOMAIN} using certbot [dns standalone](https://github.com/siilike/certbot-dns-standalone) plugin.
|
||||||
|
This task is done automatically when creating the node stack if SETUP_LETSENCRYPT variable is not empty.
|
||||||
|
|
||||||
|
If you already launched myos node stack before, the ${DOMAIN} certificates has been automatically generated by openssl and you should remove them before trying to generate them with letsencrypt.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ make node-down
|
||||||
|
$ docker volume rm node_myos
|
||||||
|
```
|
||||||
|
|
||||||
|
You can then test the letsencrypt certificate generation using DEBUG mode that force to use the letsencrypt staging server.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ make node SETUP_LETSENCRYPT=true DEBUG=true
|
||||||
|
```
|
||||||
|
|
||||||
|
If letsencrypt certificate generation fails, you can retry the generation of a staging certificate.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ make node-certbot-staging
|
||||||
|
```
|
||||||
|
|
||||||
|
Once the certificate generation is working, you can ask for a valid certificate.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ make node-down
|
||||||
|
$ docker volume rm node_myos
|
||||||
|
$ make node SETUP_LETSENCRYPT=true
|
||||||
|
```
|
||||||
|
|
||||||
### Debug
|
### Debug
|
||||||
|
|
||||||
* Show docker compose yaml config
|
* Show docker compose yaml config
|
||||||
|
|
|
@ -41,7 +41,6 @@ CONFIG_REPOSITORY_URI ?= $(shell printf '$(CONFIG_REPOSITORY_URL)\n' |
|
||||||
CONFIG_REPOSITORY_URL ?= $(call pop,$(APP_UPSTREAM_REPOSITORY))/$(notdir $(CONFIG))
|
CONFIG_REPOSITORY_URL ?= $(call pop,$(APP_UPSTREAM_REPOSITORY))/$(notdir $(CONFIG))
|
||||||
CONTEXT ?= ENV $(shell awk 'BEGIN {FS="="}; $$1 !~ /^(\#|$$)/ {print $$1}' .env.dist 2>/dev/null)
|
CONTEXT ?= ENV $(shell awk 'BEGIN {FS="="}; $$1 !~ /^(\#|$$)/ {print $$1}' .env.dist 2>/dev/null)
|
||||||
CONTEXT_DEBUG ?= MAKEFILE_LIST DOCKER_ENV_ARGS ENV_ARGS APPS GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME MAKE_DIR MAKE_SUBDIRS MAKE_CMD_ARGS MAKE_ENV_ARGS UID USER
|
CONTEXT_DEBUG ?= MAKEFILE_LIST DOCKER_ENV_ARGS ENV_ARGS APPS GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME MAKE_DIR MAKE_SUBDIRS MAKE_CMD_ARGS MAKE_ENV_ARGS UID USER
|
||||||
CERTBOT ?=
|
|
||||||
DEBUG ?=
|
DEBUG ?=
|
||||||
DOCKER ?= $(shell type -p docker)
|
DOCKER ?= $(shell type -p docker)
|
||||||
DOMAIN ?= localhost
|
DOMAIN ?= localhost
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
ENV_VARS += IPFS_DAEMON_ARGS IPFS_PROFILE IPFS_VERSION
|
ENV_VARS += IPFS_DAEMON_ARGS IPFS_PROFILE IPFS_VERSION
|
||||||
IPFS_PROFILE ?= $(if $(filter-out amd64 x86_64,$(MACHINE)),lowpower,server)
|
IPFS_PROFILE ?= $(if $(filter-out amd64 x86_64,$(MACHINE)),lowpower,server)
|
||||||
IPFS_VERSION ?= 0.15.0
|
IPFS_VERSION ?= 0.16.0
|
||||||
|
|
||||||
.PHONY: bootstrap-stack-ipfs
|
.PHONY: bootstrap-stack-ipfs
|
||||||
bootstrap-stack-ipfs: ~/.ipfs
|
bootstrap-stack-ipfs: ~/.ipfs setup-sysctl
|
||||||
|
|
||||||
~/.ipfs:
|
~/.ipfs:
|
||||||
mkdir -p ~/.ipfs
|
mkdir -p ~/.ipfs
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
CMDS += node-exec stack-node-exec node-exec:% node-exec@% node-run node-run:% node-run@%
|
CMDS += node-exec stack-node-exec node-exec:% node-exec@% node-run node-run:% node-run@%
|
||||||
node ?= node/node
|
node ?= node/node
|
||||||
ENV_VARS += DOCKER_HOST_IFACE DOCKER_HOST_INET4 DOCKER_INTERNAL_DOCKER_HOST
|
ENV_VARS += DOCKER_HOST_IFACE DOCKER_HOST_INET4 DOCKER_INTERNAL_DOCKER_HOST
|
||||||
|
SETUP_LETSENCRYPT ?=
|
||||||
|
|
||||||
# target bootstrap-stack-node: Fire node-certbot node-ssl-certs
|
# target bootstrap-stack-node: Fire node-certbot node-ssl-certs
|
||||||
.PHONY: bootstrap-stack-node
|
.PHONY: bootstrap-stack-node
|
||||||
bootstrap-stack-node: docker-network-create-$(DOCKER_NETWORK_PUBLIC) $(if $(CERTBOT),node-certbot) node-ssl-certs
|
bootstrap-stack-node: docker-network-create-$(DOCKER_NETWORK_PUBLIC) $(if $(SETUP_LETSENCRYPT),node-certbot$(if $(DEBUG),-staging)) node-ssl-certs
|
||||||
|
|
||||||
# target node: Fire stack-node-up
|
# target node: Fire stack-node-up
|
||||||
.PHONY: node
|
.PHONY: node
|
||||||
|
@ -14,26 +15,38 @@ node: stack-node-up
|
||||||
.PHONY: node-%
|
.PHONY: node-%
|
||||||
node-%: stack-node-%;
|
node-%: stack-node-%;
|
||||||
|
|
||||||
# target node-ssl-certs: Create invalid ${DOMAIN}/privkey.pem and ${DOMAIN}/cert.pem certificate files
|
# target node-ssl-certs: Create invalid ${DOMAIN} certificate files with openssl
|
||||||
.PHONY: node-ssl-certs
|
.PHONY: node-ssl-certs
|
||||||
node-ssl-certs:
|
node-ssl-certs:
|
||||||
docker run --rm --mount source=$(NODE_DOCKER_VOLUME),target=/certs alpine \
|
docker run --rm --mount source=$(NODE_DOCKER_VOLUME),target=/certs alpine \
|
||||||
[ -f /certs/live/$(DOMAIN)/cert.pem -a -f /certs/live/$(DOMAIN)/privkey.pem ] \
|
[ -f /certs/live/$(DOMAIN)/fullchain.pem -a -f /certs/live/$(DOMAIN)/privkey.pem ] \
|
||||||
|| $(RUN) docker run --rm -e DOMAIN=$(DOMAIN) --mount source=$(NODE_DOCKER_VOLUME),target=/certs alpine sh -c "\
|
|| $(RUN) docker run --rm \
|
||||||
|
-e DOMAIN=$(DOMAIN) \
|
||||||
|
--mount source=$(NODE_DOCKER_VOLUME),target=/certs \
|
||||||
|
alpine sh -c "\
|
||||||
apk --no-cache add openssl \
|
apk --no-cache add openssl \
|
||||||
&& mkdir -p /certs/live/${DOMAIN} \
|
&& mkdir -p /certs/live/${DOMAIN} \
|
||||||
&& { [ -f /certs/live/${DOMAIN}/privkey.pem ] || openssl genrsa -out /certs/live/${DOMAIN}/privkey.pem 2048; } \
|
&& { [ -f /certs/live/${DOMAIN}/privkey.pem ] || openssl genrsa -out /certs/live/${DOMAIN}/privkey.pem 2048; } \
|
||||||
&& openssl req -key /certs/live/${DOMAIN}/privkey.pem -out /certs/live/${DOMAIN}/cert.pem \
|
&& openssl req -key /certs/live/${DOMAIN}/privkey.pem -out /certs/live/${DOMAIN}/cert.pem \
|
||||||
-addext extendedKeyUsage=serverAuth \
|
-addext extendedKeyUsage=serverAuth \
|
||||||
-addext subjectAltName=DNS:${DOMAIN} \
|
-addext subjectAltName=DNS:${DOMAIN},DNS:*.${DOMAIN} \
|
||||||
-subj \"/C=/ST=/L=/O=/CN=${DOMAIN}\" \
|
-subj \"/C=/ST=/L=/O=/CN=${DOMAIN}\" \
|
||||||
-x509 -days 365"
|
-x509 -days 365 \
|
||||||
|
&& rm -f /certs/live/${DOMAIN}/fullchain.pem \
|
||||||
|
&& ln -s cert.pem /certs/live/${DOMAIN}/fullchain.pem \
|
||||||
|
"
|
||||||
|
|
||||||
# target node-certbot: Create letsencrypt ${DOMAIN}/privkey.pem and ${DOMAIN}/cert.pem files
|
# target node-certbot: Create ${DOMAIN} certificate files with letsencrypt
|
||||||
.PHONY: node-certbot
|
.PHONY: node-certbot
|
||||||
node-certbot: node-docker-build-certbot
|
node-certbot: node-docker-build-certbot
|
||||||
docker run --rm --mount source=$(NODE_DOCKER_VOLUME),target=/certs alpine [ -f /certs/live/$(DOMAIN)/cert.pem -a -f /certs/live/$(DOMAIN)/privkey.pem ] \
|
docker run --rm --mount source=$(NODE_DOCKER_VOLUME),target=/certs alpine \
|
||||||
|| $(RUN) docker run --rm --mount source=$(NODE_DOCKER_VOLUME),target=/etc/letsencrypt/ --mount source=$(NODE_DOCKER_VOLUME),target=/var/log/letsencrypt/ -e DOMAIN=$(DOMAIN) --network host node/certbot \
|
[ -f /certs/live/$(DOMAIN)/cert.pem -a -f /certs/live/$(DOMAIN)/privkey.pem ] \
|
||||||
|
|| $(RUN) docker run --rm \
|
||||||
|
--mount source=$(NODE_DOCKER_VOLUME),target=/etc/letsencrypt/ \
|
||||||
|
--mount source=$(NODE_DOCKER_VOLUME),target=/var/log/letsencrypt/ \
|
||||||
|
-e DOMAIN=$(DOMAIN) \
|
||||||
|
--network host \
|
||||||
|
node/certbot \
|
||||||
--non-interactive --agree-tos --email hostmaster@${DOMAIN} certonly \
|
--non-interactive --agree-tos --email hostmaster@${DOMAIN} certonly \
|
||||||
--preferred-challenges dns --authenticator dns-standalone \
|
--preferred-challenges dns --authenticator dns-standalone \
|
||||||
--dns-standalone-address=0.0.0.0 \
|
--dns-standalone-address=0.0.0.0 \
|
||||||
|
@ -51,11 +64,17 @@ node-certbot-certificates: node-docker-build-certbot
|
||||||
node-certbot-renew: node-docker-build-certbot
|
node-certbot-renew: node-docker-build-certbot
|
||||||
docker run --rm --mount source=$(NODE_DOCKER_VOLUME),target=/etc/letsencrypt/ --network host node/certbot renew
|
docker run --rm --mount source=$(NODE_DOCKER_VOLUME),target=/etc/letsencrypt/ --network host node/certbot renew
|
||||||
|
|
||||||
# target node-certbot-staging: Create staging letsencrypt ${DOMAIN}/privkey.pem and ${DOMAIN}/cert.pem files
|
# target node-certbot-staging: Create staging ${DOMAIN} certificate files with letsencrypt
|
||||||
.PHONY: node-certbot-staging
|
.PHONY: node-certbot-staging
|
||||||
node-certbot-staging: node-docker-build-certbot
|
node-certbot-staging: node-docker-build-certbot
|
||||||
docker run --rm --mount source=$(NODE_DOCKER_VOLUME),target=/certs alpine [ -f /certs/live/$(DOMAIN)/cert.pem -a -f /certs/live/$(DOMAIN)/privkey.pem ] \
|
docker run --rm --mount source=$(NODE_DOCKER_VOLUME),target=/certs alpine \
|
||||||
|| $(RUN) docker run --rm --mount source=$(NODE_DOCKER_VOLUME),target=/etc/letsencrypt/ --mount source=$(NODE_DOCKER_VOLUME),target=/var/log/letsencrypt/ -e DOMAIN=$(DOMAIN) --network host node/certbot \
|
[ -f /certs/live/$(DOMAIN)/cert.pem -a -f /certs/live/$(DOMAIN)/privkey.pem ] \
|
||||||
|
|| $(RUN) docker run --rm \
|
||||||
|
--mount source=$(NODE_DOCKER_VOLUME),target=/etc/letsencrypt/ \
|
||||||
|
--mount source=$(NODE_DOCKER_VOLUME),target=/var/log/letsencrypt/ \
|
||||||
|
-e DOMAIN=$(DOMAIN) \
|
||||||
|
--network host \
|
||||||
|
node/certbot \
|
||||||
--non-interactive --agree-tos --email hostmaster@${DOMAIN} certonly \
|
--non-interactive --agree-tos --email hostmaster@${DOMAIN} certonly \
|
||||||
--preferred-challenges dns --authenticator dns-standalone \
|
--preferred-challenges dns --authenticator dns-standalone \
|
||||||
--dns-standalone-address=0.0.0.0 \
|
--dns-standalone-address=0.0.0.0 \
|
||||||
|
|
Loading…
Reference in New Issue