Subversion Repositories ALCASAR

Rev

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