Skip to content

[ fix ] 사전 계정 정보 주입 후, entrypoint 실행#27

Merged
dongmin0204 merged 10 commits into
developfrom
decs260403
Apr 2, 2026
Merged

[ fix ] 사전 계정 정보 주입 후, entrypoint 실행#27
dongmin0204 merged 10 commits into
developfrom
decs260403

Conversation

@dongmin0204
Copy link
Copy Markdown

🌱 관련 이슈

🌱 작업 사항

  1. 컨테이너 시작 시 마운트된 계정 정보와 USER_ID, UID, GID가 일치하는지 검증하도록 수정.
  2. Jupyter Lab이 root가 아닌 사용자 권한으로 실행되도록 변경
  3. SSH 접속 사용자 허용 설정을 보강하고, 사용자 홈/Jupyter 설정 디렉토리 생성 로직을 정리

🌱 참고 사항

  • 실행 시 USER_ID, TARGET_UID는 필수이며, 필요하면 USER_GROUP, TARGET_GID도 함께 맞춰서 넘겨야 합니다.
  • 마운트된 /etc/passwd, /etc/group 정보와 전달한 UID/GID가 다르면 컨테이너가 즉시 종료됩니다. (db와 정합성이 잘 맞아야함)
  • Jupyter는 비-root 사용자 기준으로 실행되므로, 권한 문제를 줄이려면 마운트 디렉토리 소유자 정보가 실제 사용자와 일치해야 합니다.

@dongmin0204 dongmin0204 linked an issue Apr 2, 2026 that may be closed by this pull request
5 tasks
@dongmin0204 dongmin0204 requested a review from Copilot April 2, 2026 19:14
@dongmin0204 dongmin0204 self-assigned this Apr 2, 2026
@dongmin0204 dongmin0204 changed the base branch from main to develop April 2, 2026 19:14
@dongmin0204 dongmin0204 merged commit 50d4a30 into develop Apr 2, 2026
5 checks passed
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

