sql auth and healthcheck
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Paolo Asperti 2024-02-11 21:09:40 +01:00
parent 9fca459f93
commit 8289114ee6
Signed by: paspo
GPG Key ID: 06D46905D19D5182
6 changed files with 139 additions and 2 deletions

View File

@ -1,9 +1,14 @@
FROM alpine:latest
RUN \
apk -U add proftpd proftpd-mod_tls proftpd-mod_ifsession proftpd-utils openssl perl acme.sh && \
apk -U add proftpd proftpd-mod_tls proftpd-mod_ifsession \
proftpd-mod_deflate proftpd-mod_geoip proftpd-mod_sql_sqlite \
proftpd-utils openssl perl acme.sh lftp sqlite && \
mkdir -p /var/run/proftpd /etc/proftpd/custom.conf.d/
COPY rootfs /
HEALTHCHECK --interval=2m --timeout=3s \
CMD /app/healthcheck.sh || exit 1
ENTRYPOINT ["/app/entrypoint.sh"]

View File

@ -144,3 +144,55 @@ docker exec -ti my-ftps ftpasswd --passwd --name=paolo --uid=1000 --home=/home/p
```
You also have to create and chown the user's home folder.
## sql db for user authentication
It is possible to use a sqlite db for user authentication, just add `SQLITE_AUTH=1` to the environment:
```yaml
version: "3"
services:
ftps-server:
image: docker.asperti.com/paspo/ftps
restart: always
ports:
- "21:21"
- "20:20"
- "21210-21220:21210-21220"
volumes:
- "/srv/ftps/auth:/auth"
- "/srv/ftps/conf:/etc/proftpd/custom.conf.d:ro"
- "/srv/ftps/data:/home"
- "/etc/letsencrypt:/certs:ro"
environment:
- SQLITE_AUTH=1
- MASQUERADE=ftp.mydomain.com
- PASSIVEPORTS_START=21210
- PASSIVEPORTS_END=21220
- MAXCLIENTS=500
- MAXCLIENTSPERHOST=100
- TLS_CERT=/certs/live/ftp.mydomain.com/cert.pem
- TLS_KEY=/certs/live/ftp.mydomain.com/privkey.pem
- TLS_CHAIN=/certs/live/ftp.mydomain.com/chain.pem
```
Now, instead of using `/auth/passwd`, proftpd is using `/auth/ftpd.db`.
To create a new user, you must now update this db.
To create a new user:
```bash
docker exec -ti my-ftps sqlite3 sqlite3 /auth/ftpd.db <<EOF
INSERT OR IGNORE INTO users (userid,passwd,uid,gid,homedir,shell) VALUES ('new_user','',1000,1000,'/home/new_user','/bin/false');
INSERT OR IGNORE INTO groups (groupname,gid,members) VALUES ('new_user',1000,'new_user');
EOF
```
To update a password:
```bash
PASSWD_SHA=$(echo -n ChangeThisPass | mkpasswd -m sha512)
docker exec -ti my-ftps sqlite3 sqlite3 /auth/ftpd.db <<EOF
UPDATE users SET passwd='$PASSWD_SHA' WHERE userid='new_user';
EOF
```

View File

@ -29,6 +29,42 @@ else
/app/cert-init.sh
fi
############ INIT DB if needed
SQLITE_AUTH=${SQLITE_AUTH:-no}
if [ "$SQLITE_AUTH" = "1" ] ; then
if [ ! -f /auth/ftpd.db ] ; then
sqlite3 /auth/ftpd.db < /app/init.sql
fi
fi
############ GENERATE RANDOM PASSWORD FOR HEALTHCHECK
head /dev/urandom | tr -dc A-Za-z0-9 | head -c 20 > /app/healthcheck.pwd
chmod 600 /app/healthcheck.pwd
############ UPDATE HEALTHCHECK CREDS
HEALTHCHECK_UID=1999
mkdir -p /home/healthcheck
chown ${HEALTHCHECK_UID}:${HEALTHCHECK_UID} /home/healthcheck
if [ "$SQLITE_AUTH" = "1" ] ; then
PASSWD_SHA=$(cat /app/healthcheck.pwd | mkpasswd -m sha512)
sqlite3 /auth/ftpd.db <<EOF
INSERT OR IGNORE INTO users (userid,passwd,uid,gid,homedir,shell) VALUES ('healthcheck','',${HEALTHCHECK_UID},${HEALTHCHECK_UID},'/home/healthcheck','/bin/false');
INSERT OR IGNORE INTO groups (groupname,gid,members) VALUES ('healthcheck',${HEALTHCHECK_UID},'healthcheck');
UPDATE users SET passwd='$PASSWD_SHA' WHERE userid='healthcheck';
EOF
else
cat /app/healthcheck.pwd | ftpasswd --stdin --passwd --name=healthcheck \
--uid=${HEALTHCHECK_UID} \
--home=/home/healthcheck --sha512 --shell=/bin/false --file=/auth/passwd
fi
############ CONFIGURE AUTH
if [ "$SQLITE_AUTH" = "1" ] ; then
echo "AuthOrder mod_sql.c" > /etc/prodtpd/conf.d/auth.conf
else
echo "AuthOrder mod_auth_file.c" > /etc/prodtpd/conf.d/auth.conf
fi
############ START CRON
crond -b

7
rootfs/app/healthcheck.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/sh
USER=healthcheck
LFTP_PASSWORD=$(cat /app/healthcheck.pwd)
lftp -e "set ssl-allow true; set ftp:ssl-force true; set ftp:passive-mode true;set ssl:verify-certificate false;open -u ${USER},${LFTP_PASSWORD} ftp://127.0.0.1; ls ; bye" > /dev/null
echo $?

14
rootfs/app/init.sql Normal file
View File

@ -0,0 +1,14 @@
CREATE TABLE `users` (
userid VARCHAR(30) NOT NULL UNIQUE,
passwd VARCHAR(80) NOT NULL,
uid INTEGER UNIQUE,
gid INTEGER,
homedir VARCHAR(255),
shell VARCHAR(255),
last_accessed DATETIME
);
CREATE TABLE `groups` (
groupname VARCHAR(30) NOT NULL UNIQUE,
gid INTEGER NOT NULL,
members VARCHAR(255)
);

View File

@ -1,4 +1,3 @@
AuthOrder mod_auth_file.c
AuthUserFile /auth/passwd
RequireValidShell off
ScoreBoardFile /run/proftpd/scoreboard
@ -23,4 +22,28 @@ DefaultRoot ~
DelayTable /run/proftpd/proftpd.delay
</IfModule>
<IfModule mod_deflate.c>
DeflateEngine on
</IfModule>
<IfModule mod_sql.c>
<IfModule mod_sql_sqlite.c>
SQLBackend sqlite3
SQLConnectInfo /auth/ftpd.db
SQLEngine On
SQLAuthenticate users
SQLAuthTypes OpenSSL Crypt
SQLUserInfo users userid passwd uid gid homedir shell
SQLGroupInfo groups groupname gid members
SQLNamedQuery last_accessed UPDATE "last_accessed = DATETIME('now') WHERE userid='%u'" users
SQLLog PASS last_accessed
SQLMinId 33
SQLDefaultUID 33
SQLDefaultGID 33
RequireValidShell off
</IfModule>
</IfModule>
Include /etc/proftpd/custom.conf.d/