安全加固
加固须知
本文中列出的安全加固措施为基本的加固建议项。用户应根据自身业务,重新审视整个系统的网络安全加固措施,必要时可参考业界优秀加固方案和安全专家的建议。
操作系统安全加固
防火墙配置
操作系统安装后,若配置普通用户,可以通过在“/etc/login.defs”文件中新增ALWAYS_SET_PATH字段并设置为yes,防止越权操作。
设置umask
建议用户将宿主机和容器中的umask设置为027及以上,提高文件权限。
以设置umask为027为例,具体操作如下所示。
-
以root用户登录服务器,编辑“/etc/profile”文件。
vim /etc/profile -
在“/etc/profile”文件末尾加上umask 027,保存并退出。
-
执行如下命令使配置生效。
source /etc/profile
无属主文件安全加固
因为官方Docker镜像与物理机上的操作系统存在差异,系统中的用户可能不能一一对应,导致物理机或容器运行过程中产生的文件变成无属主文件。
用户可以执行find / -nouser -o -nogroup命令,查找容器内或物理机上的无属主文件。根据文件的UID和GID创建相应的用户和用户组,或者修改已有用户的UID、用户组的GID来适配,赋予文件属主,避免无属主文件给系统带来安全隐患。
端口扫描
需要关注全网侦听的端口和非必要端口,如有非必要端口请及时关闭。建议用户关闭不安全的服务,如Telnet、FTP等。具体关闭方法请参考所使用的操作系统相关文档。
防DoS攻击
用户可以按IP限制与服务器的连接的速率对系统进行防DoS攻击,方法包括但不限于利用Linux系统自带Iptables防火墙进行预防、优化sysctl参数等。具体使用方法,用户可自行查阅相关资料。
合理配置sudo选项
-
将sudo命令中targetpw选项设置为默认要求输入目标用户的密码;防止增加sudo规则后,所有用户不需要输入root密码,就可以提权root账号执行系统命令,导致普通用户越权执行命令。该选项默认不添加,建议添加该选项。
执行cat /etc/sudoers | grep -E "^[^#]*Defaults[[:space:]]+targetpw"命令检查是否存在“Defaults targetpw”或“Defaults rootpw”配置项。如果不存在,请在“/etc/sudoers”文件的“#Defaults specification”下添加“Defaults targetpw”或者“Defaults rootpw”配置项。
-
禁止普通用户或组通过所有命令提权到root用户。
执行cat /etc/sudoers命令检查“/etc/sudoers”文件中是否存在“root ALL=(ALL:ALL) ALL”和“root ALL=(ALL) ALL”之外的其他用户或组的(ALL) ALL和(ALL:ALL) ALL。如果存在,请根据实际业务场景确认是否需要,如果确认不需要,请删除。例如user ALL=(ALL) ALL、%admin ALL=(ALL) ALL或%sudo ALL=(ALL:ALL) ALL。
增强抵抗漏洞攻击的能力
使用Linux自带的ASLR(Address Space Layout Randomization)功能,增强漏洞攻击防护能力。
在“/proc/sys/kernel/randomize_va_space”文件中写入2。
对Docker进行安全加固
启用对Docker的审计功能
-
Docker守护进程在主机里是以root权限运行的,权限很大。建议用户在主机上配置一种对Docker守护进程运行和使用状态的审计机制。一旦Docker守护进程出现越权攻击行为,可以追溯攻击事件根源。开启审计功能请参见开启对Docker的审计功能。
-
以下目录存放着跟容器相关的重要信息,建议对如下目录和关键文件配置审计功能。
- /usr/bin/dockerd
- /var/lib/docker
- /etc/docker
- /etc/default/docker
- /etc/sysconfig/docker
- /etc/docker/daemon.json
- /usr/bin/docker-containerd
- /usr/bin/containerd
- /usr/bin/docker-runc
- docker.service
- docker.socket
以上目录为Docker默认的安装目录,如果为Docker创建了单独的分区,路径可能会变。开启审计功能请参见开启对Docker的审计功能。
开启审计功能,系统会收集日志等相关信息。默认情况下主机没有开启审计功能,可以通过以下方式添加审计规则。
Note
开启审计机制需要安装auditd软件,如Ubuntu可使用apt install -y auditd命令进行安装。
-
在文件“/etc/audit/audit.rules”中添加规则,每个规则为一行,规则的格式如下。
-w file_path -k docker表 1 参数说明
参数 说明 -w 筛选文件路径。 file_path 开启审计规则的文件路径,如: - file_path为/usr/bin/docker时,表示开启主机对Docker守护进程的审计。
- file_path为/etc/docker时,表示开启主机对Docker相关目录和关键文件审计。
-k 筛选字符串,用于按照规定的关键字筛选。 Note
如果“/etc/audit/audit.rules”文件中有“This file is automatically generated from /etc/audit/rules.d”,此时修改“/etc/audit/audit.rules”文件无效,需要修改“/etc/audit/rules.d/audit.rules”文件才能生效。如在Ubuntu系统中需要修改“/etc/audit/rules.d/audit.rules”文件。
-
配置完成后需要重启日志守护进程。
service auditd restart
设置Docker配置文件权限
-
TLS CA证书文件属主和属组设为root:root,权限设为400。
保护TLS CA证书文件(用参数--tlscacert指定CA证书文件的路径),防止其被篡改。证书文件用于指定的CA证书认证Docker服务器。因此,其属主和属组必须是root,权限必须为400,才能保证CA证书的完整性。
可以通过以下方式设置。
-
执行以下命令,将文件的属主和属组设为root。
chown root:root <path to TLS CA certificate file>Note
path to TLS CA certificate file路径一般为“/usr/local/share/ca-certificates”。
-
将文件权限设为400。
chmod 400 <path to TLS CA certificate file>
-
“/etc/docker/daemon.json”文件权限配置
-
“daemon.json”文件属主和属组设为root:root,文件权限设为600。
“daemon.json”文件包含更改Docker守护进程的敏感参数,是重要的全局配置文件,其属主和属组必须是root,且只对root可写,以保证文件的完整性,该文件并不是默认存在的。
-
如果“daemon.json”文件默认不存在,说明产品没有使用该文件进行配置,那么可以执行以下命令,在启动参数中将配置文件设置为空,不使用该文件作为默认配置文件,避免被攻击者恶意创建并修改配置。
docker --config-file="" -
如果产品环境存在“daemon.json”文件,说明已经使用了该文件进行配置操作,需要设置相应权限,防止被恶意修改。
-
执行以下命令,将文件的属主和属组设为root。
chown root:root /etc/docker/daemon.json -
执行以下命令,将文件权限设为600。
chmod 600 /etc/docker/daemon.json
-
-
表 1 Docker相关目录和文件权限控制
| 目录 | 文件属主 | 文件权限 |
|---|---|---|
| /etc/default/docker | root:root | 644或更严格 |
| /etc/sysconfig/docker | root:root | 644或更严格 |
| docker.service | root:root | 644 |
| docker.sock | root:docker | 660 |
| /etc/docker | root:root | 755或更严格 |
| docker.socket | root:root | 644或更严格 |
Note
文件或目录不存在时可忽略。
控制Docker容器的运行用户
使用Docker时,建议客户在运行容器时使用非root用户或root用户非特权容器的方式。
关闭容器中不安全的协议
为避免安全风险,建议用户使用安全协议,如SSHv2、TLS1.2、TLS1.3、IPsec、SFTP和SNMPv3等。若容器中使用了不安全协议,如Telnet、FTP、SSH v1.x、TFTP、SNMPv1、SNMPv2c、SSL2.0、SSL3.0和TLS1.0等,在不影响业务正常运行的情况下建议关闭或使用安全协议替代。
为Docker创建单独分区
Docker安装后默认目录是“/var/lib/docker”,用于存放Docker相关的文件,包括镜像、容器等。当该目录存储已满时,Docker和主机可能无法使用。因此,建议创建一个单独的分区(逻辑卷),用来存放Docker文件。
- 新安装的设备,创建一个单独的分区,用于挂载“/var/lib/docker”目录,请参见操作系统磁盘分区。
- 已完成安装的系统,请使用逻辑卷管理器(LVM)创建分区。
限制容器的文件句柄和fork进程数
为避免攻击者在容器内使用命令启动fork炸弹,造成拒绝服务,建议用户设置全局默认的ulimit,对创建的文件句柄、进程数进行限制。
-
打开配置文件。
- CentOS 7.6默认为“/usr/lib/systemd/system/docker.service”文件。
- Ubuntu 22.04默认为“/lib/systemd/system/docker.service”文件。
-
修改配置文件。
在配置文件中找到“/usr/bin/dockerd”所在行,并在该行后面增加nofile(创建的文件句柄)参数和nproc(进程)参数的限制。
修改示例如下,请根据实际情况设置对应的值。
... # the default is not to use systemd for cgroups because the delegate issues still # exists and systemd currently does not support the cgroup feature set required # for containers run by docker /usr/bin/dockerd --default-ulimit nofile=20480:40960 --default-ulimit nproc=1024:2048 ...其中--default-ulimit nproc=1024:2048表示限制进程数量为1024个,可以在进程中修改该值,但是不能超过2048,且第一个值要小于或等于第二个值。nofile配置含义同nproc。
容器镜像安全加固
- 建议在基础镜像中创建非root用户,并且以非root用户启动镜像、启动进程,同时仅授予用户必要的capability,避免高权限用户造成容器逃逸等安全风险。
- 合理控制镜像中文件的属主和权限,避免不必要的越权访问造成容器逃逸等安全风险。
- 及时修复基础镜像中的漏洞。
- 分发镜像时,建议开启Docker的Content Trust功能。
- 应避免在Dockerfile中使用ADD指令,使用ADD操作未知来源的文件,存在安全风险。
- 应避免在Dockerfile中存储敏感信息。
- 应避免单独使用update更新指令。
- 为容器增加健康检查机制,并核查健康检查指定的脚本或命令的合法性,需要确保脚本或命令不会导致业务或系统异常。
- 应避免在容器中包含SUID和SGID权限的文件和目录。
- 为容器设置系统资源的配额,避免容器占用过多的系统资源,导致资源耗尽。系统资源包括但不限于CPU、内存。
启用Live Restore功能
默认情况下,当Docker守护程序终止时,会关闭正在运行的容器。启用该功能后,守护程序不可用时容器会继续运行。具体配置请参考Docker官方资料。
限制容器间不受控的互相网络通信
同一主机上所有容器间默认不限制网络通信。因此,每个容器都可以读取同一主机上容器网络中的所有报文,这可能导致信息在无意中被泄露到其他容器。因此,建议对容器间的通信进行限制。
修改Docker的启动参数,增加“--icc=false”参数,关闭容器之间的通信,示例如下所示。
……
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd --userland-proxy=false --icc=false -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
……
禁用用户空间代理
建议修改Docker的启动参数,增加“--userland-proxy=false”参数,在启动时禁用用户空间代理,减小设备的攻击面。示例如下所示。
……
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd --userland-proxy=false --icc=false -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
……
容器安全加固
建议用户在生产环境中进行如下操作,加固镜像。
- 在基础镜像中创建非root用户,并且以非root用户启动镜像、启动进程,同时仅授予用户必要的capability,避免高权限用户造成容器逃逸等安全风险。
- 合理控制镜像中文件的属主和权限,避免不必要的越权访问造成容器逃逸等安全风险。
- 及时修复基础镜像中的漏洞。
- 分发镜像时,建议开启Docker的Content Trust功能。
seccomp配置可约束容器的系统调用,减少容器对系统的影响面,具体参见seccomp.md。
在Kubernetes的1.19以下的版本中,seccomp使用的是annotations[seccomp.security.alpha.kubernetes.io/pod]注解方式。在1.19及以上的版本,seccomp特性已经GA。1.19及以上版本推荐使用securityContext.seccompProfile进行配置,并且1.27版本开始注解方式不再生效,具体参见:Kubernetes Removals and Major Changes In v1.27。所以用户需要根据不同的Kubernetes版本与容器安全需求,自行修改seccomp配置。
需要修改启动配置文件的MindCluster组件中已经提供了两种不同的配置方式。以下是Resilience Controller的seccomp配置,其他组件都预留了相关的配置。
Note
- 除Elastic Agent、TaskD组件外,所有MindCluster组件都需修改启动配置文件。
- 各组件配置文件的说明请参见表1。
metadata:
labels:
app: resilience-controller
##### For Kubernetes versions lower than 1.19, seccomp is used with annotations.
annotations:
seccomp.security.alpha.kubernetes.io/pod: runtime/default
spec:
##### For Kubernetes versions 1.19 and above, seccomp is used with securityContext.
# securityContext:
# seccompProfile:
# type: RuntimeDefault
...
Kubernetes安全加固
Kubernetes需要进行如下加固:
-
kube-apiserver加强:
-
修改启动参数“--profiling”的值设置为“false”,防止用户动态修改kube-apiserver日志级别。
-
修改或增加启动参数“--tls-cipher-suites”,设置它的值如下,避免使用不安全的TLS加密套件带来风险。
--tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 -
修改或增加启动参数“--audit-policy-file”,配置K8s的审计策略,具体配置可参考Kubernetes官方文档。
-
-
kubelet加强:
-
为防止单Pod占用过多进程数,可以开启SupportPodPidsLimit,并设置--pod-max-pids。在kubelet配置文件的KUBELET_KUBEADM_ARGS项增加--feature-gates=SupportPodPidsLimit=true --pod-max-pids=<max pid number>,配置修改后,重启生效。具体可参考Kubernetes官方文档。
-
修改或增加启动参数“--tls-cipher-suites”,设置它的值如下,避免使用不安全的TLS加密套件带来风险。
--tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384Note
K8s v1.19及以上版本支持TLS v1.3的加密套件,建议使用高版本的K8s时,加上TLS v1.3的加密套件。
-
-
若K8s集群使用的OS kernel内核版本大于或等于4.6,安装完K8s后手动开启AppArmor或者SELinux。
-
其余安全加固内容可参考Kubernetes官方文档Security相关内容,也可以参考业界其他优秀加固方案。
-
请在K8s中为上层业务平台配置合适的权限,如限制账号可访问的API组等,避免上层业务操作不必要的K8s资源,详细可参考官方文档。
ClusterD安全加固
ClusterD运行后,会启动gRPC服务端侦听训练容器内gRPC客户端的消息,完成断点续训特性。ClusterD默认情况下会使用非安全的gRPC通信方式,用户可采用TLS/SSL加密方式通信,防止通信过程被攻击。
下面将以ClusterD和NodeD的双向认证为例,介绍ClusterD安全加固的详细步骤。在本示例中,ClusterD为服务端,NodeD为客户端。
在进行双向认证前,用户需准备好以下证书文件。
- rootCA.crt
- client.crt
- client.key
- server.crt
- server.key
-
拉取nginx镜像。
docker pull nginx -
在路径A下创建文件夹cert,将前提条件中的证书文件rootCA.crt、server.crt、server.key放入cert文件夹下。
-
在路径A下新建一个文件夹conf,在该文件夹下新建一个名为nginx.conf的文件,并将以下内容写入文件中:
worker_processes 1; worker_cpu_affinity 0001; worker_rlimit_nofile 4096; events { worker_connections 4096; } http { port_in_redirect off; server_tokens off; autoindex off; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log info; limit_req_zone global zone=req_zone:100m rate=20r/s; limit_conn_zone global zone=north_conn_zone:100m; server { listen <ClusterD的pod IP>:9500 ssl; # ClusterD的Pod IP地址,端口与ClusterD配置文件中的端口保持一致,如为IPv6地址,则配置为[<ClusterD的pod IP>]:9500 ssl; http2 on; proxy_ssl_session_reuse off; add_header Referrer-Policy "no-referrer"; add_header X-XSS-Protection "1; mode=block"; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; add_header Strict-Transport-Security " max-age=31536000; includeSubDomains "; add_header Content-Security-Policy "default-src 'self'"; add_header Cache-control "no-cache, no-store, must-revalidate"; add_header Pragma no-cache; add_header Expires 0; ssl_session_tickets off; ssl_certificate /etc/nginx/conf.d/cert/server.crt; # 服务端证书路径(权限400) ssl_certificate_key /etc/nginx/conf.d/cert/server.key; # 服务端私钥路径,私钥不能明文配置(权限400) ssl_client_certificate /etc/nginx/conf.d/cert/rootCA.crt; ssl_verify_client on; ssl_verify_depth 2; send_timeout 60; limit_req zone=req_zone burst=20 nodelay; limit_conn north_conn_zone 20; keepalive_timeout 60; proxy_read_timeout 900; proxy_connect_timeout 60; proxy_send_timeout 60; client_header_timeout 60; client_body_timeout 10; client_header_buffer_size 2k; large_client_header_buffers 4 8k; client_body_buffer_size 16K; client_max_body_size 20m; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"; ssl_session_timeout 10s; ssl_session_cache shared:SSL:10m; location / { grpc_pass grpc://<ClusterD的pod IP>:8899; # ClusterD的Pod IP地址。如果ClusterD启动参数useProxy开启,此处IP地址为127.0.0.1。如为IPv6地址,则配置为grpc://[<ClusterD的pod IP>]:8899; } } } -
在ClusterD启动YAML文件中修改或新增以下加粗字段。
# ClusterD启动命令中配置-useProxy=true,开启本地代理 args: [ "/usr/local/bin/clusterd -logFile=/var/log/mindx-dl/clusterd/clusterd.log -logLevel=0 -useProxy=true" ] # Deployment中的containers项增加 - name: nginx image: nginx:latest imagePullPolicy: Never command: [ "/bin/bash", "-c", "--"] args: [ "sleep infinity" ] volumeMounts: - name: nginx-cert mountPath: /etc/nginx/conf.d/cert - name: nginx-conf mountPath: /etc/nginx/conf # Deployment中的volumes项增加 - name: nginx-cert hostPath: path: /{路径A}/cert # x509证书、私钥目录路径,请将路径A替换成步骤2中的文件路径 - name: nginx-conf hostPath: path: /{路径A}/config # nginx启动配置文件,请将路径A替换成步骤2中的文件路径 # Service中的ports项改为如下 - protocol: TCP port: 8899 targetPort: 9500 -
执行以下命令启动ClusterD服务。
kubectl apply -f clusterd-v{version}.yaml -
执行以下命令查看ClusterD的Pod IP,将查询到的Pod IP写入步骤3的nginx.conf文件中。
kubectl get pod -A -o wide | grep clusterd -
启动nginx。
## 进入nginx容器 kubectl exec -it -n mindx-dl clusterd-{xxx} -c nginx bash #请将{xxx}替换为ClusterD的Pod启动以后K8s随机生成的Pod ID ## 执行以下命令启动nginx,并根据提示输入密钥口令 nginx -c /etc/nginx/conf/nginx.conf -
启动NodeD服务。
-
在路径B中创建文件夹cert,将前提条件中的证书文件rootCA.crt、client.crt、client.key放入cert文件夹下。
-
在路径B下新建一个文件夹conf,在该文件夹下新建一个名为nginx.conf的文件,并将以下内容写入文件中:
worker_processes 1; worker_cpu_affinity 0001; worker_rlimit_nofile 4096; events { worker_connections 4096; } http { port_in_redirect off; server_tokens off; autoindex off; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; grpc_buffer_size 16M; limit_req_zone global zone=req_zone:100m rate=20r/s; limit_conn_zone global zone=north_conn_zone:100m; server { listen 127.0.0.1:8899; http2 on; ssl_session_tickets off; limit_req zone=req_zone burst=20 nodelay; limit_conn north_conn_zone 20; keepalive_timeout 60; proxy_read_timeout 900; proxy_connect_timeout 60; proxy_send_timeout 60; client_header_timeout 60; client_body_timeout 10; client_header_buffer_size 200k; large_client_header_buffers 4 800k; client_body_buffer_size 160K; client_max_body_size 20m; location / { grpc_pass grpcs://<ClusterD的service IP>:9500; # ClusterD的service IP地址,service IP可通过以下命令进行查询:kubectl get svc -A | grep clusterd。如为IPv6地址,则配置为grpcs://[<ClusterD的service IP>]:9500; grpc_ssl_verify on; grpc_ssl_trusted_certificate /etc/nginx/conf.d/cert/rootCA.crt; grpc_ssl_verify_depth 2; grpc_ssl_certificate /etc/nginx/conf.d/cert/client.crt; grpc_ssl_certificate_key /etc/nginx/conf.d/cert/client.key; grpc_ssl_protocols TLSv1.2 TLSv1.3; grpc_ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"; grpc_ssl_name <服务证书中的SAN或CN>; # 服务证书的SAN或CN } } } -
在NodeD的启动YAML文件中新增以下加粗字段。
# 新增启动参数 sleep 150 args: [ "sleep 150; /usr/local/bin/noded -logFile=/var/log/mindx-dl/noded/noded.log -logLevel=0" ] # containers项增加 - name: nginx image: nginx:latest imagePullPolicy: Never command: [ "/bin/bash", "-c", "--"] args: [ "sleep infinity" ] volumeMounts: - name: nginx-cert mountPath: /etc/nginx/conf.d/cert - name: nginx-conf mountPath: /etc/nginx/conf # volumes项增加 - name: nginx-cert hostPath: path: /{路径B}/cert # x509证书、私钥目录路径 - name: nginx-conf hostPath: path: /{路径B}/config # nginx启动配置文件 -
执行以下命令启动NodeD。
kubectl apply -f noded-v{version}.yaml -
进入NodeD容器,新增域名解析规则。
## 进入noded容器 kubectl exec -it -n <noded pod ns> <noded pod name> bash ## 新增域名映射规则 echo 127.0.0.1 clusterd-grpc-svc.mindx-dl.svc.cluster.local >> /etc/hosts -
启动nginx。
## 进入nginx容器 kubectl exec -it -n mindx-dl noded-{xxx} -c nginx bash # {xxx}表示NodeD的Pod启动以后K8s随机生成的Pod id ## 启动nginx nginx -c /etc/nginx/conf/nginx.conf
-
TaskD安全加固
TaskD运行后,会启动gRPC客户端与ClusterD进行gRPC通信,同时TaskD内部组件(Manager、Proxy、Agent、Worker)之间也存在gRPC通信。TaskD默认情况下会使用非安全的gRPC通信方式,用户可采用TLS/SSL加密方式通信,防止通信过程被攻击。
下面将以nginx为例,指导用户通过本地网络代理对TaskD跨节点的通信进行加密认证。
在进行双向认证前,用户需准备好以下证书文件。
- rootCA.crt
- client.crt
- client.key
- server.crt
- server.key
-
拉取nginx镜像。
docker pull nginx -
将前提条件中的全部证书文件放入路径A下。
-
准备master Pod的nginx代理配置文件。在路径A下新建一个文件夹conf,在该文件夹下新建一个名为master_nginx.conf的文件,并将以下内容写入文件中:
worker_processes 1; worker_cpu_affinity 0001; worker_rlimit_nofile 4096; events { worker_connections 4096; } http { access_log /etc/nginx/access.log; error_log /etc/nginx/error.log; server { listen 127.0.0.1:8899; http2 on; location / { grpc_pass grpcs://{ClusterD的Pod IP}:9500; # 如为IPv6地址,则配置为grpcs://[{ClusterD的Pod IP}]:9500; grpc_ssl_verify on; grpc_ssl_trusted_certificate /etc/nginx/rootCA.crt; grpc_ssl_certificate /etc/nginx/client.crt; grpc_ssl_certificate_key /etc/nginx/client.key; grpc_ssl_verify_depth 2; grpc_ssl_protocols TLSv1.2 TLSv1.3; grpc_ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"; grpc_ssl_name {服务证书中的SAN或CN}; } } # 单Pod任务无需配置如下server server { listen {master Pod的IP}:9601 ssl; # 如为IPv6地址,则配置为[{master Pod的IP}]:9601 ssl; proxy_ssl_session_reuse off; http2 on; ssl_certificate /etc/nginx/server.crt; # 服务端证书路径(权限400) ssl_certificate_key /etc/nginx/server.key; # 服务端私钥路径,私钥不能明文配置(权限400) ssl_client_certificate /etc/nginx/rootCA.crt; # 根证书路径 ssl_verify_client on; ssl_verify_depth 2; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"; location / { grpc_pass grpc://127.0.0.1:9601; } } } -
单Pod任务请跳过本步骤。准备worker Pod的nginx代理配置文件。在路径A下新建一个文件夹conf,在该文件夹下新建一个名为worker_nginx.conf的文件,并将以下内容写入文件中。
worker_processes 1; worker_cpu_affinity 0001; worker_rlimit_nofile 4096; events { worker_connections 4096; } http { access_log /etc/nginx/access.log; error_log /etc/nginx/error.log; server { listen 127.0.0.1:9601; http2 on; location / { grpc_pass grpcs://{master svc ip}:9601; # svc ip地址可通过kubectl get svc -A |grep {jobname}命令进行查询, 如为IPv6地址,则配置为grpcs://[{master svc ip}]:9601; grpc_ssl_verify on; grpc_ssl_trusted_certificate /etc/nginx/rootCA.crt; grpc_ssl_certificate /etc/nginx/client.crt; grpc_ssl_certificate_key /etc/nginx/client.key; grpc_ssl_verify_depth 2; grpc_ssl_protocols TLSv1.2 TLSv1.3; grpc_ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"; grpc_ssl_name DomainCA.com; } } } -
在任务YAML中注入使用本地代理的环境变量。
env: - name: TTP_PORT value: "8000" - name: LOCAL_PROXY_ENABLE value: "on" # 使用本地代理通信的开关 -
在任务Pod中新增如下字段。
# Deployment中的containers项增加 - name: nginx image: nginx:latest imagePullPolicy: Never command: [ "/bin/bash", "-c", "--"] args: [ "sleep infinity" ] volumeMounts: - name: nginx-conf mountPath: /etc/nginx # Deployment中的volumes项增加 - name: nginx-conf hostPath: path: /{路径A}/ # nginx启动配置文件和证书密钥文件所在路径,请将路径A替换成步骤2中的文件路径 -
进入任务Pod启动nginx,包括master pod nginx和worker pod nginx。单Pod任务请跳过本步骤。
## 进入nginx容器 kubectl exec -it -n {任务 namespace} {任务Pod name} -c nginx bash ## 执行以下命令启动nginx,并根据提示输入密钥口令 nginx -c /etc/nginx/conf/{master或worker}_nginx.conf
Elastic Agent安全加固
Note
Elastic Agent组件已经日落,相关资料将于2026年12月30日的版本删除。
Elastic Agent的安全加固请参见TaskD安全加固章节。
查看命令行操作记录
命令行操作日志记录在系统history中。
当安装、升级、卸载Container Manager,或者通过Container Manager查询容器恢复进度等时,会将history中的历史命令记录保存到“~/.bash_history”文件中。所以,可以直接查看.bash_history文件就能找到命令行的记录。
历史命令会先缓存在内存中,只有当终端正常退出时才会写入“~/.bash_history”文件。执行以下命令可立即将内存中的历史记录写入.bash_history文件:
history -a
在Linux系统中,history命令一般默认保存最新的1000条命令。如果需要修改保存的命令数量,比如只保留200条历史命令,则可以在“/etc/profile”文件中修改HISTSIZE环境变量。修改方法如下:
-
使用编辑器(如vim编辑器)修改。
-
使用sed直接修改,命令如下:
sed -i 's/^HISTSIZE=number/HISTSIZE=newNumber/' /etc/profile,number表示修改前的命令数量,newNumber表示修改后的命令数量。以保存的命令数量从1000改为200为例:
sed -i 's/^HISTSIZE=1000/HISTSIZE=200/' /etc/profile
修改完成之后需要执行source /etc/profile使环境变量生效。
如果需要在历史命令文件中有时间戳记录(搭配用户、IP 这些自定义信息),可以在“/etc/profile”中添加如下配置:
export HISTTIMEFORMAT="%F %T $USER_IP:`whoami` "
添加完成之后需要执行source /etc/profile命令使环境变量生效。添加时间戳之后,history命令结果如下所示:
2025-12-02 20:44:34 xxx.xxx.xxx.xxx:root systemctl start container-manager.service
2025-12-02 20:44:34 xxx.xxx.xxx.xxx:root systemctl restart container-manager.timer
2025-12-02 20:44:34 xxx.xxx.xxx.xxx:root systemctl restart container-manager.service
2025-12-02 20:44:34 xxx.xxx.xxx.xxx:root systemctl status container-manager.service
2025-12-02 20:44:34 xxx.xxx.xxx.xxx:root systemctl status container-manager.service
此外,如果需要将历史命令记录在自定义文件中,可以在“/etc/profile”中设置HISTFILE环境变量,设置完成之后执行source /etc/profile命令使环境变量生效。比如:
HISTDIR=~/log/container-manager # 配置历史命令记录保存文件
HISTFILE="$HISTDIR/container-manager.log"
mkdir -p $HISTDIR
chmod 750 $HISTDIR
touch $HISTFILE
chmod 640 $HISTFILE
USER_IP=`who -u am i 2>/dev/null| awk '{print $NF}'|sed -e 's/[()]//g'`
if [ -z $USER_IP ]
then
USER_IP=`hostname`
fi
export HISTTIMEFORMAT="%F %T $USER_IP:`whoami` " # history命令显示格式:时间、IP、用户名、执行命令
PROMPT_COMMAND=' { date "+%Y-%m-%d %T - $(history 1 | { read x cmd; echo "$cmd"; })"; } >> $HISTFILE' # 实时将history命令写到配置的文件里
其中日志文件路径为“~/log/container-manager”,请保证磁盘空间足够,日志文件设置权限为640。