mirror of
https://github.com/bolkedebruin/rdpgw.git
synced 2026-05-14 04:10:10 +00:00
Drop baked-in TLS cert, run as 1001, refuse known placeholder secrets
The dev container image generated a TLS keypair at build time and shipped it inside the image, so every pull of the same image tag was serving the same private key. The entrypoint also reverted to USER 0 to support a dead `createusers.txt` loop and a `chmod u+s` that was a no-op (set on a binary owned by 1001). Net result was that any RCE in the gateway landed as root and the wire-trust posture relied on a shared private key. Stop generating the cert at build time: the runtime image now carries openssl and the entrypoint mints an ephemeral self-signed cert at first start when no cert is mounted at the configured path. Each container instance gets its own key. Drop USER 0 entirely; the entrypoint runs as 1001 throughout. Prune the dead createusers loop and the `chmod u+s`. Separately, the README and the dev compose files publish a small set of literal placeholder values for SessionKey, SessionEncryptionKey, and the various Token*Key fields. Operators copy-paste these into real deployments. Refuse to start when any of those literals appear in the corresponding config field.
This commit is contained in:
@@ -2,21 +2,11 @@
|
||||
FROM golang:1.24-alpine as builder
|
||||
|
||||
# Install CA certificates explicitly in builder
|
||||
RUN apk --no-cache add git gcc musl-dev linux-pam-dev openssl
|
||||
RUN apk --no-cache add git gcc musl-dev linux-pam-dev
|
||||
|
||||
# add user
|
||||
RUN adduser --disabled-password --gecos "" --home /opt/rdpgw --uid 1001 rdpgw
|
||||
|
||||
# certificate generation
|
||||
RUN mkdir -p /opt/rdpgw && cd /opt/rdpgw && \
|
||||
random=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) && \
|
||||
openssl genrsa -des3 -passout pass:$random -out server.pass.key 2048 && \
|
||||
openssl rsa -passin pass:$random -in server.pass.key -out key.pem && \
|
||||
rm server.pass.key && \
|
||||
openssl req -new -sha256 -key key.pem -out server.csr \
|
||||
-subj "/C=US/ST=VA/L=SomeCity/O=MyCompany/OU=MyDivision/CN=rdpgw" && \
|
||||
openssl x509 -req -days 365 -in server.csr -signkey key.pem -out server.pem
|
||||
|
||||
# build rdpgw and set rights
|
||||
ARG CACHEBUST
|
||||
RUN git clone https://github.com/bolkedebruin/rdpgw.git /app && \
|
||||
@@ -25,12 +15,13 @@ RUN git clone https://github.com/bolkedebruin/rdpgw.git /app && \
|
||||
CGO_ENABLED=0 GOOS=linux go build -trimpath -tags '' -ldflags '' -o '/opt/rdpgw/rdpgw' ./cmd/rdpgw && \
|
||||
CGO_ENABLED=1 GOOS=linux go build -trimpath -tags '' -ldflags '' -o '/opt/rdpgw/rdpgw-auth' ./cmd/auth && \
|
||||
chmod +x /opt/rdpgw/rdpgw && \
|
||||
chmod +x /opt/rdpgw/rdpgw-auth && \
|
||||
chmod u+s /opt/rdpgw/rdpgw-auth
|
||||
chmod +x /opt/rdpgw/rdpgw-auth
|
||||
|
||||
FROM alpine:latest
|
||||
# Install CA certificates in final stage
|
||||
RUN apk --no-cache add linux-pam musl tzdata ca-certificates && update-ca-certificates
|
||||
# Install CA certificates and (for the dev compose) openssl so the
|
||||
# entrypoint can mint an ephemeral self-signed cert at startup. No cert
|
||||
# is baked into the image, so each container instance gets its own key.
|
||||
RUN apk --no-cache add linux-pam musl tzdata ca-certificates openssl && update-ca-certificates
|
||||
|
||||
# make tempdir in case filestore is used
|
||||
ADD tmp.tar /
|
||||
@@ -47,6 +38,5 @@ COPY --from=builder /app/cmd/rdpgw/templates /opt/rdpgw/templates
|
||||
# Copy assets directory from the app source
|
||||
COPY --chown=1001 --from=builder /app/assets /opt/rdpgw/assets
|
||||
|
||||
USER 0
|
||||
WORKDIR /opt/rdpgw
|
||||
ENTRYPOINT ["/bin/sh", "/run.sh"]
|
||||
|
||||
@@ -1,34 +1,25 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
USER=rdpgw
|
||||
cd /opt/rdpgw
|
||||
|
||||
file="/root/createusers.txt"
|
||||
if [ -f $file ]
|
||||
then
|
||||
while IFS=: read -r username password is_sudo
|
||||
do
|
||||
echo "Username: $username, Password: **** , Sudo: $is_sudo"
|
||||
|
||||
if getent passwd "$username" > /dev/null 2>&1
|
||||
then
|
||||
echo "User Exists"
|
||||
else
|
||||
adduser -s /sbin/nologin "$username"
|
||||
echo "$username:$password" | chpasswd
|
||||
fi
|
||||
done <"$file"
|
||||
# Generate an ephemeral self-signed cert at first start when one is not
|
||||
# already mounted/present at the configured path. Each container instance
|
||||
# gets its own key; nothing is baked into the image. This is intended for
|
||||
# the dev compose stack -- production deployments should mount a real
|
||||
# certificate, or set Tls=auto so rdpgw obtains one from Let's Encrypt.
|
||||
CERT="${RDPGW_SERVER__CERT_FILE:-/opt/rdpgw/server.pem}"
|
||||
KEY="${RDPGW_SERVER__KEY_FILE:-/opt/rdpgw/key.pem}"
|
||||
if [ ! -f "${CERT}" ] && [ ! -f "${KEY}" ]; then
|
||||
echo "Generating ephemeral self-signed cert at ${CERT} / ${KEY} (dev only)"
|
||||
openssl req -x509 -newkey rsa:2048 -keyout "${KEY}" -out "${CERT}" \
|
||||
-sha256 -days 365 -nodes \
|
||||
-subj "/CN=rdpgw-ephemeral"
|
||||
fi
|
||||
|
||||
cd /opt/rdpgw || exit 1
|
||||
|
||||
if [ -n "${RDPGW_SERVER__AUTHENTICATION}" ]; then
|
||||
if [ "${RDPGW_SERVER__AUTHENTICATION}" = "local" ]; then
|
||||
echo "Starting rdpgw-auth"
|
||||
/opt/rdpgw/rdpgw-auth &
|
||||
fi
|
||||
if [ "${RDPGW_SERVER__AUTHENTICATION}" = "local" ]; then
|
||||
echo "Starting rdpgw-auth"
|
||||
/opt/rdpgw/rdpgw-auth &
|
||||
fi
|
||||
|
||||
# drop privileges and run the application
|
||||
su -c /opt/rdpgw/rdpgw "${USER}" -- "$@" &
|
||||
wait
|
||||
exit $?
|
||||
exec /opt/rdpgw/rdpgw "$@"
|
||||
|
||||
Reference in New Issue
Block a user