- 一.系統環境
- 二.前言
- 三.Open Policy Agent 簡介
- 四.Rego 語言簡介
- 五.配置基本環境
- 六.docker安裝OPA外掛
- 6.1 安裝docker
- 6.2 docker安裝OPA外掛
- 6.3 啟用OPA
- 七.OPA規則
- 7.1 允許docker所有操作
- 7.2 禁止docker所有操作
- 7.3 禁止建立允許所有系統呼叫的docker容器
- 7.4 根據Authz-User判斷使用者是否具有建立pod許可權
- 八.總結
一.系統環境
本文主要基於Docker version 20.10.16和Linux作業系統Ubuntu 18.04。
伺服器版本 | docker軟體版本 | CPU架構 |
---|---|---|
Ubuntu 18.04.5 LTS | Docker version 20.10.16 | x86_64 |
二.前言
在容器化技術中,Docker 已經成為廣泛使用的工具。然而,隨著容器數量的增加,確保容器之間的安全隔離變得越來越重要。Docker 提供了各種安全特性,但有時我們可能需要更細粒度的訪問控制策略。Open Policy Agent(OPA)是一個開源的通用策略引擎,可以與 Docker 整合,以實現更靈活的訪問控制。本文將介紹如何在 Docker 中使用 OPA 進行訪問控制。
三.Open Policy Agent 簡介
OPA 是一個開源的通用策略引擎,可以評估策略並做出決策。OPA 可以應用於各種場景,例如網路安全、訪問控制、資料保護等。在 Docker 環境中,OPA 可以用於評估容器之間的訪問請求,並根據預定義的策略做出決策,Open Policy Agent(OPA)的官網為:https://www.openpolicyagent.org/。
雖然 Docker 提供了各種安全特性,例如網路隔離、資源限制等,但有時我們可能需要更細粒度的訪問控制策略。例如,我們可能希望限制某些容器對特定資源的訪問,或根據容器的標籤和屬性來控制訪問許可權。這就是 OPA 發揮作用的地方。透過整合 OPA,我們可以實現更靈活、可擴充套件的訪問控制策略。
一般情況下,我們使用docker執行docker命令是沒有什麼限制的,安裝OPA外掛,並啟用OPA,建立了相關的OPA規則之後,使用docker執行docker命令,需要先訪問OPA規則,如果OPA規則表示你有許可權執行命令,則docker命令執行成功,否則執行失敗。
四.Rego 語言簡介
Rego 是一種用於編寫策略的語言,是 OPA 的核心組成部分。它是一種宣告性語言,可以描述複雜的資料結構和邏輯。Rego 語法簡潔,易於理解,使得編寫策略變得更加簡單。在本文中,我們將使用 Rego 語言編寫訪問控制策略。
五.配置基本環境
本次使用一臺新的Ubuntu機器(使用別的系統也行),下面給新機器配置基本環境。
檢視Ubuntu系統版本。
root@localhost:~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.5 LTS
Release: 18.04
Codename: bionic
首先設定主機名。
root@localhost:~# vim /etc/hostname
root@localhost:~# cat /etc/hostname
ubuntuk8sclient
配置節點靜態IP地址(可選)。如果您對Ubuntu系統不熟悉,請檢視部落格《centos系統和Ubuntu系統命令區別以及常見操作》。
root@localhost:~# vim /etc/netplan/01-netcfg.yaml
root@localhost:~# cat /etc/netplan/01-netcfg.yaml
network:
version: 2
renderer: networkd
ethernets:
ens32:
dhcp4: no
addresses: [192.168.110.139/24]
gateway4: 192.168.110.2
nameservers:
addresses: [192.168.110.2,114.114.114.114]
使網路卡配置生效。
root@localhost:~# netplan apply
測試機器是否可以訪問網路。
root@localhost:~# ping www.baidu.com
PING www.baidu.com (14.215.177.39) 56(84) bytes of data.
64 bytes from www.baidu.com (14.215.177.39): icmp_seq=1 ttl=128 time=54.3 ms
64 bytes from www.baidu.com (14.215.177.39): icmp_seq=2 ttl=128 time=44.6 ms
64 bytes from www.baidu.com (14.215.177.39): icmp_seq=3 ttl=128 time=41.3 ms
64 bytes from www.baidu.com (14.215.177.39): icmp_seq=4 ttl=128 time=37.0 ms
64 bytes from www.baidu.com (14.215.177.39): icmp_seq=5 ttl=128 time=43.7 ms
^C
--- www.baidu.com ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4007ms
rtt min/avg/max/mdev = 37.072/44.239/54.332/5.695 ms
檢視IP。
root@localhost:~# ifconfig
ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.110.139 netmask 255.255.255.0 broadcast 192.168.110.255
inet6 fe80::20c:29ff:fe97:b27b prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:97:b2:7b txqueuelen 1000 (Ethernet)
RX packets 20269 bytes 22473377 (22.4 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 7755 bytes 544420 (544.4 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 1650 bytes 119324 (119.3 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1650 bytes 119324 (119.3 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
配置IP和主機名對映。
root@localhost:~# vim /etc/hosts
root@localhost:~# cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 tom
192.168.110.139 ubuntuk8sclient
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
配置軟體源。
root@ubuntuk8sclient:~# vim /etc/apt/sources.list
#軟體源如下,最後三行是k8s源
root@ubuntuk8sclient:~# cat /etc/apt/sources.list
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu bionic stable
# deb-src [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu bionic stable
apt-key.gpg是k8s的deb源公鑰,載入k8s的deb源公鑰命令為:apt-key add apt-key.gpg。
下載並載入k8s的deb源公鑰命令為:curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - ; apt-get update,但是谷歌的網址訪問不了,我們直接去網上下載apt-key.gpg檔案。
root@ubuntuk8sclient:~# ls
apt-key.gpg
載入k8s的deb源公鑰。
root@ubuntuk8sclient:~# cat apt-key.gpg | apt-key add -
OK
更新軟體源。
root@ubuntuk8sclient:~# apt-get update
關閉防火牆。
root@ubuntuk8sclient:~# ufw disable
Firewall stopped and disabled on system startup
Linux swapoff命令用於關閉系統交換分割槽(swap area)。如果不關閉swap,就會在kubeadm初始化Kubernetes的時候報錯:“[ERROR Swap]: running with swap on is not supported. Please disable swap”。
root@ubuntuk8sclient:~# swapoff -a ;sed -i '/swap/d' /etc/fstab
root@ubuntuk8sclient:~# cat /etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>
/dev/mapper/tom--vg-root / ext4 errors=remount-ro 0 1
此時基本環境就配置完畢了。
六.docker安裝OPA外掛
6.1 安裝docker
安裝docker。
root@ubuntuk8sclient:~# apt-get install docker-ce -y
root@ubuntuk8sclient:~# which docker
/usr/bin/docker
檢視docker安裝包。
root@ubuntuk8sclient:~# dpkg -l | grep docker
ii docker-ce 5:20.10.16~3-0~ubuntu-bionic amd64 Docker: the open-source application container engine
ii docker-ce-cli 5:20.10.16~3-0~ubuntu-bionic amd64 Docker CLI: the open-source application container engine
ii docker-ce-rootless-extras 5:20.10.16~3-0~ubuntu-bionic amd64 Rootless support for Docker.
ii docker-scan-plugin 0.17.0~ubuntu-bionic amd64 Docker scan cli plugin.
設定docker開機自啟動並現在啟動docker。
root@ubuntuk8sclient:~# systemctl enable docker --now
Synchronizing state of docker.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable docker
檢視docker狀態。
root@ubuntuk8sclient:~# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2022-05-27 17:39:41 CST; 2min 27s ago
Docs: https://docs.docker.com
Main PID: 2574 (dockerd)
Tasks: 8
CGroup: /system.slice/docker.service
└─2574 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
May 27 17:39:37 ubuntuk8sclient dockerd[2574]: time="2022-05-27T17:39:37.223612352+08:00" level=info msg="ClientConn switching balancer to \"pick_first\"" module=grpc
May 27 17:39:37 ubuntuk8sclient dockerd[2574]: time="2022-05-27T17:39:37.512415652+08:00" level=warning msg="Your kernel does not support swap memory limit"
May 27 17:39:37 ubuntuk8sclient dockerd[2574]: time="2022-05-27T17:39:37.512456896+08:00" level=warning msg="Your kernel does not support CPU realtime scheduler"
May 27 17:39:37 ubuntuk8sclient dockerd[2574]: time="2022-05-27T17:39:37.512593678+08:00" level=info msg="Loading containers: start."
May 27 17:39:40 ubuntuk8sclient dockerd[2574]: time="2022-05-27T17:39:40.261550128+08:00" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used t
檢視docker版本。
root@ubuntuk8sclient:~# docker --version
Docker version 20.10.16, build aa7e414
配置docker阿里雲映象加速器。
root@ubuntuk8sclient:~# vim /etc/docker/daemon.json
root@ubuntuk8sclient:~# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://frz7i079.mirror.aliyuncs.com"]
}
重新載入配置檔案,重啟docker。
root@ubuntuk8sclient:~# systemctl daemon-reload ; systemctl restart docker
root@ubuntuk8sclient:~# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2022-05-27 17:45:41 CST; 5s ago
Docs: https://docs.docker.com
Main PID: 4330 (dockerd)
Tasks: 8
CGroup: /system.slice/docker.service
└─4330 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
下載一個nginx映象。
root@ubuntuk8sclient:~# docker pull nginx
root@ubuntuk8sclient:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 4 months ago 141MB
現在建立docker容器是沒有限制的,可以自由建立和刪除。關於docker容器的詳細操作,請檢視部落格《一文搞懂docker容器基礎:docker映象管理,docker容器管理》。
#使用nginx映象建立容器
root@ubuntuk8sclient:~# docker run -dit --name=nginxweb --restart=always nginx
16d5558fbe8d8956d61714326bea89e5a86424503c323dab03e729927f71fb5b
#檢視容器
root@ubuntuk8sclient:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
16d5558fbe8d nginx "/docker-entrypoint.…" 16 seconds ago Up 13 seconds 80/tcp nginxweb
#刪除容器
root@ubuntuk8sclient:~# docker rm -f nginxweb
nginxweb
root@ubuntuk8sclient:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6.2 docker安裝OPA外掛
在安裝OPA外掛之前,先介紹下docker外掛常用命令,Docker外掛是增強Docker引擎功能的程序外擴充套件。docker plugin命令用於管理外掛。
docker plugin create #從rootfs和配置建立一個外掛。外掛資料目錄必須包含config.json和rootfs目錄。
docker plugin disable #禁用外掛
docker plugin enable #啟用外掛
docker plugin inspect #顯示一個或多個外掛的詳細資訊
docker plugin install #安裝一個外掛
docker plugin ls #列出所有外掛
docker plugin push #將外掛推送到登錄檔
docker plugin rm #刪除一個或多個外掛
docker plugin set #更改外掛的設定
docker plugin upgrade #升級現有外掛
/etc/docker/policies用來存放opa規則。
root@ubuntuk8sclient:~# mkdir -p /etc/docker/policies
root@ubuntuk8sclient:~# ls /etc/docker/
daemon.json key.json policies
檢視docker外掛,現在沒有任何外掛。
root@ubuntuk8sclient:~# docker plugin list
ID NAME DESCRIPTION ENABLED
下載好的docker外掛會放在/var/lib/docker/plugins/目錄。
root@ubuntuk8sclient:~# ls /var/lib/docker/plugins/
storage tmp
安裝OPA外掛。
root@ubuntuk8sclient:~# docker plugin install openpolicyagent/opa-docker-authz-v2:0.8 opa-args="-policy-file /opa/policies/authz.rego"
Plugin "openpolicyagent/opa-docker-authz-v2:0.8" is requesting the following privileges:
- network: [host]
- mount: [/etc/docker]
Do you grant the above permissions? [y/N] y
0.8: Pulling from openpolicyagent/opa-docker-authz-v2
Digest: sha256:2fbbef244625e57f2beb7967a1b21c43ce5c7e6ec823fb1c35fe1b327ae3a1c4
cb581d64bd7f: Complete
Installed plugin openpolicyagent/opa-docker-authz-v2:0.8
現在OPA外掛就安裝好了。
root@ubuntuk8sclient:~# docker plugin list
ID NAME DESCRIPTION ENABLED
20b4566c59fc openpolicyagent/opa-docker-authz-v2:0.8 A policy-enabled authorization plugin for Do… true
docker OPA外掛安裝好之後,在/var/lib/docker/plugins/目錄下。
root@ubuntuk8sclient:~# ls /var/lib/docker/plugins/
20b4566c59fc71641bda21da72d75299405e9c5c8b4cc859f6ab636f4f19cc52 storage tmp
檢視OPA屬性。
注意:"-policy-file /opa/policies/authz.rego"裡的/opa不是作業系統裡的/opa目錄,而是/etc/docker/下的opa。
docker plugin inspect 20b4566c59fc顯示的Mounts選項可以看出,/etc/docker目錄掛載到/opa目錄了,所以訪問容器/opa目錄就相當於訪問宿主機/etc/docker目錄。
root@ubuntuk8sclient:~# docker plugin inspect 20b4566c59fc
[
{
"Config": {
......
#注意:"-policy-file /opa/policies/authz.rego"裡的/opa不是作業系統裡的/opa目錄,而是/etc/docker/下的opa,
#docker plugin inspect 20b4566c59fc顯示的Mounts選項可以看出,/etc/docker目錄掛載到/opa目錄了,所以訪問容器/opa目錄就相當於訪問宿主機/etc/docker目錄
"Mounts": [
{
"Description": "",
"Destination": "/opa",
"Name": "policy",
"Options": [
"bind",
"ro"
],
"Settable": [
"source"
],
"Source": "/etc/docker",
"Type": "none"
}
],
......
"Mounts": [
{
"Description": "",
"Destination": "/opa",
"Name": "policy",
"Options": [
"bind",
"ro"
],
"Settable": [
"source"
],
"Source": "/etc/docker",
"Type": "none"
}
]
}
}
]
6.3 啟用OPA
安裝OPA外掛之後需要啟用OPA,"authorization-plugins": ["openpolicyagent/opa-docker-authz-v2:0.8"]指定OPA外掛。
root@ubuntuk8sclient:~# cd /etc/docker/policies/
root@ubuntuk8sclient:/etc/docker/policies# vim /etc/docker/daemon.json
root@ubuntuk8sclient:/etc/docker/policies# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://frz7i079.mirror.aliyuncs.com"],
"authorization-plugins": ["openpolicyagent/opa-docker-authz-v2:0.8"]
}
重啟docker,這樣就啟用了OPA。
root@ubuntuk8sclient:/etc/docker/policies# systemctl daemon-reload ; systemctl restart docker
七.OPA規則
7.1 允許docker所有操作
下面開始編寫OPA規則,OPA規則使用rego語言編寫,allow := true 表示允許所有操作。
root@ubuntuk8sclient:/etc/docker/policies# vim authz.rego
root@ubuntuk8sclient:/etc/docker/policies# cat /etc/docker/policies/authz.rego
package docker.authz
allow := true
可以檢視映象及其所有操作。
root@ubuntuk8sclient:/etc/docker/policies# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 5 months ago 141MB
7.2 禁止docker所有操作
編輯OPA規則,allow := false表示禁止所有操作。
root@ubuntuk8sclient:/etc/docker/policies# vim /etc/docker/policies/authz.rego
root@ubuntuk8sclient:/etc/docker/policies# cat /etc/docker/policies/authz.rego
package docker.authz
allow := false
現在docker的所有操作都執行不了了。
root@ubuntuk8sclient:/etc/docker/policies# docker images
Error response from daemon: authorization denied by plugin openpolicyagent/opa-docker-authz-v2:0.8: request rejected by administrative policy
root@ubuntuk8sclient:/etc/docker/policies# docker ps
Error response from daemon: authorization denied by plugin openpolicyagent/opa-docker-authz-v2:0.8: request rejected by administrative policy
7.3 禁止建立允許所有系統呼叫的docker容器
OPA規則設定為允許所有docker請求。
root@ubuntuk8sclient:/etc/docker/policies# vim /etc/docker/policies/authz.rego
root@ubuntuk8sclient:/etc/docker/policies# cat /etc/docker/policies/authz.rego
package docker.authz
#allow := true允許所有docker請求
allow := true
使用nginx映象建立一個允許所有系統呼叫的容器,--security-opt seccomp:unconfined表示允許所有系統呼叫。關於系統呼叫的詳細操作,請檢視部落格《在kubernetes裡使用seccomp限制容器的系統呼叫》。
root@ubuntuk8sclient:/etc/docker/policies# docker run -dit --restart=always --name=nginxweb --security-opt seccomp:unconfined nginx
033a0e8e38c56a00400eeefe5424f55ca953e320e6d668831f4cdc580837294f
root@ubuntuk8sclient:/etc/docker/policies# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
033a0e8e38c5 nginx "/docker-entrypoint.…" 5 seconds ago Up 4 seconds 80/tcp nginxweb
檢視nginxweb的屬性,在docker inspect nginxweb的輸出中,可以看到HostConfig.SecurityOpt[seccomp:unconfined],建立docker指定的選項都可以在docker inspect裡看到。
root@ubuntuk8sclient:/etc/docker/policies# docker inspect nginxweb
[
{
......
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": [
"seccomp:unconfined"
],
"UTSMode": "",
......
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
}
}
]
刪除docker容器。
root@ubuntuk8sclient:/etc/docker/policies# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
033a0e8e38c5 nginx "/docker-entrypoint.…" 6 minutes ago Up 6 minutes 80/tcp nginxweb
root@ubuntuk8sclient:/etc/docker/policies# docker rm -f nginxweb
nginxweb
root@ubuntuk8sclient:/etc/docker/policies# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
修改OPA規則,現在OPA規則HostConfig.SecurityOpt[_] == "seccomp:unconfined"都deny了,所以docker指定--security-opt seccomp:unconfined選項時,就執行不了了。
root@ubuntuk8sclient:/etc/docker/policies# vim /etc/docker/policies/authz.rego
root@ubuntuk8sclient:/etc/docker/policies# cat /etc/docker/policies/authz.rego
package docker.authz
#預設拒絕
default allow = false
#allow這裡可以寫all,表示允許所有
#表示除了拒絕之外的那些都允許
allow {
not deny
}
#表示拒絕seccomp_unconfined
deny {
seccomp_unconfined
}
#seccomp_unconfined的詳細資訊
seccomp_unconfined {
# This expression asserts that the string on the right-hand side is equal
# to an element in the array SecurityOpt referenced on the left-hand side.
input.Body.HostConfig.SecurityOpt[_] == "seccomp:unconfined"
}
現在允許所有系統呼叫的docker容器就建立不了了,備註:--security-opt seccomp:unconfined 表示允許所有的系統呼叫。
root@ubuntuk8sclient:/etc/docker/policies# docker run -dit --restart=always --name=nginxweb --security-opt seccomp:unconfined nginx
docker: Error response from daemon: authorization denied by plugin openpolicyagent/opa-docker-authz-v2:0.8: request rejected by administrative policy.
See 'docker run --help'.
建立普通的容器就可以成功。
root@ubuntuk8sclient:/etc/docker/policies# docker run -dit --restart=always --name=nginxweb nginx
304948d90988bbba4b7c0503980c60dfd636f2dccd33e90f2158fc93b6c7c63c
root@ubuntuk8sclient:/etc/docker/policies# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
304948d90988 nginx "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 80/tcp nginxweb
root@ubuntuk8sclient:/etc/docker/policies# docker rm -f nginxweb
nginxweb
root@ubuntuk8sclient:/etc/docker/policies# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7.4 根據Authz-User判斷使用者是否具有建立pod許可權
使用harbor搭建一個映象倉庫,映象倉庫裡新建專案,可以設定是否允許匿名使用者pull映象,如果設定了不允許匿名使用者pull映象,則客戶端必須docker login登入才行,否則docker pull拉取不了映象,docker push的話必須登入,不能匿名使用者push映象到映象倉庫。關於harbor映象倉庫的詳細操作,請檢視部落格《搭建docker映象倉庫(二):使用harbor搭建本地映象倉庫》。
當我們使用docker login登入harbor之後,Docker 會將 token 儲存在 ~/.docker/config.json 檔案中,從而作為拉取私有映象的憑證。
root@ubuntuk8sclient:~# mkdir ~/.docker
root@ubuntuk8sclient:/etc/docker/policies# cat >~/.docker/config.json <<EOF
> {
> "HttpHeaders": {
> "Authz-User": "alice"
> }
> }
> EOF
config.json表示現在是alice登入拉取私有映象的。
root@ubuntuk8sclient:~# cat ~/.docker/config.json
{
"HttpHeaders": {
"Authz-User": "alice"
}
}
編輯OPA規則,如果使用者被授予讀寫許可權,則允許建立容器。
root@ubuntuk8sclient:~# vim /etc/docker/policies/authz.rego
root@ubuntuk8sclient:~# cat /etc/docker/policies/authz.rego
package docker.authz
#預設拒絕
default allow = false
# allow if the user is granted read/write access.
#如果使用者被授予讀寫許可權,則允許
allow {
user_id := input.Headers["Authz-User"]
user := users[user_id]
not user.readOnly
}
# allow if the user is granted read-only access and the request is a GET.
#如果使用者被授予只讀訪問許可權並且請求是GET,則允許
allow {
user_id := input.Headers["Authz-User"]
users[user_id].readOnly
input.Method == "GET"
}
# users defines permissions for the user. In this case, we define a single
# attribute 'readOnly' that controls the kinds of commands the user can run.
#bob使用者只讀,alice使用者讀寫
users := {
"bob": {"readOnly": true},
"alice": {"readOnly": false},
}
現在是"Authz-User": "alice",alice具有讀寫許可權,成功建立容器。
root@ubuntuk8sclient:~# docker run -dit --restart=always --name=nginxweb nginx
e6aeb23a91a55fbad3fd5db9d0ac87ade1be13e990d17e6a29e9f0ca83cb5424
root@ubuntuk8sclient:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e6aeb23a91a5 nginx "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 80/tcp nginxweb
root@ubuntuk8sclient:~# docker rm -f nginxweb
nginxweb
表示現在是bob登入拉取私有映象的。
root@ubuntuk8sclient:~# vim ~/.docker/config.json
root@ubuntuk8sclient:~# cat ~/.docker/config.json
{
"HttpHeaders": {
"Authz-User": "bob"
}
}
bob只有只讀許可權,並且只能執行get,建立容器失敗。
root@ubuntuk8sclient:~# docker run -dit --restart=always --name=nginxweb nginx
docker: Error response from daemon: authorization denied by plugin openpolicyagent/opa-docker-authz-v2:0.8: request rejected by administrative policy.
See 'docker run --help'.
八.總結
本文介紹瞭如何使用 Open Policy Agent(OPA)為 Docker 容器提供訪問控制。透過使用 OPA,我們可以輕鬆地實現細粒度的訪問控制策略,從而提高 Docker 容器的安全性。