-
Notifications
You must be signed in to change notification settings - Fork 3
/
fms-request-cert-dns-route53.sh
executable file
·276 lines (229 loc) · 8.9 KB
/
fms-request-cert-dns-route53.sh
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#!/usr/bin/env bash
set -u
set -o pipefail
# setup
# -----------------------------------------------------
# load the variables from the conf file
# assumes that the conf file is in the same folder as this script
parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
cd "$parent_path"
filePath="01-fms-certbot.conf"
if [ ! -f "$filePath" ]; then
echo "missing ${filePath}"
exit 1
fi
while read -r LINE; do
# Remove leading and trailing whitespaces, and carriage return
CLEANED_LINE=$(echo "$LINE" | awk '{$1=$1};1' | tr -d '\r')
if [[ $CLEANED_LINE != '#'* ]] && [[ $CLEANED_LINE == *'='* ]]; then
export "$CLEANED_LINE"
fi
done < "$filePath"
# -----------------------------------------------------
# This script runs the certbot generation and imports the certificate into FileMaker Server.
# Please ensure that FileMaker Server is running prior to running this script.
# Usage:
# ./fms-request-cert-dns-route53.sh
# the relevant commands that need to run as sudo have the -E flag to preserve the environment variables
# Detects if FileMaker Server is still running
isServerRunning()
{
fmserver=$(ps axc | sed "s/.*:..... /\"/" | sed s/$/\"/ | grep fmserver)
if [[ -z $fmserver ]] ; then
return 0 # fmserver is not running
fi
return 1 # fmserver is running
}
# Used to redirect errors to stderr
err()
{
echo "$*" >&2
}
# Test to see if Certbot is installed
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
# Ubuntu
if [[ ! -e "/snap/bin/certbot" ]] ; then
err "[ERROR] Certbot not installed. Exiting..."
# Install Certbot Package
# snap install --classic certbot
# Prepare Certbot Command
# ln -s /snap/bin/certbot /usr/bin/certbot
exit 1
fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
# MacOS
if [[ ! -e "/opt/homebrew/bin/certbot" ]] ; then
err "[ERROR] Certbot not installed. Exiting..."
# Install Homebrew
# /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Prepare Homebrew
# (echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> /Users/$USER/.zprofile
# zsh
# eval "$(/opt/homebrew/bin/brew shellenv)"
# Install Certbot
# brew install certbot
exit 1
fi
fi
# FileMaker Admin Console Login Information
if [ $PROMPT == 0 ] ; then
if [[ -n "${FAC_USERNAME}" ]]; then
FAC_USER="${FAC_USERNAME}"
else
err " [ERROR]: The FileMaker Server Admin Console Credentials was not set. Set FAC_USERNAME as an environment variable using export FAC_USERNAME="
err " If FAC_USERNAME and FAC_PASSWORD have been set, make sure to run the script using sudo -E ./fm_request_cert.sh"
err " Additionally, make sure that to set FAC_PASSWORD as an environment variable using export FAC_PASSWORD="
exit 1
fi
if [[ -n "${FAC_PASSWORD}" ]]; then
FAC_PASS="${FAC_PASSWORD}"
else
err " [ERROR]: The FileMaker Server Admin Console Credentials was not set. Set FAC_PASSWORD as an environment variable using export FAC_PASSWORD="
exit 1
fi
else
# Prompt user for values
echo " Enter email for Let's Encrypt Notifications."
read -p " > Email: " EMAIL
echo " Enter the domain for Certificate Generation. Note: Wildcards are not supported."
read -p " > Domain: " DOMAIN
echo " To import the certificates and restart FileMaker Server, enter the FileMaker Admin Console credentials:"
read -s -p " > Username: " FAC_USER
echo ""
read -s -p " > Password: " FAC_PASS
echo ""
echo " Do you want to restart FileMaker Server after the certificate is generated?"
read -p " > Restart (0 for no, 1 for yes): " RESTART_SERVER
echo " Do you want to generate a test certificate?"
read -p " > Test Validation (0 for no, 1 for yes): " TEST_CERTIFICATE
echo " Enter the AWS Access Key for AWS user account."
read -p " > AWS key: " AWS_KEY
echo " Enter the AWS Access Secret for AWS user account."
read -p " > AWS secret: " AWS_SECRET
fi
# DO NOT EDIT - FileMaker Directories
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
CERTBOTPATH="/opt/FileMaker/FileMaker Server/CStore/Certbot"
elif [[ "$OSTYPE" == "darwin"* ]]; then
CERTBOTPATH="/Library/FileMaker Server/CStore/Certbot"
fi
# Set up paths for necessary directories
if [[ ! -e "$CERTBOTPATH" ]] ; then
echo "[WARNING]: $CERTBOTPATH not found. Creating necessary directories."
sudo -E mkdir -p "$CERTBOTPATH"
fi
echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
# Disggregate domain list into arguments
DOMAIN+=","
DOMAINLIST=""
IFS=',' read -ra ADDR <<< "$DOMAIN"
FIRST_DOMAIN=""
for CUR_DOMAIN in "${ADDR[@]}"; do
if [[ -z "${FIRST_DOMAIN}" ]] ; then
# First domain in list will be used for the name of the folder
FIRST_DOMAIN=${CUR_DOMAIN}
fi
DOMAINLIST+="-d ${CUR_DOMAIN} "
done
# Check to see if a directory already exists for the domain
if [[ -e "$CERTBOTPATH/live/$FIRST_DOMAIN" ]] ; then
err "[ERROR]: A directory with the domain $FIRST_DOMAIN already exists. Please backup and remove the folder \"$CERTBOTPATH/live/$FIRST_DOMAIN/\""
exit 1
fi
# If updating current certificate (UPDATE_EXISTING_CERT) is set to 1
EXPAND_PARAM=""
if [[ $UPDATE_EXISTING_CERT -eq 1 ]] ; then
EXPAND_PARAM=" --expand"
fi
# Test Parameter
TEST_CERT_PARAM=""
if [[ $TEST_CERTIFICATE -eq 1 ]] ; then
TEST_CERT_PARAM=" --dry-run"
fi
if [[ $TEST_CERTIFICATE -eq 1 ]] ; then
echo "Generating test certificate request."
else
echo "Generating certificate request."
fi
# Run the certbot certificate generation command
sudo -E certbot certonly --dns-route53 $TEST_CERT_PARAM $DOMAINLIST --agree-tos --non-interactive -m $EMAIL --config-dir "$CERTBOTPATH" --work-dir "$CERTBOTPATH" --logs-dir "$CERTBOTPATH" $EXPAND_PARAM
# Capture return code for running certbot command
RETVAL=$?
if [ $RETVAL != 0 ] ; then
err "[ERROR]: Certbot returned with a nonzero failure code. Check $CERTBOTPATH/letsencrypt.log for more information."
exit 1
fi
PRIVKEYPATH=$(sudo -E realpath "$CERTBOTPATH/live/$FIRST_DOMAIN/privkey.pem")
echo "Private key: $PRIVKEYPATH"
CERTFILEPATH=$(sudo -E realpath "$CERTBOTPATH/live/$FIRST_DOMAIN/fullchain.pem")
echo "Certificate: $CERTFILEPATH"
# grant fmserver:fmsadmin group ownership
if [ -e "$CERTBOTPATH" ] ; then
sudo -E chown -R fmserver:fmsadmin "$CERTBOTPATH"
else
err "[ERROR]: FileMaker Certbot folder was not found. Exiting..."
exit 1
fi
if sudo -E test -f "$PRIVKEYPATH"; then
sudo -E chown -R fmserver:fmsadmin "$PRIVKEYPATH"
else
err "[ERROR]: An error occurred with certificate generation. No private key found at $PRIVKEYPATH"
exit 1
fi
if sudo -E test -f "$CERTFILEPATH"; then
sudo -E chown -R fmserver:fmsadmin "$CERTFILEPATH"
else
err "[ERROR]: An error occurred with certificate generation. No certificate found at $CERTFILEPATH"
exit 1
fi
# if we are testing, we don't need to import/restart
if [[ $TEST_CERTIFICATE -eq 1 ]] ; then
exit 1
fi
echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
# import certificates
echo "Importing Certificates:"
echo "Certificate: $CERTFILEPATH"
echo "Private key: $PRIVKEYPATH"
sudo -E fmsadmin certificate import "$CERTFILEPATH" --keyfile "$PRIVKEYPATH" -y -u $FAC_USER -p $FAC_PASS
# Capture return code for running certbot command
RETVAL=$?
if [ $RETVAL != 0 ] ; then
err "[ERROR]: FileMaker Server was unable to import the generated certificate."
exit 1
fi
# check if user wants to restart server
if [[ $RESTART_SERVER == 1 ]] ; then
echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
echo "Restarting FileMaker Server."
isServerRunning
serverIsRunning=$?
if [ $serverIsRunning -eq 1 ] ; then
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
sudo service fmshelper stop
elif [[ "$OSTYPE" == "darwin"* ]]; then
sudo launchctl stop com.filemaker.fms
fi
fi
waitCounter=0
while [[ $waitCounter -lt $MAX_WAIT_AMOUNT ]] && [[ $serverIsRunning -eq 1 ]]
do
sleep 10
isServerRunning
serverIsRunning=$?
echo "Waiting for FileMaker Server process to terminate..."
waitCounter=$((waitCounter++))
done
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
sudo service fmshelper start
elif [[ "$OSTYPE" == "darwin"* ]]; then
sudo launchctl start com.filemaker.fms
fi
fi
# set up cronjob on MacOS for automatic renewal
if [[ "$OSTYPE" == "darwin"* ]]; then
echo "Setting up cronjob for Certbot automatic renewal."
echo "0 0,12 * * * root $(command -v python3) -c 'import random; import time; time.sleep(random.random() * 3600)' && sudo $(command -v certbot) renew -q" | sudo tee -a /etc/crontab > /dev/null
fi
echo "Lets Encrypt certificate request script completed without any errors."
exit 0