Subversion Repositories ALCASAR

Rev

Rev 3163 | Rev 3169 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log

Rev Author Line No. Line
2304 tom.houday 1
#!/bin/bash
2
#
3
# $Id: alcasar-letsencrypt.sh 3168 2024-01-17 15:28:46Z rexy $
4
#
5
# alcasar-letsencrypt.sh
6
# by Tom HOUDAYER
7
#
8
# This script is distributed under the Gnu General Public License (GPL)
9
#
10
# Manage Let's Encrypt for ALCASAR integration
11
 
12
CONF_FILE="/usr/local/etc/alcasar-letsencrypt"
13
 
14
ACCOUNT_EMAIL=""
15
DOMAIN=""
16
DNS_API=""
17
 
18
DEBUG=false
19
STAGING_SERVER=""
20
FORCE=""
21
OPT_PARAMS=""
22
 
23
ACMESH_HOME="/usr/local/etc/letsencrypt"
24
ACMESH_BIN="/opt/acme.sh/acme.sh"
25
 
26
usage="Usage: alcasar-letsencrypt.sh
27
       --issue -d alcasar.domain.tld --email alcasar@domain.tld [--dns-api dns_registrar] [--force] [--staging]
28
       --renew [-d alcasar.domain.tld] [--force] [--staging]"
29
 
30
 
31
################################################################################
32
#                                    ISSUE                                     #
33
################################################################################
34
issue() {
35
	if [ ! -f $ACMESH_BIN ]; then
36
		echo "The client does not seem to be installed."
37
		return 1
38
	fi
39
 
40
	TMP_OUTPUT=$(mktemp --suffix=_ALCASAR-LE)
41
 
42
	if [ ! -z $ACCOUNT_EMAIL ]; then
43
		emailField=" --accountemail $ACCOUNT_EMAIL"
44
		sed -i "s/^email=.*/email=$ACCOUNT_EMAIL/" $CONF_FILE
45
	else
46
		emailField=""
47
	fi
3168 rexy 48
	rm -rf $ACMESH_HOME/certs/*
2304 tom.houday 49
	$DEBUG && debugOpt=" --debug" || debugOpt=""
2596 tom.houday 50
	[ ! -z "$DNS_API" ] && dnsApiOpt="$DNS_API" || dnsApiOpt="--yes-I-know-dns-manual-mode-enough-go-ahead-please"
2304 tom.houday 51
	$ACMESH_BIN --config-home $ACMESH_HOME/data \
52
		$STAGING_SERVER $FORCE $debugOpt \
53
		$emailField \
2596 tom.houday 54
		--issue --dns $dnsApiOpt -d $DOMAIN \
2304 tom.houday 55
		$OPT_PARAMS \
56
		> $TMP_OUTPUT 2>&1
57
	exitCode=$?
58
 
59
	$DEBUG && cat $TMP_OUTPUT && echo -e "\n\n"
60
 
61
	sed -i "s/^domainRequest=.*/domainRequest=$DOMAIN/" $CONF_FILE
62
	sed -i "s/^dateIssueRequest=.*/dateIssueRequest=$(date +%s)/" $CONF_FILE
63
	sed -i "s/^dnsapi=.*/dnsapi=${DNS_API:="dns"}/" $CONF_FILE
64
 
65
	if ! _handle_client_response $TMP_OUTPUT; then
66
		if [ $exitCode -ne 0 ]; then
67
			echo -e "Error!\n"
68
			cat $TMP_OUTPUT
69
			rm -f $TMP_OUTPUT
70
			return 1
71
		else
72
			echo -e "Unknown state\n"
73
			cat $TMP_OUTPUT
74
		fi
75
	fi
76
 
77
	rm -f $TMP_OUTPUT
78
}
79
 
80
 
