lxc-attach(1) | lxc-attach(1) |
NAME¶
lxc-attach - 실행 중인 컨테이너 내에 프로세스를 실행
SYNOPSIS¶
lxc-attach
{-n, --name name} [-f, --rcfile config_file] [-a, --arch
arch] [-e, --elevated-privileges privileges] [-s, --namespaces
namespaces] [-R, --remount-sys-proc] [--keep-env] [--clear-env] [-L,
--pty-log file] [-v, --set-var variable] [--keep-var
variable] [-u, --uid uid] [-g, --gid gid] [--
command]
설명¶
lxc-attach는 name으로 지정한 컨테이너 내에 command를 실행한다. 해당 컨테이너는 실행중이어야 한다.
만약 command가 지정되지 않았다면, lxc-attach가 현재 실행 중인 쉘이 컨테이너 안에도 있는지 검사하고 이를 실행한다. 만약 컨테이너 안에 사용자가 존재하지 않거나, nsswitch가 제대로 동작하지 않는 경우에는 이 명령이 실패하게 된다.
이전 버전의 lxc-attach는 단순히 컨테이너의 특정 네임스페이스 내에서 쉘이나 명령어를 pseudo 터미널 할당 없이 실행하였다. 이는 다른 특권 수준을 갖는 사용자 영역 컨텍스트 간의 전환후 TIOCSTI ioctl를 호출하여 입력을 가로챌 수 있는 취약점이 있다. 새로운 버전의 lxc-attach는 쉘이나 명령어를 실행하기 전, 호스트에서 pseudo 터미널 마스터/슬레이브 쌍을 할당하고, 터미널을 가리키고 있던 표준 입출력 파일 디스크립터들을 pseudo 터미널의 슬레이브로 연결한다. 터미널을 가리키고 있던 표준 입출력 파일 디스크립터가 아예 없었다면, lxc-attach는 pseudo 터미널 할당을 시도하지 않음에 주의해야 한다. 단순히 컨테이너 네임스페이스 내부에서 쉘이나 지정한 명령어를 실행할 뿐이다.
옵션¶
- -f, --rcfile config_file
- 컨테이너의 가상화 및
고립 기능들을 설정할
파일을 지정한다.
이전에 만들어졌던 컨테이너에 설정 파일이 이미 있더라도, 이 옵션이 지정되어 있다면 해당 파일을 사용한다.
- -a, --arch arch
- 명령어를 실행하는 컨테이너의 아키텍처를 지정한다. 이 옵션은 컨테이너의 설정파일에서 지정한 lxc.arch 옵션과 같은 것만 사용할 수 있다. lxc.conf(5)를 참조 바란다. 기본값은 실행 중인 컨테이너의 아키텍처이다.
- -e, --elevated-privileges privileges
- 컨테이너 내부에서
command를 실행할 때 privilege를
제거하지 않는다.
만약 이 옵션이
지정되었다면, 새로운
프로세스는
컨테이너의 cgroup에
추가되지 않는다.
그리고 실행 전 capability도
제거하지 않는다.
만약 모든 privilege를 얻고 싶지 않을 경우에는 CGROUP|LSM와 같이 파이프(|)로 구분된 리스트를 사용할 수 있다. 허용되는 값은 CGROUP、CAP、LSM이다. 각각 cgroup, capability, MAC label을 나타낸다. (파이프 기호는 CGROUP\|LSM처럼 \로 처리를 해주거나, "CGROUP|LSM"처럼 따옴표를 붙여야 한다.)
경고 : 만약 명령어가 attach된 메인프로세스가 종료된 후에, 실행 상태로 남아있는 서브프로세스를 시작하려고 한다면, 컨테이너 내부로 privilege 누수가 발생할 수 있다. 컨테이너 내에서 데몬을 시작(또는 재시작)하는 것은 문제가 될 수 있다. 특히 만약 데몬이 많은 서브프로세스 를 실행하는 경우라면, 예를 들어 cron와 sshd와 같은 경우는 문제가 될 수 있다. 충분한 주의를 기울여서 사용하여야 한다.
- -s, --namespaces namespaces
- 컨테이너의 어떤
네임스페이스와
연결할지 지정한다.
NETWORK|IPC와 같이
파이프(|)로 구분된
리스트를 사용할 수
있다. 허용되는 값은
MOUNT, PID, UTSNAME, IPC, USER ,
NETWORK이다. 이를
사용하여, 컨테이너의
네트워크
네임스페이스를
사용하면서도 다른
네임스페이스는
호스트의 것을 그대로
사용하는 등의 조작이
가능하다. (파이프
기호는 MOUNT\|PID처럼 \로
처리를 해주거나,
"MOUNT|PID"처럼
따옴표를 붙여야
한다.)
중요 : 이 옵션은 -e 옵션을 포함하고 있다.
- -R, --remount-sys-proc
- -s를 사용하여
마운트
네임스페이스를
포함하지 않았을 때,
이 플래그는 lxc-attach가
/proc와 /sys를 remount 하게
만든다. 이는 현재와
다른 네임스페이스
컨텍스트를
반영시키기 위함이다.
좀더 자세한 설명은 주의섹션을 참고하면 된다.
만약 마운트 네임스페이스에 연결하려고 한다면, 이 옵션은 무시된다.
- --keep-env
- 현재의 환경변수를 실행할 프로그램에도 그대로 적용한다. 이것은 현재 기본 동작이지만 (버전 0.9에서), 향후에 충분히 바뀔 수도 있다. 왜냐하면, 이것은 컨테이너에게 바람직하지 않은 정보를 넘겨줄 수 있는 위험성이 있기 때문이다. 따라서 이 기능에 의존하고 있다면, 향후에도 이를 보장할 수 있도록 이 옵션을 사용하는 것이 좋다. 또한 현재 환경 변수와 더불어, container=lxc도 설정된다.
- --clear-env
- 프로그램을 실행하기 전에 모든 환경변수를 지운다. 이를 통해 바람직하지 않은 환경변수 누출을 막을 수 있다. container=lxc 만이 프로그램이 실행되기 전에 설정되는 유일한 환경변수이다.
- -L, --pty-log file
- lxc-attach의 출력을
기록할 파일을
지정한다.
중요: 표준 입출력 파일 디스크립터가 pty를 참조하지 않으면, 기록되지 않는다.
- -v, --set-var variable
- 컨테이너 내에서 실행되는 프로그램이 볼 수 있는 환경변수를 추가한다. 이는 "VAR=VALUE" 형태로 지정되며, 여러 번 지정할 수 있다.
- --keep-var variable
- \-\-clear-env와 함께 사용되며, 지정한 환경변수를 지우지 않고 그대로 유지한다. 여러 번 지정할 수 있다.
- -u, --uid uid
- 지정된 사용자 ID uid로 command를 container 내부에 실행한다.
- --g, --gid gid
- 지정된 그룹 ID gid로 command를 container 내부에 실행한다.
공통 옵션¶
이 옵션들은 대부분의 lxc 명령어들에서 공통으로 쓰인다.
- -?, -h, --help
- 사용법을 기존 출력하는 것보다 길게 출력한다.
- --usage
- 사용법을 표시한다.
- -q, --quiet
- 결과를 표시하지 않는다.
- -P, --lxcpath=PATH
- 컨테이너 경로를 직접 지정한다. 기본값은 /var/lib/lxc이다.
- -o, --logfile=FILE
- 로그의 경로를 FILE로 지정한다. 기본값은 로그를 출력하지 않는 것이다.
- -l, --logpriority=LEVEL
- 로그 수준을 LEVEL로
지정한다. 기본값은
ERROR이다. 사용 가능한 값
: FATAL, ALERT, CRIT, WARN, ERROR, NOTICE, INFO, DEBUG, TRACE.
이 옵션은 로그 파일에만 적용된다는 사실을 주의해야 한다. stderr로 출력되는 ERROR 로그에는 영향을 끼치지 않는다.
- -n, --name=NAME
- 컨테이너 식별자로 NAME을 사용한다. 컨테이너 식별자의 형식은 알파벳-숫자 문자열이다.
- --rcfile=FILE
- 컨테이너의 가상화 및
고립 기능들을 설정할
파일을 지정한다.
이전에 만들어졌던 컨테이너에 설정 파일이 이미 있더라도, 이 옵션이 지정되어 있다면 해당 파일을 사용한다.
- --version
- 버전 정보를 표시한다.
예제¶
존재하는 컨테이너의 내부에 새로운 쉘을 실행한다.
lxc-attach -n container
실행중인 Debian 컨테이너의 cron 서비스를 재시작한다.
lxc-attach -n container -- /etc/init.d/cron restart
NET_ADMIN capability없이 실행중인 컨테이너의 네트워크 링크 eth1을 비활성화하였다. -e 옵션을 사용하여 capability를 높였고, ip 툴이 설치되어있다고 가정하였다.
lxc-attach -n container -e -- /sbin/ip link delete eth1
호환성¶
(pid와 마운트 네임스페이스를 포함한) attach가 동작하기 위해서는 커널의 버전이 3.8 이상이거나 패치가 적용된 커널이어야 한다. 좀더 자세히 보려면 lxc 웹사이트를 참고하면 된다. lxc-attach는 패치되지 않은 커널 버전 3.7 이하면 실패된다.
그러나 -s를 사용하여 NETWORK, IPC, UTSNAME 네임스페이스 들만 지정한다면, 패치되지 않은 커널 3.0 이상에서도 성공적으로 동작한다.
사용자 네임스페이스와 연결되기 위해서는 커널 버전이 3.8 이상이어야 하고 사용자 네임스페이스가 활성화되어야 한다.
주의¶
리눅스의 /proc와 /sys 파일시스템은 네임스페이스의해 영향받는 몇가지 정보들을 포함하고 있다. 예를 들어 /proc의 프로세스 id로 된 폴더들이나 /sys/class/net의 네트워크 인터페이스 정보 등이다. pseudo 파일시스템을 마운트하는 프로세스의 네임스페이스가 여기에 어떤 정보를 표시할지 결정하는 것이지, /proc 또는 /sys에 접근하는 프로세스의 네임스페이스가 결정하는 것은 아니다.
-s 를 사용하여 컨테이너의 pid 네임스페이스에만 attach 시키고 마운트 네임스페이스(컨테이너의 /proc는 포함하고, 호스트의 것은 포함하지 않는)는 attach 시키지 않는 경우, /proc의 내용은 컨테이너의 것이 아닌 호스트의 것이 된다. 네트워크 네임스페이스만을 연결하고 /sys/class/net의 내용을 읽을 때도 같은 현상이 있다.
이러한 문제를 해결하기 위해, -R 옵션이 제공된다. 해당 옵션은 attach되는 프로세스의 네트워크/pid 네임스페이스를 반영하기 위해 /proc와 /sys를 다시 마운트한다. 호스트의 실제 파일시스템에 방해가 되지 않기 위해 마운트 네임스페이스는 공유되지 않는다(lxc-unshare의 동작과 비슷). /proc와 /sys 파일시스템을 제외하고 호스트 마운트 네임스페이스와 동일한 새로운 마운트 네임스페이스가 주어지게 된다.
이전 버전의 lxc-attach는 몇몇 중요한 서브시스템에 쓰기가 가능한 cgroup 내에 없더라도, 사용자가 컨테이너의 네임스페이스에 연결할 수 있는 버그가 있었다. 새로운 버전의 lxc-attach는 현재 사용자가 몇몇 중요한 서브시스템에 쓰기 권한이 있는 cgroup에 속하는지 여부를 검사한다. 그러므로 lxc-attach는 사용자에 따라 실패하는 경우도 있다. (예를 들어, 로그인 시 비특권 사용자가 중요 서브시스템에 쓰기가 가능한 cgroup에 위치하지 않은 경우) 하지만 이러한 동작은 정확한 것이고 더 안전한 것이다.
보안¶
-e와 -s 옵션을 사용할때는 주의해야 한다. 잘못 사용하게 하면 컨테이너들 간의 고립(isolation)을 깨트릴 수 있다.
참조¶
lxc(7), lxc-create(1), lxc-copy(1), lxc-destroy(1), lxc-start(1), lxc-stop(1), lxc-execute(1), lxc-console(1), lxc-monitor(1), lxc-wait(1), lxc-cgroup(1), lxc-ls(1), lxc-info(1), lxc-freeze(1), lxc-unfreeze(1), lxc-attach(1), lxc.conf(5)
2024-09-19 |