-
Notifications
You must be signed in to change notification settings - Fork 3
[ fix ] 사전 계정 정보 주입 후, entrypoint 실행 #27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
111a3a2
e6218c7
57552dd
66eb231
61ec4e5
c96b127
296d5b7
e2e8442
443aaae
2a45f60
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,54 +1,92 @@ | ||||||||||||||
| #!/bin/bash | ||||||||||||||
| set -euo pipefail | ||||||||||||||
|
|
||||||||||||||
| : "${USER_ID:?USER_ID is required}" | ||||||||||||||
| : "${TARGET_UID:?TARGET_UID is required}" | ||||||||||||||
|
|
||||||||||||||
| USER_GROUP="${USER_GROUP:-$USER_ID}" | ||||||||||||||
| TARGET_GID="${TARGET_GID:-$TARGET_UID}" | ||||||||||||||
| USER_HOME="/home/$USER_ID" | ||||||||||||||
| JUPYTER_DIR="$USER_HOME/decs_jupyter_lab" | ||||||||||||||
| JUPYTER_CONFIG_DIR="$USER_HOME/.jupyter" | ||||||||||||||
| JUPYTER_CONFIG_FILE="$JUPYTER_CONFIG_DIR/jupyter_notebook_config.py" | ||||||||||||||
|
|
||||||||||||||
| ensure_account_matches_mounts() { | ||||||||||||||
| local passwd_entry | ||||||||||||||
| local group_entry | ||||||||||||||
| local actual_uid | ||||||||||||||
| local actual_gid | ||||||||||||||
| local actual_home | ||||||||||||||
| local actual_group_gid | ||||||||||||||
|
|
||||||||||||||
| passwd_entry="$(getent passwd "$USER_ID" || true)" | ||||||||||||||
| if [[ -z "$passwd_entry" ]]; then | ||||||||||||||
| echo "[ERROR] User '$USER_ID' not found in mounted /etc/passwd" >&2 | ||||||||||||||
| exit 1 | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| sudo apt update | ||||||||||||||
| sudo apt install -y auditd | ||||||||||||||
| IFS=: read -r _ _ actual_uid actual_gid _ actual_home _ <<<"$passwd_entry" | ||||||||||||||
|
|
||||||||||||||
| # /etc/audit/audit.rules 파일에 줄 추가 | ||||||||||||||
| echo "-a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F auid=$USER_ID -k rm_commands" >> /etc/audit/audit.rules | ||||||||||||||
| if [[ "$actual_uid" != "$TARGET_UID" ]]; then | ||||||||||||||
| echo "[ERROR] USER_ID '$USER_ID' has uid '$actual_uid', expected '$TARGET_UID'" >&2 | ||||||||||||||
| exit 1 | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| # history 명령어 칠 때 명령어를 입력한 시간이 같이 나오게 하는 명령어 | ||||||||||||||
| echo 'HISTTIMEFORMAT="[%Y-%m-%d %H:%M:%S] "' >> /etc/profile | ||||||||||||||
| echo 'export HISTTIMEFORMAT' >> /etc/profile | ||||||||||||||
| if [[ "$actual_gid" != "$TARGET_GID" ]]; then | ||||||||||||||
| echo "[ERROR] USER_ID '$USER_ID' has gid '$actual_gid', expected '$TARGET_GID'" >&2 | ||||||||||||||
| exit 1 | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| if ! id "$USER_ID" >/dev/null 2>&1; then | ||||||||||||||
| # 유저 디렉토리 존재하지 않는 경우, 디렉토리와 skel 생성 | ||||||||||||||
| if [ ! -d "/home/$USER_ID/" ]; then | ||||||||||||||
| cp -R /etc/skel/. "/home/$USER_ID" | ||||||||||||||
| chmod -R 700 "/home/$USER_ID" # 초기 권한 설정 후 아래에서 변경 | ||||||||||||||
|
|
||||||||||||||
| # history -w 현재시간.txt파일을 만들고, /var/log/audit로 이동하는 부분임. 사용자가 로그아웃 할 때 | ||||||||||||||
| echo 'cd ~' >> /home/$USER_ID/.bash_logout | ||||||||||||||
| echo 'current_time=$(date +%Y-%m-%d_%H-%M-%S)' >> /home/$USER_ID/.bash_logout | ||||||||||||||
| echo 'history -w $current_time.txt' >> /home/$USER_ID/.bash_logout | ||||||||||||||
| echo 'sudo mv $current_time.txt /var/log/audit/' >> /home/$USER_ID/.bash_logout | ||||||||||||||
| if [[ "$actual_home" != "$USER_HOME" ]]; then | ||||||||||||||
| echo "[ERROR] USER_ID '$USER_ID' has home '$actual_home', expected '$USER_HOME'" >&2 | ||||||||||||||
| exit 1 | ||||||||||||||
| fi | ||||||||||||||
| useradd -s /bin/bash -d /home/$USER_ID -u $UID $USER_ID | ||||||||||||||
|
|
||||||||||||||
| # sudo 권한 제공 | ||||||||||||||
| echo "$USER_ID ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers | ||||||||||||||
| group_entry="$(getent group "$USER_GROUP" || true)" | ||||||||||||||
| if [[ -z "$group_entry" ]]; then | ||||||||||||||
| echo "[ERROR] Group '$USER_GROUP' not found in mounted /etc/group" >&2 | ||||||||||||||
| exit 1 | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| # 비밀번호 설정 | ||||||||||||||
| echo "$USER_ID:$USER_PW" | chpasswd | ||||||||||||||
| IFS=: read -r _ _ actual_group_gid _ <<<"$group_entry" | ||||||||||||||
| if [[ "$actual_group_gid" != "$TARGET_GID" ]]; then | ||||||||||||||
| echo "[ERROR] USER_GROUP '$USER_GROUP' has gid '$actual_group_gid', expected '$TARGET_GID'" >&2 | ||||||||||||||
| exit 1 | ||||||||||||||
| fi | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| # 서버관리자와 유저계정의 ssh 접속을 허용 및 다중접속 허용 | ||||||||||||||
| sed -i "/^#PermitRootLogin/a AllowUsers svmanager" /etc/ssh/sshd_config | ||||||||||||||
| sed -i "/^#PermitRootLogin/a AllowUsers $USER_ID" /etc/ssh/sshd_config | ||||||||||||||
| sed -i 's/^UsePAM yes/UsePAM no/' /etc/ssh/sshd_config | ||||||||||||||
| fi | ||||||||||||||
| ensure_sshd_allow_user() { | ||||||||||||||
| local user_name="$1" | ||||||||||||||
| 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 | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| # 그룹이 존재하지 않을 경우 생성하고 사용자를 그룹에 추가 | ||||||||||||||
| if ! getent group "$USER_GROUP" >/dev/null 2>&1; then | ||||||||||||||
| groupadd -g $GID "$USER_GROUP" | ||||||||||||||
| fi | ||||||||||||||
| usermod -aG "$USER_GROUP" "$USER_ID" | ||||||||||||||
| apt-get update | ||||||||||||||
| apt-get install -y auditd | ||||||||||||||
|
Comment on lines
+69
to
+70
|
||||||||||||||
| 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
AI
Apr 2, 2026
There was a problem hiding this comment.
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
AI
Apr 2, 2026
There was a problem hiding this comment.
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
AI
Apr 2, 2026
There was a problem hiding this comment.
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).
| 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ensure_sshd_allow_useronly checks for an exact line match (AllowUsers <user>). If sshd_config already hasAllowUserswith multiple users/patterns on one line, this will append a duplicate directive and can lead to confusing/incorrect allowlists. Consider parsing/updating an existingAllowUsersline (or using a single consolidated directive) instead of only appending exact matches.