Linux의 샌드 박스에서 신뢰할 수없는 C 프로그램을 실행하는 방법이 있는지 궁금합니다. 프로그램이 파일이나 네트워크 연결을 열지 못하도록 막거나 분기, exec 등을 차단하는 것이 있습니까?
서버에 업로드되고 단위 테스트가 실행되는 작은 프로그램, 숙제 일 것입니다. 따라서 프로그램은 수명이 짧습니다.
Linux의 샌드 박스에서 신뢰할 수없는 C 프로그램을 실행하는 방법이 있는지 궁금합니다. 프로그램이 파일이나 네트워크 연결을 열지 못하도록 막거나 분기, exec 등을 차단하는 것이 있습니까?
서버에 업로드되고 단위 테스트가 실행되는 작은 프로그램, 숙제 일 것입니다. 따라서 프로그램은 수명이 짧습니다.
답변:
Systrace 를 사용 하여 신뢰할 수없는 프로그램을 대화 형 및 자동 모드로 샌드 박스 화 했습니다. ptrace()
특별한 권한없이 Linux 시스템에서 사용할 수 있는 기반 백엔드와 커널 패치가 필요한 훨씬 더 빠르고 강력한 백엔드가 있습니다.
를 사용하여 유닉스 계열 시스템에서 샌드 박스를 만드는 것도 가능 chroot(1)
하지만 그렇게 쉽지도 안전하지는 않습니다. Linux 컨테이너 와 FreeBSD jail 은 chroot에 대한 더 나은 대안입니다. Linux의 또 다른 대안은 SELinux 또는 AppArmor 와 같은 보안 프레임 워크를 사용하는 것입니다. 이것이 제가 프로덕션 시스템을 위해 제안하는 것입니다.
당신이하고 싶은 것이 정확히 무엇인지 말씀하시면 더 많은 도움을 드릴 수 있습니다.
편집하다:
Systrace는 귀하의 경우에 적합하지만 AppArmor 또는 SELinux와 같은 Linux 보안 모델을 기반으로하는 것이 더 표준이므로 배포에 따라 선호되는 대안 이라고 생각합니다 .
편집 2 :
chroot(1)
대부분의 (모든?) 유닉스 계열 시스템에서 사용할 수 있지만 몇 가지 문제가 있습니다.
그것은 깨질 수 있습니다. 실제로 시스템에서 신뢰할 수없는 C 프로그램을 컴파일하거나 실행하려는 경우 특히이 문제에 취약합니다. 그리고 당신의 학생들이 나와 같은 사람이라면 누군가가 감옥에서 탈출하려고 할 것입니다.
작업에 필요한 모든 것이 포함 된 완전한 독립 파일 시스템 계층을 만들어야합니다. chroot에 컴파일러가있을 필요는 없지만 컴파일 된 프로그램을 실행하는 데 필요한 모든 것이 포함되어야합니다. 이를 돕는 유틸리티가 있지만 여전히 사소한 것은 아닙니다.
chroot를 유지해야합니다. 독립적이기 때문에 chroot 파일은 배포와 함께 업데이트되지 않습니다. chroot를 정기적으로 다시 만들거나 필요한 업데이트 도구를 포함해야합니다.이 경우 본질적으로 완전한 Linux 배포판이어야합니다. 또한 시스템 및 사용자 데이터 (암호, 입력 파일 등)를 호스트 시스템과 동기화 상태로 유지해야합니다.
chroot()
파일 시스템 만 보호합니다. 악성 프로그램이 네트워크 소켓을 열거 나 잘못 작성된 것이 사용 가능한 모든 리소스를 빨아들이는 것을 막지는 않습니다.
자원 사용 문제는 모든 대안에서 일반적입니다. 파일 시스템 할당량 은 프로그램이 디스크를 채우는 것을 방지합니다. 적절한 ulimit
( setrlimit()
C에서) 설정은 메모리 남용 및 포크 폭탄으로부터 보호 할 수있을뿐만 아니라 CPU 돼지를 막을 수 있습니다. nice(1)
더 중요하다고 생각되는 모든 작업에 문제없이 컴퓨터를 사용할 수 있도록 해당 프로그램의 우선 순위를 낮출 수 있습니다.
최근 에 Linux에서 샌드 박스 기술에 대한 개요를 작성했습니다 . 가장 쉬운 방법은 포크 등을 신경 쓰지 않는다면 Linux 컨테이너 (lxc)를 사용하는 것입니다.이 환경에서는 실제로 중요하지 않습니다. 프로세스에 읽기 전용 루트 파일 시스템, 격리 된 루프백 네트워크 연결을 제공 할 수 있으며 여전히 쉽게 종료하고 메모리 제한 등을 설정할 수 있습니다.
코드가 메모리를 할당 할 수 없기 때문에 Seccomp는 약간 어려울 것입니다.
Selinux는 다른 옵션이지만 컨테이너보다 더 많은 작업이 될 수 있다고 생각합니다.
Qemu를 사용하여 과제를 빠르게 테스트 할 수 있습니다. 아래 절차는 5 년 된 랩톱에서 5 초도 채 걸리지 않습니다.
학생이 "-1"줄이 도착할 때까지 각 줄에 서명되지 않은 int를 사용하는 프로그램을 개발해야한다고 가정 해 보겠습니다. 그런 다음 프로그램은 모든 int의 평균을 내고 "Average : % f"를 출력해야합니다. 프로그램을 완전히 분리하여 테스트하는 방법은 다음과 같습니다.
먼저 root.bin
Jslinux 에서 가져 와서 사용자 영역으로 사용할 것입니다 (tcc C 컴파일러가 있음).
wget https://github.com/levskaya/jslinux-deobfuscated/raw/master/root.bin
학생의 제출물을에 넣고 싶으 root.bin
므로 루프 장치를 설정합니다.
sudo losetup /dev/loop0 root.bin
(이 경우에도 fuseext2를 사용할 수 있지만 매우 안정적이지 않습니다. 안정화되면 루트가 필요하지 않습니다.)
빈 디렉토리 만들기 :
mkdir mountpoint
마운트 root.bin
:
sudo mount /dev/loop0 mountpoint
마운트 된 파일 시스템 입력 :
cd mountpoint
.
권리 수정 :
sudo chown -R `whoami` .
mkdir -p etc/init.d
vi etc/init.d
:
#!/bin/sh
cd /root
echo READY 2>&1 > /dev/ttyS0
tcc assignment.c 2>&1 > /dev/ttyS0
./a.out 2>&1 > /dev/ttyS0
chmod +x etc/init.d/rcS
제출을 VM에 복사합니다.
cp ~/student_assignment.c root/assignment.c
VM의 루트 FS를 종료합니다.
cd ..
sudo umount mountpoint
mkfifo /tmp/guest_output
별도의 터미널을 열고 게스트 출력 수신을 시작합니다.
dd if=/tmp/guest_output bs=1
다른 터미널에서 :
qemu-system-i386 -kernel vmlinuz-3.5.0-27-generic -initrd root.bin -monitor stdio -nographic -serial pipe:/tmp/guestoutput
(방금 Ubuntu 커널을 사용했지만 많은 커널이 작동합니다)
게스트 출력에 "READY"가 표시되면 qemu 프롬프트에서 VM으로 키를 보낼 수 있습니다. 예를 들어이 과제를 테스트하려면 다음을 수행 할 수 있습니다.
(qemu) sendkey 1
(qemu) sendkey 4
(qemu) sendkey ret
(qemu) sendkey 1
(qemu) sendkey 0
(qemu) sendkey ret
(qemu) sendkey minus
(qemu) sendkey 1
(qemu) sendkey ret
지금 Average = 12.000000
게스트 출력 파이프에 나타납니다. 그렇지 않으면 학생은 실패한 것입니다.
quit
테스트를 통과 한 프로그램은 https://stackoverflow.com/a/14424295/309483 입니다. tcclib.h
대신 사용하십시오 stdio.h
.
사용자 모드 Linux를 사용해보십시오 . CPU 집약적 인 작업의 경우 약 1 %의 성능 오버 헤드가 있지만 I / O 집약적 인 작업의 경우 6 배 더 느릴 수 있습니다.
Firejail은이를위한 가장 포괄적 인 도구 중 하나입니다. seccomp, 파일 시스템 컨테이너, 기능 등을 지원합니다.
가상 머신 내에서 실행하면 원하는 모든 보안 및 제한이 제공됩니다.
QEMU 는 이에 적합 할 것이며 모든 작업 (응용 프로그램 다운로드, 디스크 이미지 업데이트, QEMU 시작, 내부 응용 프로그램 실행 및 나중에 검색 할 수 있도록 출력 저장)은 자동화 된 테스트 실행을 위해 스크립팅 될 수 있습니다.
ptrace (strace) 체크 아웃을 기반으로하는 sanboxing에 관한 경우 :
" sydbox "샌드 박스 및 " pinktrace "프로그래밍 라이브러리 (C99이지만 내가 아는 한 python 및 ruby에 대한 바인딩이 있습니다).
주제와 관련된 수집 된 링크 :
http://www.diigo.com/user/wierzowiecki/sydbox
(직접 링크는 아니지만 아직 평판 포인트가 충분하지 않습니다.)
seccomp 및 seccomp-bpf는 최소한의 노력으로이를 수행합니다 : https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt
이것은 또한 유망 해 보인다. syscall 인터셉트를 사용하는 Linux 용 파일 시스템 샌드 박스.
좋아, 그들이 나를 많이 도왔던 모든 답변 덕분에. 그러나 나는 그들 중 누구도 원래 질문을 한 사람에게 해결책으로 제안하지 않을 것입니다. 언급 된 모든 도구는 교사, 교사, 교수로서 학생들의 코드를 테스트하기 위해 많은 작업을 필요로합니다. 이 경우 가장 좋은 방법은 내 생각에 virtualbox입니다. 좋아, 그것은 완전한 x68 시스템을 에뮬레이트하고 이런 식으로 샌드 박싱의 의미와 관련이 없지만 프로그래밍 선생님을 상상한다면 그에게 가장 좋을 것입니다. 그래서 "apt-get install virtualbox"는 데비안 기반 시스템에 있고 다른 모든 시스템은 http://virtualbox.org/로 이동합니다. 로 이동하여 VM을 만들고 iso를 추가하고 설치를 클릭 한 다음 잠시 기다렸다가 운이 좋습니다. 사용자 모드 리눅스를 설정하거나 무거운 strace 작업을 수행하는 것보다 훨씬 더 쉽게 사용할 수 있습니다.
그리고 만약 당신이 당신의 학생들이 당신을 해킹하는 것에 대한 두려움이 있다면, 당신은 권위 문제가있는 것 같고, 그에 대한 해결책은 그들이주는 일에서 단지 한 입의 악성 코드를 증명할 수 있다면 그들로부터 살아있는 일광을 고소 할 것이라고 위협 할 것입니다. 당신...
또한 클래스가 있고 그것의 1 %가 그가 그런 일을 할 수있는만큼 좋다면, 그런 간단한 작업으로 그들을 지루하게하지 말고 그들이 더 많은 코드를 작성해야하는 큰 것들을 제공하십시오. 통합 학습은 모든 사람에게 가장 적합하므로 오래된 교착 상태 구조에 릴레이하지 마십시오 ...
또한 웹 검색 및 소프트웨어 테스트와 같은 작업에 사용하는 중요한 작업 (예 : 증명 및 시험 작성)에 동일한 컴퓨터를 사용하지 마십시오.
중요한 일에는 오프라인 컴퓨터를 사용하고 다른 모든 일에는 온라인 컴퓨터를 사용하십시오.
그러나 편집증 교사가 아닌 다른 모든 사람들에게 (누구도 화를 내고 싶지는 않습니다. 저는 프로그래머 교사가되기 전에 보안과 우리 사회에 대한 기본을 배워야한다는 의견 일뿐입니다 ...)
... 다른 모든 사람들을 위해 ...
해피 해킹 !!