-
Notifications
You must be signed in to change notification settings - Fork 8
/
entrypoint
272 lines (231 loc) · 8.04 KB
/
entrypoint
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
#!/bin/bash
set -e
mkdir -p /config/fail2ban
mkdir -p /config/userkeys
mkdir -p /config/sshd/keys
# Modify default fail2ban.conf file
sed -i 's|^logtarget = /var/log/fail2ban.log|logtarget = /config/fail2ban/fail2ban.log|' /etc/fail2ban/fail2ban.conf
sed -i 's|^dbfile = /var/lib/fail2ban/fail2ban.sqlite3|dbfile = /config/fail2ban/fail2ban.sqlite3|' /etc/fail2ban/fail2ban.conf
# Copy default config files if removed
if [[ ! -e /config/fail2ban/fail2ban.conf ]]; then
echo "$(date) [err] fail2ban.conf missing from /config/fail2ban/... Replacing with default backup!"
cp "/etc/fail2ban/fail2ban.conf" "/config/fail2ban/fail2ban.conf"
else
echo "$(date) [info] Existing fail2ban.conf found. Copying to container filesystem!"
rm /etc/fail2ban/fail2ban.conf
cp "/config/fail2ban/fail2ban.conf" "/etc/fail2ban/fail2ban.conf"
fi
# Copy default config files if removed
if [[ ! -e /config/fail2ban/jail.conf ]]; then
echo "$(date) [err] jail.conf missing from /config/fail2ban/... Replacing with default backup!"
cp "/etc/default/f2ban/jail.conf" "/config/fail2ban/jail.conf"
rm /etc/fail2ban/jail.conf
cp "/config/fail2ban/jail.conf" "/etc/fail2ban/jail.conf"
else
echo "$(date) [info] Existing jail.conf found. Copying to container filesystem!"
rm /etc/fail2ban/jail.conf
cp "/config/fail2ban/jail.conf" "/etc/fail2ban/jail.conf"
fi
if [[ ! -e /config/sshd/sshd_config ]]; then
echo "$(date) [err] sshd_config missing from /config/sshd/... Replacing with default backup!"
cp "/etc/default/sshd/sshd_config" "/config/sshd/sshd_config"
rm /etc/ssh/sshd_config
cp "/config/sshd/sshd_config" "/etc/ssh/sshd_config"
else
echo "$(date) [info] Existing sshd_config found. Copying to container filesystem!"
rm /etc/ssh/sshd_config
cp "/config/sshd/sshd_config" "/etc/ssh/sshd_config"
fi
# Paths
userConfPath="/config/sshd/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"
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 /home/$user/.ssh
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
# copy user key, if it exists
key_file="/config/userkeys/$user.pub"
if [ -f $key_file ]; then
chown $uid /home/$user/.ssh
chmod 700 /home/$user/.ssh
echo "Copying key for $user"
dest_key_file="/home/$user/.ssh/$user.pub"
if [ -f $dest_key_file ]; then
rm $dest_key_file
fi
cp $key_file $dest_key_file
chown $uid $dest_key_file
chmod 600 $dest_key_file
# echo key into authorized_keys and set perms
cat $key_file > /home/$user/.ssh/authorized_keys
chown $uid /home/$user/.ssh/authorized_keys
chmod 600 /home/$user/.ssh/authorized_keys
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 host keys only on first run
if [ ! -f "$userConfFinalPath" ]; then
# Generate unique ssh keys for this container, if needed
if [ ! -f /config/sshd/keys/ssh_host_ed25519_key ]; then
echo "Generating sshd key..."
ssh-keygen -t ed25519 -f /config/sshd/keys/ssh_host_ed25519_key -N ''
fi
if [ ! -f /config/sshd/keys/ssh_host_rsa_key ]; then
echo "Generating sshd rsa key..."
ssh-keygen -t rsa -b 4096 -f /config/sshd/keys/ssh_host_rsa_key -N ''
fi
fi
echo "Checking for new users..."
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 in /config/sshd/users.conf file see Github readme for help"
touch /config/sshd/users.conf
exit 3
fi
# Source custom scripts, if any
if [ -d /config/sshd/scripts ]; then
for f in /config/sshd/scripts/*; 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
#sed -i 's/^backend = auto/backend = systemd/' /etc/fail2ban/jail.conf
if [[ -e /var/run/fail2ban/fail2ban.sock ]]; then
rm /var/run/fail2ban/fail2ban.sock
fi
if [[ -e /var/run/sshd.pid ]]; then
rm /var/run/sshd.pid
fi
if [[ -e /var/log/auth.log ]]; then
> /var/log/auth.log
fi
if $startSshd; then
echo "Executing syslog-ng"
service syslog-ng start
echo "Executing sshd"
service ssh start
if [ ! -e "/config/fail2ban/fail2ban.log" ]; then
touch "/config/fail2ban/fail2ban.log"
fi
if [ ! -e "/var/log/auth.log" ]; then
touch "/var/log/auth.log"
fi
echo "Executing fail2ban"
service fail2ban start
tail -F /config/fail2ban/fail2ban.log -F /var/log/auth.log
else
echo "Executing $@"
exec "$@"
fi