81
################################################################################
82
#                                    RENEW                                     #
83
################################################################################
84
renew() {
85
	if [ ! -f $ACMESH_BIN ]; then
86
		echo "The client does not seem to be installed."
87
		return 1
88
	fi
89
 
90
	TMP_OUTPUT=$(mktemp --suffix=_ALCASAR-LE)
91
 
92
	$DEBUG && debugOpt=" --debug" || debugOpt=""
2596 tom.houday 93
	[ ! -z "$DNS_API" ] && dnsApiOpt="" || dnsApiOpt="--yes-I-know-dns-manual-mode-enough-go-ahead-please"
2304 tom.houday 94
	$ACMESH_BIN --config-home $ACMESH_HOME/data \
95
		$STAGING_SERVER $FORCE $debugOpt \
2596 tom.houday 96
		--renew -d $DOMAIN $dnsApiOpt \
2304 tom.houday 97
		$OPT_PARAMS \
98
		> $TMP_OUTPUT 2>&1
99
	exitCode=$?
100
 
101
	$DEBUG && cat $TMP_OUTPUT && echo -e "\n\n"
102
 
103
	if ! _handle_client_response $TMP_OUTPUT; then
104
		if [ $exitCode -ne 0 ]; then
105
			echo -e "Error!\n"
106
			cat $TMP_OUTPUT
107
			rm -f $TMP_OUTPUT
108
			return 1
109
		else
110
			echo -e "Unknown state\n"
111
			cat $TMP_OUTPUT
112
		fi
113
	fi
114
 
115
	rm -f $TMP_OUTPUT
116
}
117
 
118
 
119
################################################################################
120
#                                  CRON TASK                                   #
121
################################################################################
122
cron_task() {
123
	if [ $(grep '^dateNextRenewal=' $CONF_FILE | cut -d'=' -f2) -le $(date +%s) ]; then
124
		logger -t alcasar-letsencrypt "Launch CRON task."
125
		renew
126
	fi
127
}
128
 
129
 
130
################################################################################
131
#                            HANDLE CLIENT RESPONSE                            #
132
################################################################################
133
_handle_client_response() {
134
	[ $# -lt 1 ] && return 1
135
	responseFile=$1
136
 
137
	# issue / renew
138
	if [ $(cat $responseFile | grep "Add the following TXT record:" -c) -ne 0 ]; then
139
		challenge=$(cat $responseFile | grep -E "TXT value: '[0-9a-zA-Z_-]+'" -o | cut -d"'" -f2)
140
		sed -i "s/^challenge=.*/challenge=$challenge/" $CONF_FILE
141
 
142
		echo "Add the following TXT record:"
143
		echo "Domain:    '_acme-challenge.$DOMAIN'"
144
		echo "TXT value: '$challenge'"
145
	elif [ $(cat $responseFile | grep "Cert success." -c) -ne 0 ]; then
146
		sed -i "s/^challenge=.*/challenge=/" $CONF_FILE
147
		sed -i "s/^dateIssued=.*/dateIssued=$(date +%s)/" $CONF_FILE
148
		sed -i "s/^dateNextRenewal=.*/dateNextRenewal=$(date +%s -d '2 months - 3 days')/" $CONF_FILE
149
 
150
		install_cert
151
		logger -t alcasar-letsencrypt "Certificate \"$DOMAIN\" imported."
152
		echo "Certificate imported."
153
		[ -z $DNS_API ] && echo "Note: you can delete the TXT record."
154
	elif [ $(cat $responseFile | grep "Domains not changed." -c) -ne 0 ]; then
155
		echo "Domain not changed"
156
	elif [ $(cat $responseFile | grep "$DOMAIN is already verified, skip dns-01." -c) -ne 0 ]; then
157
		echo "Domain already verified"
158
	elif [ $(cat $responseFile | grep "Error add txt for domain:_acme-challenge.$DOMAIN" -c) -ne 0 ]; then
159
		echo "Error add txt for domain:_acme-challenge.$DOMAIN"
160
	elif [ $(cat $responseFile | grep "Please add the TXT records to the domains, and retry again." -c) -ne 0 ]; then
161
		echo "Dns record not added yet, you need to add it manually and retry again."
162
	elif [ $(cat $responseFile | grep 'new-authz error: {"type":"urn:acme:error:malformed","detail":"Error creating new authz :: \(.*\)","status": 400}' -c) -ne 0 ]; then
163
		errorMsg=$(cat $responseFile | grep 'new-authz error: {"type":"urn:acme:error:malformed","detail":"Error creating new authz :: \(.*\)","status": 400}' | sed 's/.*new-authz error: {"type":"urn:acme:error:malformed","detail":"Error creating new authz :: \(.*\)","status": 400}.*/\1/')
164
		echo "Incorrect domain name"
165
		echo "$errorMsg"
166
	elif [ $(cat $responseFile | grep "'$DOMAIN' is not a issued domain, skip." -c) -ne 0 ]; then
167
		echo "'$DOMAIN' is not a issued domain"
168
 
169
	# renew
170
	elif [ $(cat $responseFile | grep "Skip, Next renewal time is: " -c) -ne 0 ]; then
171
		nextRenewal=$(cat $responseFile | grep 'Skip, Next renewal time is: ' | sed 's/.*Skip, Next renewal time is: \(.*\)/\1/')
172
		echo "Skip, Next renewal time is: $nextRenewal"
173
		echo "Add '--force' to force to renew."
174
	elif [ $(cat $responseFile | grep "$DOMAIN:Verify error:Correct value not found for DNS challenge" -c) -ne 0 ]; then
175
		echo "Correct value not found for DNS challenge"
176
	elif [ $(cat $responseFile | grep "Unable to update challenge :: The challenge is not pending." -c) -ne 0 ]; then
177
		echo "The challenge is not pending. You need to issue."
178
	else
179
		return 2
180
	fi
181
 
182
	return 0
183
}
184
 
185
 
186
################################################################################
187
#                             INSTALL CERTIFICATE                              #
188
################################################################################
189
install_cert() {
190
	echo "Importing certificate to ALCASAR..."
3163 rexy 191
	LE_cert_folder="$( echo "$ACMESH_HOME/certs/$DOMAIN"*"")"
192
	if [ ! -f $LE_cert_folder"/"$DOMAIN.cer ]; then
2304 tom.houday 193
		echo "Certificate not found."
194
		return 1
195
	fi
196
 
197
	/usr/local/bin/alcasar-importcert.sh \
3163 rexy 198
		-i $LE_cert_folder"/"$DOMAIN.cer \
199
		-k $LE_cert_folder"/"$DOMAIN.key \
200
		-c $LE_cert_folder/fullchain.cer \
2304 tom.houday 201
		> /dev/null 2>&1
202
 
203
	if [ $? -ne 0 ]; then
204
		echo "Error."
205
		return 1
206
	fi
207
}
208
 
209
 
210
################################################################################
211
#                                     MAIN                                     #
212
################################################################################
213
 
2596 tom.houday 214
if [ $# -eq 0 ]; then
2304 tom.houday 215
	echo "$usage"
216
	exit 1
217
fi
218
 
219
cmd=""
220
 
221
while [ $# -gt 0 ]; do
222
	case $1 in
223
		-\? | -h | --help)
224
			echo "$usage"
225
			exit 0
226
			;;
227
 
228
		--issue)
229
			cmd="issue"
230
			shift 1
231
			;;
232
		--renew)
