Skip to content

Commit badc4ac

Browse files
committed
Add ssh-container example image
1 parent 07160b0 commit badc4ac

4 files changed

Lines changed: 201 additions & 0 deletions

File tree

ssh-container/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ssh_client_keys
2+
ssh_host_keys

ssh-container/Dockerfile

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
FROM ghcr.io/nearnodeflash/nnf-dm-copy-offload:0.1.19
2+
3+
# Build arguments for user UID/GID
4+
ARG USER_UID=1234
5+
ARG USER_GID=1234
6+
7+
# Set environment variables
8+
ENV USER_UID=${USER_UID}
9+
ENV USER_GID=${USER_GID}
10+
11+
ENV USER="mpiuser"
12+
ENV SESSION_DIR="/home/mpiuser/ssh-session"
13+
ENV KEYS_DIR="/home/mpiuser/ssh-session/keys"
14+
15+
# Modify existing mpiuser to use specified UID/GID
16+
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
17+
RUN TARGET_GROUP=$(getent group ${USER_GID} | cut -d: -f1) && \
18+
if [ -z "$TARGET_GROUP" ]; then \
19+
groupmod -g ${USER_GID} mpiuser; \
20+
TARGET_GROUP="mpiuser"; \
21+
fi && \
22+
usermod -u ${USER_UID} -g ${USER_GID} mpiuser
23+
SHELL ["/bin/sh", "-c"]
24+
25+
# Set up SSH directory for mpiuser
26+
RUN mkdir -p /home/mpiuser/.ssh && \
27+
mkdir -p ${SESSION_DIR} && \
28+
mkdir -p ${KEYS_DIR}
29+
30+
# Copy SSH host keys
31+
COPY ssh_host_keys/ssh_host_rsa_key ${KEYS_DIR}/ssh_host_rsa_key
32+
COPY ssh_host_keys/ssh_host_rsa_key.pub ${KEYS_DIR}/ssh_host_rsa_key.pub
33+
34+
# Copy client public key for authorized access
35+
COPY ssh_client_keys/mpiuser_key.pub ${KEYS_DIR}mpiuser_key.pub
36+
RUN cat ${KEYS_DIR}mpiuser_key.pub > ${KEYS_DIR}/authorized_keys
37+
38+
# Override any entrypoint from base image and set our own
39+
COPY entrypoint.sh /entrypoint.sh
40+
RUN chmod a+x /entrypoint.sh
41+
42+
# Set proper permissions on keys
43+
RUN chmod 600 ${KEYS_DIR}/ssh_host_rsa_key && \
44+
chmod 644 ${KEYS_DIR}/ssh_host_rsa_key.pub && \
45+
chmod 600 ${KEYS_DIR}/authorized_keys && \
46+
chmod 700 /home/mpiuser/.ssh && \
47+
chown -R ${USER_UID}:${USER_GID} /home/mpiuser
48+
49+
USER mpiuser
50+
WORKDIR /home/mpiuser
51+
52+
# Configure SSH - port is set at runtime so we don't hardcode it here
53+
RUN echo "HostKey $KEYS_DIR/ssh_host_rsa_key" > "$SESSION_DIR/sshd_config" && \
54+
echo "AuthorizedKeysFile $KEYS_DIR/authorized_keys" >> "$SESSION_DIR/sshd_config" && \
55+
echo "PermitRootLogin no" >> "$SESSION_DIR/sshd_config" && \
56+
echo "PasswordAuthentication no" >> "$SESSION_DIR/sshd_config"
57+
58+
# Labels for identifying the UID/GID
59+
LABEL uid="${USER_UID}"
60+
LABEL gid="${USER_GID}"
61+
LABEL description="SSH container with mpiuser (UID:${USER_UID}, GID:${USER_GID})"
62+
63+
ENTRYPOINT ["/entrypoint.sh"]

