Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
CONTRIBUTING.md
deploy
!deploy/requirements.txt
!deploy/docker/distribution/**
Dockerfile
docs
lega.*
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ deploy/docker/*
!deploy/docker/Makefile
!deploy/docker/README.md
!deploy/docker/*.sample
!deploy/docker/docker-compose.distribution.yml
!deploy/docker/cega
!deploy/docker/distribution
!deploy/docker/distribution/**


# =====================================
Expand Down
67 changes: 67 additions & 0 deletions deploy/docker/distribution/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
FROM ubuntu:22.04

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential pkg-config git gcc g++ make cmake automake autoconf libtool \
libfuse3-dev libglib2.0-dev libpq-dev libssl-dev libpam0g-dev libedit-dev \
zlib1g-dev libsystemd-dev patch ca-certificates util-linux libcap2-bin fuse3 \
&& rm -rf /var/lib/apt/lists/*

RUN set -eux; \
groupadd -r lega; \
useradd -r -g lega -s /usr/sbin/nologin lega; \
groupadd -r requesters; \
groupadd -r -g 999 postgres || groupadd -r postgres; \
useradd -r -u 999 -g postgres -s /usr/sbin/nologin postgres || \
useradd -r -g postgres -s /usr/sbin/nologin postgres; \
useradd -r -s /usr/sbin/nologin ega-sshd

RUN mkdir -p /opt/LocalEGA/etc/sshd /opt/LocalEGA/etc/nss /opt/LocalEGA/homes /opt/LocalEGA/security \
&& echo "user_allow_other" >> /etc/fuse.conf

COPY src/distribution/src /tmp/distribution/src

WORKDIR /tmp/distribution/src/crypt4gh-fs
RUN autoreconf -i \
&& ./configure --prefix=/opt/LocalEGA \
&& make \
&& make install

WORKDIR /tmp/distribution/src/nss
RUN make \
&& make install EGA_LIBDIR=/opt/LocalEGA/lib \
&& echo '/opt/LocalEGA/lib' > /etc/ld.so.conf.d/LocalEGA.conf \
&& ldconfig

WORKDIR /tmp/distribution/src/pam
RUN make clean \
&& make \
&& make install EGA_PAMDIR=/lib/security

WORKDIR /tmp/distribution/src/openssh/src
RUN patch -p1 -N < ../patches/systemd-readyness.patch || true \
&& patch -p1 -N < ../patches/sftp.patch || true \
&& autoreconf \
&& ./configure --prefix=/opt/LocalEGA \
--with-pam --with-pam-service=ega \
--with-zlib --with-openssl --with-libedit \
--with-privsep-user=ega-sshd --with-privsep-path=/run/ega-sshd \
--without-xauth --without-maildir --without-selinux \
--with-systemd --with-pid-dir=/run/ega-sshd \
&& make \
&& make install-nosysconf

COPY deploy/docker/distribution/sshd_config /usr/local/share/ega/sshd_config
COPY deploy/docker/distribution/nsswitch.conf /etc/nsswitch.conf
COPY deploy/docker/distribution/pam.sshd /usr/local/share/ega/pam.sshd
COPY src/distribution/src/crypt4gh-fs/fs.conf.sample /usr/local/share/ega/fs.conf.sample
COPY deploy/docker/distribution/entrypoint.sh /usr/local/bin/ega-distribution-entrypoint

RUN chmod +x /usr/local/bin/ega-distribution-entrypoint

ENV PATH="/opt/LocalEGA/bin:/opt/LocalEGA/sbin:${PATH}"

EXPOSE 2223

ENTRYPOINT ["/usr/local/bin/ega-distribution-entrypoint"]
66 changes: 66 additions & 0 deletions deploy/docker/distribution/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env bash
set -euo pipefail

SSHD_CONFIG=/opt/LocalEGA/etc/sshd/sshd_config
SSHD_CONFIG_TEMPLATE=/usr/local/share/ega/sshd_config
PAM_SSHD_TEMPLATE=/usr/local/share/ega/pam.sshd
FUSE_DB_CONF=/opt/LocalEGA/etc/fuse-vault-db.conf
FUSE_DB_CONF_TEMPLATE=/usr/local/share/ega/fs.conf.sample
SSHD_BIN=/opt/LocalEGA/sbin/sshd

if [[ ! -x "${SSHD_BIN}" ]]; then
SSHD_BIN=/opt/LocalEGA/bin/sshd
fi

mkdir -p /run/ega-sshd /opt/LocalEGA/etc/sshd /opt/LocalEGA/homes /opt/LocalEGA/etc/nss
chmod 0755 /run/ega-sshd
chown root:root /opt/LocalEGA/homes
chmod 0755 /opt/LocalEGA/homes

if [[ -f "${SSHD_CONFIG_TEMPLATE}" ]]; then
cp "${SSHD_CONFIG_TEMPLATE}" "${SSHD_CONFIG}"
fi

if [[ -f "${PAM_SSHD_TEMPLATE}" ]]; then
cp "${PAM_SSHD_TEMPLATE}" /etc/pam.d/ega
cp "${PAM_SSHD_TEMPLATE}" /etc/pam.d/sshd
fi

if [[ ! -f "${FUSE_DB_CONF}" ]]; then
if [[ -z "${FUSE_DB_DSN:-}" ]]; then
echo "FATAL: ${FUSE_DB_CONF} missing and FUSE_DB_DSN not set" >&2
exit 1
fi
{
echo "dsn = ${FUSE_DB_DSN}"
if [[ -f "${FUSE_DB_CONF_TEMPLATE}" ]]; then
grep -v '^dsn = ' "${FUSE_DB_CONF_TEMPLATE}"
fi
} > "${FUSE_DB_CONF}"
fi

if [[ "${EGA_PRECREATE_HOMES:-1}" != "0" ]]; then
USERS_FILE=/opt/LocalEGA/etc/nss/users
if [[ -f "${USERS_FILE}" ]]; then
while IFS=: read -r username _ uid gid _ homedir _; do
if [[ -n "${homedir}" && ! -d "${homedir}" ]]; then
mkdir -p "${homedir}"
chown root:"${gid}" "${homedir}"
chmod 0550 "${homedir}"
fi
done < "${USERS_FILE}"
fi
fi


if [[ ! -f /opt/LocalEGA/etc/sshd/host_ed25519_key ]]; then
/opt/LocalEGA/bin/ssh-keygen -t ed25519 -N '' -f /opt/LocalEGA/etc/sshd/host_ed25519_key
fi

if [[ ! -f /opt/LocalEGA/etc/sshd/host_rsa_key ]]; then
/opt/LocalEGA/bin/ssh-keygen -t rsa -b 3072 -N '' -f /opt/LocalEGA/etc/sshd/host_rsa_key
fi

touch /opt/LocalEGA/etc/sshd/banner

exec "${SSHD_BIN}" -D -e -f "${SSHD_CONFIG}"
23 changes: 23 additions & 0 deletions deploy/docker/distribution/nss-sync.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
set -euo pipefail

SYNC_INTERVAL_SECONDS="${SYNC_INTERVAL_SECONDS:-60}"

ensure_homes() {
local users_file="/opt/LocalEGA/etc/nss/users"
if [[ ! -f "${users_file}" ]]; then
return
fi
while IFS=: read -r _ _ _ gid _ homedir _; do
if [[ -n "${homedir}" && ! -d "${homedir}" ]]; then
mkdir -p "${homedir}"
chown root:"${gid}" "${homedir}"
chmod 0550 "${homedir}"
fi
done < "${users_file}"
}

while true; do
ensure_homes
sleep "${SYNC_INTERVAL_SECONDS}"
done
4 changes: 4 additions & 0 deletions deploy/docker/distribution/nsswitch.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
passwd: files egafiles systemd
group: files egafiles systemd
shadow: files egafiles
gshadow: files
18 changes: 18 additions & 0 deletions deploy/docker/distribution/pam.sshd
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#%PAM-1.0
#
# PAM configuration for the SFTP EGA service (container)
#

# Check the passwords. Die if it fails. We don't allow root to try
auth requisite pam_ega_auth.so

# Create homedir before chroot validation
account requisite pam_ega_homedir.so subdir=outbox attrs=02700 bail_on_exists

# Validate the user exists in NSS
account requisite pam_ega_localnss.so group=lega display=requesters

# No can do
password required pam_deny.so

session requisite pam_ega_mount.so supp_group=lega umask=0007 unmount_on_close conf=conf_fd:/opt/LocalEGA/etc/fuse-vault-db.conf lock=/run/%s.lock mnt=/opt/LocalEGA/homes/%s/outbox child_notify=parent_fd -- /opt/LocalEGA/bin/crypt4gh-db.fs -f -o ro,default_permissions,allow_root,fsname=EGAFS,max_idle_threads=2
35 changes: 35 additions & 0 deletions deploy/docker/distribution/sshd_config
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
Port 2223
PidFile /run/ega-sshd/sshd.pid

Banner /opt/LocalEGA/etc/sshd/banner

HostKey /opt/LocalEGA/etc/sshd/host_ed25519_key
HostKey /opt/LocalEGA/etc/sshd/host_rsa_key

UseDNS no

UsePAM yes
PasswordAuthentication no
ChallengeResponseAuthentication yes
AuthenticationMethods keyboard-interactive:pam

DenyUsers root
AllowGroups requesters

PermitRootLogin no
PermitEmptyPasswords no

DisableForwarding yes

Subsystem sftp internal-sftp -d outbox -R
ForceCommand internal-sftp -d outbox -R

ChrootDirectory %h

AuthorizedKeysCommand /usr/bin/cat /opt/LocalEGA/etc/authorized_keys/%U
AuthorizedKeysCommandUser postgres

Compression no

LoginGraceTime 30
MaxStartups 10:30:60
44 changes: 44 additions & 0 deletions deploy/docker/docker-compose.distribution.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
services:
distribution:
build:
context: ../..
dockerfile: deploy/docker/distribution/Dockerfile
image: localega/distribution:latest
container_name: distribution
ports:
- "2224:2223"
networks:
- vault
environment:
FUSE_DB_DSN: ${FUSE_DB_DSN:?set FUSE_DB_DSN (e.g. postgresql://distribution:${DISTRIBUTION_DB_PASSWORD:?set DISTRIBUTION_DB_PASSWORD}@vault-db:5432/ega?application_name=EGADistFS)}
volumes:
- ${LOCALEGA_BASE:-/opt/LocalEGA}/vault:/opt/LocalEGA/vault:ro
- ${LOCALEGA_BASE:-/opt/LocalEGA}/vault.bkp:/opt/LocalEGA/vault.bkp:ro
- ${LOCALEGA_BASE:-/opt/LocalEGA}/etc:/opt/LocalEGA/etc
- ${LOCALEGA_BASE:-/opt/LocalEGA}/homes:/opt/LocalEGA/homes
devices:
- /dev/fuse:/dev/fuse
cap_add:
- SYS_ADMIN
security_opt:
- apparmor:unconfined
restart: unless-stopped
depends_on:
- nss-sync

nss-sync:
image: ubuntu:22.04
container_name: nss-sync
environment:
SYNC_INTERVAL_SECONDS: ${SYNC_INTERVAL_SECONDS:-60}
volumes:
- ${LOCALEGA_BASE:-/opt/LocalEGA}/etc:/opt/LocalEGA/etc
- ${LOCALEGA_BASE:-/opt/LocalEGA}/homes:/opt/LocalEGA/homes
- ./distribution/nss-sync.sh:/usr/local/bin/nss-sync.sh:ro
networks:
- vault
entrypoint: ["/bin/bash", "/usr/local/bin/nss-sync.sh"]
restart: unless-stopped

networks:
vault:
Loading