-
Notifications
You must be signed in to change notification settings - Fork 1
/
bootstrap.sh
244 lines (203 loc) · 6.77 KB
/
bootstrap.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
#!/bin/bash
set -e
# Paths
userConfPath="/etc/sftp/users.conf"
userConfPathLegacy="/etc/sftp-users.conf"
userConfFinalPath="/var/run/sftp/users.conf"
# Extended regular expression (ERE) for arguments
reUser='[A-Za-z0-9._][A-Za-z0-9._-]{0,31}' # POSIX.1-2008
rePass='[^:]{0,255}'
reUid='[[:digit:]]*'
reGid='[[:digit:]]*'
reDir='[^:]*'
reArgs="^($reUser)(:$rePass)(:e)?(:$reUid)?(:$reGid)?(:$reDir)?$"
reArgsMaybe="^[^:[:space:]]+:.*$" # Smallest indication of attempt to use argument
reArgSkip='^([[:blank:]]*#.*|[[:blank:]]*)$' # comment or empty line
function log() {
echo "[entrypoint] $@"
}
function validateArg() {
name="$1"
val="$2"
re="$3"
if [[ "$val" =~ ^$re$ ]]; then
return 0
else
log "ERROR: Invalid $name \"$val\", do not match required regex pattern: $re"
return 1
fi
}
function createUser() {
log "Parsing user data: \"$@\""
IFS=':' read -a args <<< $@
skipIndex=0
chpasswdOptions=""
useraddOptions="--no-user-group --shell /bin/bash"
user="${args[0]}"; validateArg "username" "$user" "$reUser" || return 1
pass="${args[1]}"; validateArg "password" "$pass" "$rePass" || return 1
if [ "${args[2]}" == "e" ]; then
chpasswdOptions="-e"
skipIndex=1
fi
uid="${args[$[$skipIndex+2]]}"; validateArg "UID" "$uid" "$reUid" || return 1
gid="${args[$[$skipIndex+3]]}"; validateArg "GID" "$gid" "$reGid" || return 1
dir="${args[$[$skipIndex+4]]}"; validateArg "dirs" "$dir" "$reDir" || return 1
if getent passwd $user > /dev/null; then
log "WARNING: User \"$user\" already exists. Skipping."
return 0
fi
if [ -n "$uid" ]; then
useraddOptions="$useraddOptions --non-unique --uid $uid"
fi
if [ -n "$gid" ]; then
if ! getent group $gid > /dev/null; then
groupadd --gid $gid "group_$gid"
fi
useraddOptions="$useraddOptions --gid $gid"
fi
useradd $useraddOptions $user
mkdir -p /home/$user
chown root:root /home/$user
chmod 755 /home/$user
# Retrieving user id to use it in chown commands instead of the user name
# to avoid problems on alpine when the user name contains a '.'
uid="$(id -u $user)"
if [ -n "$pass" ]; then
echo "$user:$pass" | chpasswd $chpasswdOptions
else
usermod -p "*" $user # disabled password
fi
if [ ! -f /home/$user/.vimrc ]; then
mv /vimrc /home/$user/.vimrc
chown $user:users /home/$user/.vimrc
fi
if [ ! -f /home/$user/.tmux.conf ]; then
mv /tmux /home/$user/.tmux.conf
chown $user:users /home/$user/.tmux.conf
fi
if [ -d /opt/user ]; then
chown $user:users -R /opt/user
fi
# Make sure dirs exists
if [ -n "$dir" ]; then
IFS=',' read -a dirArgs <<< $dir
for dirPath in ${dirArgs[@]}; do
dirPath="/home/$user/$dirPath"
if [ ! -d "$dirPath" ]; then
log "Creating directory: $dirPath"
mkdir -p $dirPath
chown -R $uid:users $dirPath
else
log "Directory already exists: $dirPath"
fi
done
fi
}
# Allow running other programs, e.g. bash
if [[ -z "$1" || "$1" =~ $reArgsMaybe ]]; then
startSshd=true
else
startSshd=false
fi
# Backward compatibility with legacy config path
if [ ! -f "$userConfPath" -a -f "$userConfPathLegacy" ]; then
mkdir -p "$(dirname $userConfPath)"
ln -s "$userConfPathLegacy" "$userConfPath"
fi
# Create users only on first run
if [ ! -f "$userConfFinalPath" ]; then
mkdir -p "$(dirname $userConfFinalPath)"
# Append mounted config to final config
if [ -f "$userConfPath" ]; then
cat "$userConfPath" | grep -v -E "$reArgSkip" > "$userConfFinalPath"
fi
if $startSshd; then
# Append users from arguments to final config
for user in "$@"; do
echo "$user" >> "$userConfFinalPath"
done
fi
if [ -n "$SFTP_USERS" ]; then
# Append users from environment variable to final config
usersFromEnv=($SFTP_USERS) # as array
for user in "${usersFromEnv[@]}"; do
echo "$user" >> "$userConfFinalPath"
done
fi
# Check that we have users in config
if [[ -f "$userConfFinalPath" && "$(cat "$userConfFinalPath" | wc -l)" > 0 ]]; then
# Import users from final conf file
while IFS= read -r user || [[ -n "$user" ]]; do
createUser "$user"
done < "$userConfFinalPath"
elif $startSshd; then
log "FATAL: No users provided!"
exit 3
fi
fi
/usr/bin/ruby /usr/local/bin/init_bastion.rb
/usr/bin/ruby /usr/local/bin/load_ssh_keys.rb
# Generate unique ssh keys for this container, if needed
if [ ! -f /etc/ssh/ssh_host_ed25519_key ]; then
echo "Missing ED25519 Host Key, generating..."
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ''
fi
if [ ! -f /etc/ssh/ssh_host_rsa_key ]; then
echo "Missing RSA Host Key, generating..."
ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ''
fi
# Source custom scripts, if any
if [ -d /etc/sftp.d ]; then
for f in /etc/sftp.d/*; do
if [ -x "$f" ]; then
log "Running $f ..."
$f
else
log "Could not run $f, because it's missing execute permission (+x)."
fi
done
unset f
fi
sudo -u sftpuser cat << 'EOF' > /home/sftpuser/.profile
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
EOF
sudo -u sftpuser echo "export METADATA_AUTH=${METADATA_AUTH}" >> /home/sftpuser/.bashrc
sudo -u sftpuser echo "export METADATA_URL=${METADATA_URL}" >> /home/sftpuser/.bashrc
sudo -u sftpuser echo "export METADATA_SERVICE=${METADATA_SERVICE}" >> /home/sftpuser/.bashrc
chown sftpuser:users /home/sftpuser/.profile
chown sftpuser:users /home/sftpuser/.bashrc
log "Configuring Relay for PHP"
RELAY_INI_DIR=/etc/php/8.2/mods-available/
RELAY_EXT_DIR=$(/usr/bin/php-config --extension-dir)
RELAY_INI="${RELAY_INI_DIR}relay.ini"
if [ -f /usr/src/relay/relay-pkg.so ]; then
# if $PHP_INI_DIR/60-relay.ini does not exist, cp relay.ini to $PHP_INI_DIR/60-relay.ini
# Allow customizations outside of the defined env vars.
if [ ! -f "$RELAY_INI" ]; then
cp /usr/src/relay/relay.ini "$RELAY_INI"
/usr/sbin/phpenmod relay
fi
cp "/usr/src/relay/relay-pkg.so" "$RELAY_EXT_DIR/relay.so"
fi
sudo -u sftpuser /usr/bin/wp package install wp-cli/profile-command
# run everything in /scripts
if [ -d /opt/user/startup-scripts ]; then
for f in /opt/user/startup-scripts/*; do
if [ -x "$f" ]; then
log "Running $f ..."
$f || true
else
log "Could not run $f."
fi
done
unset f
fi
if $startSshd; then
log "Executing sshd"
exec /usr/sbin/sshd -D -e
else
log "Executing $@"
exec "$@"
fi