1、k8s安全配置 - 网络策略
官方文档:https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/
测试案例:
kubectl run network-pod1 --image=busybox:1.28 -n network-test -- sleep 24h
kubectl run network-pod2 --image=busybox:1.28 -n network-test -- sleep 24h
kubectl run network-pod --image=busybox:1.28 -n network-test1 -- sleep 24h
kubectl run nginx1 --image=nginx -n network-test
kubectl run test1 --image=busybox:1.28 -- sleep 24h
kubectl run test2 --image=busybox:1.28 -- sleep 24h
案例1:拒绝命名空间下所有Pod出入站流量
拒绝network-test名称空间下的所有pod的出、入站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-test-deny
namespace: network-test
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
- pod完全孤立
案例2:拒绝其他命名空间Pod访问
network-test命名空间下所有pod可以互相访问,也可以访问其他 命名空间Pod,但其他命名空间不能访问test命名空间Pod。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-test-deny
namespace: network-test
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {}
案例3:允许其他命名空间Pod访问指定应用
允许其他命名空间访问network-test命名空间指定Pod(带有run=network-pod1标签的Pod)
- 无法添加策略(比较复杂)
案例4:同一个命名空间下应用之间限制访问
将network-test命名空间中标签为run=nginx1的pod隔离, 只允许标签为run=test1的pod访问80端口
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-test-deny
namespace: network-test
spec:
podSelector:
matchLabels:
run: nginx1
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
run: test1
ports:
- protocol: TCP
port: 80
- 该策略是,只允许同一名称空间的带有run=test1标签的pod访问(测试时需要添加pod)
案例5:只允许指定命名空间中的应用访问
允许指定名称空间(ns=network-test2)的所有pod以及其他名称空间中带有指定标签(run=test1)的pod访问network-test名称空间中带有run=nginx1的Pod
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-test-deny
namespace: network-test
spec:
podSelector:
matchLabels:
run: nginx1
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
ns: network-test2
- from:
- namespaceSelector: {}
podSelector:
matchLabels:
run: test1
2、k8s集群强化讲义
案例1:对用户授权访问K8s(TLS证书)
- 用户组:用户组的好处是无需单独为某个用户创建权限,统一为这个组名进 行授权,所有的用户都以组的身份访问资源
为dev用户组统一授权
1、将certs.sh文件中的aliang-csr.json下的O字段改为dev,并重新生成证书和kubeconfig文件
2、将dev用户组绑定Role(pod-reader)
3、测试,只要O字段都是dev,这些用户持有的kubeconfig文件都拥有相同的权限
案例2:对应用程序授权访问K8s(ServiceAccount)
先了解下ServiceAccount,简称SA,是一种用于让程序访问K8s API的服务账号。
• 当创建naamespace时,会自动创建一个名为default的SA,这个SA没有绑定任何权限
• 当default SA创建时,会自动创建一个default-token-xxx的secret,并自动关联到SA
• 当创建Pod时,如果没有指定SA,会自动为pod以volume方式挂载这个default SA,在容器目录:/var/run/secrets/kubernetes.io/serviceaccount
验证默认SA权限:kubectl —as=system:serviceaccount:default:default get pods
kubectl —as=system:serviceaccount:命名空间:sa名称 get pods
授权容器中Python程序对K8s API访问权限
创建Role
创建ServiceAccount
将ServiceAccount与Role绑定
为Pod指定自定义的SA
进入容器里执行Python程序测试操作K8s API权限
3、k8s容器运行环境安全加固
案例:容器文件系统访问限制
步骤:
1、将自定义策略配置文件保存到/etc/apparmor.d/
2、加载配置文件到内核:apparmor_parser
3、Pod注解指定策略配置名
工作流程:
4、最小化微服务漏洞
案例1:设置容器以普通用户运行
背景:容器中的应用程序默认以root账号运行的,这个root与宿主机root账号是相同的,拥有大部分对Linux内核的系统调用权限,这样是不安全的,所以我们应该将容器以普通用户运行,减少应用程序对权限的使用。
可以通过两种方法设置普通用户:
- Dockerfile里使用USER指定运行用户
- K8s里指定spec.securityContext.runAsUser,指定容器默认用户UID
cat security-context.yaml
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
containers:
- name: web
image: lizhenliang/flask-demo:root
securityContext:
allowPrivilegeEscalation: false
案例2:容器使用特权
背景:容器中有些应用程序可能需要访问宿主机设备、修改内核等需求,在默认情况下,容器没这个有这个能力,因此这时会考虑给容器设置特权模式。
启用特权模式:
启用特权模式就意味着,你要为容器提供了访问Linux内核的所有能力,这是很危险的,为了减少系统调用的供给,可以使用Capabilities为容器赋予仅所需的能力。
cat privileged-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: privileged-pod
spec:
containers:
- name: web
image: nginx
securityContext:
privileged: true
6、监控、审计和运行时安全
- 验证:tail -f /var/log/messages(告警通知默认输出到标准输出和系统日志)
1、监控系统二进制文件目录读写(默认规则)
vi /etc/falco/falco_rules.yaml
# File categories
- macro: bin_dir
condition: fd.directory in (/bin, /sbin, /usr/bin, /usr/sbin)
- macro: bin_dir_mkdir
condition: >
(evt.arg.path startswith /bin/ or
evt.arg.path startswith /sbin/ or
evt.arg.path startswith /usr/bin/ or
evt.arg.path startswith /usr/sbin/)
2、监控根目录或者/root目录写入文件(默认规则)
vi /etc/falco/falco_rules.yaml
# This detects writes immediately below / or any write anywhere below /root
- macro: root_dir
condition: (fd.directory=/ or fd.name startswith /root/)
3、监控运行交互式Shell的容器(默认规则)
vi /etc/falco/falco_rules.yaml
4、监控容器创建的不可信任进程(自定义规则)
vi /etc/falco/falco_rules.yaml
# 监控容器创建的不可信任进程规则,在falco_rules.local.yaml文件添加:
- rule: Unauthorized process on nginx containers
condition: spawned_process and container and container.image startswith nginx and not proc.name in (nginx)
desc: test
output: "Unauthorized process on nginx containers (user=%user.name container_name=%container.name container_id=%container.id image=%container.image.repository shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline terminal=%proc.tty)"
priority: WARNING