자바 DockerSandbox 라이브러리
DockerSandbox라는 Apache 2.0 라이선스로 작업한 오픈 소스 라이브러리를 소개하려고 합니다. 컨테이너화된 샌드박스 환경에서 코드를 실행할 수 있도록 하는 Docker Java 클라이언트https://github.com/docker-java/docker-java에 래퍼 API를 제공합니다. StepikOrg가 https://github.com/StepicOrg/epicbox에서 epicbox와 함께 Python에 제공하는 것과 유사한 Java용 기능을 제공합니다.
사용하기 쉬운 Java용 API를 제공하여 가능한 한 자세한 내용을 적게 하는 것을 목표로 합니다. 설정해야 하는 모든 것은 샌드박스로 지정하려는 언어를 실행할 수 있는 Docker 이미지입니다. 이 게시물은 API의 초기 안정 릴리스와 이를 사용하는 방법의 예를 설명합니다.
사용 사례
원격 코드 제출 서버(예: Replit)와 같은 다른 소스에서 수신할 수 있는 신뢰할 수 없는 코드를 실행하려고 한다고 가정합니다. 이 코드를 수락하는 서버는 단순히 하위 프로세스를 가동하여 코드를 실행할 수 있습니다. 그러나 여기에는 다음과 같은 보안 위험이 있습니다.
Docker는 여전히 코드 실행 측면에서 가장 안전하지 않지만(여전히 취약성이 있고 훨씬 더 높은 오버헤드가 있는 가상 머신 경로를 사용할 수 있음) 라이브러리는 컨테이너에서 최소 권한을 가진 사용자의 설정을 지시하여 몇 가지 예방 조치를 취합니다.
sandbox
라는 프로필(나중에 자세히 설명)을 통해 사용됩니다. Docker 컨테이너의 네트워크도 비활성화할 수 있습니다.이 라이브러리를 사용하면 코드를 실행할 때마다 Docker 컨테이너를 스핀업할 수 있으므로 코드가 컨테이너 내부에서 악의적인 작업을 수행하더라도 코드 실행이 완료되면 컨테이너가 파괴됩니다. 이 프로세스를 더 쉽게 만들기 위해 Docker Java 클라이언트 라이브러리에 추상화 계층을 추가합니다.
예시
다음은 루트 사용자를 사용하여 프로그램을 컴파일한 다음 사용된 샌드박스를 사용하여 gcc_run 프로필을 사용하여 프로그램을 실행하는 gcc_compile 프로필을 사용하여 C 프로그램을 컴파일하는 데 사용되는 라이브러리의 예입니다.
package io.github.edwardUL99.docker.sandbox;
import io.github.edwardUL99.docker.sandbox.api.Docker;
import io.github.edwardUL99.docker.sandbox.api.DockerSandbox;
import io.github.edwardUL99.docker.sandbox.api.components.Result;
import io.github.edwardUL99.docker.sandbox.api.components.WorkingDirectory;
public class Example {
public static void main(String[] args) {
DockerSandbox sandbox = DockerSandbox.builder()
.withJson("profiles.json") // see profiles.json in the root of the project for the example file
// Or you can do withShellProfiles(Docker.Shell.SH or Docker.Shell.BASH, profiles)
.withBinding("/path/to/local:/path/to/remote")
.withEnvironmentVariables("VAR1=VALUE1", "VAR2=VALUE2")
.build();
sandbox.start("/home/sandbox");
try {
Docker.Command command = new Docker.Command("gcc main.c -o main");
Result result = sandbox.run("gcc_compile", command,
new WorkingDirectory.UploadedFile("main.c", "/path/to/main.c"));
// do something with result
command = new Docker.Command("./main");
result = sandbox.run("gcc_run", command, "Stdin Input"); // notice how this run command uses the compiled file from the previous execution
// but you don't have to re-upload it as generated files from the previous call
// are shared
// do something with result
// the call to finish in the finally block will free any resources such as created files on the host machine in the working directory
} catch (Exception ex) {
ex.printStackTrace();
sandbox.cleanup(); // clean up any created containers that didn't get removed
} finally {
sandbox.finish(); // ensure all resources are freed
}
}
}
sandbox.cleanup()
에 대한 호출은 예외가 발생하는 경우 매달린 컨테이너가 모두 지워지도록 합니다. sandbox.finish()
는 생성된 컨테이너가 해체되도록 하기 위해 finally 블록에 배치됩니다. gcc_run
및 gcc_compile
프로필은 여기에서 볼 수 있습니다.{
"name": "gcc_compile",
"image": "gcc-docker",
"container-name": "gcc-docker",
"user": "root",
"networkDisabled": true
},
{
"name": "gcc_run",
"image": "gcc-docker",
"container-name": "gcc-docker",
"user": "sandbox",
"networkDisabled": true
}
sandbox.start("/home/sandbox")
에 대한 호출은 gcc_compile
실행에서 생성된 파일을 gcc_run
실행에서 생성된 컨테이너와 공유할 수 있도록 샌드박스에 작업 디렉토리 마운트를 설정합니다. 즉, 여기서 컴파일 출력은 실행 컨테이너에서 실행됩니다.설정
라이브러리를 설정하려면 1개 이상
Profile
을 정의해야 합니다. 프로필에는 sandbox.run
호출에 전달되는 프로필의 이름, Docker 이미지의 이름, 가동 컨테이너에 부여할 이름, 명령을 실행할 사용자, 마지막으로 네트워크를 활성화/비활성화하는 사용자가 포함됩니다. 컨테이너에 대한 연결성.이러한 프로필은 다음 구조의 JSON 파일에서 정의할 수 있습니다.
{
"profiles": [
... profiles go here
],
"docker_host": "unix:///var/run/docker.sock",
"shell": "bash"
}
또한 Docker 컨테이너에서 실행할 Docker 엔진 및 셸의 호스트를 구성합니다. 구성 시 JSON 파일의 경로를 샌드박스 빌더에 전달합니다. 샘플
profiles.json
및 샘플 이미지는 GitHub 리포지토리에서 제공됩니다.프로필과 셸은 다음과 같이 프로그래밍 방식으로 구성할 수도 있습니다.
dockerSandbox = DockerSandbox.builder()
.withShellProfiles(Docker.Shell.BASH, new Profile("java_run", "java-docker", "java-docker", "sandbox"),
new Profile("java_compile", "java-docker", "java-docker", "root"),
new Profile("gcc_run", "gcc-docker", "gcc-docker", "sandbox"),
new Profile("gcc_compile", "gcc-docker", "gcc-docker", "root"))
.withEnvironmentVariables("VAR1=VALUE1", "VAR2=VALUE2", "VAR3=VALUE3")
.build();
다운로드
다음 좌표에서 Maven을 사용하여 라이브러리를 다운로드할 수 있습니다.
<artifactId>io.github.edwardUL99</artifactId>
<groupId>docker-sandbox</groupId>
<version>1.0.0</version>
감사합니다
시간을 내어 이 게시물을 읽어주셔서 감사합니다. 도서관이 누군가에게 도움이 되었으면 합니다. 기능 요청이 있거나 버그를 발견하면 GitHub 리포지토리에 보고할 수 있습니다 :)
Reference
이 문제에 관하여(자바 DockerSandbox 라이브러리), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/edwardul99/java-dockersandbox-library-4m39텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)