├── .gitignore ├── README.md ├── Vagrantfile ├── ifkakao-handson ├── 1-handson-setup.txt ├── 2-container-filesystem.txt ├── 3-container-namespace-cgroups.txt └── 4-make-container.txt ├── ifkakao2022_container-internal.pdf ├── m1 ├── README.md ├── Vagrantfile └── parallels │ ├── README.md │ └── Vagrantfile ├── overlaynw ├── README.md ├── Vagrantfile └── overlaynet │ ├── arpd.py │ ├── attach_ctn.sh │ ├── check.sh │ ├── create_overlay.sh │ ├── l2l3miss.py │ └── reset.sh └── scripts ├── chroot_ps.sh ├── chroot_sh.sh └── copy_tools.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .vagrant 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # container-internal 2 | 컨테이너 인터널 실습 리포입니다. 3 | > 맥/윈도우 x86기반 환경을 안내합니다. 4 | Mac M1, M2 arm 계열환경안내는 https://github.com/sam0kim/container-internal/tree/main/m1 를 참고해 주세요 5 | 6 | ## 실습 환경 갖추기 7 | ### 실습 안내 8 | - 발표 pdf 다운로드: https://github.com/sam0kim/container-internal/raw/main/ifkakao2022_container-internal.pdf 9 | - Mac/윈도우 환경에서 VirtualBox 와 Vagrant 기반으로 테스트 되었습니다 10 | - Mac 이외 OS 환경에서도 가급적 “Vagrant + VirtualBox” 사용을 권장드립니다. 11 | > Vagrant 기반 실습환경 준비가 어려운 분들은 아래 "Vagrant 미지원 시 실습환경 갖추기"를 참고해주세요. 12 | 13 | ### 실습 도구 14 | - Virtualbox 공식 다운로드 및 설치 https://www.virtualbox.org/wiki/Downloads 15 | - Vagrant 공식 다운로드 및 설치 https://www.vagrantup.com/downloads 16 | 17 | 맥 OS기준 (M1제외) Virtualbox 및 Vagrant 설치 방법은 다음과 같습니다. 18 | 19 | 설치 방법 20 | ```bash 21 | # virtualbox 설치 22 | brew install virtualbox --cask 23 | # vagrant 설치 24 | brew install vagrant --cask 25 | ``` 26 | 27 | Virtualbox 설정 28 | - (설정1) 시스템 환경 설정에서 “Oracle” 허용 및 맥 재부팅 29 | ``` 30 | 시스템 환경설정 > 보안 및 개인 정보 보호 > 일반 > 하단에 Oracle 관련 설치 허용 31 | ``` 32 | - (설정2) 네트워크 range 설정 33 | (참고) https://www.virtualbox.org/manual/ch06.html#network_hostonly 34 | ```bash 35 | $ sudo -i 36 | # mkdir -p /etc/vbox/ 37 | # vi /etc/vbox/networks.conf 38 | * 0.0.0.0/0 ::/0 39 | ``` 40 | FAQ 41 | 1) VM기동(vagrant up) 중 에러 메시지1 42 | ``` 43 | ... 44 | VBoxManage: error: VBoxNetAdpCtl: Error while adding new interface: failed to open /dev/vboxnetctl: No such file or directory 45 | ... 46 | ``` 47 | Sol) 위의 Virtualbox (설정1)을 확인해 주세요 48 | 49 | 2) VM기동(vagrant up) 중 에러 메시지2 50 | ``` 51 | Valid ranges can be modified in the /etc/vbox/networks.conf file 52 | ``` 53 | Sol) 위의 Virtualbox (설정2)를 확인해 주세요 54 | 55 | ### 실습 환경 56 | 아래 Vagrantfile을 사용합니다. 57 | - Mac/윈도우 Intel,x86계열 https://raw.githubusercontent.com/sam0kim/container-internal/main/Vagrantfile 58 | 59 | Vagrant 기본 사용법. vagrant는 "Vagrantfile" 경로를 기준으로 동작합니다. 60 | ```bash 61 | # VM 중지와 재개 62 | $ vagrant suspend 63 | $ vagrant resume 64 | 65 | # VM 종료와 기동 66 | $ vagrant halt 67 | $ vagrant up 68 | 69 | # VM 재기동 70 | $ vagrant reload 71 | 72 | # VM 재설정/기동 73 | $ vagrant reload --provision 74 | 75 | # VM 상태 확인 (VM 목록별 상태 출력) 76 | $ vagrant status 77 | 78 | # VM 터미널 접속 79 | $ vagrant ssh 80 | ``` 81 | 82 | ### 실습 참고 83 | - 실습 터미널 : VM 터미널 창을 두 개를 준비해주세요. (Vagrantfile 경로에서 실행) 84 | ```bash 85 | vagrant ssh ubuntu1804 86 | ``` 87 | - 실습 계정 : root 계정을 기본으로 합니다. 88 | ```bash 89 | vagrant@ubuntu1804:~$ sudo -Es 90 | root@ubuntu1804:~# 91 | ``` 92 | - 실습 경로 : /tmp 를 기본으로 합니다. 93 | ```bash 94 | root@ubuntu1804:~# cd /tmp 95 | root@ubuntu1804:/tmp# 96 | ``` 97 | > Q. 실습경로를 제한하는 이유? 98 | > > virtualbox의 특수한 mount 경로 사용 시 심볼릭 링크 제한 등 실습이 원활하지 않을 수 있어 실습경로를 통일합니다. 99 | - 실습 종료 : chroot, unshare, nsneter, docker exec 등 컨테이너 사용 시 각 실습이 끝나면 “exit” 로 컨테이너 프로세스를 종료해 주세요. 100 | ```bash 101 | bash-4.4# exit 102 | exit 103 | root@ubuntu1804:/tmp# 104 | ``` 105 | 106 | ## Vagrant 미지원 시 실습환경 갖추기 107 | - 본 가이드는 Vagrant 기반 실습환경 구성이 어려운 경우에 해당합니다. 108 | - Ubuntu(1804) 환경을 2개 준비해 주세요. * 무료클라우드 활용 등 109 | 110 | ### 실습 환경 갖추기 111 | 각자 준비된 Ubuntu(1804) 환경에서 아래 설치 스크립트를 실행해 주세요 112 | - Pre-requisite 113 | ```bash 114 | apt-get update \ 115 | && apt-get -y install gcc \ 116 | && apt-get -y install make \ 117 | && apt-get -y install pkg-config \ 118 | && apt-get -y install libseccomp-dev \ 119 | && apt-get -y install tree \ 120 | && apt-get -y install jq \ 121 | && apt-get -y install bridge-utils 122 | ``` 123 | - Docker 설치 124 | ```bash 125 | apt-get -y install apt-transport-https ca-certificates curl gnupg-agent software-properties-common > /dev/null 2>&1 \ 126 | && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - \ 127 | && add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \ 128 | && apt-get update \ 129 | && apt-get -y install docker-ce docker-ce-cli containerd.io > /dev/null 2>&1 130 | ``` 131 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | BOX_IMAGE = "bento/ubuntu-18.04" 2 | HOST_NAME = "ubuntu1804" 3 | 4 | $pre_install = <<-SCRIPT 5 | echo ">>>> pre-install <<<<<<" 6 | sudo apt-get update && 7 | sudo apt-get -y install gcc && 8 | sudo apt-get -y install make && 9 | sudo apt-get -y install pkg-config && 10 | sudo apt-get -y install libseccomp-dev && 11 | sudo apt-get -y install tree && 12 | sudo apt-get -y install jq && 13 | sudo apt-get -y install bridge-utils 14 | 15 | echo ">>>>> install docker <<<<<<" 16 | sudo apt-get -y install apt-transport-https ca-certificates curl gnupg lsb-release > /dev/null 2>&1 && 17 | sudo mkdir -p /etc/apt/keyrings && 18 | sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg && 19 | echo \ 20 | "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ 21 | $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null 2>&1 && 22 | sudo apt-get update && 23 | sudo apt-get -y install docker-ce docker-ce-cli docker-compose-plugin > /dev/null 2>&1 24 | SCRIPT 25 | 26 | Vagrant.configure("2") do |config| 27 | 28 | config.vm.define HOST_NAME do |subconfig| 29 | subconfig.vm.box = BOX_IMAGE 30 | subconfig.vm.hostname = HOST_NAME 31 | subconfig.vm.network :private_network, ip: "192.168.104.2" 32 | subconfig.vm.provider "virtualbox" do |v| 33 | v.memory = 1536 34 | v.cpus = 2 35 | end 36 | subconfig.vm.provision "shell", inline: $pre_install 37 | end 38 | 39 | end 40 | -------------------------------------------------------------------------------- /ifkakao-handson/1-handson-setup.txt: -------------------------------------------------------------------------------- 1 | # Final Stage 2 | 3 | 4 | ## 실습준비 5 | 6 | mkdir handson 7 | cd handson 8 | vi Vagrantfile 9 | 10 | ``` 11 | BOX_IMAGE = "bento/ubuntu-18.04" 12 | HOST_NAME = "ubuntu1804" 13 | 14 | $pre_install = <<-SCRIPT 15 | echo ">>>> pre-install <<<<<<" 16 | sudo apt-get update && 17 | sudo apt-get -y install gcc && 18 | sudo apt-get -y install make && 19 | sudo apt-get -y install pkg-config && 20 | sudo apt-get -y install libseccomp-dev && 21 | sudo apt-get -y install tree && 22 | sudo apt-get -y install jq && 23 | sudo apt-get -y install bridge-utils 24 | 25 | echo ">>>>> install docker <<<<<<" 26 | sudo apt-get -y install apt-transport-https ca-certificates curl gnupg-agent software-properties-common > /dev/null 2>&1 && 27 | sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && 28 | sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && 29 | sudo apt-get update && 30 | sudo apt-get -y install docker-ce docker-ce-cli containerd.io > /dev/null 2>&1 31 | SCRIPT 32 | 33 | Vagrant.configure("2") do |config| 34 | 35 | config.vm.define HOST_NAME do |subconfig| 36 | subconfig.vm.box = BOX_IMAGE 37 | subconfig.vm.hostname = HOST_NAME 38 | subconfig.vm.network :private_network, ip: "192.168.104.2" 39 | subconfig.vm.provider "virtualbox" do |v| 40 | v.memory = 1536 41 | v.cpus = 2 42 | end 43 | subconfig.vm.provision "shell", inline: $pre_install 44 | end 45 | 46 | end 47 | ``` 48 | 49 | vagrant up 50 | 51 | ### 터미널창 2개 준비 52 | vagrant ssh 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /ifkakao-handson/2-container-filesystem.txt: -------------------------------------------------------------------------------- 1 | # 컨테이너 파일시스템 2 | 3 | ## chroot 4 | 5 | ### sh 복사 6 | cd /tmp 7 | mkdir -p myroot/bin; 8 | cp /bin/sh myroot/bin/; 9 | mkdir -p myroot/{lib64,lib/x86_64-linux-gnu}; 10 | cp /lib/x86_64-linux-gnu/libc.so.6 myroot/lib/x86_64-linux-gnu/; 11 | cp /lib64/ld-linux-x86-64.so.2 myroot/lib64; 12 | 13 | ### ls 복사 14 | cp /bin/ls myroot/bin/; 15 | cp /lib/x86_64-linux-gnu/{libselinux.so.1,libc.so.6,libpcre.so.3,libdl.so.2,libpthread.so.0} myroot/lib/x86_64-linux-gnu/; 16 | cp /lib64/ld-linux-x86-64.so.2 myroot/lib64/; 17 | 18 | ### 루트 및 격리 확인 19 | ls / 20 | cd ../../../ 21 | ls 22 | cd / 23 | ls 24 | 25 | ### Mission: ps복사 (혼자 꼭 해보세요) 26 | wget https://raw.githubusercontent.com/sam0kim/container-internal/main/scripts/chroot_ps.sh; 27 | bash chroot_ps.sh; 28 | 29 | ### nginx 이미지 복사 30 | mkdir nginx-root 31 | docker export $(docker create nginx) | tar -C nginx-root -xvf - 32 | chroot nginx-root /bin/sh 33 | 34 | ### 탈옥코드 작성 35 | vi escape_chroot.c 36 | ``` 37 | #include 38 | #include 39 | 40 | int main(void) 41 | { 42 | mkdir(".out", 0755); 43 | chroot(".out"); 44 | chdir("../../../../../"); 45 | chroot("."); 46 | return execl("/bin/sh", "-i", NULL); 47 | } 48 | ``` 49 | 50 | ### 탈옥코드 컴파일 51 | gcc -o myroot/escape_chroot escape_chroot.c 52 | 53 | 54 | ## pivot_root 55 | 56 | ### unshare 마운트네임스페이스 57 | unshare --mount /bin/sh 58 | mkdir new_root 59 | mount -t tmpfs none new_root 60 | 61 | ### pivot_root 62 | cp -r myroot/* new_root 63 | 64 | mkdir new_root/put_old 65 | 66 | cd new_root 67 | pivot_root . put_old 68 | cd / 69 | 70 | 71 | ## overlay mount 72 | 73 | ### copy which 74 | mkdir -p tools/usr/bin; 75 | cp /usr/bin/which tools/usr/bin/; 76 | 77 | ### copy rm 78 | mkdir -p tools/{bin,lib64,lib/x86_64-linux-gnu}; 79 | cp /bin/rm tools/bin/; 80 | cp /lib/x86_64-linux-gnu/libc.so.6 tools/lib/x86_64-linux-gnu/; 81 | cp /lib64/ld-linux-x86-64.so.2 tools/lib64; 82 | 83 | ### rootfs 84 | mkdir -p rootfs/{container,work,merge} 85 | 86 | mount -t overlay overlay -o lowerdir=tools:myroot,upperdir=rootfs/container,workdir=rootfs/work rootfs/merge 87 | 88 | -------------------------------------------------------------------------------- /ifkakao-handson/3-container-namespace-cgroups.txt: -------------------------------------------------------------------------------- 1 | # 컨테이너 격리와 자원 2 | 3 | ## PID네임스페이스 4 | 5 | ### unshare PID네임스페이스 6 | unshare -fp --mount-proc /bin/sh 7 | 8 | 9 | ## NETWORK 네임스페이스 10 | 11 | ### 1:1 통신 12 | ip link add veth0 type veth peer name veth1; 13 | 14 | ip netns add RED; 15 | ip netns add BLUE; 16 | 17 | ip link set veth0 netns RED; 18 | ip link set veth1 netns BLUE; 19 | 20 | ip netns exec RED ip link set veth0 up; 21 | ip netns exec BLUE ip link set veth1 up; 22 | 23 | ip netns exec RED ip addr add 11.11.11.2/24 dev veth0; 24 | ip netns exec BLUE ip addr add 11.11.11.3/24 dev veth1; 25 | 26 | 27 | ## USER네임스페이스 28 | 29 | ### 일반계정 도커 컨테이너 실행 30 | docker run -it ubuntu /bin/sh 31 | 32 | ### 일반계정 USER네임스페이스 Remap 33 | unshare -U --map-root-user /bin/sh 34 | 35 | 36 | ### Cgroups 생성 37 | tree -L 1 /sys/fs/cgroup/cpu 38 | 39 | cgcreate -a root -g cpu:mycgroup 40 | tree -L 1 /sys/fs/cgroup/cpu 41 | tree -L 1 /sys/fs/cgroup/cpu/mycgroup 42 | 43 | cat /sys/fs/cgroup/cpu/mycgroup/cpu.cfs_quota_us 44 | cat /sys/fs/cgroup/cpu/mycgroup/cpu.cfs_period_us 45 | 46 | cgset -r cpu.cfs_quota_us=30000 mycgroup 47 | cat /sys/fs/cgroup/cpu/mycgroup/cpu.cfs_quota_us 48 | 49 | cgexec -g cpu:mycgroup stress -c 1 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /ifkakao-handson/4-make-container.txt: -------------------------------------------------------------------------------- 1 | # Final Stage 2 | 3 | 4 | ## 사전준비 5 | 6 | ### 이미지 준비 7 | cd /tmp; 8 | wget https://raw.githubusercontent.com/sam0kim/container-internal/main/scripts/copy_tools.sh; 9 | bash copy_tools.sh; 10 | 11 | 12 | ### 네트워크 준비 13 | ip netns add RED; 14 | ip netns add BLUE; 15 | 16 | ip link add veth0 netns RED type veth peer name veth1 netns BLUE; 17 | 18 | ip netns exec RED ip addr add dev veth0 11.11.11.2/24; 19 | ip netns exec RED ip link set veth0 up; 20 | 21 | ip netns exec BLUE ip addr add dev veth1 11.11.11.3/24; 22 | ip netns exec BLUE ip link set veth1 up; 23 | 24 | 25 | ## RED 컨테이너 26 | 27 | ### RED Cgroups 28 | mkdir /sys/fs/cgroup/cpu/red; 29 | mkdir /sys/fs/cgroup/memory/red; 30 | 31 | echo 40000 > /sys/fs/cgroup/cpu/red/cpu.cfs_quota_us; 32 | echo 209715200 > /sys/fs/cgroup/memory/red/memory.limit_in_bytes; 33 | echo 0 > /sys/fs/cgroup/memory/red/memory.swappiness; 34 | 35 | ### RED 격리 36 | unshare -m -u -i -fp nsenter --net=/var/run/netns/RED /bin/sh; 37 | 38 | ### RED Cgroups 할당 39 | echo "1" > /sys/fs/cgroup/cpu/red/cgroup.procs; 40 | echo "1" > /sys/fs/cgroup/memory/red/cgroup.procs; 41 | 42 | ### RED 파일시스템 43 | mkdir /redfs; 44 | mkdir /redfs/container; 45 | mkdir /redfs/work; 46 | mkdir /redfs/merge; 47 | 48 | mount -t overlay overlay -o lowerdir=/tmp/tools:/tmp/myroot,upperdir=/redfs/container,workdir=/redfs/work /redfs/merge 49 | 50 | mkdir -p /redfs/merge/put_old 51 | 52 | cd /redfs/merge; 53 | pivot_root . put_old; 54 | cd /; 55 | 56 | (루트와 put_old 비교해 봅니다. 보안언급) 57 | 58 | mount -t proc proc /proc; 59 | umount -l put_old; 60 | rm -rf put_old; 61 | 62 | (프로세스 확인 및 PID네임스페이스 격리 언급) 63 | ps -ef 64 | 65 | (호스트네임 조회 후 아래 호스트네임 변경) 66 | hostname RED 67 | 68 | 69 | ## BLUE 컨테이너 70 | 71 | ### BLUE Cgroups 72 | mkdir /sys/fs/cgroup/cpu/blue; 73 | mkdir /sys/fs/cgroup/memory/blue; 74 | 75 | echo 40000 > /sys/fs/cgroup/cpu/blue/cpu.cfs_quota_us; 76 | echo 209715200 > /sys/fs/cgroup/memory/blue/memory.limit_in_bytes; 77 | echo 0 > /sys/fs/cgroup/memory/blue/memory.swappiness; 78 | 79 | ### BLUE 격리 80 | unshare -m -u -i -fp nsenter --net=/var/run/netns/BLUE /bin/sh; 81 | 82 | ### BLUE Cgroups 할당 83 | echo "1" > /sys/fs/cgroup/cpu/blue/cgroup.procs; 84 | echo "1" > /sys/fs/cgroup/memory/blue/cgroup.procs; 85 | 86 | ### BLUE 파일시스템 87 | mkdir /bluefs; 88 | mkdir /bluefs/container; 89 | mkdir /bluefs/work; 90 | mkdir /bluefs/merge; 91 | 92 | mount -t overlay overlay -o lowerdir=/tmp/tools:/tmp/myroot,upperdir=/bluefs/container,workdir=/bluefs/work /bluefs/merge 93 | 94 | mkdir -p /bluefs/merge/put_old 95 | 96 | cd /bluefs/merge; 97 | pivot_root . put_old; 98 | cd /; 99 | 100 | (루트와 put_old 비교해 봅니다. 보안언급) 101 | 102 | mount -t proc proc /proc; 103 | umount -l put_old; 104 | rm -rf put_old; 105 | 106 | (프로세스 확인 및 PID네임스페이스 격리 언급) 107 | ps -ef 108 | 109 | (호스트네임 조회 후 아래 호스트네임 변경) 110 | hostname BLUE 111 | 112 | 113 | ## 테스트 114 | 115 | ### RED/BLUE ping 116 | (네트워크네임스페이스와 브릿지 통신 요약 설명) 117 | 118 | ### 리소스 제한 확인 119 | (CPU 쓰로틀링 확인) 120 | (메모리 OOMKill 확인) 121 | 122 | 123 | ## 실습환경 초기화 ====================== 124 | ip netns del BLUE;ip netns del RED; 125 | cgdelete -g cpu:red;cgdelete -g memory:red; 126 | cgdelete -g cpu:blue;cgdelete -g memory:blue; 127 | rm -rf /redfs;rm -rf /bluefs; 128 | rm -rf /tmp/tools; 129 | -------------------------------------------------------------------------------- /ifkakao2022_container-internal.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sam0kim/container-internal/b6622b3b59362c8d36428ca1b6c8f2c9fcf80178/ifkakao2022_container-internal.pdf -------------------------------------------------------------------------------- /m1/README.md: -------------------------------------------------------------------------------- 1 | # container-internal 2 | Mac arm (m1, m2) 계열 환경을 안내합니다. 3 | > VirtualBox 는 arm 계열 환경을 지원하지 않습니다. (2022.10 기준) 따라서 QEMU를 이용하여 VM 환경을 준비합니다. QEMU 에서 private network 지원에 제약이 있어 오버레이네트워크 등 분산VM 실습환경은 제공이 되지 않습니다. 이점 참고 부탁드립니다. 4 | > parallels 사용자는 다음을 참고해주세요. https://github.com/sam0kim/container-internal/tree/main/m1/parallels 5 | 6 | ## 실습 환경 갖추기 7 | ### 실습 안내 8 | - Mac M1(arm) 환경에서 QEMU 와 Vagrant 기반으로 테스트 되었습니다 9 | 10 | ### 실습 도구 11 | - Vagrant 공식 다운로드 및 설치 https://www.vagrantup.com/downloads 12 | 13 | Mac M1 환경에서 환경 설치 방법은 다음과 같습니다. 14 | 15 | 설치 방법 16 | ```bash 17 | # vagrant 설치 18 | brew install vagrant --cask 19 | 20 | # qemu 설치 21 | brew install qemu 22 | 23 | # plugin 설치 24 | vagrant plugin install vagrant-qemu 25 | ``` 26 | 27 | ### 실습 환경 28 | 아래 Vagrantfile을 사용합니다. 29 | - Mac M1,M2 arm계열 https://raw.githubusercontent.com/sam0kim/container-internal/main/m1/Vagrantfile 30 | 31 | Vagrant 기본 사용법. vagrant는 "Vagrantfile" 경로를 기준으로 동작합니다. 32 | ```bash 33 | # VM 종료와 기동 34 | $ vagrant halt 35 | $ vagrant up 36 | 37 | # VM 상태 확인 (VM 목록별 상태 출력) 38 | $ vagrant status 39 | 40 | # VM 터미널 접속 41 | $ vagrant ssh 42 | ``` 43 | 44 | ### 실습 참고 45 | - 실습 터미널 : VM 터미널 창을 두 개를 준비해주세요. (Vagrantfile 경로에서 실행) 46 | ```bash 47 | vagrant ssh ubuntu1804 48 | ``` 49 | - 실습 계정 : root 계정을 기본으로 합니다. 50 | ```bash 51 | vagrant@ubuntu1804:~$ sudo -Es 52 | root@ubuntu1804:~# 53 | ``` 54 | - 실습 경로 : /tmp 를 기본으로 합니다. 55 | ```bash 56 | root@ubuntu1804:~# cd /tmp 57 | root@ubuntu1804:/tmp# 58 | ``` 59 | > Q. 실습경로를 제한하는 이유? 60 | > > virtualbox의 특수한 mount 경로 사용 시 심볼릭 링크 제한 등 실습이 원활하지 않을 수 있어 실습경로를 통일합니다. 61 | - 실습 종료 : chroot, unshare, nsneter, docker exec 등 컨테이너 사용 시 각 실습이 끝나면 “exit” 로 컨테이너 프로세스를 종료해 주세요. 62 | ```bash 63 | bash-4.4# exit 64 | exit 65 | root@ubuntu1804:/tmp# 66 | ``` 67 | -------------------------------------------------------------------------------- /m1/Vagrantfile: -------------------------------------------------------------------------------- 1 | BOX_IMAGE = "generic/ubuntu1804" 2 | HOST_NAME = "ubuntu1804" 3 | 4 | $pre_install = <<-SCRIPT 5 | echo ">>>> pre-install <<<<<<" 6 | sudo apt-get update && 7 | sudo apt-get -y install gcc && 8 | sudo apt-get -y install make && 9 | sudo apt-get -y install pkg-config && 10 | sudo apt-get -y install libseccomp-dev && 11 | sudo apt-get -y install tree && 12 | sudo apt-get -y install jq && 13 | sudo apt-get -y install bridge-utils 14 | 15 | echo ">>>> install go <<<<<<" 16 | curl -O https://storage.googleapis.com/golang/go1.15.7.linux-amd64.tar.gz > /dev/null 2>&1 && 17 | tar xf go1.15.7.linux-amd64.tar.gz && 18 | sudo mv go /usr/local/ && 19 | echo 'PATH=$PATH:/usr/local/go/bin' | tee /home/vagrant/.bash_profile 20 | 21 | echo ">>>>> install docker <<<<<<" 22 | sudo apt-get -y install apt-transport-https ca-certificates curl gnupg lsb-release > /dev/null 2>&1 && 23 | sudo mkdir -p /etc/apt/keyrings && 24 | sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg && 25 | echo \ 26 | "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ 27 | $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null 2>&1 && 28 | sudo apt-get update && 29 | sudo apt-get -y install docker-ce docker-ce-cli docker-compose-plugin > /dev/null 2>&1 30 | SCRIPT 31 | 32 | Vagrant.configure("2") do |config| 33 | 34 | config.vm.define HOST_NAME do |subconfig| 35 | subconfig.vm.box = BOX_IMAGE 36 | subconfig.vm.hostname = HOST_NAME 37 | subconfig.vm.network :private_network, ip: "192.168.104.2" 38 | subconfig.vm.provider "qemu" do |qe| 39 | qe.arch = "x86_64" 40 | qe.machine = "q35" 41 | qe.cpu = "max" 42 | qe.net_device = "virtio-net-pci" 43 | end 44 | subconfig.vm.provision "shell", inline: $pre_install 45 | end 46 | 47 | end 48 | 49 | -------------------------------------------------------------------------------- /m1/parallels/README.md: -------------------------------------------------------------------------------- 1 | # container-internal 2 | Mac arm (m1, m2) 계열 parallels 사용자 안내입니다. 3 | 4 | ## 실습 환경 갖추기 5 | ### 실습 안내 6 | - Mac M1(arm) 환경에서 Parallels 와 Vagrant 기반으로 테스트 되었습니다 7 | 8 | ### 실습 도구 9 | - Vagrant 공식 다운로드 및 설치 https://www.vagrantup.com/downloads 10 | 11 | Mac M1 환경에서 환경 설치 방법은 다음과 같습니다. 12 | 13 | 설치 방법 14 | ```bash 15 | # vagrant 설치 16 | brew install vagrant --cask 17 | 18 | # parallels 다운로드 및 설치 19 | 공식사이트 안내를 따라 주세요. https://www.parallels.com/kr/products/desktop/ 20 | 21 | # plugin 설치 22 | vagrant plugin install vagrant-parallels 23 | ``` 24 | 25 | ### 실습 환경 26 | 아래 Vagrantfile을 사용합니다. 27 | - https://raw.githubusercontent.com/sam0kim/container-internal/main/m1/parallels/Vagrantfile 28 | 29 | Vagrant 기본 사용법. vagrant는 "Vagrantfile" 경로를 기준으로 동작합니다. 30 | ```bash 31 | # VM 종료와 기동 32 | $ vagrant halt 33 | $ vagrant up 34 | 35 | # VM 상태 확인 (VM 목록별 상태 출력) 36 | $ vagrant status 37 | 38 | # VM 터미널 접속 39 | $ vagrant ssh 40 | ``` 41 | 42 | ### 실습 참고 43 | - 실습 터미널 : VM 터미널 창을 두 개를 준비해주세요. (Vagrantfile 경로에서 실행) 44 | ```bash 45 | vagrant ssh ubuntu2004 46 | ``` 47 | - 실습 계정 : root 계정을 기본으로 합니다. 48 | ```bash 49 | vagrant@ubuntu2004:~$ sudo -Es 50 | root@ubuntu2004:~# 51 | ``` 52 | - 실습 경로 : /tmp 를 기본으로 합니다. 53 | ```bash 54 | root@ubuntu2004:~# cd /tmp 55 | root@ubuntu2004:/tmp# 56 | ``` 57 | > Q. 실습경로를 제한하는 이유? 58 | > > virtualbox의 특수한 mount 경로 사용 시 심볼릭 링크 제한 등 실습이 원활하지 않을 수 있어 실습경로를 통일합니다. 59 | - 실습 종료 : chroot, unshare, nsneter, docker exec 등 컨테이너 사용 시 각 실습이 끝나면 “exit” 로 컨테이너 프로세스를 종료해 주세요. 60 | ```bash 61 | bash-4.4# exit 62 | exit 63 | root@ubuntu2004:/tmp# 64 | ``` 65 | -------------------------------------------------------------------------------- /m1/parallels/Vagrantfile: -------------------------------------------------------------------------------- 1 | BOX_IMAGE = "jeffnoxon/ubuntu-20.04-arm64" 2 | HOST_NAME = "ubuntu2004" 3 | 4 | $pre_install = <<-SCRIPT 5 | echo ">>>> pre-install <<<<<<" 6 | sudo apt-get update && 7 | sudo apt-get -y install gcc && 8 | sudo apt-get -y install make && 9 | sudo apt-get -y install pkg-config && 10 | sudo apt-get -y install libseccomp-dev && 11 | sudo apt-get -y install tree && 12 | sudo apt-get -y install jq && 13 | sudo apt-get -y install bridge-utils 14 | 15 | echo ">>>>> install docker <<<<<<" 16 | sudo apt-get -y install apt-transport-https ca-certificates curl gnupg lsb-release > /dev/null 2>&1 && 17 | sudo mkdir -p /etc/apt/keyrings && 18 | sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg && 19 | echo \ 20 | "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ 21 | $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null 2>&1 && 22 | sudo apt-get update && 23 | sudo apt-get -y install docker-ce docker-ce-cli docker-compose-plugin > /dev/null 2>&1 24 | SCRIPT 25 | 26 | Vagrant.configure("2") do |config| 27 | 28 | config.vm.define HOST_NAME do |subconfig| 29 | subconfig.vm.box = BOX_IMAGE 30 | subconfig.vm.hostname = HOST_NAME 31 | subconfig.vm.network :private_network, ip: "192.168.104.2" 32 | subconfig.vm.provider "virtualbox" do |v| 33 | v.memory = 1536 34 | v.cpus = 2 35 | end 36 | subconfig.vm.provision "shell", inline: $pre_install 37 | end 38 | 39 | end 40 | -------------------------------------------------------------------------------- /overlaynw/README.md: -------------------------------------------------------------------------------- 1 | # 오버레이 네트워크 2 | 3 | overlay network 실습을 위한 vagrant 환경구성 방법을 설명합니다. 4 | 5 | ### 디렉토리 6 | ``` 7 | overlaynw # ----- 오버레이 네트워크 실습폴더 8 | ㄴ overlaynet # ----- 다이내믹 오버레이 실습스크립트 9 | arpd.py # ----- L2,L3 miss event를 catch하여 arp cache,fdb 등록 10 | attach_ctn.sh # ----- 컨테이너 생성 스크립트 11 | check.sh # ----- check app_solicit. neighbor 이벤트 전송 활성화 여부 12 | create_overlay.sh # ----- vxlan, bridge 생성 스크립트 13 | l2l3miss.py # ----- L2,L3 이벤트 확인 데몬 14 | reset.sh # ----- 초기화 15 | README.md # ----- 실습가이드 문서 16 | Vagrantfile # ----- vagrant 실습 환경 구성 파일 17 | ``` 18 | 19 | ### 환경 구성 20 | 21 | Git clone 22 | ```bash 23 | $ git clone https://github.com/sam0kim/container-internal.git 24 | ``` 25 | 26 | VM 생성 27 | ```bash 28 | $ cd container-internal/overlaynw 29 | $ vagrant up 30 | ``` 31 | 32 | VM 확인 33 | ```bash 34 | $ vagrant status 35 | ``` 36 | 37 | VM 접속 38 | ```bash 39 | ### 터미널#1 접속 40 | $ vagrant ssh ubuntu1804 41 | 42 | ### 터미널#2 접속 43 | $ vagrant ssh ubuntu1804-2 44 | 45 | ``` -------------------------------------------------------------------------------- /overlaynw/Vagrantfile: -------------------------------------------------------------------------------- 1 | BOX_IMAGE = "bento/ubuntu-18.04" 2 | HOST_NAME = "ubuntu1804" 3 | HOST_NAME2 = "ubuntu1804-2" 4 | 5 | $pre_install = <<-SCRIPT 6 | echo ">>>> pre-install <<<<<<" 7 | sudo apt-get update && 8 | sudo apt-get -y install gcc && 9 | sudo apt-get -y install make && 10 | sudo apt-get -y install pkg-config && 11 | sudo apt-get -y install libseccomp-dev && 12 | sudo apt-get -y install tree && 13 | sudo apt-get -y install jq && 14 | sudo apt-get -y install bridge-utils 15 | sudo apt-get -y install python-pip > /dev/null 2>&1 && 16 | pip install pyroute2==0.5.18 17 | 18 | echo ">>>> install go <<<<<<" 19 | curl -O https://storage.googleapis.com/golang/go1.15.7.linux-amd64.tar.gz > /dev/null 2>&1 && 20 | tar xf go1.15.7.linux-amd64.tar.gz && 21 | sudo mv go /usr/local/ && 22 | echo 'PATH=$PATH:/usr/local/go/bin' | tee /home/vagrant/.bash_profile 23 | 24 | echo ">>>>> install docker <<<<<<" 25 | sudo apt-get -y install apt-transport-https ca-certificates curl gnupg-agent software-properties-common > /dev/null 2>&1 && 26 | sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && 27 | sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && 28 | sudo apt-get update && 29 | sudo apt-get -y install docker-ce docker-ce-cli containerd.io > /dev/null 2>&1 30 | SCRIPT 31 | 32 | Vagrant.configure("2") do |config| 33 | 34 | config.vm.define HOST_NAME do |subconfig| 35 | subconfig.vm.box = BOX_IMAGE 36 | subconfig.vm.hostname = HOST_NAME 37 | subconfig.vm.network :private_network, ip: "192.168.104.2" 38 | subconfig.vm.provider "virtualbox" do |v| 39 | v.memory = 1536 40 | v.cpus = 2 41 | end 42 | subconfig.vm.provision "shell", inline: $pre_install 43 | end 44 | 45 | config.vm.define HOST_NAME2 do |subconfig| 46 | subconfig.vm.box = BOX_IMAGE 47 | subconfig.vm.hostname = HOST_NAME2 48 | subconfig.vm.network :private_network, ip: "192.168.104.3" 49 | subconfig.vm.provider "virtualbox" do |v| 50 | v.memory = 1536 51 | v.cpus = 2 52 | end 53 | subconfig.vm.provision "shell", inline: $pre_install 54 | end 55 | 56 | end -------------------------------------------------------------------------------- /overlaynw/overlaynet/arpd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # To use this without l2miss/l3miss from vxlan, enable app_solicit on your interface 4 | # echo 1 | sudo tee -a /proc/sys/net/ipv4/neigh/eth0/app_solicit 5 | 6 | from pyroute2 import NetNS 7 | from pyroute2.netlink.rtnl import ndmsg 8 | from pyroute2.netlink.exceptions import NetlinkError 9 | import logging 10 | import os 11 | 12 | vxlan_ns="overns" 13 | #logging.basicConfig(level=logging.INFO) 14 | logging.basicConfig(level=logging.DEBUG) 15 | 16 | ipr = NetNS(vxlan_ns) 17 | ipr.bind() 18 | 19 | storage_home = "/vagrant/overlaynet/storage" 20 | storage_arp = storage_home + "/arp" 21 | storage_fdb = storage_home + "/fdb" 22 | 23 | while True: 24 | msg = ipr.get() 25 | for m in msg: 26 | logging.debug("Received an event: {}".format(m['event'])) 27 | if m['event'] != "RTM_GETNEIGH" : 28 | continue 29 | if 'ifindex' not in m : 30 | continue 31 | 32 | ifindex=m['ifindex'] 33 | ifname=ipr.get_links(ifindex)[0].get_attr("IFLA_IFNAME") 34 | 35 | if m.get_attr("NDA_DST") is not None: 36 | ipaddr=m.get_attr("NDA_DST") 37 | logging.info("L3Miss on {}: Who has IP: {}?".format(ifname,ipaddr)) 38 | 39 | arp_path = storage_arp + "/" + ipaddr 40 | if os.path.exists(arp_path): 41 | f = open(arp_path, 'r') 42 | mac_addr = f.readline().rstrip() 43 | f.close() 44 | logging.info("Populating ARP table from File: IP {} is {}".format(ipaddr,mac_addr)) 45 | try: 46 | logging.info("ifindex {}, ipaddr {}, mac_addr {}".format(ifindex,ipaddr,mac_addr)) 47 | ipr.neigh('add', dst=ipaddr, lladdr=mac_addr, ifindex=ifindex, state=ndmsg.states['permanent']) 48 | except NetlinkError as (code, message): 49 | print(message) 50 | 51 | if m.get_attr("NDA_LLADDR") is not None: 52 | lladdr=m.get_attr("NDA_LLADDR") 53 | logging.info("L2Miss on {}: Who has MAC: {}?".format(ifname,lladdr)) 54 | 55 | fdb_path = storage_fdb + "/" + lladdr 56 | if os.path.exists(fdb_path): 57 | f = open(fdb_path, 'r') 58 | dst_host=f.readline().rstrip() 59 | f.close() 60 | logging.info("Populating FIB table from File: MAC {} is on host {}".format(lladdr, dst_host)) 61 | try: 62 | logging.info("ifindex {}, lladdr {}, dst_host {}".format(ifindex,lladdr,dst_host)) 63 | ipr.fdb('add', ifindex=ifindex, lladdr=lladdr, dst=dst_host) 64 | except NetlinkError as (code, message): 65 | print(message) -------------------------------------------------------------------------------- /overlaynw/overlaynet/attach_ctn.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | containerns=${1:-pinkns} 4 | ip=${2:-2} 5 | 6 | # set host ip and interface 7 | host_ipaddr=$(ifconfig eth1 &>/dev/null;if [ "$?" == 1 ];then ifconfig eth0; fi | awk '{ print $2}' | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}") 8 | 9 | # set virtual lladdr & ipaddr 10 | mac=$ip 11 | if [[ "$ip" -lt 10 ]];then 12 | mac="0${ip}" 13 | fi 14 | lladdr="02:42:c0:a8:00:${mac}" 15 | ipaddr="11.11.11.${ip}" 16 | 17 | # storage for arp/fdb 18 | storage_home="/vagrant/overlaynet/storage" 19 | storage_arp="${storage_home}/arp" 20 | storage_fdb="${storage_home}/fdb" 21 | 22 | #------------------------------------------------# 23 | 24 | # reset 25 | cnt=$(sudo ip netns | grep $containerns | wc -l) 26 | if [ $cnt == 1 ];then 27 | echo "reset ${containerns}" 28 | sudo ip netns del $containerns 29 | rm "${storage_arp}/${ipaddr}" 30 | rm "${storage_fdb}/${lladdr}" 31 | fi 32 | 33 | # create netns 34 | sudo ip netns add $containerns 35 | 36 | # create veth interfaces - vethO (overns), eth0 (containerns) 37 | vethO="vethO${ip}" 38 | sudo ip link add dev $vethO mtu 1450 netns overns type veth peer name eth0 mtu 1450 netns $containerns 39 | 40 | # attach first peer to the bridge in our overlay namespace 41 | sudo ip netns exec overns ip link set $vethO master br0 42 | sudo ip netns exec overns ip link set $vethO up 43 | 44 | # move second peer tp container network namespace and configure it 45 | sudo ip netns exec $containerns ip link set dev eth0 address $lladdr 46 | sudo ip netns exec $containerns ip addr add dev eth0 "${ipaddr}/24" 47 | sudo ip netns exec $containerns ip link set dev eth0 up 48 | 49 | # write arp/fdb info to File 50 | echo $lladdr > "${storage_arp}/${ipaddr}" 51 | echo $host_ipaddr > "${storage_fdb}/${lladdr}" 52 | -------------------------------------------------------------------------------- /overlaynw/overlaynet/check.sh: -------------------------------------------------------------------------------- 1 | echo "check app_solicit" 2 | cat /proc/sys/net/ipv4/neigh/eth*/app_solicit 3 | -------------------------------------------------------------------------------- /overlaynw/overlaynet/create_overlay.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # reset 4 | sudo ip netns delete overns 2> /dev/null && echo "Deleting existing overlay" 5 | 6 | # create overns 7 | sudo ip netns add overns 8 | sudo ip netns exec overns ip link add dev br0 type bridge 9 | sudo ip netns exec overns ip addr add dev br0 11.11.11.1/24 10 | sudo ip link add dev vxlan1 netns overns type vxlan id 42 proxy learning l2miss l3miss dstport 4789 11 | sudo ip netns exec overns ip link set vxlan1 master br0 12 | sudo ip netns exec overns ip link set vxlan1 up 13 | sudo ip netns exec overns ip link set br0 up -------------------------------------------------------------------------------- /overlaynw/overlaynet/l2l3miss.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # To use this without l2miss/l3miss from vxlan, enable app_solicit on your interface 4 | # echo 1 | sudo tee -a /proc/sys/net/ipv4/neigh/eth0/app_solicit 5 | 6 | from pyroute2 import NetNS 7 | from pyroute2.netlink.rtnl import ndmsg 8 | from pyroute2.netlink.exceptions import NetlinkError 9 | import logging 10 | 11 | vxlan_ns="overns" 12 | if_family = {2 : "AF_INET"} 13 | nud_state = { 14 | 0x01 : "NUD_INCOMPLETE", 15 | 0x02 : "NUD_REACHABLE", 16 | 0x04 : "NUD_STALE", 17 | 0x08 : "NUD_DELAY", 18 | 0x10 : "NUD_PROBE", 19 | 0x20 : "NUD_FAILED", 20 | 0x40 : "NUD_NOARP", 21 | 0x80 : "NUD_PERMANENT", 22 | 0x00 : "NUD_NONE" 23 | } 24 | type = { 25 | 0 : "RTN_UNSPEC", 26 | 1 : "RTN_UNICAST", 27 | 2 : "RTN_LOCAL", 28 | 3 : "RTN_BROADCAST", 29 | 4 : "RTN_ANYCAST", 30 | 5 : "RTN_MULTICAST", 31 | 6 : "RTN_BLACKHOLE", 32 | 7 : "RTN_UNREACHABLE", 33 | 8 : "RTN_PROHIBIT", 34 | 9 : "RTN_THROW", 35 | 10 : "RTN_NAT", 36 | 11 : "RTN_XRESOLVE" 37 | } 38 | 39 | logging.basicConfig(level=logging.DEBUG) 40 | 41 | ns = NetNS(vxlan_ns) 42 | ns.bind() 43 | 44 | while True: 45 | msg = ns.get() 46 | for m in msg: 47 | logging.debug("Received an event: {}".format(m['event'])) 48 | if m['event'] != "RTM_GETNEIGH" : 49 | continue 50 | if 'ifindex' not in m : 51 | continue 52 | 53 | ifindex=m['ifindex'] 54 | ifname=ns.get_links(ifindex)[0].get_attr("IFLA_IFNAME") 55 | 56 | logging.debug("------------ ndmsg start ------------") 57 | logging.debug("Family: {}".format(if_family.get(m['family'],m['family']))) 58 | logging.debug("Interface {} index: {}".format(ifname,ifindex)) 59 | logging.debug("State: {}".format(nud_state.get(m['state'],m['state']))) 60 | logging.debug("Flags: {}".format(m['flags'])) 61 | logging.debug("Type: {}".format(type.get(m['ndm_type'],m['ndm_type']))) 62 | logging.debug("------------ ndmsg end --------------") 63 | 64 | if m.get_attr("NDA_DST") is not None: 65 | ipaddr=m.get_attr("NDA_DST") 66 | logging.info("L3Miss on {}: Who has IP: {}? Check arp table on {}".format(ifname,ipaddr,vxlan_ns)) 67 | 68 | if m.get_attr("NDA_LLADDR") is not None: 69 | lladdr=m.get_attr("NDA_LLADDR") 70 | logging.info("L2Miss on {}: Who has MAC: {}? Check bridge fdb on {}".format(ifname,lladdr,vxlan_ns)) 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /overlaynw/overlaynet/reset.sh: -------------------------------------------------------------------------------- 1 | arr_ns=$(ip netns list | awk '{print $1}') 2 | 3 | for i in $arr_ns 4 | do 5 | `ip netns del "$i"` 6 | done 7 | 8 | storage_home="/vagrant/overlaynet/storage" 9 | rm -f ${storage_home}/*/* 10 | -------------------------------------------------------------------------------- /scripts/chroot_ps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # copy ps 4 | ldd /bin/ps; 5 | cp /bin/ps /tmp/myroot/bin/; 6 | cp /lib/x86_64-linux-gnu/{libprocps.so.6,libdl.so.2,libc.so.6,libsystemd.so.0,librt.so.1,liblzma.so.5,libgcrypt.so.20,libpthread.so.0,libgpg-error.so.0} /tmp/myroot/lib/x86_64-linux-gnu/; 7 | mkdir -p /tmp/myroot/usr/lib/x86_64-linux-gnu; 8 | cp /usr/lib/x86_64-linux-gnu/liblz4.so.1 /tmp/myroot/usr/lib/x86_64-linux-gnu/; 9 | cp /lib64/ld-linux-x86-64.so.2 /tmp/myroot/lib64/; 10 | 11 | # copy mount 12 | ldd /bin/mount; 13 | cp /bin/mount /tmp/myroot/bin/; 14 | cp /lib/x86_64-linux-gnu/{libmount.so.1,libc.so.6,libblkid.so.1,libselinux.so.1,librt.so.1,libuuid.so.1,libpcre.so.3,libdl.so.2,libpthread.so.0} /tmp/myroot/lib/x86_64-linux-gnu/; 15 | cp /lib64/ld-linux-x86-64.so.2 /tmp/myroot/lib64/; 16 | 17 | # copy mkdir 18 | ldd /bin/mkdir; 19 | cp /bin/mkdir /tmp/myroot/bin/; 20 | cp /lib/x86_64-linux-gnu/{libselinux.so.1,libc.so.6,libpcre.so.3,libdl.so.2,libpthread.so.0} /tmp/myroot/lib/x86_64-linux-gnu/; 21 | cp /lib64/ld-linux-x86-64.so.2 /tmp/myroot/lib64/; 22 | -------------------------------------------------------------------------------- /scripts/chroot_sh.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # copy sh 4 | ldd /bin/sh 5 | mkdir -p myroot/bin; 6 | cp /bin/sh myroot/bin/; 7 | mkdir -p myroot/{lib64,lib/x86_64-linux-gnu}; 8 | cp /lib/x86_64-linux-gnu/libc.so.6 myroot/lib/x86_64-linux-gnu/; 9 | cp /lib64/ld-linux-x86-64.so.2 myroot/lib64; 10 | 11 | # copy ls 12 | ldd /bin/ls 13 | cp /bin/ls myroot/bin/; 14 | cp /lib/x86_64-linux-gnu/{libselinux.so.1,libc.so.6,libpcre.so.3,libdl.so.2,libpthread.so.0} myroot/lib/x86_64-linux-gnu/; 15 | cp /lib64/ld-linux-x86-64.so.2 myroot/lib64/; 16 | -------------------------------------------------------------------------------- /scripts/copy_tools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir -p /tmp/tools/{bin,lib64,lib/x86_64-linux-gnu,usr/lib/x86_64-linux-gnu,usr/bin}; 4 | 5 | # copy ping 6 | ldd /bin/ping; 7 | cp /bin/ping /tmp/tools/bin/; 8 | cp /lib/x86_64-linux-gnu/{libcap.so.2,libidn.so.11,libresolv.so.2,libc.so.6} /tmp/tools/lib/x86_64-linux-gnu/; 9 | cp /usr/lib/x86_64-linux-gnu/libnettle.so.6 /tmp/tools/usr/lib/x86_64-linux-gnu/; 10 | 11 | # copy stress 12 | ldd /usr/bin/stress; 13 | cp /usr/bin/stress /tmp/tools/usr/bin/; 14 | cp /lib/x86_64-linux-gnu/{libm.so.6,libc.so.6} /tmp/tools/lib/x86_64-linux-gnu/; 15 | cp /lib64/ld-linux-x86-64.so.2 /tmp/tools/lib64/; 16 | 17 | # copy hostname 18 | ldd /bin/hostname; 19 | cp /bin/hostname /tmp/tools/bin/; 20 | cp /lib/x86_64-linux-gnu/libc.so.6 /tmp/tools/lib/x86_64-linux-gnu/; 21 | cp /lib64/ld-linux-x86-64.so.2 /tmp/tools/lib64; 22 | 23 | # copy umount 24 | ldd /bin/umount; 25 | cp /bin/umount /tmp/tools/bin/; 26 | cp /lib/x86_64-linux-gnu/{libmount.so.1,libc.so.6,libblkid.so.1,libselinux.so.1,librt.so.1,libuuid.so.1,libpcre.so.3,libdl.so.2,libpthread.so.0} /tmp/tools/lib/x86_64-linux-gnu/; 27 | cp /lib64/ld-linux-x86-64.so.2 /tmp/tools/lib64/; 28 | --------------------------------------------------------------------------------