Subversion Repositories ALCASAR

Rev

Rev 3162 | Go to most recent revision | Details | Last modification | View Log

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