diff --git a/.gitignore b/.gitignore index c036379..4f8bcc0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,6 @@ -tmp/ \ No newline at end of file +tmp/ +dos_env/* +!dos_env/README.md +dos_home/* +dos_drives/* +allowed_repo/* \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index fa553f1..e540f26 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ FROM ubuntu:22.04 ENV DEBIAN_FRONTEND=noninteractive # Install base packages and enable the dosemu2 PPA -RUN apt-get update && apt-get install -y --no-install-recommends software-properties-common gnupg openssh-server busybox-static sudo ca-certificates curl mtools unzip file xauth && add-apt-repository -y ppa:dosemu2/ppa && apt-get install -y --no-install-recommends dosemu2 && rm -rf /var/lib/apt/lists/* +RUN apt-get update && apt-get install -y --no-install-recommends software-properties-common gnupg openssh-server busybox-static sudo ca-certificates curl mtools unzip file xauth acl && add-apt-repository -y ppa:dosemu2/ppa && apt-get install -y --no-install-recommends dosemu2 && rm -rf /var/lib/apt/lists/* # Provide DOS wrapper, SvarDOS bootstrapper, and service supervisor COPY scripts/dos-shell /usr/local/bin/dos-shell diff --git a/README.md b/README.md index ace316d..67cfaab 100644 --- a/README.md +++ b/README.md @@ -188,6 +188,7 @@ docker run … -e ENABLE_TELNET=0 -e DOS_ALLOW_MODE=list -e DOS_AUDIO_MODE=force | `dos-shell: muting DOS audio for this session` | No PulseAudio/PipeWire endpoint detected when logging in over SSH. Export `DOS_AUDIO_MODE=force` if you need sound.| | `ERROR: ladspa: failed to load filter.so / libao: unable to open` | Happens when audio is muted; harmless once the override is applied. | | `Landlock ABI … not defined / landlock_init() failed` | Older kernels don’t expose `LANDLOCK_ACCESS_FS_REFER`. `dos-shell` disables Landlock automatically. | +| `mkdir: cannot create directory '/home/dosuser/.dosemu'` | Bind-mounted home directory isn’t writable. On Docker, ensure the path is owned by UID/GID 1000. For rootless Podman, keep the compose-provided `selinux: z` volume labels (or add `:z`/`:Z` when running manually) and, if needed, run `podman unshare chown -R 1000:1000 dos_home` so the namespace-mapped UID can write. | | `ERROR: using outdated config file ~/.dosemurc` | Remove the legacy file (`rm ~/.dosemurc`). `dos-shell` now writes to `~/.dosemu/dosemurc`. | | `ssh: connect … port 2222: Connection refused` | Container not running. `docker compose ps` or `docker compose up -d` to start it. | @@ -206,4 +207,4 @@ Enemy separation: `dos-shell` prints the config overrides it applies; review tho - SSH is preferred; telnet is available only if explicitly enabled and should be disabled on untrusted networks. - When audio is muted the script points libao to the `null` backend to avoid opening `/dev/dsp` or Pulse pipes. - Landlock sandboxing provides extra filesystem isolation when available. The script downgrades gracefully when the kernel is too old. -- The default credentials are intentionally simple for local development. Change them (or add public keys) before exposing the service. \ No newline at end of file +- The default credentials are intentionally simple for local development. Change them (or add public keys) before exposing the service. diff --git a/allowed_repo/.gitkeep b/allowed_repo/.gitkeep deleted file mode 100644 index 908fcff..0000000 --- a/allowed_repo/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -*** End Patch diff --git a/compose.yml b/compose.yml index 4679403..677cec4 100644 --- a/compose.yml +++ b/compose.yml @@ -15,9 +15,9 @@ services: TELNET_PORT: ${TELNET_PORT:-23} TELNET_LOGIN: /bin/login volumes: - - ./allowed_repo:/opt/allowed_repo - - ./config/dos_allowed:/etc/dos_allowed:ro - - ./dos_env:/etc/dos_env - - ./dos_home:/home/dosuser - - ./dos_drives:/opt/dos_drives + - ./allowed_repo:/opt/allowed_repo:z + - ./config/dos_allowed:/etc/dos_allowed:ro,z + - ./dos_env:/etc/dos_env:z + - ./dos_home:/home/dosuser:z + - ./dos_drives:/opt/dos_drives:z restart: unless-stopped diff --git a/dos_drives/.gitignore b/dos_drives/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/dos_drives/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/scripts/start-services.sh b/scripts/start-services.sh index b8a245a..27e8132 100755 --- a/scripts/start-services.sh +++ b/scripts/start-services.sh @@ -6,6 +6,78 @@ TELNET_LOGIN="${TELNET_LOGIN:-/bin/login}" TELNETD_BIN="${TELNETD_BIN:-/bin/busybox}" ENABLE_TELNET="${ENABLE_TELNET:-1}" +ensure_dosuser_home() { + local dos_entry dos_home dos_uid dos_gid owner_uid owner_gid + local dos_user="dosuser" + + if ! dos_entry="$(getent passwd "${dos_user}")"; then + echo "start-dos-services: unable to locate ${dos_user} account" >&2 + exit 1 + fi + + dos_home="$(printf '%s\n' "${dos_entry}" | cut -d: -f6)" + dos_uid="$(printf '%s\n' "${dos_entry}" | cut -d: -f3)" + dos_gid="$(printf '%s\n' "${dos_entry}" | cut -d: -f4)" + + if [ -z "${dos_home}" ]; then + echo "start-dos-services: ${dos_user} home directory not defined" >&2 + exit 1 + fi + + if [ ! -d "${dos_home}" ]; then + if ! install -d -m 755 -o "${dos_user}" -g "${dos_user}" "${dos_home}"; then + echo "start-dos-services: failed to create ${dos_home}" >&2 + exit 1 + fi + fi + + if runuser -u "${dos_user}" -- test -w "${dos_home}" 2>/dev/null; then + return + fi + + if ! owner_uid="$(stat -c '%u' "${dos_home}")"; then + echo "start-dos-services: warning: unable to stat ${dos_home}" >&2 + return + fi + if ! owner_gid="$(stat -c '%g' "${dos_home}")"; then + echo "start-dos-services: warning: unable to read group for ${dos_home}" >&2 + return + fi + + if [ "${owner_uid}" -ne "${dos_uid}" ] || [ "${owner_gid}" -ne "${dos_gid}" ]; then + echo "start-dos-services: adjusting ownership on ${dos_home} to ${dos_uid}:${dos_gid}" >&2 + if ! chown -R "${dos_user}:${dos_user}" "${dos_home}" 2>/dev/null; then + echo "start-dos-services: warning: failed to adjust ownership on ${dos_home} (continuing; check volume permissions)" >&2 + fi + fi + + if runuser -u "${dos_user}" -- test -w "${dos_home}" 2>/dev/null; then + return + fi + + if ! chmod u+rwx "${dos_home}" 2>/dev/null; then + echo "start-dos-services: warning: unable to update permissions on ${dos_home}" >&2 + fi + + if runuser -u "${dos_user}" -- test -w "${dos_home}" 2>/dev/null; then + return + fi + + if command -v setfacl >/dev/null 2>&1; then + if setfacl -m "u:${dos_user}:rwx" "${dos_home}" 2>/dev/null; then + if runuser -u "${dos_user}" -- test -w "${dos_home}" 2>/dev/null; then + return + fi + else + echo "start-dos-services: warning: failed to grant ACL permissions on ${dos_home}" >&2 + fi + fi + + echo "start-dos-services: warning: ${dos_home} remains unwritable by ${dos_user}; ensure the bind mount allows UID ${dos_uid} to write." >&2 +} + +ensure_dosuser_home + if [ "$ENABLE_TELNET" = "1" ]; then if [ ! -x "$TELNETD_BIN" ]; then echo "Telnet disabled: telnetd binary not found at $TELNETD_BIN" >&2