《OpenShift / RHEL / DevSecOps 汇总目录》
说明:本文已经在 OpenShift 4.13 的环境中验证
说明:
- 本文需要集群中除了管理员外还有一个一般用户。另外除了特殊说明,默认都是用集群管理员进行操作。
- 在浏览器中如果需要重新登录,需要清楚浏览器的 Cookie。
部署测试应用
- 依次执行以下命令,创建应用资源。
$ oc new-project reverse-words
$ cat << EOF | oc apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: reverse-words
labels:
name: reverse-words
spec:
replicas: 1
selector:
matchLabels:
name: reverse-words
template:
metadata:
labels:
name: reverse-words
spec:
containers:
- name: reverse-words
image: quay.io/mavazque/reversewords:latest
imagePullPolicy: Always
ports:
- name: reverse-words
containerPort: 8080
protocol: TCP
EOF
$ cat << EOF | oc apply -f -
apiVersion: v1
kind: Service
metadata:
labels:
name: reverse-words
name: reverse-words
spec:
ports:
- name: app
port: 8080
protocol: TCP
targetPort: reverse-words
selector:
name: reverse-words
sessionAffinity: None
type: ClusterIP
EOF
$ oc create route edge reverse-words --service=reverse-words --port=app --insecure-policy=Redirect
- 访问应用,确认可以将字符串反转。
$ curl -k https://$(oc get route reverse-words -o jsonpath='{.spec.host}') -X POST -d '{"word": "ABCD"}'
{"reverse_word":"DCBA"}
只有认证用户才能访问
- 创建 OAuth Proxy 用来为登录会话 cookie 加密的 Secret。
$ oc create secret generic reversewords-proxy --from-literal=session_secret=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c43)
- 创建应用使用的 serviceaccount,并通过注释说明未登录时重定向 OAuth-Proxy 的登录 route。
$ oc create serviceaccount reversewords
$ oc annotate serviceaccount reversewords serviceaccounts.openshift.io/oauth-redirectreference.reversewords='{"kind":"OAuthRedirectReference","apiVersion":"v1","reference":{"kind":"Route","name":"reverse-words-authenticated"}}'
- 更新 Deployment 和 Service。注意:本文 OpenShift 版本 4.13,所以镜像使用的是 quay.io/openshift/origin-oauth-proxy:4.13
$ cat << EOF | oc replace -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: reverse-words
labels:
name: reverse-words
spec:
replicas: 1
selector:
matchLabels:
name: reverse-words
template:
metadata:
labels:
name: reverse-words
spec:
containers:
- name: reverse-words
image: quay.io/mavazque/reversewords:latest
imagePullPolicy: Always
ports:
- name: reverse-words
containerPort: 8080
protocol: TCP
- name: oauth-proxy
args:
- -provider=openshift
- -https-address=:8888
- -http-address=
- -email-domain=*
- -upstream=http://localhost:8080
- -tls-cert=/etc/tls/private/tls.crt
- -tls-key=/etc/tls/private/tls.key
- -cookie-secret-file=/etc/proxy/secrets/session_secret
- -openshift-service-account=reversewords
- -openshift-ca=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
- -skip-auth-regex=^/metrics
image: quay.io/openshift/origin-oauth-proxy:4.13
imagePullPolicy: IfNotPresent
ports:
- name: oauth-proxy
containerPort: 8888
protocol: TCP
volumeMounts:
- mountPath: /etc/tls/private
name: secret-reversewords-tls
- mountPath: /etc/proxy/secrets
name: secret-reversewords-proxy
serviceAccountName: reversewords
volumes:
- name: secret-reversewords-tls
secret:
defaultMode: 420
secretName: reversewords-tls
- name: secret-reversewords-proxy
secret:
defaultMode: 420
secretName: reversewords-proxy
EOF
$ cat << EOF | oc apply -f -
apiVersion: v1
kind: Service
metadata:
annotations:
service.alpha.openshift.io/serving-cert-secret-name: reversewords-tls
labels:
name: reverse-words
name: reverse-words
spec:
ports:
- name: proxy
port: 8888
protocol: TCP
targetPort: oauth-proxy
- name: app
port: 8080
protocol: TCP
targetPort: reverse-words
selector:
name: reverse-words
sessionAffinity: None
type: ClusterIP
EOF
- 创建需登录才能访问的 Route。
$ oc create route reencrypt reverse-words-authenticated --service=reverse-words --port=proxy --insecure-policy=Redirect
- 打开下图中下面的 Route 地址。
- 确认会转向登录跳转确认页面,在登录后即可访问到应用。
- 通过以下方式直接访问应用受保护的访问地址,会显示 403 错误。
$ curl -k -I https://$(oc get route reverse-words-authenticated -o jsonpath='{.spec.host}')
HTTP/1.1 403 Forbidden
set-cookie: _oauth_proxy=; Path=/; Domain=reverse-words-authenticated-reverse-words.apps-crc.testing; Expires=Tue, 08 Aug 2023 05:22:50 GMT; HttpOnly; Secure
date: Tue, 08 Aug 2023 06:22:50 GMT
content-type: text/html; charset=utf-8
set-cookie: 24c429aac95893475d1e8c1316adf60f=facc03c3f22d98ccfadcfddc67771fd9; path=/; HttpOnly; Secure; SameSite=None
- 通过以下方式直接访问应用受保护的访问地址,可以从返回结果看出实际是登录跳转确认页面。
$ curl -k -L https://$(oc get route reverse-words-authenticated -o jsonpath='{.spec.host}')
只有有权的用户才能访问
- 修改 Deployment,在 container 的参数区域增加以下 2 个参数。
- -openshift-service-account=reversewords
- -openshift-sar={"resource":"namespaces","resourceName":"reverse-words","namespace":"reverse-words","verb":"get"}
- 然后在访问应用的时候使用非管理员用户登录,可以看到以下 403 Permission Denied 提示页面。这是由于该应用以及所属项目是管理员创建的,所以一般用户无权访问。
$ oc s adm policy add-role-to-user view developer
使用 ServiceAccount 访问
$ cat << EOF | oc apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
# Without this role your oauth-proxy will output
# Failed to make webhook authenticator request: tokenreviews.authentication.k8s.io is forbidden:
# User "system:serviceaccount:reverse-words:reversewords" cannot create resource "tokenreviews" in API
# group "authentication.k8s.io" at the cluster scope
name: oauth-create-tokenreviews
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: reversewords
namespace: reverse-words
EOF
$ oc create serviceaccount robot-user
$ oc adm policy add-role-to-user view -z robot-user
- -openshift-sar={"resource":"namespaces","resourceName":"reverse-words","namespace":"reverse-words","verb":"get"}
- -openshift-delegate-urls={"/":{"resource":"pods","namespace":"reverse-words","verb":"get"}}
$ TOKEN=$(oc -n reverse-words create token robot-user)
$ curl -k -H "Authorization: Bearer ${TOKEN}" https://$(oc get route reverse-words-authenticated -o jsonpath='{.spec.host}')
Reverse Words Release: NotSet. App version: v0.0.25
参考
https://linuxera.org/oauth-proxy-secure-applications-openshift/