实现Docker容器的安全性
我们现在怎么保证使用docker容器执行的安全性?
docker只不过实现了系统与系统之间的隔离 真实情况还是需要我们去排查安全问题
毕竟没有绝对的安全
执行超时
占用内存
读文件信息泄露
执行死程序
超时设置
执行容器的时候 增加超时参数的控制值
dockerClient 里面有个 awaitCompletion 属性
但是这个无论超时与否 程序都会自动向下进行运行
可以定义一个标志 如果程序执行完成 把标志设置为false
我们选择在匿名内部类里面去重写方法
ExecStartResultCallback execStartResultCallback = new ExecStartResultCallback() {
@Override
public void onComplete() {
// 如果执行完成,则表示没超时
timeout[0] = false;
super.onComplete();
}
@Override
public void onNext(Frame frame) {
StreamType streamType = frame.getStreamType();
if (StreamType.STDERR.equals(streamType)) {
errorMessage[0] = new String(frame.getPayload());
System.out.println("输出错误结果:" + errorMessage[0]);
} else {
message[0] = new String(frame.getPayload());
System.out.println("输出结果:" + message[0]);
}
super.onNext(frame);
}
};
内存限制
创建容器时指定hostConfig的参数 withMemory等方法 设置容器最大内存和资源限制
限制内存
hostConfig.withMemory(100 * 1000 * 1000L);
hostConfig.withMemorySwap(0L);
hostConfig.withCpuCount(1L);
hostConfig.withSecurityOpts(Arrays.asList("seccomp=安全管理配置字符串"));
hostConfig.setBinds(new Bind(userCodeParentPath, new Volume("/app")));
网络资源
禁止网络资源
创建容器的时候 设置容器的网络状态为关闭
CreateContainerResponse createContainerResponse = containerCmd
.withHostConfig(hostConfig)
.withNetworkDisabled(true)
.withReadonlyRootfs(true)
.withAttachStdin(true)
.withAttachStderr(true)
.withAttachStdout(true)
.withTty(true)
.exec();
权限管理
docker容器已经做了系统层面的隔离
比较安全
但是不能保证绝对安全
1.可以结合java安全管理器去使用
2.限制用户不能向root根目录写文件
CreateContainerResponse createContainerResponse = containerCmd
.withHostConfig(hostConfig)
.withNetworkDisabled(true)
.withReadonlyRootfs(true)
.withAttachStdin(true)
.withAttachStderr(true)
.withAttachStdout(true)
.withTty(true)
.exec();
3.Linux自带的一些安全管理措施
seccomp
linux内核自带的一些安全管理措施
Seccomp(安全计算模式)是 Linux 的一种安全特性,用于限制进程可以调用的系统调用。通过配置 seccomp,可以提高容器的安全性,防止恶意代码利用不必要的系统调用。配置通常通过以下方式实现:
-
Profile: 使用 seccomp profiles 定义允许和拒绝的系统调用。
-
Docker: 在 Docker 中,可以使用
--security-opt seccomp=path/to/profile.json
来指定 seccomp 配置文件。 -
默认配置: Docker 提供了一个默认的 seccomp 配置,限制了许多危险的系统调用。
我们可以在hostConfig里去开启
// 创建容器
CreateContainerCmd containerCmd = dockerClient.createContainerCmd(image);
HostConfig hostConfig = new HostConfig();
hostConfig.withMemory(100 * 1000 * 1000L);
hostConfig.withMemorySwap(0L);
hostConfig.withCpuCount(1L);
hostConfig.withSecurityOpts(Arrays.asList("seccomp=安全管理配置字符串"));
hostConfig.setBinds(new Bind(userCodeParentPath, new Volume("/app")));
CreateContainerResponse createContainerResponse = containerCmd
.withHostConfig(hostConfig)
.withNetworkDisabled(true)
.withReadonlyRootfs(true)
.withAttachStdin(true)
.withAttachStderr(true)
.withAttachStdout(true)
.withTty(true)
.exec();
System.out.println(createContainerResponse);
String containerId = createContainerResponse.getId();