233
			cmd="renew"
234
			shift 1
235
			;;
236
		--cron)
237
			cmd="cron"
238
			shift 1
239
			;;
240
		--install-cert)
241
			cmd="install-cert"
242
			shift 1
243
			;;
244
 
245
		--email)
246
			ACCOUNT_EMAIL="$2"
247
			shift 2
248
			;;
249
		--domain | -d)
250
			DOMAIN="$2"
251
			shift 2
252
			;;
253
		--dns-api)
254
			DNS_API="$2"
255
			shift 2
256
			;;
257
		--force)
258
			FORCE="--force"
259
			shift 1
260
			;;
261
		--staging)
262
			STAGING_SERVER="--staging"
263
			shift 1
264
			;;
265
		--debug)
266
			DEBUG=true
267
			shift 1
268
			;;
269
 
270
		*)
271
			found=false
272
			for param in "--dnssleep"; do
273
				if [ $1 == $param ]; then
274
					OPT_PARAMS="$OPT_PARAMS $1 $2"
275
					shift 2
276
					found=true
277
					break
278
				fi
279
			done
280
 
281
			if ! $found; then
282
				echo "Unknown argument: $1"
283
				echo "$usage"
284
				exit 1
285
			fi
286
			;;
287
	esac
288
done
289
 
290
if [ -z $DOMAIN ]; then
291
	if [ $(grep '^domainRequest=' $CONF_FILE | cut -d'=' -f2 | wc --chars) -gt 1 ]; then
292
		DOMAIN="$(grep '^domainRequest=' $CONF_FILE | cut -d'=' -f2)"
293
	else
294
		DOMAIN="$(grep '^HOSTNAME=' /usr/local/etc/alcasar.conf | cut -d'=' -f2).$(grep '^DOMAIN=' /usr/local/etc/alcasar.conf | cut -d'=' -f2)"
295
	fi
296
fi
297
 
298
case $cmd in
299
	issue)
300
		issue
301
		;;
302
	renew)
303
		renew
304
		;;
305
	cron)
306
		cron_task
307
		;;
308
	install-cert)
309
		install_cert
310
		;;
311
 
312
	*) exit 1 ;;
313
esac