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
게스트 출력 파이프에 나타납니다. 그렇지 않으면 학생은 실패한 것입니다. - qemu 종료 :
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
(직접 링크는 아니지만 아직 평판 포인트가 충분하지 않습니다.)