From 48372efb6d6af7dd9908797dc7e13955618d4fee Mon Sep 17 00:00:00 2001 From: randogoth Date: Sat, 18 Oct 2025 11:05:20 +0300 Subject: [PATCH] init --- Dockerfile | 42 ++++++++++++++++++++++ dos-shell | 88 +++++++++++++++++++++++++++++++++++++++++++++++ dos_allowed | 5 +++ sshd_config | 18 ++++++++++ start-services.sh | 20 +++++++++++ 5 files changed, 173 insertions(+) create mode 100644 Dockerfile create mode 100755 dos-shell create mode 100644 dos_allowed create mode 100644 sshd_config create mode 100755 start-services.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..acab8ba --- /dev/null +++ b/Dockerfile @@ -0,0 +1,42 @@ +FROM debian:bookworm-slim + +ENV DEBIAN_FRONTEND=noninteractive + +# Install packages +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + openssh-server \ + dosemu2 \ + dosbox-staging \ + busybox-static \ + sudo \ + ca-certificates \ + curl \ + && rm -rf /var/lib/apt/lists/* + +# Provide DOS wrapper and service supervisor +COPY dos-shell /usr/local/bin/dos-shell +COPY start-services.sh /usr/local/bin/start-dos-services +RUN chmod +x /usr/local/bin/dos-shell /usr/local/bin/start-dos-services && \ + echo "/usr/local/bin/dos-shell" >> /etc/shells + +# Create sshd runtime directory +RUN mkdir -p /var/run/sshd + +# Create dos user +RUN useradd -m -s /usr/local/bin/dos-shell dosuser && \ + mkdir -p /home/dosuser/.ssh && chown -R dosuser:dosuser /home/dosuser && \ + echo "dosuser:dosuser" | chpasswd + +# Create directories for allowed DOS files and the C: drive mount +RUN mkdir -p /opt/allowed_repo /cdrive /etc/dos_env && \ + chown -R dosuser:dosuser /opt/allowed_repo /cdrive + +# Default allowed list (can be overridden with a bind mount) +COPY dos_allowed /etc/dos_allowed + +# Configure sshd to force command for dosuser +COPY sshd_config /etc/ssh/sshd_config + +EXPOSE 22 23 +CMD ["/usr/local/bin/start-dos-services"] diff --git a/dos-shell b/dos-shell new file mode 100755 index 0000000..684e64d --- /dev/null +++ b/dos-shell @@ -0,0 +1,88 @@ +#!/bin/bash +# /usr/local/bin/dos-shell +# 1) reset C: drive contents to only the allowed files +# 2) launch dosemu with /cdrive mounted as C: + +set -euo pipefail + +ALLOWED_LIST="/etc/dos_allowed" +ALLOWED_REPO="/opt/allowed_repo" # repository of allowed DOS files stored in container +C_DRIVE="/cdrive" +ENV_DIR="/etc/dos_env" +AUTOEXEC_TEMPLATE="${ENV_DIR}/AUTOEXEC.BAT" +CONFIG_TEMPLATE="${ENV_DIR}/CONFIG.SYS" + +if [ "$(id -u)" -eq 0 ] && [ ! -d "${ENV_DIR}" ]; then + mkdir -p "${ENV_DIR}" +fi + +# clear C: drive to ensure only allowed programs are present +rm -rf "${C_DRIVE:?}/"* +mkdir -p "${C_DRIVE}" + +# Collect the list of allowed files and sync them into the C: drive +allowed_entries=() +if [ -f "${ALLOWED_LIST}" ]; then + while IFS= read -r line || [ -n "$line" ]; do + # trim whitespace + line="$(printf '%s' "$line" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" + # skip blank/comment lines + case "$line" in + ''|\#*) continue ;; + esac + allowed_entries+=("$line") + done < "${ALLOWED_LIST}" +fi + +# Copy allowed files into the DOS C: drive +for entry in "${allowed_entries[@]}"; do + src="${ALLOWED_REPO}/${entry}" + if [ -e "$src" ]; then + dst_dir="$(dirname "${entry}")" + mkdir -p "${C_DRIVE}/${dst_dir}" + cp -a "$src" "${C_DRIVE}/${dst_dir}/" + else + echo "Warning: allowed file not found: $src" >&2 + fi +done + +# Optional: create an AUTOEXEC.BAT and CONFIG.SYS or other DOS boot files +autoexec_path="${C_DRIVE}/AUTOEXEC.BAT" +config_path="${C_DRIVE}/CONFIG.SYS" + +if [ -f "${AUTOEXEC_TEMPLATE}" ]; then + cp "${AUTOEXEC_TEMPLATE}" "${autoexec_path}" +else + cat > "${autoexec_path}" <<'EOF' +@echo off +prompt [DOS]$P$G +echo Welcome to the containerized DOS environment. +EOF +fi + +if [ ${#allowed_entries[@]} -gt 0 ]; then + { + printf 'echo Allowed programs:\r\n' + for entry in "${allowed_entries[@]}"; do + dos_entry="${entry//\//\\}" + printf 'echo %s\r\n' "${dos_entry}" + done + } >> "${autoexec_path}" +else + { + printf 'echo No extra programs are currently enabled.\r\n' + } >> "${autoexec_path}" +fi + +if [ -f "${CONFIG_TEMPLATE}" ]; then + cp "${CONFIG_TEMPLATE}" "${config_path}" +fi + +# Drop privileges to dosuser if we were run as root (ssh will run as the user) +# but in case sshd runs ForceCommand as root, we switch. +if [ "$(id -u)" -eq 0 ]; then + exec runuser -u dosuser -- dosemu -quiet -K "${C_DRIVE}" +else + # running as the user already + exec dosemu -quiet -K "${C_DRIVE}" +fi diff --git a/dos_allowed b/dos_allowed new file mode 100644 index 0000000..0d703de --- /dev/null +++ b/dos_allowed @@ -0,0 +1,5 @@ +# List relative paths under /opt/allowed_repo that should be copied into C:\ +# Examples: +# utils/debug.exe +# games/prince/prince.exe +# Leave empty to boot with only the default DOS tools bundled with dosemu. diff --git a/sshd_config b/sshd_config new file mode 100644 index 0000000..4c76899 --- /dev/null +++ b/sshd_config @@ -0,0 +1,18 @@ +# minimal sshd_config for container +Port 22 +ListenAddress 0.0.0.0 +Protocol 2 +PermitRootLogin no +PasswordAuthentication yes +ChallengeResponseAuthentication no +UsePAM yes +X11Forwarding no +PrintMotd no +AcceptEnv LANG LC_* +Subsystem sftp /usr/lib/openssh/sftp-server + +# Force our wrapper for dosuser (prevents a normal shell) +Match User dosuser + ForceCommand /usr/local/bin/dos-shell + PasswordAuthentication yes + PermitTTY yes diff --git a/start-services.sh b/start-services.sh new file mode 100755 index 0000000..b8a245a --- /dev/null +++ b/start-services.sh @@ -0,0 +1,20 @@ +#!/bin/bash +set -euo pipefail + +TELNET_PORT="${TELNET_PORT:-23}" +TELNET_LOGIN="${TELNET_LOGIN:-/bin/login}" +TELNETD_BIN="${TELNETD_BIN:-/bin/busybox}" +ENABLE_TELNET="${ENABLE_TELNET:-1}" + +if [ "$ENABLE_TELNET" = "1" ]; then + if [ ! -x "$TELNETD_BIN" ]; then + echo "Telnet disabled: telnetd binary not found at $TELNETD_BIN" >&2 + else + echo "Starting telnetd on port $TELNET_PORT" + if ! "$TELNETD_BIN" telnetd -p "$TELNET_PORT" -l "$TELNET_LOGIN"; then + echo "Warning: failed to launch telnetd; SSH remains available." >&2 + fi + fi +fi + +exec /usr/sbin/sshd -D -e