Cosign 是一個的工具,它可以在符合 OCI(Open Container Initiative,開放貨櫃計畫)標準的儲存庫中,對軟體產物進行簽署、驗證以及儲存。雖然 Cosign 最初是針對 containers (貨櫃)及與 container-related(貨櫃有關)的產物而開發,但它同樣適用於開源軟體套件和其他各種檔案類型。
例如,Cosign 可以用來對各種資料進行簽署,包括 Container image、blobs (binary large objects)、像 README 檔、SBOM(軟體物料清單)、 Kubernetes Helm Charts、Tekton bundles(an OCI artifact containing Tekton CI/CD resources like tasks)等等。
透過對軟體簽署,你可以證明「你」確實是你所聲明的身份,這也能建立一個信任基礎,使得開發者和使用你軟體的人能夠驗證該軟體產物確實是由你創建的。同時,他們也能確認該產物未被第三方竄改。對於在開發流程中需要使用軟體庫、貨櫃或其他產物的人來說,已簽署的產物能夠讓你更放心,因為你知道所採用的程式碼或貨櫃來自一個值得信賴的來源。
$ sudo curl -o /usr/local/bin/cosign \
-L "https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64"
$ sudo chmod +x /usr/local/bin/cosign
# Check Version
$ cosign version
______ ______ _______. __ _______ .__ __.
/ | / __ \ / || | / _____|| \ | |
| ,----'| | | | | (----`| | | | __ | \| |
| | | | | | \ \ | | | | |_ | | . ` |
| `----.| `--' | .----) | | | | |__| | | |\ |
\______| \______/ |_______/ |__| \______| |__| \__|
cosign: A tool for Container Signing, Verification and Storage in an OCI registry.
GitVersion: v2.4.1
GitCommit: 9a4cfe1aae777984c07ce373d97a65428bbff734
GitTreeState: clean
BuildDate: 2024-10-03T17:01:50Z
GoVersion: go1.22.7
Compiler: gc
Platform: linux/amd64
$ mkdir sign; cd sign
$ cosign generate-key-pair
Enter password for private key:
Enter password for private key again:
Private key written to cosign.key
Public key written to cosign.pub
$ ls -l
total 8
-rw-------. 1 rancher users 653 Feb 3 23:31 cosign.key
-rw-r--r--. 1 rancher users 178 Feb 3 23:31 cosign.pub
$ podman login docker.io --compat-auth-file ~/.docker/config.json
Username: hahappyman
Password:
Login Succeeded!
$ cosign sign --key cosign.key docker.io/hahappyman/alpine
Enter password for private key:
...
By typing 'y', you attest that (1) you are not submitting the personal data of any other person; and (2) you understand and agree to the statement and the Agreement terms at the URLs listed above.
Are you sure you would like to continue? [y/N] y
tlog entry created with index: 168432318
Pushing signature to: index.docker.io/hahappyman/alpine
# 驗證 container image 有簽名
$ cosign verify --key cosign.pub docker.io/hahappyman/alpine | jq .
Verification for index.docker.io/hahappyman/alpine:latest --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- Existence of the claims in the transparency log was verified offline
- The signatures were verified against the specified public key
[
{
"critical": {
"identity": {
"docker-reference": "index.docker.io/hahappyman/alpine"
},
"image": {
"docker-manifest-digest": "sha256:def822f9851ca422481ec6fee59a9966f12b351c62ccb9aca841526ffaa9f748"
},
"type": "cosign container image signature"
},
"optional": {
"Bundle": {
"SignedEntryTimestamp": "MEUCIDbGUgBokwb4V+MIbOu8tCt05dUDiTD6YsYKACY9cWveAiEA0jWB6gkq1Vp1bZ0/A+wQNw9qKjiYxZC/um47n8ueJZc=",
"Payload": {
"body": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiIwNjEwNzBmZDAwOTk3MWQ3MzA1ZWU2MjE2NmIxZWJhMTVhMjI5OTdjMGEzZmZiMWQyNWY2NzMwYjY1OGNlM2M2In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJRzlrSjcwLzRIQll6d3FjOHBBeTRoNFc0d0toc0k4NzZlTStCNlJOS0IyOUFpRUExT0JuTDg1TEc0c0poSTkyaCtzcTNiS2JnSm9rcVFXclVMbGpqdlg0My9RPSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCUVZVSk1TVU1nUzBWWkxTMHRMUzBLVFVacmQwVjNXVWhMYjFwSmVtb3dRMEZSV1VsTGIxcEplbW93UkVGUlkwUlJaMEZGWWsxNE1sWmFOR0o2VFRoMWVsRjNjbE1yUlZsa1RrUTNaaXMxTUFwR1pGa3hkM05NYUVkelEyOVRXRmw2VUdsaWJIZDRVRkJIVjBadE9HbEJaSGhUV1RVNE5tUmhUblY2Y2xFMmF6QldTRTl4UkVNNFRtMW5QVDBLTFMwdExTMUZUa1FnVUZWQ1RFbERJRXRGV1MwdExTMHRDZz09In19fX0=",
"integratedTime": 1738636249,
"logIndex": 168432318,
"logID": "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"
}
}
}
}
]
$ sudo podman build -t docker.io/hahappyman/alpine -f - . <<EOF
FROM quay.io/cloudwalker/alpine
CMD echo just a test
EOF
$ sudo podman push docker.io/hahappyman/alpine
Getting image source signatures
Copying blob 3e01818d79cd done |
Copying config bdfe5ec11e done |
Writing manifest to image destination
$ cosign verify --key cosign.pub docker.io/hahappyman/alpine | jq .
Error: no signatures found
main.go:69: error during command execution: no signatures found
$ curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo s
h -s -- -b /usr/local/bin v0.41.0
$ trivy image --ignore-unfixed --format cosign-vuln --output vuln.json docker.io/hahappyman/alpine@sha256:def822f9851ca422481ec6fee59a9966f12b351c62ccb9aca841526ffaa9f748
# 產生證明
# 1. 安裝 Kyverno
$ kubectl create -f https://github.com/kyverno/kyverno/releases/download/v1.13.0/install.yaml
# 2. 確認 Kyverno pod 正常運作
$ kubectl -n kyverno get pods
NAME READY STATUS RESTARTS AGE
kyverno-admission-controller-545dd46f74-j8plr 1/1 Running 0 7m36s
kyverno-background-controller-5c8cbbb888-tqlf2 1/1 Running 0 7m36s
kyverno-cleanup-controller-7494bd4d8f-vrsxk 1/1 Running 0 7m36s
kyverno-reports-controller-69989df659-nw28s 1/1 Running 0 7m36s
# 3. Install a policy
$ cat <<EOF | envsubst | kubectl apply -f -
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: check-vulnerabilities
spec:
validationFailureAction: Enforce
background: false
webhookTimeoutSeconds: 30
failurePolicy: Fail
rules:
- name: checking-vulnerability-scan-not-older-than-one-hour
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "*"
attestations:
- type: https://cosign.sigstore.dev/attestation/vuln/v1
conditions:
- all:
- key: "{{ time_since('','{{ metadata.scanFinishedOn }}', '') }}"
operator: LessThanOrEquals
value: "1h"
attestors:
- count: 1
entries:
- keys:
publicKeys: |-
$(sed 's/^/ /' ~/sign/cosign.pub)
EOF
$ kubectl run app-unsigned --image=docker.io/anaisurlichs/cns-website:0.1.1
Error from server: admission webhook "mutate.kyverno.svc-fail" denied the request:
resource Pod/default/app-unsigned was blocked due to the following policies
check-vulnerabilities:
checking-vulnerability-scan-not-older-than-one-hour: |
image attestations verification failed, verifiedCount: 0, requiredCount: 1, error: no matching attestations: error verifying bundle: comparing public key PEMs, expected -----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbMx2VZ4bzM8uzQwrS+EYdND7f+50
FdY1wsLhGsCoSXYzPiblwxPPGWFm8iAdxSY586daNuzrQ6k0VHOqDC8Nmg==
-----END PUBLIC KEY-----
, got -----BEGIN CERTIFICATE-----
MIIC1TCCAlugAwIBAgIUCaDDp3gxDc+aCC2jACWbBSleuCYwCgYIKoZIzj0EAwMw
NzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRl
cm1lZGlhdGUwHhcNMjQwMTA4MTQyNDEzWhcNMjQwMTA4MTQzNDEzWjAAMFkwEwYH
KoZIzj0CAQYIKoZIzj0DAQcDQgAE0XTT4yiarpOHiQLZviJBN4WXb1ibml5JMHHl
CRYBS3+WVkrEtDN1P/tnDlaKzM8AuKjOebvBO6ElY5O6ng4VpaOCAXowggF2MA4G
A1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUfMeV
lPkZSIEl2vp33nABx42ptzQwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4Y
ZD8wJAYDVR0RAQH/BBowGIEWdXJsaWNoc2FuYWlzQGdtYWlsLmNvbTAsBgorBgEE
AYO/MAEBBB5odHRwczovL2dpdGh1Yi5jb20vbG9naW4vb2F1dGgwLgYKKwYBBAGD
vzABCAQgDB5odHRwczovL2dpdGh1Yi5jb20vbG9naW4vb2F1dGgwgYoGCisGAQQB
1nkCBAIEfAR6AHgAdgDdPTBqxscRMmMZHhyZZzcCokpeuN48rf+HinKALynujgAA
AYzpdbEbAAAEAwBHMEUCIQCXkciXtNvEvXk+G5XymRiprfSF+YEqYrBFbVIk7h4Z
MwIgUIHzK5MczeS90QxhwX/lVNOay86CHMGknmFpLgUb8/4wCgYIKoZIzj0EAwMD
aAAwZQIwQtSOZauh5ubyjj3MR+Sn6E3BPBMt2TuC2aaoLSFUHm/FP6RYFTpFgOPW
Ow/wWkyRAjEApKPUppzjYmWzPwDhKNFOvzLmjng00lrCmIXYajGhv1FW8l0jZTgb
KfN07EfupRrM
-----END CERTIFICATE-----
$
建立 Google Mail 帳號
Jun 5, 2025OpenShift 的 Egress IP 功能允許您確保一個或多個 Pod(來自一個或多個專案)的流量,在離開叢集網路時,透過 SNAT 機制,讓屬於特定 namespace 底下 Pods 的流量對外呈現固定 Source IP。
Jun 5, 2025Step1: 建立 Project(Namespace)test
Jun 5, 2025並切換成 root 使用者
May 27, 2025or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up