컨테이너 시작 시 외부에서 마운트된 계정(/etc/passwd, /etc/group)과 전달된 UID/GID 정합성을 검증하고, Jupyter Lab을 비-root 사용자로 실행하도록 entrypoint 동작을 재구성하는 PR입니다(이슈 #26 흐름의 root/non-root 충돌 완화 목적).

Changes:

  • entrypoint.sh에서 USER/UID/GID 정합성 검증 로직 추가 및 Jupyter를 gosu로 비-root 실행하도록 변경
  • SSH AllowUsers 설정 보강 및 홈/Jupyter 설정 디렉토리 준비 로직 정리
  • Docker 이미지에 gosu 패키지 추가, README 이미지 태그 최신화

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.

File Description
README.md 최신 이미지 태그를 260403로 갱신하고 변경사항 설명을 업데이트
entrypoint.sh 계정/권한 검증, SSH allowlist 보강, Jupyter 비-root 실행 및 관련 디렉토리 준비 로직으로 재작성
Dockerfile entrypoint에서 사용하는 gosu 패키지 설치 추가

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread entrypoint.sh
Comment on lines +69 to +70
apt-get update
apt-get install -y auditd
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

apt-get update/apt-get install is being run at container startup. This makes startup slower and can fail in restricted/offline environments, and it also makes the runtime behavior depend on the state of apt repos at run time. Prefer installing auditd in the Dockerfile during image build (and remove these lines from the entrypoint).

Suggested change
apt-get update
apt-get install -y auditd
if ! command -v auditd >/dev/null 2>&1; then
echo "[ERROR] Required package 'auditd' is not installed in the image. Install it during image build instead of at container startup." >&2
exit 1
fi

Copilot uses AI. Check for mistakes.
Comment thread entrypoint.sh
Comment on lines +72 to +77
# /etc/audit/audit.rules 파일에 줄 추가
echo "-a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F auid=$TARGET_UID -k rm_commands" >> /etc/audit/audit.rules

# 사용자와 그룹이 모두 준비된 후, 소유권과 권한을 설정합니다.
chown -R "$USER_ID:$USER_GROUP" "/home/$USER_ID"
chmod 750 "/home/$USER_ID"
# history 명령어 칠 때 명령어를 입력한 시간이 같이 나오게 하는 명령어
echo 'HISTTIMEFORMAT="[%Y-%m-%d %H:%M:%S] "' >> /etc/profile
echo 'export HISTTIMEFORMAT' >> /etc/profile
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These echo >> writes are not idempotent: every container start will append another identical audit rule and another HISTTIMEFORMAT export to /etc/profile, causing unbounded duplication. Add a guard (e.g., grep -q for an existing line / key) before appending, or write the files in an overwrite/managed-block way.

Copilot uses AI. Check for mistakes.
Comment thread entrypoint.sh
Comment on lines +60 to +66
if ! getent passwd "$user_name" >/dev/null 2>&1; then
echo "[WARN] Skipping AllowUsers for missing account '$user_name'" >&2
return 0
fi
if ! grep -qxF "AllowUsers $user_name" /etc/ssh/sshd_config; then
printf '\nAllowUsers %s\n' "$user_name" >> /etc/ssh/sshd_config
fi
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ensure_sshd_allow_user only checks for an exact line match (AllowUsers <user>). If sshd_config already has AllowUsers with multiple users/patterns on one line, this will append a duplicate directive and can lead to confusing/incorrect allowlists. Consider parsing/updating an existing AllowUsers line (or using a single consolidated directive) instead of only appending exact matches.

Suggested change
if ! getent passwd "$user_name" >/dev/null 2>&1; then
echo "[WARN] Skipping AllowUsers for missing account '$user_name'" >&2
return 0
fi
if ! grep -qxF "AllowUsers $user_name" /etc/ssh/sshd_config; then
printf '\nAllowUsers %s\n' "$user_name" >> /etc/ssh/sshd_config
fi
local sshd_config="/etc/ssh/sshd_config"
local tmp_config
if ! getent passwd "$user_name" >/dev/null 2>&1; then
echo "[WARN] Skipping AllowUsers for missing account '$user_name'" >&2
return 0
fi
if awk -v user="$user_name" '
/^[[:space:]]*#/ { next }
/^[[:space:]]*AllowUsers([[:space:]]|$)/ {
for (i = 2; i <= NF; i++) {
if ($i == user) {
found = 1
exit
}
}
}
END { exit(found ? 0 : 1) }
' "$sshd_config"; then
return 0
fi
if awk '
/^[[:space:]]*#/ { next }
/^[[:space:]]*AllowUsers([[:space:]]|$)/ { found = 1; exit }
END { exit(found ? 0 : 1) }
' "$sshd_config"; then
tmp_config="$(mktemp)"
awk -v user="$user_name" '
!updated && /^[[:space:]]*AllowUsers([[:space:]]|$)/ {
print $0 " " user
updated = 1
next
}
{ print }
' "$sshd_config" > "$tmp_config"
cat "$tmp_config" > "$sshd_config"
rm -f "$tmp_config"
else
printf '\nAllowUsers %s\n' "$user_name" >> "$sshd_config"
fi

Copilot uses AI. Check for mistakes.
Comment thread entrypoint.sh
echo "trying jupyter lab..."
nohup /opt/anaconda3/bin/jupyter lab --NotebookApp.token=$TOKEN --config=/home/$USER_ID/.jupyter/jupyter_notebook_config.py >/dev/null 2>&1 &
echo "jupyter lab listening!"
sed -i "1i c.JupyterApp.config_file_name = 'jupyter_notebook_config.py'\nc.NotebookApp.allow_origin = '*'\nc.NotebookApp.ip = '0.0.0.0'\nc.NotebookApp.open_browser = False\nc.NotebookApp.allow_remote_access = True\nc.NotebookApp.allow_root = False\nc.NotebookApp.notebook_dir='$JUPYTER_DIR'" "$JUPYTER_CONFIG_FILE"
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sed -i "1i ..." prepends the same config block on every container start, even when the config file already exists, which will quickly corrupt the config with repeated duplicated settings. Make this update idempotent (e.g., check for a sentinel line before inserting, or manage the file via a template/overwrite approach).

Suggested change
sed -i "1i c.JupyterApp.config_file_name = 'jupyter_notebook_config.py'\nc.NotebookApp.allow_origin = '*'\nc.NotebookApp.ip = '0.0.0.0'\nc.NotebookApp.open_browser = False\nc.NotebookApp.allow_remote_access = True\nc.NotebookApp.allow_root = False\nc.NotebookApp.notebook_dir='$JUPYTER_DIR'" "$JUPYTER_CONFIG_FILE"
if ! grep -Fqx "c.JupyterApp.config_file_name = 'jupyter_notebook_config.py'" "$JUPYTER_CONFIG_FILE"; then
sed -i "1i c.JupyterApp.config_file_name = 'jupyter_notebook_config.py'\nc.NotebookApp.allow_origin = '*'\nc.NotebookApp.ip = '0.0.0.0'\nc.NotebookApp.open_browser = False\nc.NotebookApp.allow_remote_access = True\nc.NotebookApp.allow_root = False\nc.NotebookApp.notebook_dir='$JUPYTER_DIR'" "$JUPYTER_CONFIG_FILE"
else
echo "Jupyter config settings already present; skipping update."
fi

Copilot uses AI. Check for mistakes.
Comment thread entrypoint.sh
Comment on lines 119 to 121
# ssh restart
service ssh restart

Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The entrypoint restarts SSH but does not ensure host keys exist (e.g., via ssh-keygen -A) before restart. Given the prior failure mode (sshd: no hostkeys available -- exiting.), add a check/generation step before service ssh restart so SSH reliably comes up even if keys are missing.

Copilot uses AI. Check for mistakes.
Comment thread entrypoint.sh
Comment on lines +79 to 80
ensure_account_matches_mounts

Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ensure_account_matches_mounts is invoked after apt-get update/install and other system mutations. To fail fast (and avoid doing network/package work when UID/GID mismatch will immediately exit), run the account/UID/GID validation as early as possible before any installs/file modifications.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ fix ] 도커 이미지 내의 sudo 권한 관련 이슈 문제 해결

4 participants