当前位置:网站首页>安全保障基于软件全生命周期-PSP应用
安全保障基于软件全生命周期-PSP应用
2022-07-28 12:49:00 【taoli-qiao】
安全保障是基于软件全生命周期的,即贯穿了开发-分发-不熟-运行所有环节。在各个环节都可以进行一些安全活动保证系统安全。例如在代码开发环节从需求阶段即可加入安全的需求分析以及对应的保证策略,在代码提交前进行静态代码安全扫描、依赖扫描、IAC扫描等保证提交的代码安全。

在分发环节,image需要push到代码仓库上进行存储,那么对于代码仓库可以进行安全隔离,提交的image进行安全扫描,对镜像进行签名以及签名验证等保障push到registry的image是安全的。

在运行环节,也可遵循一些安全保障优秀实践,例如
- 只有经过批准的进程能在容器命名空间内运行
- 禁止并报告未经授权的资源访问
- 监控网络流量以检测恶意活动
- 服务网格是另外一种常见的服务层抽象,它为已经编排的服务提供了整合和补充功能,而不会改变工作负载软件本身(如API流量的日志记录,传输加密,可观测性标记、认证和授权等)
分层对运行的应用实施安全保证,具体的措施如Network Policy,Pod Security,Container Security,Pod security Policy等等。

上面介绍了一些通用概念,接着将通过实际例子演示上面提到的一些具体安全保障措施如何保障运行时安全的。
第一:以Non-root身份运行容器
在DockerFile中通过User命令切换成非root用户,通过groupadd,useradd添加用户,通过USER username来制定后面的命令用非root用户来运行。
FROM python:3.9.5-slim
RUN pip install flask && \
groupadd -r flask && useradd -r -g flask flask && \
mkdir /src && \
chown -R flask:flask /src
USER flask
COPY app.py /src/app.py
WORKDIR /src
ENV FLASK_APP=app.py
EXPOSE 5000
CMD ["flask", "run", "-h", "0.0.0.0"]例如下面的实际例子,在Dockerfile中定义非root用户执行ENTRYPOINT命令
FROM ubuntu
ENV MY_SERVICE_PORT=80
ENV MY_SERVICE_PORT1=80
ENV MY_SERVICE_PORT2=80
ENV MY_SERVICE_PORT3=80
LABEL multi.label1="value1" multi.label2="value2" other="value3"
ADD bin/amd64/httpserver /httpserver
EXPOSE 8080
RUN useradd -m --uid 1000 web-admin && \
echo "web-admin ALL=NOPASSWD: ALL" >> /etc/sudoers
RUN chown web-admin /httpserver
USER web-admin
ENTRYPOINT ["/httpserver"]在部署文件中指定非root用户来运行容器。
apiVersion: apps/v1
kind: Deployment
metadata:
name: non-root-httpserver
spec:
replicas: 1
selector:
matchLabels:
app: httpserver
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "80"
labels:
app: httpserver
spec:
securityContext:
runAsUser: 1000
containers:
- name: httpserver
imagePullPolicy: Always
image: cncamp/httpserver:v1.0-nonroot
ports:
- containerPort: 80
serviceAccount: fake-user第二:集群间组件采用TLS加密进行安全通信,例如如果部署多个etcd的member,那么member之间访问可配置TLS加密,保证访问安全。

第三:添加NodeRestriction标签:准入控制器限制了kubelet可以修改Node和Pod对象,kubelet只可以修改自己的Node API对象,只能修改绑定到节点的Pod对象。可以对节点添加node-restriction.kubernetes.io前缀的标签,这样kubelet就不能删除节点了。
第四:Securtiy Policy:安全上下文描述了允许请求访问某个节点上的特定用户,获得特定权限访问主机网络等。Kubelets提供了三种配置的Security Context。
Container-level security context:仅应用到指定容器
Pod-leve security context:应用到Pod内所有的容器以及Volume
Pod Security Policies(PSP):应用到集群内部所有的Pod以及Volume
例如,查看被Istio注入的简单的toolbox的Pod的yaml文件,可以看到有securityContext的信息,drop all表示取消所有权限,1337进程号的User 来运行的容器。

再比如查看CoreDNS的pod的security context,有NET_BIND_SERVICE权限。

在看Calico pod的security context,因为要修改主机网络配置,权限比较大,privileged=true。

Pod Security Policies(PSP)是集群级的Pod安全策略,自动为集群内的Pod和Volume设置Security Context,Security Context设置的各字段和含义如下表所示

接下来通过实际例子演示如何通过PSP控制权限,PSP默认是不开启的,所以为了开启PSP,需要修改kube-apiserver.yaml中的配置信息,且因为开启后PSP就生效,所以提前通过Role/RoleBinding分配一个很大的权限,否则生效后很多操作都无法进行。启动前的PSP文件内容如下所示:这里的privileged=true,允许所有端口,所有Capalilities,任意用户运行。
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: privileged
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*'
spec:
privileged: true
allowPrivilegeEscalation: true
allowedCapabilities:
- '*'
volumes:
- '*'
hostNetwork: true
hostPorts:
- min: 0
max: 65535
hostIPC: true
hostPID: true
runAsUser:
rule: 'RunAsAny'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'
接着创建ClusterRole,这个Role的含义是:将名称为privileged的podsecuritypolicies use到这个role上,也就是role具备上面定义的PSP权限。然后通过RoleBinding将Role的权限赋值给kube-system namespace下面的所有serviceaccount和nodes对象。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: privileged-psp
rules:
- apiGroups:
- policy
resourceNames:
- privileged
resources:
- podsecuritypolicies
verbs:
- use
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kube-system-psp
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: privileged-psp
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:nodes
namespace: kube-system
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:serviceaccounts:kube-system接着执行命令kubectl apply让上面的对象生效,修改/etc/kubernetes/manifests/kube-apiserver.yaml,开启PSP(--enable-admission-plugins=PodSecurityPolicy),配置文件修改后,APIServer会自动重启让配置生效。

