1
1
#! /bin/sh
2
+ set -e
3
+ default_uid=0
4
+ default_gid=0
5
+ default_unprivileged_user=certbot
6
+ default_unprivileged_group=certbot
7
+
8
+ if [ " $DEBUG " = " true" ]; then
9
+ set -x
10
+ fi
2
11
3
12
# ###############################################################################
4
13
# Functions
@@ -9,6 +18,41 @@ cleanup() {
9
18
exit 0
10
19
}
11
20
21
+ debug_print () {
22
+ if [ " $DEBUG " = " true" ]; then
23
+ echo " $1 "
24
+ fi
25
+ }
26
+
27
+ configure_uid_and_gid () {
28
+ debug_print " Preparing environment for $PUID :$PGID ..."
29
+
30
+ # Handle existing user with the same UID
31
+ if id -u " ${PUID} " > /dev/null 2>&1 ; then
32
+ old_user=$( id -nu " ${PUID} " )
33
+ debug_print " UID ${PUID} already exists for user ${old_user} . Moving to a new UID."
34
+ usermod -u " 999${PUID} " " ${old_user} "
35
+ fi
36
+
37
+ # Handle existing group with the same GID
38
+ if getent group " ${PGID} " > /dev/null 2>&1 ; then
39
+ old_group=$( getent group " ${PGID} " | cut -d: -f1)
40
+ debug_print " GID ${PGID} already exists for group ${old_group} . Moving to a new GID."
41
+ groupmod -g " 999${PGID} " " ${old_group} "
42
+ fi
43
+
44
+ # Change UID and GID of run_as user and group
45
+ usermod -u " ${PUID} " " ${default_unprivileged_user} " 2>&1 > /dev/null || echo " Error changing user ID."
46
+ groupmod -g " ${PGID} " " ${default_unprivileged_user} " 2>&1 > /dev/null || echo " Error changing group ID."
47
+
48
+ # Ensure the correct permissions are set for all required directories
49
+ chown -R " ${default_unprivileged_user} :${default_unprivileged_group} " \
50
+ /etc/letsencrypt \
51
+ /var/lib/letsencrypt \
52
+ /var/log/letsencrypt \
53
+ /opt/certbot
54
+ }
55
+
12
56
configure_windows_file_permissions () {
13
57
# Permissions must be created after volumes have been mounted; otherwise, windows file system permissions will override
14
58
# the permissions set within the container.
@@ -40,8 +84,28 @@ replace_symlinks() {
40
84
done
41
85
}
42
86
87
+ is_default_privileges () {
88
+ [ " ${PUID:- $default_uid } " = " $default_uid " ] && [ " ${PGID:- $default_gid } " = " $default_gid " ]
89
+ }
90
+
43
91
run_certbot () {
44
- certbot certonly \
92
+ # Ensure the log directory is set to 700
93
+ chmod 700 /var/log/letsencrypt
94
+ chown " ${PUID} :${PGID} " /var/log/letsencrypt
95
+
96
+ if is_default_privileges; then
97
+ certbot_cmd=" certbot"
98
+ else
99
+ certbot_cmd=" su-exec ${default_unprivileged_user} certbot"
100
+ fi
101
+
102
+ debug_print " Running certbot with command: $certbot_cmd "
103
+
104
+ # Add -v flag if DEBUG is enabled
105
+ debug_flag=" "
106
+ [ " $DEBUG " = " true" ] && debug_flag=" -v"
107
+
108
+ $certbot_cmd $debug_flag certonly \
45
109
--dns-cloudflare \
46
110
--dns-cloudflare-credentials /cloudflare.ini \
47
111
-d " $CERTBOT_DOMAINS " \
@@ -79,6 +143,10 @@ trap cleanup TERM INT
79
143
80
144
validate_environment_variables
81
145
146
+ if ! is_default_privileges; then
147
+ configure_uid_and_gid
148
+ fi
149
+
82
150
if [ " $REPLACE_SYMLINKS " = " true" ]; then
83
151
configure_windows_file_permissions
84
152
fi
@@ -110,32 +178,44 @@ echo "-----------------------------------------------------------"
110
178
# Create Cloudflare configuration file
111
179
echo " dns_cloudflare_api_token = $CLOUDFLARE_API_TOKEN " > /cloudflare.ini
112
180
chmod 600 /cloudflare.ini
181
+ if ! is_default_privileges; then
182
+ chown " ${PUID} :${PGID} " /cloudflare.ini
183
+ fi
113
184
114
- # Run certbot initially to get the certificates
115
- run_certbot
116
-
117
- # Infinite loop to keep the container running and periodically check for renewals
118
- while true ; do
119
- # POSIX-compliant way to show next run time
120
- current_timestamp=$( date +%s)
121
- next_timestamp=$(( current_timestamp + RENEWAL_INTERVAL))
122
- next_run=$( date -r " $next_timestamp " ' +%Y-%m-%d %H:%M:%S %z' 2> /dev/null || date ' +%Y-%m-%d %H:%M:%S %z' )
123
- echo " Next certificate renewal check will be at ${next_run} "
124
-
125
- # Store PID of sleep process and wait for it
126
- sleep " $RENEWAL_INTERVAL " &
127
- sleep_pid=$!
128
- wait $sleep_pid
129
- wait_status=$?
130
-
131
- # Check if we received a signal (more portable check)
132
- case $wait_status in
133
- 0) : ;; # Normal exit
134
- * ) cleanup ;;
135
- esac
136
-
137
- if ! run_certbot; then
138
- echo " Error: Certificate renewal failed. Exiting."
139
- exit 1
185
+ # Check if a command was passed to the container
186
+ if [ $# -gt 0 ]; then
187
+ if is_default_privileges; then
188
+ exec " $@ "
189
+ else
190
+ exec su-exec " ${default_unprivileged_user} " " $@ "
140
191
fi
141
- done
192
+ else
193
+ # Run certbot initially to get the certificates
194
+ run_certbot
195
+
196
+ # Infinite loop to keep the container running and periodically check for renewals
197
+ while true ; do
198
+ # POSIX-compliant way to show next run time
199
+ current_timestamp=$( date +%s)
200
+ next_timestamp=$(( current_timestamp + RENEWAL_INTERVAL))
201
+ next_run=$( date -r " $next_timestamp " ' +%Y-%m-%d %H:%M:%S %z' 2> /dev/null || date ' +%Y-%m-%d %H:%M:%S %z' )
202
+ echo " Next certificate renewal check will be at ${next_run} "
203
+
204
+ # Store PID of sleep process and wait for it
205
+ sleep " $RENEWAL_INTERVAL " &
206
+ sleep_pid=$!
207
+ wait $sleep_pid
208
+ wait_status=$?
209
+
210
+ # Check if we received a signal (more portable check)
211
+ case $wait_status in
212
+ 0) : ;; # Normal exit
213
+ * ) cleanup ;;
214
+ esac
215
+
216
+ if ! run_certbot; then
217
+ echo " Error: Certificate renewal failed. Exiting."
218
+ exit 1
219
+ fi
220
+ done
221
+ fi
0 commit comments