add ssh ecryptfs auto mount

This commit is contained in:
Yann Autissier 2022-04-10 02:21:44 +00:00
parent d328ae3e24
commit e6fe7dcf0c
9 changed files with 133 additions and 39 deletions

View File

@ -8,16 +8,23 @@ RUN apt-get update \
ecryptfs-utils \ ecryptfs-utils \
fail2ban \ fail2ban \
iptables \ iptables \
less \
libpam-script \
neovim \ neovim \
python3-pip \
&& pip install ssh-crypt \
&& apt-get clean \ && apt-get clean \
&& rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/* && rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/*
COPY ${DOCKER_BUILD_DIR}/run.sh /app RUN cp /usr/share/doc/libpam-script/examples/logscript /usr/share/libpam-script \
COPY ${DOCKER_BUILD_DIR}/setup_ecryptfs.sh /app && sed -i 's/LOGFILE=\/tmp/LOGFILE=\/var\/log/' /usr/share/libpam-script/logscript \
COPY ${DOCKER_BUILD_DIR}/setup_locales.sh /app && for script in auth acct passwd ses_open ses_close; do \
COPY ${DOCKER_BUILD_DIR}/setup_sshd.sh /app ln -s /usr/share/libpam-script/logscript "/usr/share/libpam-script/pam_script_${script}"; \
COPY ${DOCKER_BUILD_DIR}/setup_timezone.sh /app done \
COPY ${DOCKER_BUILD_DIR}/setup_users.sh /app && ln -s /usr/share/libpam-script /etc/pam-script
WORKDIR /app
COPY ${DOCKER_BUILD_DIR}/*.sh /app/
CMD [] CMD []
ENTRYPOINT ["/app/run.sh"] ENTRYPOINT ["/app/run.sh"]

View File

@ -1,4 +1,5 @@
#!/bin/sh #!/bin/sh
[ -n "${DEBUG}" ] && set -x
### every exit != 0 fails the script ### every exit != 0 fails the script
set -eu set -eu
@ -9,8 +10,9 @@ if [ ! -f /app/.setup_done ]; then
/app/setup_timezone.sh /app/setup_timezone.sh
fi fi
# /home is mounted in RAM and does not survive on restart /app/setup_ecryptfs.sh /dev/shm
/app/setup_ecryptfs.sh # /shared encryption will not survive on restart
/app/setup_ecryptfs.sh /shared
/app/setup_users.sh /app/setup_users.sh
## Start-up our services manually (since Docker container will not invoke all init scripts). ## Start-up our services manually (since Docker container will not invoke all init scripts).
@ -24,28 +26,30 @@ service dbus start
service rsyslog start service rsyslog start
# prevent fail2ban to fail starting # prevent fail2ban to fail starting
touch /var/log/auth.log touch /var/log/auth.log
# prevent tail -f to fail starting
touch /var/log/pam-script.log
# prevent fail2ban to fail restarting # prevent fail2ban to fail restarting
rm -f /var/run/fail2ban/fail2ban.sock rm -f /var/run/fail2ban/fail2ban.sock
# Start fail2ban (for security reasons) # Start fail2ban (for security reasons)
service fail2ban start service fail2ban start
cleanup() { cleanup() {
/bin/umount -fl /home /bin/umount -fl /home ||:
service dbus stop service dbus stop
service fail2ban stop service fail2ban stop
service rsyslog stop service rsyslog stop
service ssh stop service ssh stop
kill $PID 2>/dev/null kill "$PID" 2>/dev/null
exit exit
} }
trap "cleanup" INT TERM trap "cleanup" INT TERM
if [ $# -eq 0 ]; then if [ $# -eq 0 ]; then
exec tail -f /dev/null & exec tail -f /var/log/fail2ban.log /var/log/syslog /var/log/auth.log /var/log/pam-script.log &
PID=$! && wait PID=$! && wait
else else
# WARNING: cleanup is not called # WARNING: cleanup is not called
exec /bin/bash -c "set -e && $@" exec /bin/bash -c "set -e && $*"
fi fi
cleanup cleanup

View File

@ -1,21 +1,19 @@
#!/bin/sh #!/bin/sh
[ -n "${DEBUG}" ] && set -x
set -eu set -eu
CIPHER="${ECRYPTFS_CIPHER:-aes}" CIPHER="${ECRYPTFS_CIPHER:-aes}"
KEY_BYTES="${ECRYPTFS_KEY_BYTES:-32}" KEY_BYTES="${ECRYPTFS_KEY_BYTES:-16}"
LOWER_DIR="${ECRYPTFS_LOWER_DIR:-/home}" LOWER_DIR="${1:-${ECRYPTFS_LOWER_DIR:-/home}}"
UPPER_DIR="${ECRYPTFS_UPPER_DIR:-${LOWER_DIR}}" UPPER_DIR="${ECRYPTFS_UPPER_DIR:-${LOWER_DIR}}"
ALIAS="${ECRYPTFS_ALIAS:-${LOWER_DIR##*/}}"
PASSPHRASE="${ECRYPTFS_PASSPHRASE:-$(/usr/bin/base64 /dev/urandom |/usr/bin/head -c 64)}" PASSPHRASE="${ECRYPTFS_PASSPHRASE:-$(/usr/bin/base64 /dev/urandom |/usr/bin/head -c 64)}"
KEY="${ECRYPTFS_KEY:-passphrase:passphrase_passwd=${PASSPHRASE}}" KEY="${ECRYPTFS_KEY:-passphrase:passphrase_passwd=${PASSPHRASE}}"
SIG="${ECRYPTFS_SIG:-$(printf "%s" "${PASSPHRASE}" |/usr/bin/ecryptfs-add-passphrase - |/usr/bin/awk '$5 == "sig" {print substr($6,2,16); exit;}')}"
FNEK_SIG="${ECRYPTFS_FNEK_SIG:-$(printf "%s" "${PASSPHRASE}" |/usr/bin/ecryptfs-add-passphrase --fnek - |/usr/bin/awk '$5 == "sig" && NR == 2 {print substr($6,2,16)}')}" FNEK_SIG="${ECRYPTFS_FNEK_SIG:-$(printf "%s" "${PASSPHRASE}" |/usr/bin/ecryptfs-add-passphrase --fnek - |/usr/bin/awk '$5 == "sig" && NR == 2 {print substr($6,2,16)}')}"
mkdir -p ${LOWER_DIR} ${UPPER_DIR} ${HOME}/.ecryptfs # ecryptfs already mounted ?
printf "%s\n" "${LOWER_DIR} ${UPPER_DIR} ecryptfs" > ${HOME}/.ecryptfs/${ALIAS}.conf grep -q "${LOWER_DIR} ${UPPER_DIR} ecryptfs " /proc/mounts 2>/dev/null && break
printf "%s\n" "${SIG}" > ${HOME}/.ecryptfs/${ALIAS}.sig
printf "%s\n" "${FNEK_SIG}" >> ${HOME}/.ecryptfs/${ALIAS}.sig mkdir -p "${LOWER_DIR}" "${UPPER_DIR}"
# mount.ecryptfs_private ${ALIAS}
/bin/mount -t ecryptfs -o \ /bin/mount -t ecryptfs -o \
key="${KEY}",\ key="${KEY}",\
@ -30,5 +28,7 @@ ecryptfs_unlink_sigs\
"${LOWER_DIR}" "${UPPER_DIR}" 1>/dev/null "${LOWER_DIR}" "${UPPER_DIR}" 1>/dev/null
# Overwrite sensible variables with random data # Overwrite sensible variables with random data
ECRYPTFS_KEY="$(/usr/bin/base64 /dev/urandom |/usr/bin/head -c 64)"
ECRYPTFS_PASSPHRASE="$(/usr/bin/base64 /dev/urandom |/usr/bin/head -c 64)" ECRYPTFS_PASSPHRASE="$(/usr/bin/base64 /dev/urandom |/usr/bin/head -c 64)"
KEY="$(/usr/bin/base64 /dev/urandom |/usr/bin/head -c 64)"
PASSPHRASE="$(/usr/bin/base64 /dev/urandom |/usr/bin/head -c 64)" PASSPHRASE="$(/usr/bin/base64 /dev/urandom |/usr/bin/head -c 64)"

