|
2 | 2 |
|
3 | 3 | _Who do you trust?_ |
4 | 4 |
|
5 | | -Paranoia is a tool to analyse and export trust bundles (e.g., "ca-certificates") from container images. These certificates identify the certificate authorites that your container trusts when establishing TLS connections. The design of TLS is that any certificate authority that your container trusts can issue a certificate for any domain. This means that a malicious or compromised certificate authority could issue a certificate to impersonate any other service, including your internal infrastructure. |
| 5 | +Paranoia is a tool to analyse and export trust bundles (e.g., "ca-certificates") from container images. |
| 6 | +These certificates identify the certificate authorities that your container trusts when establishing TLS connections. |
| 7 | +The design of TLS is that any certificate authority that your container trusts can issue a certificate for any domain. |
| 8 | +This means that a malicious or compromised certificate authority could issue a certificate to impersonate any other service, including your internal infrastructure. |
6 | 9 |
|
7 | | -Paranoia can be used to inspect and validate the certificates within your container images. This gives you visibility into which certificate authorities your container images are trusting; allows you to forbid or require certificates at build-time in CI; and help you decide _who to trust_ in your container images. |
| 10 | +Paranoia can be used to inspect and validate the certificates within your container images. |
| 11 | +This gives you visibility into which certificate authorities your container images are trusting; allows you to forbid or require certificates at build-time in CI; and help you decide _who to trust_ in your container images. |
8 | 12 |
|
9 | 13 | Paranoia is built by [Jetstack](https://jetstack.io) and made available under the Apache 2.0 license, see [LICENSE.txt](LICENSE.txt). |
10 | 14 |
|
11 | | -## Limitations |
12 | | - |
13 | | -Paranoia will detect certificate authorities in most cases, and is especially useful at finding accidental inclusion or for conducting a certificate authority inventory. However there are some limitations to bear in mind while using Paranoia: |
14 | | -- Paranoia only functions on container images, not running containers. Anything added into the container at runtime is not seen. |
15 | | -- If a certificate is found, that doesn’t guarantee that the container will trust it as a certificate authority. It could, for example, be an unused leftover file. |
16 | | -- It’s possible for an attacker to ‘hide’ a certificate authority from Paranoia (e.g., by encoding it in a format Paranoia doesn’t understand). In general Paranoia isn’t designed to defend against an adversary with supply chain write access intentionally sneaking obfuscated certificate authorities into container images. |
17 | | - |
18 | | -## Command Line Usage |
19 | | - |
20 | | -### Inspect |
21 | | - |
22 | | -Checks found certificates and reports on whether they're valid, expired, due to expire in the next 6 months or are on |
23 | | -[Mozilla's Removed CA Certificate Report](https://ccadb-public.secure.force.com/mozilla/RemovedCACertificateReportCSVFormat). |
24 | | - |
25 | | -```shell |
26 | | -$ paranoia inspect alpine:latest |
27 | | -Certificate CN=Hellenic Academic and Research Institutions RootCA 2011,O=Hellenic Academic and Research Institutions Cert. Authority,C=GR |
28 | | -┗ 🚨 removed from Mozilla trust store, no reason given |
29 | | -Certificate CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL |
30 | | -┗ ⚠️️ expires soon ( expires on 2022-12-08T11:10:28Z, 20 weeks 6 days until expiry) |
31 | | -Found 132 certificates total, of which 2 had issues |
32 | | -``` |
33 | | -
|
34 | | -### Validate |
| 15 | +## Installation |
35 | 16 |
|
36 | | -Compares found certificates against a given configuration file (`.paranoia.yaml` by default) and reports on any |
37 | | -conflicts. |
| 17 | +### Binaries |
38 | 18 |
|
39 | | -**Flags:** |
| 19 | +Binaries for common platforms and architectures are provided on the [releases](https://github.com/jetstack/paranoia/releases/latest). |
40 | 20 |
|
41 | | -`--permissive`: Enables permissive mode, allowing all certificates unless explicitly forbidden. When not |
42 | | -enabled `validate` defaults to `strict` mode where all certificates are forbidden unless explicitly allowed. |
| 21 | +### Go Install |
43 | 22 |
|
44 | | -`--quiet`: Forces the process to end with exit code 0 regardless of whether conflicts are found. Output remains the same. |
45 | | -
|
46 | | -`-c --config`: Takes a file path and allows the use of a specified config file rather than the default, `.paranoia.yaml`. |
47 | | -
|
48 | | -Example config: |
49 | | -```yaml |
50 | | -version: "1" |
51 | | -allow: |
52 | | - - fingerprints: |
53 | | - sha256: 30FBBA2C32238E2A98547AF97931E550428B9B3F1C8EEB6633DCFA86C5B27DD3 |
54 | | - comment: "A certificate we're okay with but don't explicitly need" |
55 | | -forbid: |
56 | | - - fingerprints: |
57 | | - sha256: 4348A0E9444C78CB265E058D5E8944B4D84F9662BD26DB257F8934A443C70161 |
58 | | - comment: "A certificate we definitely don't want" |
59 | | -require: |
60 | | - - fingerprints: |
61 | | - sha1: a7c36ea226e1adc60c4aa7866b79ed9e7831103c |
62 | | - comment: "A certificate that must be present" |
63 | | -``` |
| 23 | +If you have [Go](https://go.dev/) installed you can install Paranoia using Go directly. |
64 | 24 |
|
65 | 25 | ```shell |
66 | | -$ paranoia validate some-image:latest --config some_config.yaml |
67 | | -Validating certificates with 1 allowed, 1 forbidden, and 1 required certificates, in strict mode |
68 | | -Scanned 3 certificates in image some-image:latest, found issues. |
69 | | -Certificate with SHA256 fingerprint 4348A0E9444C78CB265E058D5E8944B4D84F9662BD26DB257F8934A443C70161 in location etc/ssl/certs/ca-certificates.crt was forbidden Comment: A certificate we definitely don't want |
70 | | -Certificate with SHA256 fingerprint 30FBBA2C32238E2A98547AF97931E550428B9B3F1C8EEB6633DCFA86C5B27DD3 in location etc/ssl/certs/ca-certificates.crt was not allowed |
71 | | -Certificate with SHA1 a7c36ea226e1adc60c4aa7866b79ed9e7831103c was required, but was not found Comment: A certificate that must be present |
72 | | -exit status 1 |
| 26 | +go install github.com/jetstack/paranoia@latest |
73 | 27 | ``` |
74 | | -**Note:** Comments on allowed certificate fingerprints will never be displayed in the output as we don't report on |
75 | | -allowances. However, they can be very helpful for anyone who needs to maintain the file. |
76 | 28 |
|
77 | | -### Export |
| 29 | +## Examples |
78 | 30 |
|
79 | | -Outputs data on all found certificates, including the file location, owner, valid from and valid to dates and the SHA256 |
80 | | -fingerprint (useful for populating a config file for use with the `validate` command). |
| 31 | +Paranoia can be used to list out the certificates in a container image: |
81 | 32 |
|
82 | 33 | ```shell |
83 | 34 | $ paranoia export alpine:latest |
84 | 35 | File Location Subject |
85 | 36 | /etc/ssl/certs/ca-certificates.crt CN=ACCVRAIZ1,OU=PKIACCV,O=ACCV,C=ES |
86 | 37 | /etc/ssl/certs/ca-certificates.crt OU=AC RAIZ FNMT-RCM,O=FNMT-RCM,C=ES |
87 | 38 | /etc/ssl/certs/ca-certificates.crt CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS,OU=Ceres,O=FNMT-RCM,C=ES,2.5.4.97=#130f56415445532d51323832363030344a |
88 | | -/etc/ssl/certs/ca-certificates.crt SERIALNUMBER=G63287510,CN=ANF Secure Server Root CA,OU=ANF CA Raiz,O=ANF Autoridad de Certificacion,C=ES |
89 | | -/etc/ssl/certs/ca-certificates.crt CN=Actalis Authentication Root CA,O=Actalis S.p.A./03358520967,L=Milan,C=IT |
90 | | -/etc/ssl/certs/ca-certificates.crt CN=AffirmTrust Commercial,O=AffirmTrust,C=US |
91 | | -/etc/ssl/certs/ca-certificates.crt CN=AffirmTrust Networking,O=AffirmTrust,C=US |
92 | | -/etc/ssl/certs/ca-certificates.crt CN=AffirmTrust Premium,O=AffirmTrust,C=US |
93 | | -/etc/ssl/certs/ca-certificates.crt CN=AffirmTrust Premium ECC,O=AffirmTrust,C=US |
94 | 39 | … |
95 | 40 | /etc/ssl/certs/ca-certificates.crt CN=vTrus ECC Root CA,O=iTrusChina Co.\,Ltd.,C=CN |
96 | 41 | /etc/ssl/certs/ca-certificates.crt CN=vTrus Root CA,O=iTrusChina Co.\,Ltd.,C=CN |
97 | 42 | Found 140 certificates |
98 | 43 | ``` |
99 | 44 |
|
100 | | -The `--output` (or `-o`) flag allows specifying the output mode for export. |
| 45 | +Export them for further audit: |
101 | 46 |
|
102 | | -- `--output pretty` is the default, and gives a table view of the data. |
103 | | -- `--output wide` also uses a table layout, but includes more infomation. |
104 | | -- `--output json` emits JSON. |
105 | | -- `--output pem` emits all full certificates in PEM format. |
| 47 | +```shell |
| 48 | +paranoia export --output json python:3 | jq '.certificates[].fingerprintSHA256' | head -n 5 |
106 | 49 |
|
107 | | -### Global flags |
| 50 | +"ebd41040e4bb3ec742c9e381d31ef2a41a48b6685c96e7cef3c1df6cd4331c99" |
| 51 | +"6dc47172e01cbcb0bf62580d895fe2b8ac9ad4f873801e0c10b9c837d21eb177" |
| 52 | +"16af57a9f676b0ab126095aa5ebadef22ab31119d644ac95cd4b93dbf3f26aeb" |
| 53 | +"73c176434f1bc6d5adf45b0e76e727287c8de57616c1e6e6141a2b2cbc7d8e4c" |
| 54 | +"d7a7a0fb5d7e2731d771e9484ebcdef71d5f0c3e0a2948782bc83ee0ea699ef4" |
| 55 | +``` |
108 | 56 |
|
109 | | -`--platform`: Specifies the platform in the form `os/arch[/variant][:osversion]` (e.g. `linux/amd64`) |
| 57 | +Detect internal certificates left over from internal testing: |
110 | 58 |
|
111 | | -## CI Usage |
| 59 | +```shell |
| 60 | +cat << EOF > .paranoia.yaml |
| 61 | +version: "1" |
| 62 | +forbid: |
| 63 | + - comment: "An internal-only cert" |
| 64 | + fingerprints: |
| 65 | + sha256: bd40be0eccfce513ab318882f03962e4e2ec3799b51392e82805d9249e426d28 |
| 66 | +EOF |
| 67 | +paranoia validate my-image |
| 68 | +``` |
112 | 69 |
|
113 | | -The functionality of Paranoia is well suited to running in CI pipelines, either producing reports on a schedule or |
114 | | -as a check before or after the release of a new container image. |
| 70 | +Find certificates inside binaries: |
115 | 71 |
|
116 | | -Below are some examples: |
| 72 | +```shell |
| 73 | +paranoia export -o json consul:latest | jq '.certificates[] | select(.fileLocation == "/bin/consul")' |
| 74 | +{ |
| 75 | + "fileLocation": "/bin/consul", |
| 76 | + "owner": "CN=Circonus Certificate Authority,OU=Circonus,O=Circonus\\, Inc.,L=Columbia,ST=Maryland,C=US,1.2.840.113549.1.9.1=#0c0f636140636972636f6e75732e6e6574", |
| 77 | + "parser": "pem", |
| 78 | + "signature": "01C1B65D790706D2CAAD1D30406911D41884789A9D4FEBBCE31EE7B7628019A8C7B6643C46C1FDB684B18272B33880DAB68EB51C5546D731B9948C8A3D918890EC2F1CC8A751FAD1786BF2599FEEA17A63EB1997B577E8A65B9F67B368EA11B6C425F5D86A10C7BCCE02FBEA9F5867913AF409749A08A27D3B5EC8D8E332E216", |
| 79 | + "notBefore": "2009-12-23T19:17:06Z", |
| 80 | + "notAfter": "2019-12-21T19:17:06Z", |
| 81 | + "fingerprintSHA1": "063ff657e055b0036d794cda892c85417c07739a", |
| 82 | + "fingerprintSHA256": "0c97e0898343c5b1973c6568a15c8c853dd663d363020071e34f789859ece19f" |
| 83 | +} |
| 84 | +``` |
117 | 85 |
|
118 | | -### GitHub Actions |
| 86 | +## Limitations |
119 | 87 |
|
120 | | -Paranoia is used on itself after container image build to confirm that it only contains the certificates that we expect. |
121 | | -The full workflow can be found [here](.github/workflows/publish.yaml). |
| 88 | +Paranoia will detect certificate authorities in most cases, and is especially useful at finding accidental inclusion or for conducting a certificate authority inventory. |
| 89 | +However, there are some limitations to bear in mind while using Paranoia: |
122 | 90 |
|
123 | | -In it we use our [paranoia action](action.yml) to run the validation, using the `file://` prefix to read the container |
124 | | -image from a local file, as opposed to pulling it from a container registry: |
| 91 | +- Paranoia only functions on container images, not running containers. |
| 92 | + Anything added into the container at runtime is not seen. |
| 93 | +- If a certificate is found, that doesn’t guarantee that the container will trust it as a certificate authority. |
| 94 | + It could, for example, be an unused leftover file. |
| 95 | +- It’s possible for an attacker to ‘hide’ a certificate authority from Paranoia (e.g., by encoding it in a format Paranoia doesn’t understand). |
| 96 | + In general Paranoia isn’t designed to defend against an adversary with supply chain write access intentionally sneaking obfuscated certificate authorities into container images. |
125 | 97 |
|
126 | | -```yaml |
127 | | -... |
128 | | -- name: Build and export to Docker |
129 | | - uses: docker/build-push-action@v3 |
130 | | - with: |
131 | | - context: . |
132 | | - load: true |
133 | | - cache-from: type=gha |
134 | | - cache-to: type=gha,mode=max |
135 | | - outputs: type=docker,dest=${{ env.CONTAINER_TAR }} |
| 98 | +## Usage |
136 | 99 |
|
137 | | -- name: "Run Paranoia container" |
138 | | - uses: ./ |
139 | | - with: |
140 | | - action: validate |
141 | | - target_tar: file://${{ env.CONTAINER_TAR }} |
142 | | -... |
143 | | -``` |
| 100 | +The usage documentation for Paranoia is included in the help text. |
| 101 | +Invoke a command with `--help` for usage instructions, or see the manual pages. |
0 commit comments