SSH 비-인터랙티브와 인터랙티브 세션
ssh로 세션 시작 시 몰랐던 것들
SSH 비-인터랙티브와 인터랙티브 세션
상황
- HDFS 클러스터 구축 시,
start-dfs.sh로 클러스터를 띄웠을 때JAVA_HOME을 잡지 못해서 노드가 안 뜨는 상황
해결
start-dfs.sh 실행 과정 확인
- ✅
start-dfs.sh는 각 노드에 SSH를 통한 비-인터랙티브 세션으로 명령어를 전달함core-site.xml의fs.defaultFS설정은 클러스터 구성 정보 중 하나로, 데몬 실행 위치를 직접 결정하진 않음 - 환경 변수는
hadoop-env.sh에서 정의되며, 주요 변수는 다음과 같음:JAVA_HOME,HADOOP_HOME,HADOOP_CONF_DIR,HADOOP_LOG_DIR
- 실행 노드 기준으로:
hdfs --daemon start namenodehdfs --daemon start secondarynamenode
workers파일에 명시된 호스트에 대해:- 각각
ssh를 통해hdfs --daemon start datanode실행
- 각각
최종 방법
PermitUserEnvironment yes로 진행하였으나 보안 위험을 고려하여hadoop-env.sh에 명시- 관련 내용은 아래 참고
SSH 비-인터랙티브와 인터랙티브 세션 차이점
| 항목 | 비-인터랙티브 세션 | 인터랙티브 세션 (로그인 쉘) | 인터랙티브 세션 (비-로그인 쉘) |
|---|---|---|---|
| 사용자 상호작용 | ❌ | ✅ | ✅ |
| 쉘 유형 | 비-로그인 쉘 | 로그인 쉘(SSH 원격 로그인 시) | 비-로그인 쉘(터미널 새 셸 실행 시) |
| 시작 파일 | 로드 안 함 | - /etc/profile - ~/.bash_profile- ~/.bash_login- ~/.profile | ~/.bashrc |
| 사용 사례 | - 자동화 - 스크립트 실행 - 배치 작업 | - 원격 서버 관리 - 환경 설정 테스트 | - 로컬 터미널 작업 - 스크립트 디버깅 |
| 세션 시작 방법 | - ssh user@host 'command'- 예: ssh user@host 'ls -l' | - ssh user@host- 원격 쉘 시작 | - 로컬에서 새 셸 실행 - 예: bash, zsh |
✅
/etc/profile을 실행할 때, 자동으로/etc/profile.d/*.sh스크립트들도 함께 로드됨
세션 별 환경변수 적용 방법
비-인터랙티브 세션
- 시작 파일 로드 안하므로 아래와 같은 방법 중 하나로 환경변수 설정함
- 소싱:
ssh user@host 'source ~/.bashrc && command' - 전체 경로:
ssh user@host '/path/to/command' - 변수 명시:
ssh user@host 'VAR=value command' - SSH 설정:
SendEnv/AcceptEnv PermitUserEnvironment yes로~/.ssh/environment(보안 주의)
- 소싱:
인터랙티브 세션 (로그인 쉘)
- 시작 파일에서 환경 변수 로드함
- 필요 시
~/.bashrc소싱함
인터랙티브 세션 (비-로그인 쉘)
- 시작 파일에서 환경 변수 로드함
- 필요 시 추가 소싱함
비교: /etc/environment vs /etc/profile
차이점
| 항목 | /etc/environment | /etc/profile |
|---|---|---|
| 파일 형식 | - 키-값 쌍 형식 - 예: VAR=value- 셸 스크립트 아님 | - Bash 셸 스크립트 - 조건문/루프 등 포함 가능 |
| 로드 시점 | - PAM 모듈(pam_env) 사용- 모든 세션에 로드함 - (로그인, 비-로그인, 비-인터랙티브 포함) | - 로그인 쉘에서만 로드함 - 비-인터랙티브 세션에서는 로드 안 함 |
| 사용 범위 | - 시스템 전역 - 모든 사용자 및 프로세스에 적용함 | - 주로 로그인 쉘 사용자 - 셸별 설정 가능함 |
| 구문 복잡성 | - 단순한 변수 정의만 가능함 | - 동적 설정 지원함 - 예: if 문, 변수 치환 |
보안 관련 활용
| 항목 | /etc/environment | /etc/profile |
|---|---|---|
| 장점 | - 모든 세션에 일관 적용함 - 비-인터랙티브 세션에서도 보장함 | - 로그인 쉘에서 동적 설정 가능함 - 사용자별 커스터마이징 용이함 |
| 보안 강화 | - 읽기 전용 권한 설정함 - 예: chmod 644- 관리자만 수정 가능함 | - 실행 권한 제한함 - 예: chmod 755- 신뢰할 수 있는 스크립트만 포함함 |
| 사용 예 | - JAVA_HOME=/usr/lib/jvm/java 정의함 | - export JAVA_HOME=/usr/lib/jvm/java- 조건문으로 설정 가능함 |
| 권장 선택 | - 비-인터랙티브 세션에서 선호함 | - 복잡한 셸 설정 필요 시 사용함 - 비-인터랙티브 세션에서는 소싱 추가함 |
SSH 환경 변수 설정 보안 강화 방법
SendEnv/AcceptEnv및PermitUserEnvironment yes- 위 방법을 사용한 환경 변수 설정은 편리하지만 보안 위험이 있음
SSH 환경 변수 설정 보안 비교 표
| 구분 | SendEnv / AcceptEnv 설정 | PermitUserEnvironment 설정 |
|---|---|---|
| 보안 위험 | - 민감 정보 노출 (예: API 키) - 허용 변수 조작 위험 - 과도한 범위 허용 시 악용 가능함 | - 사용자 수정 가능 파일(~/.ssh/environment)- PATH, LD_PRELOAD 통한 권한 상승- 보안 정책 충돌 위험이 있음 |
| 설정 위치 | - 클라이언트 설정: ~/.ssh/config- 서버 설정: /etc/ssh/sshd_config | - 서버 설정: /etc/ssh/sshd_config- 사용자 설정: ~/.ssh/environment, ~/.ssh/authorized_keys |
| 보안 강화 방법 | - AcceptEnv로 허용 변수 최소화함예: AcceptEnv LANG LC_*- SendEnv로 필요한 변수만 전송함예: SendEnv MY_VAR- 서버 측 변수 값 검증함 (정규식 등) - SSH 로그 모니터링함 ( /var/log/auth.log) | - PermitUserEnvironment no 설정 유지함- 전역 변수는 /etc/environment, /etc/profile에 정의함- authorized_keys에 environment="VAR=value" 명시함- ~/.ssh 디렉토리 및 파일 권한 강화함 (chmod 700, chmod 600) |
| 대표 예시 | - 클라이언트 설정:SendEnv LANG LC_*- 서버 설정: AcceptEnv LANG LC_* | - authorized_keys 내 설정:environment="JAVA_HOME=/usr/lib/jvm/java" ssh-rsa AAAAB3... |
| 권장 여부 | ✅ 사용 가능 (보안 설정 주의 시 효과적) | ⚠️ 가급적 비활성화 권장 (기본값 no 유지) |
⚠️ PermitUserEnvironment yes의 주요 보안 위험
| 위험 항목 | 설명 |
|---|---|
| 사용자 제어 파일 | ~/.ssh/environment 파일은 사용자 본인이 수정할 수 있어, PATH, LD_PRELOAD, LD_LIBRARY_PATH 등의 환경 변수를 악의적으로 조작할 수 있음 |
| 권한 상승 가능성 | 환경 변수를 이용해 시스템 명령 경로를 바꾸거나 악성 바이너리를 실행시켜 권한 상승 시도 가능 |
| 시스템 전역 영향 | 로그인 시 환경 변수가 자동으로 로드되며, 전체 시스템 동작에 예기치 않은 영향을 줄 수 있음 |
| 정책 위반 가능성 | 보안 정책상 사용자별 임의 환경 설정이 금지된 경우, 해당 설정은 정책 위반 요소가 됨 |
| 감사 및 추적 어려움 | 환경 변수에 의해 발생한 비정상 동작을 추적하기 어려우며, 문제 분석과 디버깅이 복잡해짐 |
⚠️ 비활성화 권장 이유
| 항목 | 설명 |
|---|---|
| 보안 원칙 위반 | 사용자 개별 설정은 “최소 권한 원칙(Principle of Least Privilege)”에 어긋남 |
| 운영 및 관리 어려움 | 사용자별 환경이 달라질 경우 서버 관리 및 자동화에 혼란을 유발함 |
| 더 안전한 대안 존재 | /etc/environment, /etc/profile, ~/.bashrc 등을 통한 통제 가능한 환경 설정 방식이 존재함 |
기본값은 no | 주요 리눅스 배포판에서 PermitUserEnvironment 기본값이 no인 이유는 바로 이 보안 문제 때문임 |
공통 보안 권장 사항
- 최소 권한 원칙:
- SSH 사용자에게 최소 권한 부여함(예:
sudo제한)
- SSH 사용자에게 최소 권한 부여함(예:
- SSH 서버 강화:
AllowUsers또는AllowGroups로 접속 제한함- 예:
AllowUsers user1 user2
- 패치 및 업데이트:
- OpenSSH 최신 버전 유지, 취약점 패치함
- 방화벽 설정:
- SSH 포트(22) 접근을 특정 IP로 제한함
- 예:
ufw allow from 192.168.1.0/24 to any port 22
- 키 기반 인증:
- 비밀번호 인증 비활성화함(
PasswordAuthentication no) - 키 생성:
ssh-keygen -t rsa -b 4096, 배포:ssh-copy-id user@host
- 비밀번호 인증 비활성화함(
대안 접근법
- 명시적 명령어:
- 환경 변수를 명령어에 직접 포함함
- 예:
ssh user@host 'JAVA_HOME=/usr/lib/jvm/java command'
- 스크립트 기반 설정:
- 원격 호스트에 환경 변수 스크립트 배포함
- 예:
ssh user@host 'bash -c "source /path/to/env.sh && command"'
- 구성 관리 도구:
- Ansible, Puppet, Docker로 환경 변수 관리하고, SSH 의존성 최소화함
This post is licensed under CC BY 4.0 by the author.