View File

@ -0,0 +1,50 @@
#!/bin/sh
[ -n "${DEBUG}" ] && set -x
[ ! -f "${HOME}/.ecryptfs/auto-mount" ] && break
LOWER_DIR="${1:-${ECRYPTFS_LOWER_DIR:-${HOME}/Secure}}"
UPPER_DIR="${ECRYPTFS_UPPER_DIR:-${LOWER_DIR}}"
ALIAS="${ECRYPTFS_ALIAS:-${LOWER_DIR##*/}}"
mkdir -p "${LOWER_DIR}" "${UPPER_DIR}"
# ecryptfs already mounted ?
grep -q "${LOWER_DIR} ${UPPER_DIR} ecryptfs " /proc/mounts 2>/dev/null && break
# we should always use the same key when multiple keys are loaded in ssh-agent
if [ -f "${HOME}/.ecryptfs/${ALIAS}.key" ]; then
ssh_key_fingerprint=$(cat "${HOME}/.ecryptfs/${ALIAS}.key")
else
ssh_key_fingerprint=$(/usr/bin/ssh-add -l 2>/dev/null |awk '{print $2; exit;}')
[ -n "${ssh_key_fingerprint}" ] && printf "%s\n" "${ssh_key_fingerprint}" > "${HOME}/.ecryptfs/${ALIAS}.key"
fi
# select ssh key
ssh_key=$(/usr/bin/ssh-add -l 2>/dev/null |awk '$2 == "'${ssh_key_fingerprint:-undef}'" {print $3}')
[ -z "${ssh_key}" ] && echo "WARNING: Unable to find ssh key ${ssh_key} in ssh agent ${SSH_AUTH_SOCK}" && break
if [ -f "${HOME}/.ecryptfs/${ALIAS}.ssh" ]; then
PASSPHRASE=$(/usr/local/bin/ssh-crypt -b -d -k "${ssh_key}" -i "${HOME}/.ecryptfs/${ALIAS}.ssh")
else
PASSPHRASE="${ECRYPTFS_PASSPHRASE:-$(/usr/bin/base64 /dev/urandom |/usr/bin/head -c 64)}"
printf "%s" "${PASSPHRASE}" |/usr/local/bin/ssh-crypt -b -e -k "${ssh_key}" -o "${HOME}/.ecryptfs/${ALIAS}.ssh"
fi
SIG="${ECRYPTFS_SIG:-$(printf "%s" "${PASSPHRASE}" |/usr/bin/ecryptfs-add-passphrase - |/usr/bin/awk '$5 == "sig" {print substr($6,2,16); exit;}')}"
FNEK_SIG="${ECRYPTFS_FNEK_SIG:-$(printf "%s" "${PASSPHRASE}" |/usr/bin/ecryptfs-add-passphrase --fnek - |/usr/bin/awk '$5 == "sig" && NR == 2 {print substr($6,2,16)}')}"
# Overwrite sensible variables with random data
ECRYPTFS_PASSPHRASE="$(/usr/bin/base64 /dev/urandom |/usr/bin/head -c 64)"
PASSPHRASE="$(/usr/bin/base64 /dev/urandom |/usr/bin/head -c 64)"
if [ ! -f "${HOME}/.ecryptfs/${ALIAS}.conf" ]; then
printf "%s %s ecryptfs\n" "${LOWER_DIR}" "${UPPER_DIR}" > "${HOME}/.ecryptfs/${ALIAS}.conf"
fi
if [ ! -f "${HOME}/.ecryptfs/${ALIAS}.sig" ]; then
printf "%s\n" "${SIG}" > "${HOME}/.ecryptfs/${ALIAS}.sig"
printf "%s\n" "${FNEK_SIG}" >> "${HOME}/.ecryptfs/${ALIAS}.sig"
else
grep "${SIG}" "${HOME}/.ecryptfs/${ALIAS}.sig" >/dev/null
grep "${FNEK_SIG}" "${HOME}/.ecryptfs/${ALIAS}.sig" >/dev/null
fi
/sbin/mount.ecryptfs_private "${ALIAS}"