ssh-container/Makefile

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# TODO: Set the UID and GID To match the user who is going to use this container. Due to security, the UID and GID
2+
# *must* be baked in to the image in order for sshd to obtain the correct permissions to enable ssh security.
3+
UID ?= 1060
4+
GID ?= 100
5+
6+
# NOTE: SSH_PORT is only for local testing purposes. In Rabbit User Containers, the port is assigned dynamically via the
7+
# NNF_CONTAINER_PORTS environment variable.
8+
SSH_PORT ?= 5123
9+
10+
# SSH key files - these are generated locally and used in the container. The mpiuser_key is used for ssh authentication
11+
# to connect to the container. Do not lose the client keys.
12+
SSH_HOST_KEY_DIR = ./ssh_host_keys
13+
SSH_HOST_RSA_KEY = $(SSH_HOST_KEY_DIR)/ssh_host_rsa_key
14+
SSH_CLIENT_KEY_DIR = ./ssh_client_keys
15+
SSH_CLIENT_KEY = $(SSH_CLIENT_KEY_DIR)/mpiuser_key
16+
17+
# Image name and tag
18+
IMAGE_NAME ?= ssh-container
19+
TAG ?= latest
20+
21+
# CONTAINER_TOOL defines the container tool to be used for building images.
22+
# Be aware that the target commands are only tested with Docker which is
23+
# scaffolded by default. However, you might want to replace it to use other
24+
# tools. (i.e. podman)
25+
CONTAINER_TOOL ?= docker
26+
27+
# Container name for easier management
28+
CONTAINER_NAME = ssh-container-$(UID)-$(GID)
29+
30+
.PHONY: all docker-build clean ssh-keys client-keys run stop connect status help
31+
32+
all: docker-build
33+
34+
help: ## Show this help message
35+
@echo "Available targets:"
36+
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " %-15s %s\n", $$1, $$2}' $(MAKEFILE_LIST)
37+
38+
# Generate SSH host keys
39+
ssh-keys: ## Generate SSH host keys for the container
40+
@echo "Generating SSH host keys..."
41+
@mkdir -p $(SSH_HOST_KEY_DIR)
42+
@if [ ! -f $(SSH_HOST_RSA_KEY) ]; then \
43+
ssh-keygen -t rsa -b 4096 -f $(SSH_HOST_RSA_KEY) -N '' -C "SSH host RSA key"; \
44+
fi
45+
@echo "SSH host keys generated successfully"
46+
47+
# Generate SSH client keys for authentication
48+
client-keys: ## Generate SSH client keys for authentication
49+
@echo "Generating SSH client keys..."
50+
@mkdir -p $(SSH_CLIENT_KEY_DIR)
51+
@if [ ! -f $(SSH_CLIENT_KEY) ]; then \
52+
ssh-keygen -t rsa -b 4096 -f $(SSH_CLIENT_KEY) -N '' -C "mpiuser@ssh-container"; \
53+
echo ""; \
54+
echo "Client key generated: $(SSH_CLIENT_KEY)"; \
55+
echo "Public key: $(SSH_CLIENT_KEY).pub"; \
56+
echo ""; \
57+
echo "To connect without password:"; \
58+
echo " ssh -i $(SSH_CLIENT_KEY) -p $(SSH_PORT) mpiuser@localhost"; \
59+
echo ""; \
60+
fi
61+
62+
# Build the container image
63+
docker-build: ssh-keys client-keys ## Build the container image with specified UID/GID
64+
@echo "Building $(CONTAINER_TOOL) image with UID=$(UID), GID=$(GID)..."
65+
$(CONTAINER_TOOL) build \
66+
--platform linux/amd64 \
67+
--build-arg USER_UID=$(UID) \
68+
--build-arg USER_GID=$(GID) \
69+
-t $(IMAGE_NAME):$(TAG) \
70+
-t $(IMAGE_NAME):uid$(UID)-gid$(GID) \
71+
.
72+
@echo "$(CONTAINER_TOOL) image built successfully"
73+
@echo "Image tags:"
74+
@echo " - $(IMAGE_NAME):$(TAG)"
75+
@echo " - $(IMAGE_NAME):uid$(UID)-gid$(GID)"
76+
@echo ""
77+
@echo "To inspect UID/GID/PORT labels:"
78+
@echo " $(CONTAINER_TOOL) inspect $(IMAGE_NAME):$(TAG) | grep -A 10 Labels"
79+
80+
# Run the container
81+
run: docker-build ## Run the container with SSH service
82+
$(CONTAINER_TOOL) run -d \
83+
--platform linux/amd64 \
84+
--name $(CONTAINER_NAME) \
85+
-p $(SSH_PORT):$(SSH_PORT) \
86+
-e NNF_CONTAINER_PORTS=$(SSH_PORT) \
87+
$(IMAGE_NAME):$(TAG)
88+
@echo "Container started with SSH on port $(SSH_PORT) (accessible via host port $(SSH_PORT))"
89+
@echo "Connect with: make connect"
90+
91+
# Stop and remove container
92+
stop: ## Stop and remove the container
93+
-$(CONTAINER_TOOL) stop $(CONTAINER_NAME)
94+
-$(CONTAINER_TOOL) rm $(CONTAINER_NAME)
95+
96+
# Check container status
97+
status: ## Check if the container is running
98+
@if $(CONTAINER_TOOL) ps | grep -q $(CONTAINER_NAME); then \
99+
echo "Container $(CONTAINER_NAME) is running"; \
100+
$(CONTAINER_TOOL) ps | grep $(CONTAINER_NAME); \
101+
else \
102+
echo "Container $(CONTAINER_NAME) is not running"; \
103+
fi
104+
105+
# Connect to the running container using SSH keys
106+
connect: ## Connect to the container via SSH
107+
@if [ ! -f $(SSH_CLIENT_KEY) ]; then \
108+
echo "Client key not found. Run 'make client-keys' first."; \
109+
exit 1; \
110+
fi
111+
@if ! $(CONTAINER_TOOL) ps | grep -q $(CONTAINER_NAME); then \
112+
echo "Container $(CONTAINER_NAME) is not running."; \
113+
echo "Run 'make run' to start the container first."; \
114+
echo "Or run 'make status' to check container status."; \
115+
exit 1; \
116+
fi
117+
@echo "Connecting to SSH container..."
118+
ssh -i $(SSH_CLIENT_KEY) -p $(SSH_PORT) -o StrictHostKeyChecking=no mpiuser@localhost
119+
120+
# Clean up generated files and containers
121+
clean: stop ## Clean up generated files and containers
122+
rm -rf $(SSH_HOST_KEY_DIR)
123+
rm -rf $(SSH_CLIENT_KEY_DIR)
124+
-$(CONTAINER_TOOL) rmi $(IMAGE_NAME):$(TAG)
125+
-$(CONTAINER_TOOL) rmi $(IMAGE_NAME):uid$(UID)-gid$(GID)

ssh-container/entrypoint.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/sh
2+
3+
ls -la /home/mpiuser
4+
ls -la /home/mpiuser/ssh-session
5+
6+
export -p > /home/mpiuser/ssh-session/env.sh
7+
echo "[ -f /home/mpiuser/ssh-session/env.sh ] && . /home/mpiuser/ssh-session/env.sh" >> "$HOME"/.profile
8+
9+
echo "Port $NNF_CONTAINER_PORTS" >> /home/mpiuser/ssh-session/sshd_config && \
10+
11+
/usr/sbin/sshd -D -f "/home/mpiuser/ssh-session/sshd_config" -E "/home/mpiuser/ssh-session/sshd.log"

0 commit comments

Comments
 (0)