diff --git a/.working/rocky93-ssh/Containerfile b/.working/rocky93-ssh/Containerfile deleted file mode 100644 index 418fc51..0000000 --- a/.working/rocky93-ssh/Containerfile +++ /dev/null @@ -1,107 +0,0 @@ -################################################################ -# Notes: -# The purpose is to establish a base OS configuration with a non-root -# provisioning user. As the provisioning user does NOT have a password, -# we need to create a user that will automatically sudo. -# So honestly..I am conflicted. -# -FROM rockylinux:9.3 - -# Update and install required packages -RUN dnf -y update && \ - dnf -y install \ - python3 \ - python3-pip \ - sudo \ - systemd \ - openssh-server \ - iproute \ - && dnf clean all \ - && rm -rf /var/cache/dnf - -# Remove unnecessary packages and users for security -RUN for user in games news; do userdel -r $user 2>/dev/null || true; done - -# Ensure sudo has correct permissions -RUN chown 0:0 /usr/bin/sudo && \ - chmod 4755 /usr/bin/sudo && \ - ls -l /usr/bin/sudo - -# Mask unnecessary systemd services -RUN systemctl mask systemd-machine-id-commit.service - -# Create provisioner user and set up sudo -# -# https://access.redhat.com/solutions/4060861 -# Lock the password but ensure shadow entry exists -RUN useradd -m -s /bin/bash jackaltx && \ - echo "jackaltx ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/jackaltx && \ - chmod 440 /etc/sudoers.d/jackaltx && \ - passwd -l jackaltx - -# Verify the shadow entry exists and is correct -RUN grep jackaltx /etc/shadow && \ - pwck -r - -# But we might need to explicitly configure PAM for the container environment -# this is a Rocky on github thing. It cannot use the default user to authenticate. -# Add PAM configuration for sudo -# RUN echo "auth sufficient pam_unix.so" > /etc/pam.d/sudo && \ -# echo "account required pam_unix.so" >> /etc/pam.d/sudo && \ -# echo "session required pam_unix.so" >> /etc/pam.d/sudo - -# Create ansible temp directory with proper permissions -RUN mkdir -p /tmp/ansible-jackaltx && \ - chown jackaltx:jackaltx /tmp/ansible-jackaltx && \ - chmod 700 /tmp/ansible-jackaltx - -# Set up SSH -RUN mkdir -p /home/jackaltx/.ssh && \ - chmod 700 /home/jackaltx/.ssh && \ - mkdir -p /run/sshd - -# SSH key will be added during build -ARG SSH_KEY -RUN echo "$SSH_KEY" > /home/jackaltx/.ssh/authorized_keys && \ - chmod 600 /home/jackaltx/.ssh/authorized_keys && \ - chown -R jackaltx:jackaltx /home/jackaltx/.ssh - -# Configure SELinux for SSH (if enabled) -RUN if command -v semanage >/dev/null 2>&1; then \ - semanage fcontext -a -t ssh_home_t "/home/jackaltx/.ssh(/.*)?" && \ - restorecon -R -v /home/jackaltx/.ssh \ - ; fi - -# Generate SSH host keys and configure SSH -RUN ssh-keygen -A && \ - chmod 600 /etc/ssh/ssh_host_* && \ - systemctl enable sshd - -# Add to Containerfiles - Enhanced SSH Security -RUN sed -i 's/#MaxAuthTries.*/MaxAuthTries 3/' /etc/ssh/sshd_config && \ - sed -i 's/#LoginGraceTime.*/LoginGraceTime 60/' /etc/ssh/sshd_config && \ - sed -i 's/#AllowAgentForwarding.*/AllowAgentForwarding no/' /etc/ssh/sshd_config && \ - echo "AllowUsers jackaltx" >> /etc/ssh/sshd_config - -# Add to Containerfiles - Enhanced Sudo Configuration -RUN echo "Defaults timestamp_timeout=15" >> /etc/sudoers.d/timeout && \ - echo "Defaults logfile=/var/log/sudo.log" >> /etc/sudoers.d/logging && \ - echo "Defaults use_pty" >> /etc/sudoers.d/pty && \ - echo "Defaults secure_path=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"" >> /etc/sudoers.d/secure_path - -# Add to Containerfiles - Secure Important Directories -RUN chmod 700 /etc/sudoers.d && \ - chmod 440 /etc/sudoers.d/* && \ - find /etc/ssh -type f -name 'ssh_host_*_key' -exec chmod 600 {} \; && \ - find /etc/ssh -type f -name 'ssh_host_*_key.pub' -exec chmod 644 {} \; - -# Add to Containerfiles - System Security Settings -RUN echo "umask 027" >> /etc/profile && \ - echo "TMOUT=900" >> /etc/profile && \ - echo "readonly TMOUT" >> /etc/profile - -# Verify permissions -RUN ls -l /usr/bin/sudo && \ - ls -l /etc/sudoers.d/jackaltx && \ - id jackaltx && \ - grep -r "jackaltx" /etc/sudoers.d/ diff --git a/.working/rocky93-ssh/inventory.yml b/.working/rocky93-ssh/inventory.yml deleted file mode 100644 index 47b8155..0000000 --- a/.working/rocky93-ssh/inventory.yml +++ /dev/null @@ -1,9 +0,0 @@ -all: - hosts: - rocky_container: - ansible_connection: community.docker.docker - ansible_host: test_container - ansible_user: jackaltx - ansible_python_interpreter: python3 - ansible_remote_tmp: /tmp/ansible-${USER} - ansible_pipelining: true diff --git a/.working/rocky93-ssh/playbook.yml b/.working/rocky93-ssh/playbook.yml deleted file mode 100644 index 2391dd2..0000000 --- a/.working/rocky93-ssh/playbook.yml +++ /dev/null @@ -1,36 +0,0 @@ ---- -- name: Configure Rocky Linux container - hosts: rocky_container - gather_facts: no - become: yes - - tasks: - - name: Update all packages - dnf: - name: "*" - state: latest - - - name: Install additional packages - dnf: - name: - - vim - - wget - - git - - tmux - state: present - - - name: Ensure SSH directory has correct permissions - file: - path: /home/jackaltx/.ssh - state: directory - mode: "0700" - owner: jackaltx - group: jackaltx - - - name: Ensure authorized_keys has correct permissions - file: - path: /home/jackaltx/.ssh/authorized_keys - state: file - mode: "0600" - owner: jackaltx - group: jackaltx diff --git a/CLAUDE.md b/CLAUDE.md index 56d14c0..9a02afb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -11,24 +11,29 @@ These are deliberately minimal - don't suggest adding features. User wants stock ## Quick Commands ```bash -# Build (requires SSH_KEY and token) -./build.sh debian12-ssh -./build.sh rocky9x-ssh -./build.sh ubuntu24-ssh +# Setup registry credentials (required first step) +source ~/.secrets/testing-containers-registry.conf github # For GitHub +source ~/.secrets/testing-containers-registry.conf gitea # For Gitea lab + +# Build containers +./build.sh -d debian -v 12 +./build.sh -d debian -v 13 +./build.sh -d rocky -v 9 +./build.sh -d rocky -v 10 +./build.sh -d ubuntu -v 24 # Test locally -export CONTAINER_TYPE=debian12-ssh -./run-podman.sh +./run-podman.sh -d debian -v 13 ssh -p 2222 jackaltx@localhost ./cleanup-podman.sh ``` ## What's Included -Three distributions: -- **debian12-ssh**: Debian 12, apt, OpenSSH -- **rocky9x-ssh**: Rocky Linux 9.x, dnf, OpenSSH -- **ubuntu24-ssh**: Ubuntu 24.04 LTS, apt, OpenSSH +Supported distributions: +- **debian**: Debian 12, 13 (apt, OpenSSH) +- **rocky**: Rocky Linux 9, 10 (dnf, OpenSSH) +- **ubuntu**: Ubuntu 24.04 LTS (apt, OpenSSH) Each has: - Python 3 (Ansible requirement) @@ -40,24 +45,50 @@ Each has: ```bash # Syntax -./build.sh +./build.sh -d DISTRO -v VERSION + +# Examples +./build.sh -d debian -v 13 +./build.sh -d rocky -v 9 +./build.sh -d ubuntu -v 24 + +# Required environment (set by sourcing registry config) +SSH_KEY # Public key to inject +CONTAINER_TOKEN # Registry authentication token +REGISTRY_HOST # Registry URL (ghcr.io or gitea.a0a0.org:3001) +REGISTRY_USER # Registry username (jackaltx) +REGISTRY_REPO # Repository name (testing-containers) +``` + +## Registry Configuration -# Environment variables -SSH_KEY # Required - public key to inject -CONTAINER_TOKEN # For ghcr.io (default registry) -GITEA_TOKEN # For Gitea registry -REGISTRY_HOST # Defaults to ghcr.io +Registry credentials stored in `~/.secrets/testing-containers-registry.conf` (NOT in repo): + +```bash +# GitHub Container Registry +source ~/.secrets/testing-containers-registry.conf github + +# Gitea Lab Registry +source ~/.secrets/testing-containers-registry.conf gitea ``` ## Key Files -- `debian12-ssh/Containerfile` - Debian build definition -- `rocky9x-ssh/Containerfile` - Rocky build definition -- `ubuntu24-ssh/Containerfile` - Ubuntu build definition +- `debian/Containerfile` - Debian/Ubuntu build definition (parameterized) +- `rocky/Containerfile` - Rocky build definition (parameterized) - `build.sh` - Build and push script - `run-podman.sh` - Local test runner - `cleanup-podman.sh` - Clean up test containers +## Image Naming + +Output images follow pattern: `{distro}-ssh:{version}` + +Examples: +- `ghcr.io/jackaltx/testing-containers/debian-ssh:13` +- `ghcr.io/jackaltx/testing-containers/rocky-ssh:9` +- `gitea.a0a0.org:3001/jackaltx/testing-containers/ubuntu-ssh:24` + ## Design Philosophy **Keep it minimal.** Don't suggest: diff --git a/README.md b/README.md index 4314758..c25c443 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Testing Containers -Factory-default container images for Ansible testing. Just SSH and Python - nothing else. +These containers are used to test my ansible project. They are packages managed +with minimal changes. I use SSH to at the transport. The idea is to use the same transport +and system management tools to minimized the difference between real and virtual. ## Purpose @@ -9,6 +11,7 @@ Minimal base images for testing Ansible roles with Molecule. Each container prov - **Python 3** - For Ansible - **OpenSSH** - Key-based authentication - **systemd** - For service management +- **lsof & ps** - Process utilities for debugging - **Factory defaults** - Stock OS configuration, updated packages ## Available Images @@ -16,22 +19,46 @@ Minimal base images for testing Ansible roles with Molecule. Each container prov ```bash # Pull from GitHub Container Registry podman pull ghcr.io/jackaltx/testing-containers/debian-ssh:12 +podman pull ghcr.io/jackaltx/testing-containers/debian-ssh:13 podman pull ghcr.io/jackaltx/testing-containers/rocky-ssh:9 +podman pull ghcr.io/jackaltx/testing-containers/rocky-ssh:10 podman pull ghcr.io/jackaltx/testing-containers/ubuntu-ssh:24 ``` | Image | Base | Package Manager | |-------|------|-----------------| | debian-ssh:12 | debian:12 | apt | +| debian-ssh:13 | debian:13 | apt | | rocky-ssh:9 | rockylinux:9 | dnf | +| rocky-ssh:10 | rockylinux:10 | dnf | | ubuntu-ssh:24 | ubuntu:24.04 | apt | ## Quick Start Note: check that port 2222 is available before using! +### Helper Scripts + ```bash -# Run container from github +# Source registry credentials (GitHub or Gitea) +source ~/.secrets/testing-containers-registry.conf github +# or +source ~/.secrets/testing-containers-registry.conf gitea + +# Run a container +./run-podman.sh -d debian -v 13 + +# SSH access (from another terminal) +ssh -p 2222 jackaltx@localhost + +# Clean up +./cleanup-podman.sh +``` + +### Manual Container Execution + +```bash +# Run container from GitHub podman run -d \ --name test_container \ --privileged \ @@ -44,24 +71,80 @@ podman run -d \ ssh -p 2222 jackaltx@localhost ``` +## Registry Configuration + +Create `~/.secrets/testing-containers-registry.conf`: + ```bash -# Login to your local gitea server -podman login ${GITEA_HOST} -u ${GITEA_USER} -p ${GITEA_TOKEN} +# Testing Containers Registry Configuration +# Source this file before running build.sh or run-podman.sh +# +# Usage: +# source ~/.secrets/testing-containers-registry.conf github +# source ~/.secrets/testing-containers-registry.conf gitea -# just to pull an image -podman pull ${GITEA_HOST}/${GITEA_USER}/testing-containers/debian-ssh:12 +REGISTRY_PROFILE="${1:-github}" - # Run container and pull -podman run -d \ - --name test_container \ - --privileged \ - -v /sys/fs/cgroup:/sys/fs/cgroup:rw \ - -p 2222:22 \ - ${GITEA_HOST}/${GITEA_USER}/testing-containers/debian-ssh:12 \ - /sbin/init +# Common config +export SSH_KEY=$(cat ~/.ssh/id_ed25519.pub) +export REGISTRY_USER="your-username" +export REGISTRY_REPO="testing-containers" + +# Profile-specific config +case "$REGISTRY_PROFILE" in + github|gh) + export REGISTRY_HOST="ghcr.io" + export CONTAINER_TOKEN="ghp_YourGitHubTokenHere" + echo "✓ Configured for GitHub Container Registry (ghcr.io)" + ;; + gitea|lab) + export REGISTRY_HOST="gitea.example.com" + export CONTAINER_TOKEN="YourGiteaTokenHere" + echo "✓ Configured for Gitea Registry (gitea.example.com)" + ;; + *) + echo "Error: Invalid registry profile '$REGISTRY_PROFILE'" + echo "Usage: source ~/.secrets/testing-containers-registry.conf [github|gitea]" + return 1 + ;; +esac + +# Display current config +echo " Registry: $REGISTRY_HOST" +echo " User: $REGISTRY_USER" +echo " Repo: $REGISTRY_REPO" +``` -# SSH access -ssh -p 2222 jackaltx@loca`lhost +**Important:** + +- Never commit this file to git +- Use GitHub Personal Access Token (PAT) with `write:packages` scope +- Use Gitea Application Token with package write permissions +- Store in `~/.secrets/` directory (outside repository) + +## Building Images + +### Build and Push to Registry + +```bash +# Source credentials first +source ~/.secrets/testing-containers-registry.conf github + +# Build specific version +./build.sh -d debian -v 12 +./build.sh -d debian -v 13 +./build.sh -d rocky -v 9 +./build.sh -d ubuntu -v 24 +``` + +### Build for Gitea + +```bash +# Source Gitea credentials +source ~/.secrets/testing-containers-registry.conf gitea + +# Build and push to Gitea +./build.sh -d debian -v 13 ``` ## Molecule Integration @@ -77,44 +160,71 @@ platforms: command: /sbin/init ``` -## Building Images +## Development -See [build.sh](build.sh) for building and pushing to registries. +### Repository Structure -### Build and publish packages on Github - -```bash -export SSH_KEY=$(cat ~/.ssh/id_ed25519.pub) -export CONTAINER_TOKEN=ghp_your_token_here -./build.sh debian12-ssh +```text +testing-containers/ +├── debian/ +│ └── Containerfile # Unified for Debian & Ubuntu +├── rocky/ +│ └── Containerfile # Rocky-specific +├── build.sh # Build & push images +├── run-podman.sh # Test containers locally +├── cleanup-podman.sh # Remove test containers +└── README.md ``` -or +### Adding New Versions -```bash -source ~/.secrets/JackaltxGithubProvision -REGISTRY_HOST=ghcr.io CONTAINER_TOKEN=${GITHUB_PKG_TOKEN} SSH_KEY=$(cat ~/.ssh/id_ed25519.pub) ./build.sh ubuntu24-ssh -``` +1. Update base image version in Containerfile ARG +2. Build with new version: `./build.sh -d debian -v 14` +3. Test locally: `./run-podman.sh -d debian -v 14` + +### Design Philosophy -### Build and publish on Local Gitea +**Keep it minimal.** These are factory-default containers for testing: + +- No configuration management tools +- No monitoring agents +- No custom configurations +- Just stock OS + SSH + Python + systemd + +This ensures consistent, predictable testing environments. + +## Troubleshooting + +### Authentication Errors + +If you see "unauthorized" errors when pulling images: ```bash -source ~/.secrets/LabGiteaToken -REGISTRY_HOST=${GITEA_HOST} ./build.sh debian13-ssh +# Make sure you've sourced the registry config +source ~/.secrets/testing-containers-registry.conf github + +# Or for private Gitea registry +source ~/.secrets/testing-containers-registry.conf gitea ``` -The ./secrets/LabGiteaToken file: +### Port Already in Use + +If port 2222 is already in use: ```bash -# This is used to set the package location -export GITEA_HOST="https://gitea.example.com +# Use custom port +LPORT=2223 ./run-podman.sh -d debian -v 13 +ssh -p 2223 jackaltx@localhost +``` -# The username -export GITEA_USER="jackaltx" +### Container Won't Start -# not your password, but an application token. -export GITEA_TOKEN= +Check that systemd is running: -# Used to access test image from your ansible user -export SSH_KEY=$(cat ~/.ssh/id_ed25519.pub) +```bash +podman exec test_container systemctl is-active sshd ``` + +## License + +See LICENSE file. diff --git a/build.sh b/build.sh index 3d0044f..1679e46 100755 --- a/build.sh +++ b/build.sh @@ -1,64 +1,104 @@ #!/bin/bash set -e -# Simple build script for testing containers -# Replaces the complex build_container.sh with pure Containerfile approach +# Unified build script for testing containers +# Usage: ./build.sh -d DISTRO -v VERSION +# Examples: +# ./build.sh -d debian -v 12 +# ./build.sh -d rocky -v 9 +# ./build.sh -d ubuntu -v 24 -# Configuration from environment -CONTAINER_TYPE="${1:-${CONTAINER_TYPE:-debian12-ssh}}" -REGISTRY_HOST="${REGISTRY_HOST:-ghcr.io}" -REGISTRY_USER="${REGISTRY_USER:-jackaltx}" -REGISTRY_REPO="${REGISTRY_REPO:-testing-containers}" -SSH_KEY="${SSH_KEY:?SSH_KEY environment variable is required}" - -# Parse CONTAINER_TYPE into DISTRO and VERSION -case "$CONTAINER_TYPE" in - debian12-ssh) - DISTRO="debian" - VERSION="12" - ;; - rocky9x-ssh) - DISTRO="rocky" - VERSION="9" - ;; - rocky10-ssh) - DISTRO="rocky" - VERSION="10" - ;; - ubuntu24-ssh) - DISTRO="ubuntu" - VERSION="24" - ;; - debian13-ssh) - DISTRO="debian" - VERSION="13" - ;; +# Parse command-line flags +DISTRO="" +VERSION="" +while getopts "d:v:" opt; do + case $opt in + d) DISTRO=$OPTARG ;; + v) VERSION=$OPTARG ;; *) - echo "Error: CONTAINER_TYPE must be one of: debian13-ssh, debian12-ssh, rocky9x-ssh, ubuntu24-ssh" - exit 1 - ;; -esac + echo "Usage: $0 -d DISTRO -v VERSION" >&2 + echo "Examples:" + echo " $0 -d debian -v 12" + echo " $0 -d debian -v 13" + echo " $0 -d rocky -v 9" + echo " $0 -d rocky -v 10" + echo " $0 -d ubuntu -v 24" + exit 1 + ;; + esac +done -# Determine authentication token -if [ "$REGISTRY_HOST" = "ghcr.io" ]; then - TOKEN="${CONTAINER_TOKEN:?CONTAINER_TOKEN required for GitHub registry}" -else - TOKEN="${GITEA_TOKEN:?GITEA_TOKEN required for Gitea registry}" +# Validate required arguments +if [ -z "$DISTRO" ] || [ -z "$VERSION" ]; then + echo "Error: -d DISTRO and -v VERSION are required" + echo "Usage: $0 -d DISTRO -v VERSION" + exit 1 fi -echo "Building ${DISTRO}-ssh:${VERSION} from $CONTAINER_TYPE..." +# Validate environment variables (should be set by sourcing registry config) +REGISTRY_HOST="${REGISTRY_HOST:?REGISTRY_HOST not set. Source ~/.secrets/testing-containers-registry.conf first}" +REGISTRY_USER="${REGISTRY_USER:?REGISTRY_USER not set}" +REGISTRY_REPO="${REGISTRY_REPO:?REGISTRY_REPO not set}" +SSH_KEY="${SSH_KEY:?SSH_KEY not set}" +CONTAINER_TOKEN="${CONTAINER_TOKEN:?CONTAINER_TOKEN not set}" -# Login to registry -echo "$TOKEN" | podman login "$REGISTRY_HOST" -u "$REGISTRY_USER" --password-stdin +# Map distro to base image and Containerfile location +case "$DISTRO" in + debian) + DISTRO_BASE="debian" + DISTRO_VERSION="$VERSION" + CONTAINERFILE_DIR="debian" + ;; + ubuntu) + DISTRO_BASE="ubuntu" + # Map version 24 → 24.04 + case "$VERSION" in + 24) DISTRO_VERSION="24.04" ;; + *) DISTRO_VERSION="$VERSION" ;; + esac + CONTAINERFILE_DIR="debian" # Ubuntu uses same Containerfile as Debian + ;; + rocky) + DISTRO_BASE="rockylinux/rockylinux" + DISTRO_VERSION="$VERSION" + CONTAINERFILE_DIR="rocky" + ;; + *) + echo "Error: DISTRO must be one of: debian, ubuntu, rocky" + exit 1 + ;; +esac -# Build image with new sub-repository naming pattern +# Image naming: distro-ssh:version (e.g., rocky-ssh:9, not rocky9-ssh) IMAGE_TAG="$REGISTRY_HOST/$REGISTRY_USER/$REGISTRY_REPO/${DISTRO}-ssh:${VERSION}" -podman build \ +echo "Building ${DISTRO}-ssh:${VERSION}..." +echo " Base image: ${DISTRO_BASE}:${DISTRO_VERSION}" +echo " Registry: $REGISTRY_HOST" +echo " Image tag: $IMAGE_TAG" + +# Login to registry +echo "$CONTAINER_TOKEN" | podman login "$REGISTRY_HOST" -u "$REGISTRY_USER" --password-stdin + +# Build image with appropriate build args +if [ "$CONTAINERFILE_DIR" = "debian" ]; then + # Debian/Ubuntu: pass both DISTRO_BASE and DISTRO_VERSION + podman build \ + --build-arg SSH_KEY="$SSH_KEY" \ + --build-arg DISTRO_BASE="$DISTRO_BASE" \ + --build-arg DISTRO_VERSION="$DISTRO_VERSION" \ + -t "$IMAGE_TAG" \ + -f "$CONTAINERFILE_DIR/Containerfile" \ + "$CONTAINERFILE_DIR/" +else + # Rocky: only pass DISTRO_VERSION + podman build \ --build-arg SSH_KEY="$SSH_KEY" \ + --build-arg DISTRO_VERSION="$DISTRO_VERSION" \ -t "$IMAGE_TAG" \ - -f "$CONTAINER_TYPE/Containerfile" \ - "$CONTAINER_TYPE/" + -f "$CONTAINERFILE_DIR/Containerfile" \ + "$CONTAINERFILE_DIR/" +fi # Push to registry podman push "$IMAGE_TAG" @@ -68,6 +108,7 @@ if [ "${TAG_LATEST:-false}" = "true" ]; then LATEST_TAG="$REGISTRY_HOST/$REGISTRY_USER/$REGISTRY_REPO/${DISTRO}-ssh:latest" podman tag "$IMAGE_TAG" "$LATEST_TAG" podman push "$LATEST_TAG" + echo "✓ Also tagged as: $LATEST_TAG" fi # Logout diff --git a/debian13-ssh/Containerfile b/debian/Containerfile similarity index 93% rename from debian13-ssh/Containerfile rename to debian/Containerfile index bc4d070..b6400e2 100644 --- a/debian13-ssh/Containerfile +++ b/debian/Containerfile @@ -1,7 +1,11 @@ ##################################################### -# create provisioner user for ansible. +# create provisioner user for ansible. + +# Build args for parameterized base image +ARG DISTRO_BASE=debian +ARG DISTRO_VERSION=12 +FROM ${DISTRO_BASE}:${DISTRO_VERSION} -FROM debian:13 ENV DEBIAN_FRONTEND=noninteractive # Update and install required packages @@ -19,6 +23,7 @@ RUN apt-get update && \ git \ tmux \ sysvinit-utils \ + lsof \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* @@ -80,4 +85,4 @@ RUN echo "umask 027" >> /etc/profile && \ # Verify final configuration RUN id jackaltx && \ - sudo -l -U jackaltx \ No newline at end of file + sudo -l -U jackaltx diff --git a/debian12-ssh/Containerfile b/debian12-ssh/Containerfile deleted file mode 100644 index 3d9e7fe..0000000 --- a/debian12-ssh/Containerfile +++ /dev/null @@ -1,83 +0,0 @@ -##################################################### -# create provisioner user for ansible. - -FROM debian:12 -ENV DEBIAN_FRONTEND=noninteractive - -# Update and install required packages -RUN apt-get update && \ - apt-get upgrade -y && \ - apt-get install -y \ - python3 \ - sudo \ - systemd \ - openssh-server \ - python3-pip \ - iproute2 \ - vim \ - wget \ - git \ - tmux \ - sysvinit-utils \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -# Remove unnecessary system users -RUN for user in games news; do userdel -r $user 2>/dev/null || true; done - -# Mask unnecessary systemd services -RUN systemctl mask systemd-machine-id-commit.service - -# I struggle here....I can set the user to the "sudo" group and pass in a password. -# But this user has no password and thus needs to have "unfettered" access to root. -# bleh...... - -# Create provisioner user and set up sudo -RUN useradd -m -s /bin/bash jackaltx && \ - echo "jackaltx ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/jackaltx - -# Create ansible temp directory with proper permissions -RUN mkdir -p /tmp/ansible-jackaltx && \ - chown jackaltx:jackaltx /tmp/ansible-jackaltx && \ - chmod 700 /tmp/ansible-jackaltx - -# Set up SSH -RUN mkdir -p /home/jackaltx/.ssh && \ - chmod 700 /home/jackaltx/.ssh - -# SSH key will be added during build -ARG SSH_KEY -RUN echo "$SSH_KEY" > /home/jackaltx/.ssh/authorized_keys && \ - chmod 600 /home/jackaltx/.ssh/authorized_keys && \ - chown -R jackaltx:jackaltx /home/jackaltx/.ssh - -# Configure SSH -RUN mkdir -p /run/sshd && \ - systemctl enable ssh - -# Add to Containerfiles - Enhanced SSH Security -RUN sed -i 's/#MaxAuthTries.*/MaxAuthTries 3/' /etc/ssh/sshd_config && \ - sed -i 's/#LoginGraceTime.*/LoginGraceTime 60/' /etc/ssh/sshd_config && \ - sed -i 's/#AllowAgentForwarding.*/AllowAgentForwarding no/' /etc/ssh/sshd_config && \ - echo "AllowUsers jackaltx" >> /etc/ssh/sshd_config - -# Add to Containerfiles - Enhanced Sudo Configuration -RUN echo "Defaults timestamp_timeout=15" >> /etc/sudoers.d/timeout && \ - echo "Defaults logfile=/var/log/sudo.log" >> /etc/sudoers.d/logging && \ - echo "Defaults use_pty" >> /etc/sudoers.d/pty && \ - echo "Defaults secure_path=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"" >> /etc/sudoers.d/secure_path - -# Add to Containerfiles - Secure Important Directories -RUN chmod 700 /etc/sudoers.d && \ - chmod 440 /etc/sudoers.d/* && \ - find /etc/ssh -type f -name 'ssh_host_*_key' -exec chmod 600 {} \; && \ - find /etc/ssh -type f -name 'ssh_host_*_key.pub' -exec chmod 644 {} \; - -# Add to Containerfiles - System Security Settings -RUN echo "umask 027" >> /etc/profile && \ - echo "TMOUT=900" >> /etc/profile && \ - echo "readonly TMOUT" >> /etc/profile - -# Verify final configuration -RUN id jackaltx && \ - sudo -l -U jackaltx \ No newline at end of file diff --git a/rocky9x-ssh/Containerfile b/rocky/Containerfile similarity index 98% rename from rocky9x-ssh/Containerfile rename to rocky/Containerfile index b7137dc..fe939d8 100644 --- a/rocky9x-ssh/Containerfile +++ b/rocky/Containerfile @@ -5,7 +5,8 @@ # we need to create a user that will automatically sudo. # So honestly..I am conflicted. # -FROM rockylinux/rockylinux:9 +ARG DISTRO_VERSION=9 +FROM rockylinux/rockylinux:${DISTRO_VERSION} # Update and install required packages RUN dnf -y update && \ @@ -21,6 +22,7 @@ RUN dnf -y update && \ git \ tmux \ procps-ng \ + lsof \ && dnf clean all \ && rm -rf /var/cache/dnf diff --git a/rocky10-ssh/Containerfile b/rocky10-ssh/Containerfile deleted file mode 100644 index baec2f6..0000000 --- a/rocky10-ssh/Containerfile +++ /dev/null @@ -1,112 +0,0 @@ -################################################################ -# Notes: -# The purpose is to establish a base OS configuration with a non-root -# provisioning user. As the provisioning user does NOT have a password, -# we need to create a user that will automatically sudo. -# So honestly..I am conflicted. -# -FROM rockylinux/rockylinux:10 - -# Update and install required packages -RUN dnf -y update && \ - dnf -y install \ - python3 \ - python3-pip \ - sudo \ - systemd \ - openssh-server \ - iproute \ - vim \ - wget \ - git \ - tmux \ - procps-ng \ - && dnf clean all \ - && rm -rf /var/cache/dnf - -# Remove unnecessary packages and users for security -RUN for user in games news; do userdel -r $user 2>/dev/null || true; done - -# Ensure sudo has correct permissions -RUN chown 0:0 /usr/bin/sudo && \ - chmod 4755 /usr/bin/sudo && \ - ls -l /usr/bin/sudo - -# Mask unnecessary systemd services -RUN systemctl mask systemd-machine-id-commit.service - -# Create provisioner user and set up sudo -# -# https://access.redhat.com/solutions/4060861 -# Lock the password but ensure shadow entry exists -RUN useradd -m -s /bin/bash jackaltx && \ - echo "jackaltx ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/jackaltx && \ - chmod 440 /etc/sudoers.d/jackaltx && \ - passwd -l jackaltx - -# Verify the shadow entry exists and is correct -RUN grep jackaltx /etc/shadow && \ - pwck -r - -# But we might need to explicitly configure PAM for the container environment -# this is a Rocky on github thing. It cannot use the default user to authenticate. -# Add PAM configuration for sudo -# RUN echo "auth sufficient pam_unix.so" > /etc/pam.d/sudo && \ -# echo "account required pam_unix.so" >> /etc/pam.d/sudo && \ -# echo "session required pam_unix.so" >> /etc/pam.d/sudo - -# Create ansible temp directory with proper permissions -RUN mkdir -p /tmp/ansible-jackaltx && \ - chown jackaltx:jackaltx /tmp/ansible-jackaltx && \ - chmod 700 /tmp/ansible-jackaltx - -# Set up SSH -RUN mkdir -p /home/jackaltx/.ssh && \ - chmod 700 /home/jackaltx/.ssh && \ - mkdir -p /run/sshd - -# SSH key will be added during build -ARG SSH_KEY -RUN echo "$SSH_KEY" > /home/jackaltx/.ssh/authorized_keys && \ - chmod 600 /home/jackaltx/.ssh/authorized_keys && \ - chown -R jackaltx:jackaltx /home/jackaltx/.ssh - -# Configure SELinux for SSH (if enabled) -RUN if command -v semanage >/dev/null 2>&1; then \ - semanage fcontext -a -t ssh_home_t "/home/jackaltx/.ssh(/.*)?" && \ - restorecon -R -v /home/jackaltx/.ssh \ - ; fi - -# Generate SSH host keys and configure SSH -RUN ssh-keygen -A && \ - chmod 600 /etc/ssh/ssh_host_* && \ - systemctl enable sshd - -# Add to Containerfiles - Enhanced SSH Security -RUN sed -i 's/#MaxAuthTries.*/MaxAuthTries 3/' /etc/ssh/sshd_config && \ - sed -i 's/#LoginGraceTime.*/LoginGraceTime 60/' /etc/ssh/sshd_config && \ - sed -i 's/#AllowAgentForwarding.*/AllowAgentForwarding no/' /etc/ssh/sshd_config && \ - echo "AllowUsers jackaltx" >> /etc/ssh/sshd_config - -# Add to Containerfiles - Enhanced Sudo Configuration -RUN echo "Defaults timestamp_timeout=15" >> /etc/sudoers.d/timeout && \ - echo "Defaults logfile=/var/log/sudo.log" >> /etc/sudoers.d/logging && \ - echo "Defaults use_pty" >> /etc/sudoers.d/pty && \ - echo "Defaults secure_path=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"" >> /etc/sudoers.d/secure_path - -# Add to Containerfiles - Secure Important Directories -RUN chmod 700 /etc/sudoers.d && \ - chmod 440 /etc/sudoers.d/* && \ - find /etc/ssh -type f -name 'ssh_host_*_key' -exec chmod 600 {} \; && \ - find /etc/ssh -type f -name 'ssh_host_*_key.pub' -exec chmod 644 {} \; - -# Add to Containerfiles - System Security Settings -RUN echo "umask 027" >> /etc/profile && \ - echo "TMOUT=900" >> /etc/profile && \ - echo "readonly TMOUT" >> /etc/profile - -# Verify permissions -RUN ls -l /usr/bin/sudo && \ - ls -l /etc/sudoers.d/jackaltx && \ - id jackaltx && \ - grep -r "jackaltx" /etc/sudoers.d/ diff --git a/run-podman.sh b/run-podman.sh index 0081553..72cffb0 100755 --- a/run-podman.sh +++ b/run-podman.sh @@ -18,47 +18,53 @@ cleanup() { # Set up error handling trap cleanup ERR -# Configuration - user must set these -CONTAINER_TYPE="${1:-${CONTAINER_TYPE:-debian12-ssh}}" - -# Parse CONTAINER_TYPE into DISTRO and VERSION for new naming pattern -case "$CONTAINER_TYPE" in - debian12-ssh) - DISTRO="debian" - VERSION="12" - ;; - debian13-ssh) - DISTRO="debian" - VERSION="13" - ;; - rocky9x-ssh) - DISTRO="rocky" - VERSION="9" - ;; - rocky10-ssh) - DISTRO="rocky" - VERSION="10" - ;; - ubuntu24-ssh) - DISTRO="ubuntu" - VERSION="24" - ;; +# Parse command-line flags +DISTRO="" +VERSION="" +while getopts "d:v:" opt; do + case $opt in + d) DISTRO=$OPTARG ;; + v) VERSION=$OPTARG ;; *) - echo "Error: CONTAINER_TYPE must be one of: debian13-ssh, debian12-ssh, rocky9x-ssh, rocky10-ssh, ubuntu24-ssh" - exit 1 - ;; -esac + echo "Usage: $0 -d DISTRO -v VERSION" >&2 + echo "Examples:" + echo " $0 -d debian -v 13" + echo " $0 -d rocky -v 9" + echo " $0 -d ubuntu -v 24" + exit 1 + ;; + esac +done + +# Validate required arguments +if [ -z "$DISTRO" ] || [ -z "$VERSION" ]; then + echo "Error: -d DISTRO and -v VERSION are required" >&2 + echo "Usage: $0 -d DISTRO -v VERSION" >&2 + exit 1 +fi -IMAGE="${IMAGE:-ghcr.io/jackaltx/testing-containers/${DISTRO}-ssh:${VERSION}}" +# Configuration from environment with defaults +REGISTRY_HOST="${REGISTRY_HOST:-ghcr.io}" +REGISTRY_USER="${REGISTRY_USER:-jackaltx}" +REGISTRY_REPO="${REGISTRY_REPO:-testing-containers}" + +# Image naming: distro-ssh:version +IMAGE="${IMAGE:-$REGISTRY_HOST/$REGISTRY_USER/$REGISTRY_REPO/${DISTRO}-ssh:${VERSION}}" CONTAINER_NAME="${CONTAINER_NAME:-test_container}" NETWORK_NAME="monitoring-net" LPORT="${LPORT:-2222}" SSH_PORT="$LPORT" -log "Version: $VERSION" +log "Starting ${DISTRO}-ssh:${VERSION}" log "Using image: $IMAGE" log "Container name: $CONTAINER_NAME" +# Login to registry if CONTAINER_TOKEN is set +if [ -n "$CONTAINER_TOKEN" ]; then + log "Logging in to $REGISTRY_HOST..." + echo "$CONTAINER_TOKEN" | podman login "$REGISTRY_HOST" -u "$REGISTRY_USER" --password-stdin >/dev/null 2>&1 +fi + # Create network if it doesn't exist if ! podman network inspect "$NETWORK_NAME" >/dev/null 2>&1; then log "Creating network $NETWORK_NAME..." @@ -91,8 +97,10 @@ podman run -d \ # Wait for container to be ready for i in {1..30}; do - if podman exec "$CONTAINER_NAME" systemctl is-active sshd >/dev/null 2>&1; then + if podman exec "$CONTAINER_NAME" systemctl is-active sshd >/dev/null 2>&1 || \ + podman exec "$CONTAINER_NAME" systemctl is-active ssh >/dev/null 2>&1; then log "Container is ready" + log "SSH: ssh -p $SSH_PORT jackaltx@localhost" exit 0 fi sleep 1 @@ -100,4 +108,4 @@ done log "ERROR: Container failed to start properly" podman logs "$CONTAINER_NAME" -exit 1 \ No newline at end of file +exit 1 diff --git a/ubuntu24-ssh/Containerfile b/ubuntu24-ssh/Containerfile deleted file mode 100644 index 5b2a6c2..0000000 --- a/ubuntu24-ssh/Containerfile +++ /dev/null @@ -1,76 +0,0 @@ -FROM docker.io/ubuntu:24.04 -ENV DEBIAN_FRONTEND=noninteractive - -# Update and install required packages -RUN apt-get update && \ - apt-get upgrade -y && \ - apt-get install -y \ - python3 \ - sudo \ - systemd \ - openssh-server \ - python3-pip \ - iproute2 \ - vim \ - wget \ - git \ - tmux \ - sysvinit-utils \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -# Remove unnecessary system users -RUN for user in games news; do userdel -r $user 2>/dev/null || true; done - -# Mask unnecessary systemd services -RUN systemctl mask systemd-machine-id-commit.service - -# Create provisioner user and set up sudo -RUN useradd -m -s /bin/bash jackaltx && \ - echo "jackaltx ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/jackaltx - -# Create ansible temp directory with proper permissions -RUN mkdir -p /tmp/ansible-jackaltx && \ - chown jackaltx:jackaltx /tmp/ansible-jackaltx && \ - chmod 700 /tmp/ansible-jackaltx - -# Set up SSH -RUN mkdir -p /home/jackaltx/.ssh && \ - chmod 700 /home/jackaltx/.ssh - -# SSH key will be added during build -ARG SSH_KEY -RUN echo "$SSH_KEY" > /home/jackaltx/.ssh/authorized_keys && \ - chmod 600 /home/jackaltx/.ssh/authorized_keys && \ - chown -R jackaltx:jackaltx /home/jackaltx/.ssh - -# Configure SSH -RUN mkdir -p /run/sshd && \ - systemctl enable ssh - -# Add to Containerfiles - Enhanced SSH Security -RUN sed -i 's/#MaxAuthTries.*/MaxAuthTries 3/' /etc/ssh/sshd_config && \ - sed -i 's/#LoginGraceTime.*/LoginGraceTime 60/' /etc/ssh/sshd_config && \ - sed -i 's/#AllowAgentForwarding.*/AllowAgentForwarding no/' /etc/ssh/sshd_config && \ - echo "AllowUsers jackaltx" >> /etc/ssh/sshd_config - -# Add to Containerfiles - Enhanced Sudo Configuration -RUN echo "Defaults timestamp_timeout=15" >> /etc/sudoers.d/timeout && \ - echo "Defaults logfile=/var/log/sudo.log" >> /etc/sudoers.d/logging && \ - echo "Defaults use_pty" >> /etc/sudoers.d/pty && \ - echo "Defaults secure_path=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"" >> /etc/sudoers.d/secure_path - -# Add to Containerfiles - Secure Important Directories -RUN chmod 700 /etc/sudoers.d && \ - chmod 440 /etc/sudoers.d/* && \ - find /etc/ssh -type f -name 'ssh_host_*_key' -exec chmod 600 {} \; && \ - find /etc/ssh -type f -name 'ssh_host_*_key.pub' -exec chmod 644 {} \; - -# Add to Containerfiles - System Security Settings -RUN echo "umask 027" >> /etc/profile && \ - echo "TMOUT=900" >> /etc/profile && \ - echo "readonly TMOUT" >> /etc/profile - -# Verify final configuration -RUN id jackaltx && \ - sudo -l -U jackaltx