因为配置了很大的权限,此时用kubectl执行各项操作仍然正常,接着来创建一个serviceaccount,对比serviceaccount绑定PSP前后的结果来理解PSP工作工程。
kubectl create namespace psp-example
kubectl create serviceaccount -n psp-example fake-user
kubectl create rolebinding -n psp-example fake-editor --clusterrole=edit --serviceaccount=psp-example:fake-user
### create alias to simulate users
```
alias kubectl-admin='kubectl -n psp-example'
alias kubectl-user='kubectl --as=system:serviceaccount:psp-example:fake-user -n psp-example'
```定义个名叫example的PSP,通过kubectl apply命令让这个PSP生效。
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: example
spec:
privileged: false # Don't allow privileged pods!
# The rest fills in some required fields.
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
runAsUser:
rule: RunAsAny
fsGroup:
rule: RunAsAny
volumes:
- '*'接着用创建的serviceaccount去尝试创建一个pod
kubectl-user create -f- <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pause
spec:
containers:
- name: pause
image: k8s.gcr.io/pause
EOF会显示创建失败,查看该serviceaccount是否绑定了上面的PSP,结果是No。

接着创建Role和Rolebinding将PSP与serviceaccount进行绑定。
### create a role which use the psp
kubectl-admin create role psp:unprivileged \
--verb=use \
--resource=podsecuritypolicy \
--resource-name=example
### bind the role to user
```
kubectl-admin create rolebinding fake-user:psp:unprivileged \
--role=psp:unprivileged \
--serviceaccount=psp-example:fake-user
```接着再用上面的serviceaccount创建pod,可以看到创建pod成功。
通过上面的例子可以看到通过定义不同权限的PSP,再将PSP的权限分配给不同的serviceaccount,从而来保障集群内的安全。
除了上面介绍了PSP,实际给节点增加Taint也是一种安全防护措施。例如:为不同的租户的节点增加Taint,这样多租户情况下实现节点的相互隔离。
边栏推荐
- POJ1860货币兑换题解
- Countdown 2 days! 2022 China Computing Conference: Mobile cloud invites you to meet with computing network for innovative development
- 记一次使用pdfbox解析pdf,获取pdf的关键数据的工具使用
- P1797重型运输 题解
- DDoS protection with iptables
- 性能超群!牛津&上海AI Lab&港大&商汤&清华强强联手,提出用于引用图像分割的语言感知视觉Transformer!代码已开源...
- Product Manager: job responsibility table
- Is azvudine, a domestic oral new coronal drug, safe? Expert authority interpretation
- C language: merge sort
- 在 Kubernetes 中部署应用交付服务(第 1 部分)
猜你喜欢

The domestic API management tool eolink is very easy to use, creating an efficient research and development tool

Some thoughts on.Net desktop development

酷炫操作预热!代码实现小星球特效

Product Manager: job responsibility table

7. Dependency injection

Deploy application delivery services in kubernetes (Part 1)

SQL每日一练(牛客新题库)——第4天:高级操作符

Denial of service DDoS Attacks

How to check if the interface cannot be adjusted? I didn't expect that the old bird of the 10-year test was planted on this interview question

不用Swagger,那我用啥?
随机推荐
Rust from introduction to mastery 01 introduction
R语言检验样本比例:使用prop.test函数执行单样本比例检验计算总体中成功样本比例p值的置信区间(设置conf.level参数指定置信水平、置信区间的大小)
了解虚拟列表背后原理,轻松实现虚拟列表
JWT login authentication + token automatic renewal scheme, well written!
Continuous (integration -- & gt; delivery -- & gt; deployment)
Analyzing the principle of DNS resolution in kubernetes cluster
Dojp1520 gate jumping problem solution
Dojnoip201708 cheese solution
[dark horse morning post] byte valuation has shrunk to $270billion; "Second uncle" video author responded to plagiarism; Renzeping said that the abolition of the pre-sale system of commercial housing
What if the server cannot be connected (the original server cannot find the target resource)
DOJNOIP201708奶酪题解
Strict mode -- let and const -- arrow function -- Deconstruction assignment -- string template symbol -- set and map -- generator function
朋友发来几个面试题
7.依赖注入
P1797 heavy transportation problem solution
Countdown 2 days! 2022 China Computing Conference: Mobile cloud invites you to meet with computing network for innovative development
Better and more modern terminal tools than xshell!
【C语言】结构体指针与结构体变量作形参的区别
Lyscript get previous and next instructions
R语言使用dpois函数生成泊松分布密度数据、使用plot函数可视化泊松分布密度数据(Poisson distribution)