Subversion Repositories ALCASAR

Rev

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