aboutsummaryrefslogtreecommitdiff
path: root/net/acme-common/files/acme.init
blob: d4ff510630db16dc525d334883c9327a2a5dc133 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/bin/sh /etc/rc.common

USE_PROCD=1
run_dir=/var/run/acme
export CHALLENGE_DIR=$run_dir/challenge
export CERT_DIR=/etc/ssl/acme
NFT_HANDLE=
HOOK=/usr/lib/acme/hook
LOG_TAG=acme

# shellcheck source=net/acme/files/functions.sh
. "$IPKG_INSTROOT/usr/lib/acme/functions.sh"

cleanup() {
	log debug "cleaning up"
	if [ -e $run_dir/lock ]; then
		rm $run_dir/lock
	fi
	if [ "$NFT_HANDLE" ]; then
		# $NFT_HANDLE contains the string 'handle XX' so pass it unquoted to nft
		nft delete rule inet fw4 input $NFT_HANDLE
	fi
}

load_options() {
	section=$1

	# compatibility for old option name
	config_get_bool staging "$section" use_staging
	if [ -z "$staging" ]; then
		config_get_bool staging "$section" staging 0
	fi
	export staging
	config_get calias "$section" calias
	export calias
	config_get dalias "$section" dalias
	export dalias
	config_get domains "$section" domains
	export domains
	export main_domain
	main_domain="$(first_arg $domains)"
	config_get keylength "$section" keylength
	if [ "$keylength" ]; then
		log warn "Option \"keylength\" is deprecated, please use key_type (e.g., ec256, rsa2048) instead."
		case $keylength in
		ec-*) key_type=${keylength/-/} ;;
		*) key_type=rsa$keylength ;;
		esac
	else
		config_get key_type "$section" key_type ec256
	fi
	export key_type
	config_get dns "$section" dns
	export dns
	config_get acme_server "$section" acme_server
	export acme_server
	config_get days "$section" days
	export days
	config_get standalone "$section" standalone 0
	export standalone
	config_get dns_wait "$section" dns_wait
	export dns_wait
	config_get webroot "$section" webroot
	if [ "$webroot" ]; then
		log warn "Option \"webroot\" is deprecated, please remove it and change your web server's config so it serves ACME challenge requests from $CHALLENGE_DIR."
		CHALLENGE_DIR=$webroot
	fi
}

first_arg() {
	echo "$1"
}

get_cert() {
	section=$1

	config_get_bool enabled "$section" enabled 1
	[ "$enabled" = 1 ] || return

	load_options "$section"
	if [ -z "$dns" ] && [ "$standalone" = 0 ]; then
		mkdir -p "$CHALLENGE_DIR"
	fi

	if [ "$standalone" = 1 ] && [ -z "$NFT_HANDLE" ]; then
		if ! NFT_HANDLE=$(nft -a -e insert rule inet fw4 input tcp dport 80 counter accept comment ACME | grep -o 'handle [0-9]\+'); then
			return 1
		fi
		log debug "added nft rule: $NFT_HANDLE"
	fi

	load_credentials() {
		eval export "$1"
	}
	config_list_foreach "$section" credentials load_credentials

	"$HOOK" get
}

load_globals() {
	section=$1

	config_get account_email "$section" account_email
	if [ -z "$account_email" ]; then
		log err "account_email option is required"
		exit 1
	fi
	export account_email

	config_get state_dir "$section" state_dir
	if [ "$state_dir" ]; then
		log warn "Option \"state_dir\" is deprecated, please remove it. Certificates now exist in $CERT_DIR."
		mkdir -p "$state_dir"
	else
		state_dir=/etc/acme
	fi
	export state_dir

	config_get debug "$section" debug 0
	export debug

	# only look for the first acme section
	return 1
}

start_service() {
	mkdir -p $run_dir
	exec 200>$run_dir/lock
	if ! flock -n 200; then
		log err "Another ACME instance is already running."
		exit 1
	fi

	trap cleanup EXIT

	config_load acme
	config_foreach load_globals acme

	config_foreach get_cert cert
}

service_triggers() {
	procd_add_config_trigger config.change acme \
		/etc/init.d/acme start
}