View File

@ -1,9 +1,10 @@
#!/bin/sh #!/bin/sh
[ -n "${DEBUG}" ] && set -x
set -eu set -eu
LANG=${LANG:-C.UTF-8} LANG=${LANG:-C.UTF-8}
LOCALES=${LOCALES:-${LANG} ${LANG##*.}} LOCALES=${LOCALES:-${LANG} ${LANG##*.}}
printf "LANG=%s\n" "${LANG}" > /etc/default/locale printf "LANG=%s\n" "${LANG}" > /etc/default/locale
rm /etc/locale.gen && printf "%s\n" "${LOCALES}" |while read locale; do rm /etc/locale.gen && printf "%s\n" "${LOCALES}" |while read -r locale; do
printf "%s\n" "${locale}" >> /etc/locale.gen printf "%s\n" "${locale}" >> /etc/locale.gen
done && locale-gen done && locale-gen

View File

@ -1,4 +1,5 @@
#!/bin/sh #!/bin/sh
[ -n "${DEBUG}" ] && set -x
set -eu set -eu
sed -i "s/^#\?PasswordAuthentication.*/PasswordAuthentication no/g" /etc/ssh/sshd_config sed -i "s/^#\?PasswordAuthentication.*/PasswordAuthentication no/g" /etc/ssh/sshd_config

View File

@ -1,4 +1,5 @@
#!/bin/sh #!/bin/sh
[ -n "${DEBUG}" ] && set -x
set -eu set -eu
TZ="${TZ:-UTC}" TZ="${TZ:-UTC}"

View File

@ -1,16 +1,33 @@
#!/bin/sh #!/bin/sh
[ -n "${DEBUG}" ] && set -x
set -eu set -eu
for user in ${USERS:-${USERNAME}}; do for user in ${USERS:-${USERNAME}}; do
id ${user} > /dev/null 2>&1 || useradd -ms /bin/bash ${user} id "${user}" > /dev/null 2>&1 || useradd -s /bin/bash "${user}"
usermod -a -G x2gouser ${user} [ ! -d "/home/${user}" ] \
mkdir -p /home/${user}/.ssh && mkdir -p "/home/${user}" \
wget -qO /home/${user}/.ssh/authorized_keys https://gitlab.com/${user}.keys 2>/dev/null \ && chown "${user}" "/home/${user}" \
|| wget -qO /home/${user}/.ssh/authorized_keys https://github.com/${user}.keys 2>/dev/null && chmod 0750 "/home/${user}"
chown -R ${user} /home/${user}/.ssh for file in .bash_logout .bashrc .profile; do
chmod 0750 /home/${user} [ ! -f "/home/${user}/${file}" ] \
&& cp "/etc/skel/${file}" "/home/${user}" \
&& chown "${user}" "/home/${user}/${file}"
done
usermod -a -G x2gouser "${user}"
mkdir -p "/home/${user}/.ssh"
wget -qO "/home/${user}/.ssh/authorized_keys" "https://gitlab.com/${user}.keys" 2>/dev/null \
|| wget -qO "/home/${user}/.ssh/authorized_keys" "https://github.com/${user}.keys" 2>/dev/null \
|| echo "WARNING: Unable to fetch ssh public keys for user ${user}."
chown "${user}" "/home/${user}/.ssh" "/home/${user}/.ssh/authorized_keys"
done done
for sudoer in ${SUDOERS:-}; do for sudoer in ${SUDOERS:-}; do
usermod -a -G sudo ${sudoer} usermod -a -G sudo "${sudoer}"
done done
mkdir -p /home/shared && chmod 1777 /home/shared for ecrypter in ${ECRYPTERS:-}; do
mkdir -p "/home/${ecrypter}/.ecryptfs"
touch "/home/${ecrypter}/.ecryptfs/auto-mount"
touch "/home/${ecrypter}/.ecryptfs/auto-umount"
chown -R "${ecrypter}" "/home/${ecrypter}/.ecryptfs"
done
ln -s /app/setup_ecryptfs_sshagent.sh /etc/profile.d/
mkdir -p /shared && chmod 1777 /shared

View File

@ -13,6 +13,8 @@ services:
- NET_RAW # iptables - NET_RAW # iptables
- SYS_ADMIN # ecryptfs - SYS_ADMIN # ecryptfs
environment: environment:
- DEBUG=${VDI_DEBUG}
- ECRYPTERS=${VDI_ECRYPTERS}
- LANG=${VDI_LANG} - LANG=${VDI_LANG}
- SUDOERS=${VDI_SUDOERS} - SUDOERS=${VDI_SUDOERS}
- TZ=${VDI_TZ} - TZ=${VDI_TZ}
@ -25,11 +27,22 @@ services:
- seccomp=unconfined # ecryptfs - seccomp=unconfined # ecryptfs
tty: true tty: true
volumes: volumes:
- type: tmpfs - home:/home:delegated
target: /home - shared:/shared:cached
tmpfs: - shm:/dev/shm:delegated
size: 8589934592 # 8GB
- type: tmpfs
target: /dev/shm volumes:
tmpfs: home:
size: 2147483648 # 2GB shared:
driver: local
driver_opts:
type: none
device: /mnt/shared
o: bind
shm:
driver: local
driver_opts:
type: tmpfs
device: tmpfs
o: mode=1777,size=2147483648 # 2GB