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

View File

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

View File

@ -1,21 +1,19 @@
#!/bin/sh
[ -n "${DEBUG}" ] && set -x
set -eu
CIPHER="${ECRYPTFS_CIPHER:-aes}"
KEY_BYTES="${ECRYPTFS_KEY_BYTES:-32}"
LOWER_DIR="${ECRYPTFS_LOWER_DIR:-/home}"
KEY_BYTES="${ECRYPTFS_KEY_BYTES:-16}"
LOWER_DIR="${1:-${ECRYPTFS_LOWER_DIR:-/home}}"
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)}"
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)}')}"
mkdir -p ${LOWER_DIR} ${UPPER_DIR} ${HOME}/.ecryptfs
printf "%s\n" "${LOWER_DIR} ${UPPER_DIR} ecryptfs" > ${HOME}/.ecryptfs/${ALIAS}.conf
printf "%s\n" "${SIG}" > ${HOME}/.ecryptfs/${ALIAS}.sig
printf "%s\n" "${FNEK_SIG}" >> ${HOME}/.ecryptfs/${ALIAS}.sig
# mount.ecryptfs_private ${ALIAS}
# ecryptfs already mounted ?
grep -q "${LOWER_DIR} ${UPPER_DIR} ecryptfs " /proc/mounts 2>/dev/null && break
mkdir -p "${LOWER_DIR}" "${UPPER_DIR}"
/bin/mount -t ecryptfs -o \
key="${KEY}",\
@ -30,5 +28,7 @@ ecryptfs_unlink_sigs\
"${LOWER_DIR}" "${UPPER_DIR}" 1>/dev/null
# 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)"
KEY="$(/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
[ -n "${DEBUG}" ] && set -x
set -eu
LANG=${LANG:-C.UTF-8}
LOCALES=${LOCALES:-${LANG} ${LANG##*.}}
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
done && locale-gen

View File

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

View File

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

View File

@ -1,16 +1,33 @@
#!/bin/sh
[ -n "${DEBUG}" ] && set -x
set -eu
for user in ${USERS:-${USERNAME}}; do
id ${user} > /dev/null 2>&1 || useradd -ms /bin/bash ${user}
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
chown -R ${user} /home/${user}/.ssh
chmod 0750 /home/${user}
id "${user}" > /dev/null 2>&1 || useradd -s /bin/bash "${user}"
[ ! -d "/home/${user}" ] \
&& mkdir -p "/home/${user}" \
&& chown "${user}" "/home/${user}" \
&& chmod 0750 "/home/${user}"
for file in .bash_logout .bashrc .profile; do
[ ! -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
for sudoer in ${SUDOERS:-}; do
usermod -a -G sudo ${sudoer}
usermod -a -G sudo "${sudoer}"
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
- SYS_ADMIN # ecryptfs
environment:
- DEBUG=${VDI_DEBUG}
- ECRYPTERS=${VDI_ECRYPTERS}
- LANG=${VDI_LANG}
- SUDOERS=${VDI_SUDOERS}
- TZ=${VDI_TZ}
@ -25,11 +27,22 @@ services:
- seccomp=unconfined # ecryptfs
tty: true
volumes:
- type: tmpfs
target: /home
tmpfs:
size: 8589934592 # 8GB
- type: tmpfs
target: /dev/shm
tmpfs:
size: 2147483648 # 2GB
- home:/home:delegated
- shared:/shared:cached
- shm:/dev/shm:delegated
volumes:
home:
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