docs: turn README into full articles
This commit is contained in:
parent
6663bcef27
commit
3f91bd2a9b
@ -1,695 +0,0 @@
|
||||
# Clair v1 API
|
||||
|
||||
- [Error Handling](#error-handling)
|
||||
- [Layers](#layers)
|
||||
- [POST](#post-layers)
|
||||
- [GET](#get-layersname)
|
||||
- [DELETE](#delete-layersname)
|
||||
- [Namespaces](#namespaces)
|
||||
- [GET](#get-namespaces)
|
||||
- [Vulnerabilities](#vulnerabilities)
|
||||
- [List](#get-namespacesnsnamevulnerabilities)
|
||||
- [POST](#post-namespacesnamevulnerabilities)
|
||||
- [GET](#get-namespacesnsnamevulnerabilitiesvulnname)
|
||||
- [PUT](#put-namespacesnsnamevulnerabilitiesvulnname)
|
||||
- [DELETE](#delete-namespacesnsnamevulnerabilitiesvulnname)
|
||||
- [Fixes](#fixes)
|
||||
- [GET](#get-namespacesnsnamevulnerabilitiesvulnnamefixes)
|
||||
- [PUT](#put-namespacesnsnamevulnerabilitiesvulnnamefixesfeaturename)
|
||||
- [DELETE](#delete-namespacesnsnamevulnerabilitiesvulnnamefixesfeaturename)
|
||||
- [Notifications](#notifications)
|
||||
- [GET](#get-notificationsname)
|
||||
- [DELETE](#delete-notificationsname)
|
||||
|
||||
## Error Handling
|
||||
|
||||
#### Description
|
||||
|
||||
Every route can optionally provide an `Error` property on the response object.
|
||||
The HTTP status code of the response should indicate what type of failure occurred and how the client should react.
|
||||
|
||||
#### Client Retry Behavior
|
||||
|
||||
| Code | Name | Retry Behavior |
|
||||
|------|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 400 | Bad Request | The body of the request invalid. The request either must be changed before being retried or depends on another request being processed before it. |
|
||||
| 404 | Not Found | The requested resource could not be found. The request must be changed before being retried. |
|
||||
| 422 | Unprocessable Entity | The request body is valid, but unsupported. This request should never be retried. |
|
||||
| 500 | Internal Server Error | The server encountered an error while processing the request. This request should be retried without change. |
|
||||
|
||||
#### Example Response
|
||||
|
||||
```http
|
||||
HTTP/1.1 400 Bad Request
|
||||
Content-Type: application/json;charset=utf-8
|
||||
Server: clair
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"Error": {
|
||||
"Message": "example error message"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Layers
|
||||
|
||||
### POST /layers
|
||||
|
||||
#### Description
|
||||
|
||||
The POST route for the Layers resource performs the analysis of a Layer from the provided path.
|
||||
|
||||
In order to analyze a container image, this route has to be called for each layer that [composes](https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/) it, in the proper order and with the parent relationship specified. For instance, to analyze an image composed of three layers A->B->C, where A is the base layer (i.e. `FROM debian:jessie`), three API calls must be made to this route, from A to C. Also, when analyzing B, A must be set as the parent, then when analyzing C, B must be defined as the parent.
|
||||
|
||||
This request blocks for the entire duration of the downloading and indexing of the layer and displays the provided Layer with an updated `IndexByVersion` property.
|
||||
The Name field must be unique globally. Consequently, using the Blob digest describing the Layer content is not sufficient as Clair won't be able to differentiate two empty filesystem diffs that belong to two different image trees.
|
||||
The Authorization field is an optional value whose contents will fill the Authorization HTTP Header when requesting the layer via HTTP.
|
||||
|
||||
#### Example Request
|
||||
|
||||
```http
|
||||
POST http://localhost:6060/v1/layers HTTP/1.1
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"Layer": {
|
||||
"Name": "523ef1d23f222195488575f52a39c729c76a8c5630c9a194139cb246fb212da6",
|
||||
"Path": "https://mystorage.com/layers/523ef1d23f222195488575f52a39c729c76a8c5630c9a194139cb246fb212da6/layer.tar",
|
||||
"Headers": {
|
||||
"Authorization": "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.EkN-DOsnsuRjRO6BxXemmJDm3HbxrbRzXglbN2S4sOkopdU4IsDxTI8jO19W_A4K8ZPJijNLis4EZsHeY559a4DFOd50_OqgHGuERTqYZyuhtF39yxJPAjUESwxk2J5k_4zM3O-vtd1Ghyo4IbqKKSy6J9mTniYJPenn5-HIirE"
|
||||
},
|
||||
"ParentName": "140f9bdfeb9784cf8730e9dab5dd12fbd704151cf555ac8cae650451794e5ac2",
|
||||
"Format": "Docker"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Example Response
|
||||
|
||||
```http
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: application/json;charset=utf-8
|
||||
Server: clair
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"Layer": {
|
||||
"Name": "523ef1d23f222195488575f52a39c729c76a8c5630c9a194139cb246fb212da6",
|
||||
"Path": "https://mystorage.com/layers/523ef1d23f222195488575f52a39c729c76a8c5630c9a194139cb246fb212da6/layer.tar",
|
||||
"Headers": {
|
||||
"Authorization": "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.EkN-DOsnsuRjRO6BxXemmJDm3HbxrbRzXglbN2S4sOkopdU4IsDxTI8jO19W_A4K8ZPJijNLis4EZsHeY559a4DFOd50_OqgHGuERTqYZyuhtF39yxJPAjUESwxk2J5k_4zM3O-vtd1Ghyo4IbqKKSy6J9mTniYJPenn5-HIirE"
|
||||
},
|
||||
"ParentName": "140f9bdfeb9784cf8730e9dab5dd12fbd704151cf555ac8cae650451794e5ac2",
|
||||
"Format": "Docker",
|
||||
"IndexedByVersion": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### GET /layers/`:name`
|
||||
|
||||
#### Description
|
||||
|
||||
The GET route for the Layers resource displays a Layer and optionally all of its features and vulnerabilities. For an image composed of three layers A->B->C, calling this route on the third layer (C) will returns all the features and vulnerabilities for the entire image, including the analysis data gathered from the parent layers (A, B). For instance, a feature (and its potential vulnerabilities) detected in the first layer (A) will be shown when querying the third layer (C). On the other hand, a feature detected in the first layer (A) but then removed in either following layers (B, C) will not appear.
|
||||
|
||||
#### Query Parameters
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
|-----------------|------|----------|-------------------------------------------------------------------------------|
|
||||
| features | bool | optional | Displays the list of features indexed in this layer and all of its parents. |
|
||||
| vulnerabilities | bool | optional | Displays the list of vulnerabilities along with the features described above. |
|
||||
|
||||
#### Example Request
|
||||
|
||||
```http
|
||||
GET http://localhost:6060/v1/layers/17675ec01494d651e1ccf81dc9cf63959ebfeed4f978fddb1666b6ead008ed52?features&vulnerabilities HTTP/1.1
|
||||
```
|
||||
|
||||
#### Example Response
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json;charset=utf-8
|
||||
Server: clair
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"Layer": {
|
||||
"Name": "17675ec01494d651e1ccf81dc9cf63959ebfeed4f978fddb1666b6ead008ed52",
|
||||
"NamespaceName": "debian:8",
|
||||
"ParentName": "140f9bdfeb9784cf8730e9dab5dd12fbd704151cf555ac8cae650451794e5ac2",
|
||||
"IndexedByVersion": 1,
|
||||
"Features": [
|
||||
{
|
||||
"Name": "coreutils",
|
||||
"NamespaceName": "debian:8",
|
||||
"Version": "8.23-4",
|
||||
"Vulnerabilities": [
|
||||
{
|
||||
"Name": "CVE-2014-9471",
|
||||
"NamespaceName": "debian:8",
|
||||
"Description": "The parse_datetime function in GNU coreutils allows remote attackers to cause a denial of service (crash) or possibly execute arbitrary code via a crafted date string, as demonstrated by the \"--date=TZ=\"123\"345\" @1\" string to the touch or date command.",
|
||||
"Link": "https://security-tracker.debian.org/tracker/CVE-2014-9471",
|
||||
"Severity": "Low",
|
||||
"FixedBy": "9.23-5"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### DELETE /layers/`:name`
|
||||
|
||||
#### Description
|
||||
|
||||
The DELETE route for the Layers resource removes a Layer and all of its children from the database.
|
||||
|
||||
#### Example Request
|
||||
|
||||
```http
|
||||
DELETE http://localhost:6060/v1/layers/17675ec01494d651e1ccf81dc9cf63959ebfeed4f978fddb1666b6ead008ed52 HTTP/1.1
|
||||
```
|
||||
|
||||
#### Example Response
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Server: clair
|
||||
```
|
||||
|
||||
|
||||
## Namespaces
|
||||
|
||||
### GET /namespaces
|
||||
|
||||
#### Description
|
||||
|
||||
The GET route for the Namespaces resource displays a list of namespaces currently being managed.
|
||||
|
||||
#### Example Request
|
||||
|
||||
```http
|
||||
GET http://localhost:6060/v1/namespaces HTTP/1.1
|
||||
```
|
||||
|
||||
#### Example Response
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json;charset=utf-8
|
||||
Server: clair
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"Namespaces": [
|
||||
{ "Name": "debian:8" },
|
||||
{ "Name": "debian:9" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Vulnerabilities
|
||||
|
||||
### GET /namespaces/`:nsName`/vulnerabilities
|
||||
|
||||
#### Description
|
||||
|
||||
The GET route for the Vulnerabilities resource displays the vulnerabilities data for a given namespace.
|
||||
|
||||
#### Query Parameters
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
|---------|------|----------|------------------------------------------------------------|
|
||||
| limit | int | required | Limits the amount of the vunlerabilities data for a given namespace. |
|
||||
| page | int | required | Displays the specific page of the vunlerabilities data for a given namespace. |
|
||||
|
||||
#### Example Request
|
||||
|
||||
```http
|
||||
GET http://localhost:6060/v1/namespaces/debian%3A8/vulnerabilities?limit=2 HTTP/1.1
|
||||
```
|
||||
|
||||
#### Example Response
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json;charset=utf-8
|
||||
Server: clair
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"Vulnerabilities": [
|
||||
{
|
||||
"Name": "CVE-1999-1332",
|
||||
"NamespaceName": "debian:8",
|
||||
"Description": "gzexe in the gzip package on Red Hat Linux 5.0 and earlier allows local users to overwrite files of other users via a symlink attack on a temporary file.",
|
||||
"Link": "https://security-tracker.debian.org/tracker/CVE-1999-1332",
|
||||
"Severity": "Low"
|
||||
},
|
||||
{
|
||||
"Name": "CVE-1999-1572",
|
||||
"NamespaceName": "debian:8",
|
||||
"Description": "cpio on FreeBSD 2.1.0, Debian GNU/Linux 3.0, and possibly other operating systems, uses a 0 umask when creating files using the -O (archive) or -F options, which creates the files with mode 0666 and allows local users to read or overwrite those files.",
|
||||
"Link": "https://security-tracker.debian.org/tracker/CVE-1999-1572",
|
||||
"Severity": "Low",
|
||||
"Metadata": {
|
||||
"NVD": {
|
||||
"CVSSv2": {
|
||||
"Score": 2.1,
|
||||
"Vectors": "AV:L/AC:L/Au:N/C:P/I:N"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"NextPage":"gAAAAABW1ABiOlm6KMDKYFE022bEy_IFJdm4ExxTNuJZMN0Eycn0Sut2tOH9bDB4EWGy5s6xwATUHiG-6JXXaU5U32sBs6_DmA=="
|
||||
}
|
||||
```
|
||||
|
||||
### POST /namespaces/`:name`/vulnerabilities
|
||||
|
||||
#### Description
|
||||
|
||||
The POST route for the Vulnerabilities resource creates a new Vulnerability.
|
||||
|
||||
#### Example Request
|
||||
|
||||
```http
|
||||
POST http://localhost:6060/v1/namespaces/debian%3A8/vulnerabilities HTTP/1.1
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"Vulnerability": {
|
||||
"Name": "CVE-2014-9471",
|
||||
"NamespaceName": "debian:8",
|
||||
"Link": "https://security-tracker.debian.org/tracker/CVE-2014-9471",
|
||||
"Description": "The parse_datetime function in GNU coreutils allows remote attackers to cause a denial of service (crash) or possibly execute arbitrary code via a crafted date string, as demonstrated by the \"--date=TZ=\"123\"345\" @1\" string to the touch or date command.",
|
||||
"Severity": "Low",
|
||||
"Metadata": {
|
||||
"NVD": {
|
||||
"CVSSv2": {
|
||||
"Score": 7.5,
|
||||
"Vectors": "AV:N/AC:L/Au:N/C:P/I:P"
|
||||
}
|
||||
}
|
||||
},
|
||||
"FixedIn": [
|
||||
{
|
||||
"Name": "coreutils",
|
||||
"NamespaceName": "debian:8",
|
||||
"Version": "8.23-1"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Example Response
|
||||
|
||||
```http
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: application/json;charset=utf-8
|
||||
Server: clair
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"Vulnerability": {
|
||||
"Name": "CVE-2014-9471",
|
||||
"NamespaceName": "debian:8",
|
||||
"Link": "https://security-tracker.debian.org/tracker/CVE-2014-9471",
|
||||
"Description": "The parse_datetime function in GNU coreutils allows remote attackers to cause a denial of service (crash) or possibly execute arbitrary code via a crafted date string, as demonstrated by the \"--date=TZ=\"123\"345\" @1\" string to the touch or date command.",
|
||||
"Severity": "Low",
|
||||
"Metadata": {
|
||||
"NVD": {
|
||||
"CVSSv2": {
|
||||
"Score": 7.5,
|
||||
"Vectors": "AV:N/AC:L/Au:N/C:P/I:P"
|
||||
}
|
||||
}
|
||||
},
|
||||
"FixedIn": [
|
||||
{
|
||||
"Name": "coreutils",
|
||||
"NamespaceName": "debian:8",
|
||||
"Version": "8.23-1"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### GET /namespaces/`:nsName`/vulnerabilities/`:vulnName`
|
||||
|
||||
#### Description
|
||||
|
||||
The GET route for the Vulnerabilities resource displays the current data for a given vulnerability and optionally the features that fix it.
|
||||
|
||||
#### Query Parameters
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
|---------|------|----------|------------------------------------------------------------|
|
||||
| fixedIn | bool | optional | Displays the list of features that fix this vulnerability. |
|
||||
|
||||
#### Example Request
|
||||
|
||||
```http
|
||||
GET http://localhost:6060/v1/namespaces/debian%3A8/vulnerabilities/CVE-2014-9471?fixedIn HTTP/1.1
|
||||
```
|
||||
|
||||
#### Example Response
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json;charset=utf-8
|
||||
Server: clair
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"Vulnerability": {
|
||||
"Name": "CVE-2014-9471",
|
||||
"NamespaceName": "debian:8",
|
||||
"Link": "https://security-tracker.debian.org/tracker/CVE-2014-9471",
|
||||
"Description": "The parse_datetime function in GNU coreutils allows remote attackers to cause a denial of service (crash) or possibly execute arbitrary code via a crafted date string, as demonstrated by the \"--date=TZ=\"123\"345\" @1\" string to the touch or date command.",
|
||||
"Severity": "Low",
|
||||
"Metadata": {
|
||||
"NVD": {
|
||||
"CVSSv2": {
|
||||
"Score": 7.5,
|
||||
"Vectors": "AV:N/AC:L/Au:N/C:P/I:P"
|
||||
}
|
||||
}
|
||||
},
|
||||
"FixedIn": [
|
||||
{
|
||||
"Name": "coreutils",
|
||||
"NamespaceName": "debian:8",
|
||||
"Version": "8.23-1"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### PUT /namespaces/`:nsName`/vulnerabilities/`:vulnName`
|
||||
|
||||
#### Description
|
||||
|
||||
The PUT route for the Vulnerabilities resource updates a given Vulnerability.
|
||||
The "FixedIn" property of the Vulnerability must be empty or missing.
|
||||
Fixes should be managed by the Fixes resource.
|
||||
If this vulnerability was inserted by a Fetcher, changes may be lost when the Fetcher updates.
|
||||
|
||||
#### Example Request
|
||||
|
||||
```http
|
||||
PUT http://localhost:6060/v1/namespaces/debian%3A8/vulnerabilities/CVE-2014-9471
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"Vulnerability": {
|
||||
"Name": "CVE-2014-9471",
|
||||
"NamespaceName": "debian:8",
|
||||
"Link": "https://security-tracker.debian.org/tracker/CVE-2014-9471",
|
||||
"Description": "The parse_datetime function in GNU coreutils allows remote attackers to cause a denial of service (crash) or possibly execute arbitrary code via a crafted date string, as demonstrated by the \"--date=TZ=\"123\"345\" @1\" string to the touch or date command.",
|
||||
"Severity": "Low",
|
||||
"Metadata": {
|
||||
"NVD": {
|
||||
"CVSSv2": {
|
||||
"Score": 7.5,
|
||||
"Vectors": "AV:N/AC:L/Au:N/C:P/I:P"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Example Response
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Server: clair
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"Vulnerability": {
|
||||
"Name": "CVE-2014-9471",
|
||||
"NamespaceName": "debian:8",
|
||||
"Link": "https://security-tracker.debian.org/tracker/CVE-2014-9471",
|
||||
"Description": "The parse_datetime function in GNU coreutils allows remote attackers to cause a denial of service (crash) or possibly execute arbitrary code via a crafted date string, as demonstrated by the \"--date=TZ=\"123\"345\" @1\" string to the touch or date command.",
|
||||
"Severity": "Low",
|
||||
"Metadata": {
|
||||
"NVD": {
|
||||
"CVSSv2": {
|
||||
"Score": 7.5,
|
||||
"Vectors": "AV:N/AC:L/Au:N/C:P/I:P"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### DELETE /namespaces/`:nsName`/vulnerabilities/`:vulnName`
|
||||
|
||||
#### Description
|
||||
|
||||
The DELETE route for the Vulnerabilities resource deletes a given Vulnerability.
|
||||
If this vulnerability was inserted by a Fetcher, it may be re-inserted when the Fetcher updates.
|
||||
|
||||
#### Example Request
|
||||
|
||||
```http
|
||||
GET http://localhost:6060/v1/namespaces/debian%3A8/vulnerabilities/CVE-2014-9471 HTTP/1.1
|
||||
```
|
||||
|
||||
#### Example Response
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Server: clair
|
||||
```
|
||||
|
||||
## Fixes
|
||||
|
||||
### GET /namespaces/`:nsName`/vulnerabilities/`:vulnName`/fixes
|
||||
|
||||
#### Description
|
||||
|
||||
The GET route for the Fixes resource displays the list of Features that fix the given Vulnerability.
|
||||
|
||||
#### Example Request
|
||||
|
||||
```http
|
||||
GET http://localhost:6060/v1/namespaces/debian%3A8/vulnerabilities/CVE-2014-9471/fixes HTTP/1.1
|
||||
```
|
||||
|
||||
#### Example Response
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json;charset=utf-8
|
||||
Server: clair
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"Features": [
|
||||
{
|
||||
"Name": "coreutils",
|
||||
"NamespaceName": "debian:8",
|
||||
"Version": "8.23-1"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### PUT /namespaces/`:nsName`/vulnerabilities/`:vulnName`/fixes/`:featureName`
|
||||
|
||||
#### Description
|
||||
|
||||
The PUT route for the Fixes resource updates a Feature that is the fix for a given Vulnerability.
|
||||
|
||||
#### Example Request
|
||||
|
||||
```http
|
||||
PUT http://localhost:6060/v1/namespaces/debian%3A8/vulnerabilities/CVE-2014-9471/fixes/coreutils HTTP/1.1
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"Feature": {
|
||||
"Name": "coreutils",
|
||||
"NamespaceName": "debian:8",
|
||||
"Version": "4.24-9"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Example Response
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Server: clair
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"Feature": {
|
||||
"Name": "coreutils",
|
||||
"NamespaceName": "debian:8",
|
||||
"Version": "4.24-9"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### DELETE /namespaces/`:nsName`/vulnerabilities/`:vulnName`/fixes/`:featureName`
|
||||
|
||||
#### Description
|
||||
|
||||
The DELETE route for the Fixes resource removes a Feature as fix for the given Vulnerability.
|
||||
|
||||
#### Example Request
|
||||
|
||||
```http
|
||||
DELETE http://localhost:6060/v1/namespaces/debian%3A8/vulnerabilities/CVE-2014-9471/fixes/coreutils
|
||||
```
|
||||
|
||||
#### Example Response
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Server: clair
|
||||
```
|
||||
|
||||
## Notifications
|
||||
|
||||
### GET /notifications/`:name`
|
||||
|
||||
#### Description
|
||||
|
||||
The GET route for the Notifications resource displays a notification that a Vulnerability has been updated.
|
||||
This route supports simultaneous pagination for both the `Old` and `New` Vulnerabilities' `OrderedLayersIntroducingVulnerability` which can be extremely long.
|
||||
The `LayersIntroducingVulnerability` property is deprecated and will eventually be removed from the API.
|
||||
|
||||
#### Query Parameters
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
|-------|--------|----------|---------------------------------------------------------------------------------------------------------------|
|
||||
| page | string | optional | Displays the specific page of the "LayersIntroducingVulnerability" property on New and Old vulnerabilities. |
|
||||
| limit | int | optional | Limits the amount of results in the "LayersIntroducingVulnerability" property on New and Old vulnerabilities. |
|
||||
|
||||
#### Example Request
|
||||
|
||||
```http
|
||||
GET http://localhost:6060/v1/notifications/ec45ec87-bfc8-4129-a1c3-d2b82622175a?limit=2 HTTP/1.1
|
||||
```
|
||||
|
||||
#### Example Response
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json;charset=utf-8
|
||||
Server: clair
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"Notification": {
|
||||
"Name": "ec45ec87-bfc8-4129-a1c3-d2b82622175a",
|
||||
"Created": "1456247389",
|
||||
"Notified": "1456246708",
|
||||
"Limit": 2,
|
||||
"Page": "gAAAAABWzJaC2JCH6Apr_R1f2EkjGdibnrKOobTcYXBWl6t0Cw6Q04ENGIymB6XlZ3Zi0bYt2c-2cXe43fvsJ7ECZhZz4P8C8F9efr_SR0HPiejzQTuG0qAzeO8klogFfFjSz2peBvgP",
|
||||
"NextPage": "gAAAAABWzJaCTyr6QXP2aYsCwEZfWIkU2GkNplSMlTOhLJfiR3LorBv8QYgEIgyOvZRmHQEzJKvkI6TP2PkRczBkcD17GE89btaaKMqEX14yHDgyfQvdasW1tj3-5bBRt0esKi9ym5En",
|
||||
"New": {
|
||||
"Vulnerability": {
|
||||
"Name": "CVE-TEST",
|
||||
"NamespaceName": "debian:8",
|
||||
"Description": "New CVE",
|
||||
"Severity": "Low",
|
||||
"FixedIn": [
|
||||
{
|
||||
"Name": "grep",
|
||||
"NamespaceName": "debian:8",
|
||||
"Version": "2.25"
|
||||
}
|
||||
]
|
||||
},
|
||||
"OrderedLayersIntroducingVulnerability": [
|
||||
{
|
||||
"Index": 1,
|
||||
"LayerName": "523ef1d23f222195488575f52a39c729c76a8c5630c9a194139cb246fb212da6"
|
||||
},
|
||||
{
|
||||
"Index": 2,
|
||||
"LayerName": "3b59c795b34670618fbcace4dac7a27c5ecec156812c9e2c90d3f4be1916b12d"
|
||||
}
|
||||
],
|
||||
"LayersIntroducingVulnerability": [
|
||||
"523ef1d23f222195488575f52a39c729c76a8c5630c9a194139cb246fb212da6",
|
||||
"3b59c795b34670618fbcace4dac7a27c5ecec156812c9e2c90d182371916b12d"
|
||||
]
|
||||
},
|
||||
"Old": {
|
||||
"Vulnerability": {
|
||||
"Name": "CVE-TEST",
|
||||
"NamespaceName": "debian:8",
|
||||
"Description": "New CVE",
|
||||
"Severity": "Low",
|
||||
"FixedIn": []
|
||||
},
|
||||
"OrderedLayersIntroducingVulnerability": [
|
||||
{
|
||||
"Index": 1,
|
||||
"LayerName": "523ef1d23f222195488575f52a39c729c76a8c5630c9a194139cb246fb212da6"
|
||||
},
|
||||
{
|
||||
"Index": 2,
|
||||
"LayerName": "3b59c795b34670618fbcace4dac7a27c5ecec156812c9e2c90d3f4be1916b12d"
|
||||
}
|
||||
],
|
||||
"LayersIntroducingVulnerability": [
|
||||
"3b59c795b34670618fbcace4dac7a27c5ecec156812c9e2c90d3f4be1916b12d",
|
||||
"523ef1d23f222195488575f52a39c729c76a8c5630c9a194139cb246fb212da6"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### DELETE /notifications/`:name`
|
||||
|
||||
#### Description
|
||||
|
||||
The delete route for the Notifications resource marks a Notification as read.
|
||||
If a notification is not marked as read, Clair will continue to notify the provided endpoints.
|
||||
The time at which this Notification was marked as read can be seen in the `Notified` property of the response GET route for Notification.
|
||||
|
||||
#### Example Request
|
||||
|
||||
```http
|
||||
DELETE http://localhost:6060/v1/notification/ec45ec87-bfc8-4129-a1c3-d2b82622175a HTTP/1.1
|
||||
```
|
||||
|
||||
#### Example Response
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Server: clair
|
||||
```
|
87
Documentation/drivers-and-data-sources.md
Normal file
87
Documentation/drivers-and-data-sources.md
Normal file
@ -0,0 +1,87 @@
|
||||
# Understanding drivers, their data sources, and creating your own
|
||||
|
||||
Clair is organized into many different software components all of which are dynamically registered at compile time.
|
||||
All of these components can be found in the `ext/` directory.
|
||||
|
||||
## Driver Types
|
||||
|
||||
| Driver Type | Functionality | Example |
|
||||
|--------------|------------------------------------------------------------------------------------|---------------|
|
||||
| featurefmt | parses features of a particular format out of a layer | apk |
|
||||
| featurens | identifies whether a particular namespaces is applicable to a layer | alpine 3.5 |
|
||||
| imagefmt | determines the location of the root filesystem location for a layer | docker |
|
||||
| notification | implements the transport used to notify of vulnerability changes | webhook |
|
||||
| versionfmt | parses and compares version strings | rpm |
|
||||
| vulnmdsrc | fetches vulnerability metadata and appends them to vulnerabilities being processed | nvd |
|
||||
| vulnsrc | fetches vulnerabilities for a set of namespaces | alpine-sec-db |
|
||||
|
||||
## Data Sources for the built-in drivers
|
||||
|
||||
| Data Source | Data Collected | Format | License |
|
||||
|-------------------------------|--------------------------------------------------------------------------|--------|-----------------|
|
||||
| [Debian Security Bug Tracker] | Debian 6, 7, 8, unstable namespaces | [dpkg] | [Debian] |
|
||||
| [Ubuntu CVE Tracker] | Ubuntu 12.04, 12.10, 13.04, 14.04, 14.10, 15.04, 15.10, 16.04 namespaces | [dpkg] | [GPLv2] |
|
||||
| [Red Hat Security Data] | CentOS 5, 6, 7 namespaces | [rpm] | [CVRF] |
|
||||
| [Oracle Linux Security Data] | Oracle Linux 5, 6, 7 namespaces | [rpm] | [CVRF] |
|
||||
| [Alpine SecDB] | Alpine 3.3, Alpine 3.4, Alpine 3.5 namespaces | [apk] | [MIT] |
|
||||
| [NIST NVD] | Generic Vulnerability Metadata | N/A | [Public Domain] |
|
||||
|
||||
[Debian Security Bug Tracker]: https://security-tracker.debian.org/tracker
|
||||
[Ubuntu CVE Tracker]: https://launchpad.net/ubuntu-cve-tracker
|
||||
[Red Hat Security Data]: https://www.redhat.com/security/data/metrics
|
||||
[Oracle Linux Security Data]: https://linux.oracle.com/security/
|
||||
[NIST NVD]: https://nvd.nist.gov
|
||||
[dpkg]: https://en.wikipedia.org/wiki/dpkg
|
||||
[rpm]: http://www.rpm.org
|
||||
[Debian]: https://www.debian.org/license
|
||||
[GPLv2]: https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
|
||||
[CVRF]: http://www.icasi.org/cvrf-licensing/
|
||||
[Public Domain]: https://nvd.nist.gov/faq
|
||||
[Alpine SecDB]: http://git.alpinelinux.org/cgit/alpine-secdb/
|
||||
[apk]: http://git.alpinelinux.org/cgit/apk-tools/
|
||||
[MIT]: https://gist.github.com/jzelinskie/6da1e2da728424d88518be2adbd76979
|
||||
|
||||
## Adding new drivers
|
||||
|
||||
In order to allow programmers to add additional behavior, Clair follows a pattern that Go programmers may recognize from the standard `database/sql` library.
|
||||
Each Driver Type defines an interface that must be implemented by drivers.
|
||||
|
||||
```go
|
||||
type DriverInterface interface {
|
||||
Action() error
|
||||
}
|
||||
|
||||
func RegisterDriver(name, DriverInterface) { ... }
|
||||
```
|
||||
|
||||
Create a new Go package containing an implementation of the driver interface.
|
||||
In the source file that implements this custom interface, create an `init()` function that registers the driver.
|
||||
|
||||
```go
|
||||
func init() {
|
||||
drivers.RegisterDriver("mydrivername", myDriverImplementation{})
|
||||
}
|
||||
|
||||
// This line causes the Go compiler to enforce that myDriverImplementation
|
||||
// implements the the DriverInterface at compile time.
|
||||
var _ drivers.DriverInterface = myDriverImplementation{}
|
||||
|
||||
type myDriverImplementation struct{}
|
||||
|
||||
func (d myDriverImplementation) Action() error {
|
||||
fmt.Println("Hello, Clair!")
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
The final step is to import the new driver in `main.go` as `_` in order ensure that the `init()` function executes, thus registering your driver.
|
||||
|
||||
```go
|
||||
import (
|
||||
...
|
||||
|
||||
_ "github.com/you/yourclairdriver"
|
||||
)
|
||||
```
|
||||
|
||||
If you believe what you've created can benefit others outside of your organization, please consider open sourcing it and creating a pull request to get it included by default.
|
@ -1,13 +1,14 @@
|
||||
# Notifications
|
||||
|
||||
Notifications are a way for Clair to inform an endpoint that changes to tracked vulnerabilities have occurred.
|
||||
Notifications are a way for Clair to inform another service that changes to tracked vulnerabilities have occurred.
|
||||
Because changes to vulnerabilities also contain the set of affected images, Clair sends only the name of the notification to another service, then depends on that service read and mark the notification as read using Clair's API.
|
||||
Because notification data can require pagination, Clair should only send the name of a notification.
|
||||
It is expected that the receiving endpoint calls the Clair API for reading notifications and marking them as read after being notified.
|
||||
If the notification is never marked as read, Clair will continue attempting to send the same notification to the endpoint indefinitely.
|
||||
If a notification is not marked as read, Clair will resend notifications at a configured interval.
|
||||
|
||||
## Webhook
|
||||
# Webhook
|
||||
|
||||
Webhook is an out-of-the-box notifier that sends the following JSON object via an HTTP POST:
|
||||
Notifications are an extensible component of Clair, but out of the box Clair supports [webhooks].
|
||||
The webhooks look like the following:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -17,11 +18,7 @@ Webhook is an out-of-the-box notifier that sends the following JSON object via a
|
||||
}
|
||||
```
|
||||
|
||||
## Custom Notifiers
|
||||
If you're interested in adding your own notification senders, read the documentation on [adding new drivers].
|
||||
|
||||
Clair can also be compiled with custom notifiers by importing them in `main.go`.
|
||||
Custom notifiers are any Go package that implements the `Notifier` interface and registers themselves with the `notifier` package.
|
||||
Notifiers are registered in [init()] similar to drivers for Go's standard [database/sql] package.
|
||||
|
||||
[init()]: https://golang.org/doc/effective_go.html#init
|
||||
[database/sql]: https://godoc.org/database/sql
|
||||
[webhooks]: https://en.wikipedia.org/wiki/Webhook
|
||||
[adding new drivers]: /Documentation/drivers-and-data-sources.md#adding-new-drivers
|
||||
|
17
Documentation/presentations.md
Normal file
17
Documentation/presentations.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Presentations
|
||||
|
||||
This document tracks projects that integrate with Clair. [Join the community](https://github.com/coreos/clair/), and help us keep the list up-to-date.
|
||||
|
||||
## Clair v1
|
||||
|
||||
| Title | Event | Video | Slides |
|
||||
|---------------------------------------------------------------------------|-------------------------------|-----------------------|-----------------------|
|
||||
| Clair: The Container Image Security Analyzer | [ContainerDays Boston 2016] | https://goo.gl/ey7QQR | https://goo.gl/WmNiwA |
|
||||
| Identifying Common Vulnerabilities and Exposures in Containers with Clair | [CoreOS Fest 2016] | https://goo.gl/fGtb9s | https://goo.gl/35gixV |
|
||||
| Clair: A Container Image Security Analyzer | [Microservices NYC] | https://goo.gl/WZaCU2 | https://goo.gl/sCXGcH |
|
||||
| Clair: A Container Image Security Analyzer | [Container Orchestration NYC] | https://goo.gl/wxi24C | https://goo.gl/VfRxv2 |
|
||||
|
||||
[ContainerDays Boston 2016]: http://dynamicinfradays.org/events/2016-boston/
|
||||
[CoreOS Fest 2016]: https://coreos.com/fest/#2016
|
||||
[Microservices NYC]: https://www.meetup.com/Microservices-NYC/events/230023492/
|
||||
[Container Orchestration NYC]: https://www.meetup.com/Kubernetes-Cloud-Native-New-York/events/229779466/
|
@ -4,5 +4,4 @@ This document tracks people and use cases for Clair in production. [Join the com
|
||||
|
||||
## [Quay.io](https://quay.io/)
|
||||
|
||||
Quay is CoreOS' enterprise-ready container registry. It displays the results of a Clair security scan on each hosted image's page.
|
||||
|
||||
Quay.io is hosted and enterprise-ready container registry. It displays the results of a Clair security scan for each image uploaded to the registry.
|
||||
|
111
Documentation/running-clair.md
Normal file
111
Documentation/running-clair.md
Normal file
@ -0,0 +1,111 @@
|
||||
# Running Clair
|
||||
|
||||
The following document outlines possible ways to deploy Clair both on your local machine and to a cluster of machines.
|
||||
|
||||
## Official Container Repositories
|
||||
|
||||
Clair is officially packaged and released as a container.
|
||||
|
||||
* [quay.io/coreos/clair] - Stable releases
|
||||
* [quay.io/coreos/clair-jwt] - Stable releases with an embedded instance of [jwtproxy]
|
||||
* [quay.io/coreos/clair-git] - Development releases
|
||||
|
||||
[quay.io/coreos/clair]: https://quay.io/repository/coreos/clair
|
||||
[jwtproxy]: https://github.com/coreos/jwtproxy
|
||||
[quay.io/coreos/clair-jwt]: https://quay.io/repository/coreos/clair-jwt
|
||||
[quay.io/coreos/clair-git]: https://quay.io/repository/coreos/clair-git
|
||||
|
||||
## Common Architecture
|
||||
|
||||
### Registry Integration
|
||||
|
||||
Clair can be integrated directly into a container registry such that the registry is responsible for interacting with Clair on behalf of the user.
|
||||
This type of setup avoids the manual scanning of images and creates a sensible location to which Clair's vulnerability notifications can be propagated.
|
||||
The registry can also be used for authorization to avoid sharing vulnerability information about images to which one might not have access.
|
||||
|
||||
![Simple Clair Diagram](https://cloud.githubusercontent.com/assets/343539/21630809/c1adfbd2-d202-11e6-9dfe-9024139d0a28.png)
|
||||
|
||||
### CI/CD Integration
|
||||
|
||||
Clair can be integrated into a CI/CD pipeline such that when a container image is produced, the step after pushing the image to a registry is to compose a request for Clair to scan that particular image.
|
||||
This type of integration is more flexible, but relies on additional components to be setup in order to secure.
|
||||
|
||||
## Deployment Strategies
|
||||
|
||||
**NOTE:** These instructions demonstrate running HEAD and not stable versions.
|
||||
|
||||
The following are community supported instructions to run Clair in a variety of ways.
|
||||
A [PostgreSQL 9.4+] database instance is required for all instructions.
|
||||
|
||||
[PostgreSQL 9.4+]: https://www.postgresql.org
|
||||
|
||||
### Cluster
|
||||
|
||||
#### Kubernetes
|
||||
|
||||
If you don't have a local Kubernetes cluster already, check out [minikube].
|
||||
|
||||
[minikube]: https://github.com/kubernetes/minikube
|
||||
|
||||
```
|
||||
git clone https://github.com/coreos/clair
|
||||
cd clair/contrib/k8s
|
||||
kubectl create secret generic clairsecret --from-file=./config.yaml
|
||||
kubectl create -f clair-kubernetes.yaml
|
||||
```
|
||||
|
||||
### Local
|
||||
|
||||
#### Docker Compose
|
||||
|
||||
```sh
|
||||
$ curl -L https://raw.githubusercontent.com/coreos/clair/master/docker-compose.yml -o $HOME/docker-compose.yml
|
||||
$ mkdir $HOME/clair_config
|
||||
$ curl -L https://raw.githubusercontent.com/coreos/clair/master/config.example.yaml -o $HOME/clair_config/config.yaml
|
||||
$ $EDITOR $HOME/clair_config/config.yaml # Edit database source to be postgresql://postgres:password@postgres:5432?sslmode=disable
|
||||
$ docker-compose -f $HOME/docker-compose.yml up -d
|
||||
```
|
||||
|
||||
Docker Compose may start Clair before Postgres which will raise an error.
|
||||
If this error is raised, manually execute `docker-compose start clair`.
|
||||
|
||||
#### Docker
|
||||
|
||||
```sh
|
||||
$ mkdir $PWD/clair_config
|
||||
$ curl -L https://raw.githubusercontent.com/coreos/clair/master/config.example.yaml -o $PWD/clair_config/config.yaml
|
||||
$ docker run -d -e POSTGRES_PASSWORD="" -p 5432:5432 postgres:9.6
|
||||
$ docker run -d -p 6060-6061:6060-6061 -v $PWD/clair_config:/config quay.io/coreos/clair-git:latest -config=/config/config.yaml
|
||||
```
|
||||
|
||||
#### Source
|
||||
|
||||
To build Clair, you need to latest stable version of [Go] and a working [Go environment].
|
||||
In addition, Clair requires some additional binaries be installed on the system [$PATH] as runtime dependencies:
|
||||
|
||||
* [git]
|
||||
* [bzr]
|
||||
* [rpm]
|
||||
* [xz]
|
||||
|
||||
[Go]: https://github.com/golang/go/releases
|
||||
[Go environment]: https://golang.org/doc/code.html
|
||||
[git]: https://git-scm.com
|
||||
[bzr]: http://bazaar.canonical.com/en
|
||||
[rpm]: http://www.rpm.org
|
||||
[xz]: http://tukaani.org/xz
|
||||
[$PATH]: https://en.wikipedia.org/wiki/PATH_(variable)
|
||||
|
||||
```sh
|
||||
$ go get github.com/coreos/clair
|
||||
$ go install github.com/coreos/clair/cmd/clair
|
||||
$ $EDITOR config.yaml # Add the URI for your postgres database
|
||||
$ ./$GOPATH/bin/clair -config=config.yaml
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### I just started up Clair and nothing appears to be working, what's the deal?
|
||||
|
||||
During the first run, Clair will bootstrap its database with vulnerability data from the configured data sources.
|
||||
It can take several minutes before the database has been fully populated, but once this data is stored in the database, subsequent updates will take far less time.
|
15
Documentation/terminology.md
Normal file
15
Documentation/terminology.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Terminiology
|
||||
|
||||
## Container
|
||||
|
||||
- *Container* - the execution of an image
|
||||
- *Image* - a set of tarballs that contain the filesystem contents and run-time metadata of a container
|
||||
- *Layer* - one of the tarballs used in the composition of an image, often expressed as a filesystem delta from another layer
|
||||
|
||||
## Specific to Clair
|
||||
|
||||
- *Ancestry* - the Clair-internal representation of an Image
|
||||
- *Feature* - anything that when present in a filesystem could be an indication of a *vulnerability* (e.g. the presence of a file or an installed software package)
|
||||
- *Feature Namespace* (featurens) - a context around *features* and *vulnerabilities* (e.g. an operating system or a programming language)
|
||||
- *Vulnerability Source* (vulnsrc) - the component of Clair that tracks upstream vulnerability data and imports them into Clair's database
|
||||
- *Vulnerability Metadata Source* (vulnmdsrc) - the component of Clair that tracks upstream vulnerability metadata and associates them with vulnerabilities in Clair's database
|
220
README.md
220
README.md
@ -11,12 +11,12 @@ Please use [releases] instead of the `master` branch in order to get stable bina
|
||||
|
||||
![Clair Logo](https://cloud.githubusercontent.com/assets/343539/21630811/c5081e5c-d202-11e6-92eb-919d5999c77a.png)
|
||||
|
||||
Clair is an open source project for the static analysis of vulnerabilities in application containers (currently including [appc] and [docker]).
|
||||
Clair is an open source project for the [static analysis] of vulnerabilities in application containers (currently including [appc] and [docker]).
|
||||
|
||||
1. In regular intervals, Clair ingests vulnerability metadata from a configured set of sources and stores it in the database.
|
||||
2. Clients use the Clair API to index their container images; this parses a list of installed _source packages_ and stores them in the database.
|
||||
3. Clients use the Clair API to query the database; correlating data is done in real time, rather than a cached result that needs re-scanning.
|
||||
4. When updates to vulnerability metadata occur, a webhook containg the affected images can be configured to page or block deployments.
|
||||
2. Clients use the Clair API to index their container images; this creates a list of _features_ present in the image and stores them in the database.
|
||||
3. Clients use the Clair API to query the database for vulnerabilities of a particular image; correlating vulnerabilities and features is done for each request, avoiding the need to rescan images.
|
||||
4. When updates to vulnerability metadata occur, a notification can be sent to alert systems that a change has occured.
|
||||
|
||||
Our goal is to enable a more transparent view of the security of container-based infrastructure.
|
||||
Thus, the project was named `Clair` after the French term which translates to *clear*, *bright*, *transparent*.
|
||||
@ -24,201 +24,35 @@ Thus, the project was named `Clair` after the French term which translates to *c
|
||||
[appc]: https://github.com/appc/spec
|
||||
[docker]: https://github.com/docker/docker/blob/master/image/spec/v1.2.md
|
||||
[releases]: https://github.com/coreos/clair/releases
|
||||
[static analysis]: https://en.wikipedia.org/wiki/Static_program_analysis
|
||||
|
||||
## When would I use Clair?
|
||||
## Getting Started
|
||||
|
||||
* You've found an image by searching the internet and want to determine if it's safe enough for you to use in production.
|
||||
* You're regularly deploying into a containerized production environment and want operations to alert or block deployments on insecure software.
|
||||
* Learn [the terminology] and about the [drivers and data sources] that power Clair
|
||||
* Watch [presentations] on the high-level goals and design of Clair
|
||||
* Follow instructions to get Clair [up and running]
|
||||
* Explore [the API] on SwaggerHub
|
||||
* Discover third party [integrations] that help integrate Clair with your infrastructure
|
||||
* Read the rest of the documentation on the [CoreOS website] or in the [Documentation directory]
|
||||
|
||||
## Documentation
|
||||
[the terminology]: /Documentation/terminology.md
|
||||
[drivers and data sources]: /Documentation/drivers-and-data-sources.md
|
||||
[presentations]: /Documentation/presentations.md
|
||||
[up and running]: /Documentation/running-clair.md
|
||||
[the API]: https://app.swaggerhub.com/apis/coreos/clair/3.0
|
||||
[integrations]: /Documentation/integrations.md
|
||||
[CoreOS website]: https://coreos.com/clair/docs/latest/
|
||||
[Documentation directory]: /Documentation
|
||||
|
||||
* [The CoreOS website] has a rendered version of the latest stable documentation
|
||||
* [Inside the Documentation directory] is the source markdown files for documentation
|
||||
## Contact
|
||||
|
||||
[The CoreOS website]: https://coreos.com/clair/docs/latest/
|
||||
[Inside the Documentation directory]: /Documentation
|
||||
- IRC: #[etcd](irc://irc.freenode.org:6667/#clair) on freenode.org
|
||||
- Bugs: [issues](https://github.com/coreos/etcd/issues)
|
||||
|
||||
## Deploying Clair
|
||||
## Contributing
|
||||
|
||||
### Container Repositories
|
||||
See [CONTRIBUTING](CONTRIBUTING.md) for details on submitting patches and the contribution workflow.
|
||||
|
||||
Clair is officially packaged and released as a container.
|
||||
## License
|
||||
|
||||
* [quay.io/coreos/clair] - Stable releases
|
||||
* [quay.io/coreos/clair-jwt] - Stable releases with an embedded instance of [jwtproxy]
|
||||
* [quay.io/coreos/clair-git] - Development releases
|
||||
|
||||
[quay.io/coreos/clair]: https://quay.io/repository/coreos/clair
|
||||
[jwtproxy]: https://github.com/coreos/jwtproxy
|
||||
[quay.io/coreos/clair-jwt]: https://quay.io/repository/coreos/clair-jwt
|
||||
[quay.io/coreos/clair-git]: https://quay.io/repository/coreos/clair-git
|
||||
|
||||
### Commercially Supported
|
||||
|
||||
Clair is professionally supported as a data source for the [Quay] Security Scanning feature.
|
||||
The setup documentation for using Clair for this environment can be found on the [Quay documentation] on the [CoreOS] website.
|
||||
Be sure to adjust the version of the documentation to the version of Quay being used in your deployment.
|
||||
|
||||
[Quay]: https://quay.io
|
||||
[Quay documentation]: https://coreos.com/quay-enterprise/docs/latest/clair.html
|
||||
[CoreOS]: https://coreos.com
|
||||
|
||||
### Community Supported
|
||||
|
||||
**NOTE:** These instructions demonstrate running HEAD and not stable versions.
|
||||
|
||||
The following are community supported instructions to run Clair in a variety of ways.
|
||||
A database instance is required for all instructions.
|
||||
|
||||
Clair currently supports and tests against:
|
||||
|
||||
* [Postgres] 9.4
|
||||
* [Postgres] 9.5
|
||||
* [Postgres] 9.6
|
||||
|
||||
[Postgres]: https://www.postgresql.org
|
||||
|
||||
#### Kubernetes
|
||||
|
||||
If you don't have a local Kubernetes cluster already, check out [minikube].
|
||||
|
||||
[minikube]: https://github.com/kubernetes/minikube
|
||||
|
||||
```
|
||||
git clone https://github.com/coreos/clair
|
||||
cd clair/contrib/k8s
|
||||
kubectl create secret generic clairsecret --from-file=./config.yaml
|
||||
kubectl create -f clair-kubernetes.yaml
|
||||
```
|
||||
|
||||
#### Docker Compose
|
||||
|
||||
```sh
|
||||
$ curl -L https://raw.githubusercontent.com/coreos/clair/master/docker-compose.yml -o $HOME/docker-compose.yml
|
||||
$ mkdir $HOME/clair_config
|
||||
$ curl -L https://raw.githubusercontent.com/coreos/clair/master/config.example.yaml -o $HOME/clair_config/config.yaml
|
||||
$ $EDITOR $HOME/clair_config/config.yaml # Edit database source to be postgresql://postgres:password@postgres:5432?sslmode=disable
|
||||
$ docker-compose -f $HOME/docker-compose.yml up -d
|
||||
```
|
||||
|
||||
Docker Compose may start Clair before Postgres which will raise an error.
|
||||
If this error is raised, manually execute `docker-compose start clair`.
|
||||
|
||||
#### Docker
|
||||
|
||||
```sh
|
||||
$ mkdir $PWD/clair_config
|
||||
$ curl -L https://raw.githubusercontent.com/coreos/clair/master/config.example.yaml -o $PWD/clair_config/config.yaml
|
||||
$ docker run -d -e POSTGRES_PASSWORD="" -p 5432:5432 postgres:9.6
|
||||
$ docker run -d -p 6060-6061:6060-6061 -v $PWD/clair_config:/config quay.io/coreos/clair-git:latest -config=/config/config.yaml
|
||||
```
|
||||
|
||||
#### Source
|
||||
|
||||
To build Clair, you need to latest stable version of [Go] and a working [Go environment].
|
||||
In addition, Clair requires some additional binaries be installed on the system [$PATH] as runtime dependencies:
|
||||
|
||||
* [git]
|
||||
* [bzr]
|
||||
* [rpm]
|
||||
* [xz]
|
||||
|
||||
[Go]: https://github.com/golang/go/releases
|
||||
[Go environment]: https://golang.org/doc/code.html
|
||||
[git]: https://git-scm.com
|
||||
[bzr]: http://bazaar.canonical.com/en
|
||||
[rpm]: http://www.rpm.org
|
||||
[xz]: http://tukaani.org/xz
|
||||
[$PATH]: https://en.wikipedia.org/wiki/PATH_(variable)
|
||||
|
||||
```sh
|
||||
$ go get github.com/coreos/clair
|
||||
$ go install github.com/coreos/clair/cmd/clair
|
||||
$ $EDITOR config.yaml # Add the URI for your postgres database
|
||||
$ ./$GOPATH/bin/clair -config=config.yaml
|
||||
```
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### Who's using Clair?
|
||||
|
||||
You can find [production users] and third party [integrations] documented in their respective pages of the local documentation.
|
||||
|
||||
[production users]: https://github.com/coreos/clair/blob/master/Documentation/production-users.md
|
||||
[integrations]: https://github.com/coreos/clair/blob/master/Documentation/integrations.md
|
||||
|
||||
### What do you mean by static analysis?
|
||||
|
||||
There are two major ways to perform analysis of programs: [Static Analysis] and [Dynamic Analysis].
|
||||
Clair has been designed to perform *static analysis*; containers never need to be executed.
|
||||
Rather, the filesystem of the container image is inspected and *features* are indexed into a database.
|
||||
By indexing the features of an image into the database, images only need to be rescanned when new *detectors* are added.
|
||||
|
||||
[Static Analysis]: https://en.wikipedia.org/wiki/Static_program_analysis
|
||||
[Dynamic Analysis]: https://en.wikipedia.org/wiki/Dynamic_program_analysis
|
||||
|
||||
### What data sources does Clair currently support?
|
||||
|
||||
| Data Source | Data Collected | Format | License |
|
||||
|-------------------------------|--------------------------------------------------------------------------|--------|-----------------|
|
||||
| [Debian Security Bug Tracker] | Debian 6, 7, 8, unstable namespaces | [dpkg] | [Debian] |
|
||||
| [Ubuntu CVE Tracker] | Ubuntu 12.04, 12.10, 13.04, 14.04, 14.10, 15.04, 15.10, 16.04 namespaces | [dpkg] | [GPLv2] |
|
||||
| [Red Hat Security Data] | CentOS 5, 6, 7 namespaces | [rpm] | [CVRF] |
|
||||
| [Oracle Linux Security Data] | Oracle Linux 5, 6, 7 namespaces | [rpm] | [CVRF] |
|
||||
| [Alpine SecDB] | Alpine 3.3, Alpine 3.4, Alpine 3.5 namespaces | [apk] | [MIT] |
|
||||
| [NIST NVD] | Generic Vulnerability Metadata | N/A | [Public Domain] |
|
||||
|
||||
[Debian Security Bug Tracker]: https://security-tracker.debian.org/tracker
|
||||
[Ubuntu CVE Tracker]: https://launchpad.net/ubuntu-cve-tracker
|
||||
[Red Hat Security Data]: https://www.redhat.com/security/data/metrics
|
||||
[Oracle Linux Security Data]: https://linux.oracle.com/security/
|
||||
[NIST NVD]: https://nvd.nist.gov
|
||||
[dpkg]: https://en.wikipedia.org/wiki/dpkg
|
||||
[rpm]: http://www.rpm.org
|
||||
[Debian]: https://www.debian.org/license
|
||||
[GPLv2]: https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
|
||||
[CVRF]: http://www.icasi.org/cvrf-licensing/
|
||||
[Public Domain]: https://nvd.nist.gov/faq
|
||||
[Alpine SecDB]: http://git.alpinelinux.org/cgit/alpine-secdb/
|
||||
[apk]: http://git.alpinelinux.org/cgit/apk-tools/
|
||||
[MIT]: https://gist.github.com/jzelinskie/6da1e2da728424d88518be2adbd76979
|
||||
|
||||
### What do most deployments look like?
|
||||
|
||||
From a high-level, most deployments integrate with the registry workflow rather than manual API usage by a human.
|
||||
They typically take up a form similar to the following diagram:
|
||||
|
||||
![Simple Clair Diagram](https://cloud.githubusercontent.com/assets/343539/21630809/c1adfbd2-d202-11e6-9dfe-9024139d0a28.png)
|
||||
|
||||
### I just started up Clair and nothing appears to be working, what's the deal?
|
||||
|
||||
During the first run, Clair will bootstrap its database with vulnerability data from the configured data sources.
|
||||
It can take several minutes before the database has been fully populated, but once this data is stored in the database, subsequent updates will take far less time.
|
||||
|
||||
### What terminology do I need to understand to work with Clair internals?
|
||||
|
||||
- *Image* - a tarball of the contents of a container
|
||||
- *Layer* - an *appc* or *Docker* image that may or may not be dependent on another image
|
||||
- *Feature* - anything that when present could be an indication of a *vulnerability* (e.g. the presence of a file or an installed software package)
|
||||
- *Feature Namespace* - a context around *features* and *vulnerabilities* (e.g. an operating system)
|
||||
- *Vulnerability Updater* - a Go package that tracks upstream vulnerability data and imports them into Clair
|
||||
- *Vulnerability Metadata Appender* - a Go package that tracks upstream vulnerability metadata and appends them into vulnerabilities managed by Clair
|
||||
|
||||
### How can I customize Clair?
|
||||
|
||||
The major components of Clair are all programmatically extensible in the same way Go's standard [database/sql] package is extensible.
|
||||
Everything extensible is located in the `ext` directory.
|
||||
|
||||
Custom behavior can be accomplished by creating a package that contains a type that implements an interface declared in Clair and registering that interface in [init()].
|
||||
To expose the new behavior, unqualified imports to the package must be added in your own custom [main.go], which should then start Clair using `Boot(*config.Config)`.
|
||||
|
||||
[database/sql]: https://godoc.org/database/sql
|
||||
[init()]: https://golang.org/doc/effective_go.html#init
|
||||
[main.go]: https://github.com/coreos/clair/blob/master/cmd/clair/main.go
|
||||
|
||||
### Are there any public presentations on Clair?
|
||||
|
||||
- _Clair: The Container Image Security Analyzer @ ContainerDays Boston 2016_ - [Event](http://dynamicinfradays.org/events/2016-boston/) [Video](https://www.youtube.com/watch?v=Kri67PtPv6s) [Slides](https://docs.google.com/presentation/d/1ExQGZs-pQ56TpW_ifcUl2l_ml87fpCMY6-wdug87OFU)
|
||||
- _Identifying Common Vulnerabilities and Exposures in Containers with Clair @ CoreOS Fest 2016_ - [Event](https://coreos.com/fest/) [Video](https://www.youtube.com/watch?v=YDCa51BK2q0) [Slides](https://docs.google.com/presentation/d/1pHSI_5LcjnZzZBPiL1cFTZ4LvhzKtzh86eE010XWNLY)
|
||||
- _Clair: A Container Image Security Analyzer @ Microservices NYC_ - [Event](https://www.meetup.com/Microservices-NYC/events/230023492/) [Video](https://www.youtube.com/watch?v=ynwKi2yhIX4) [Slides](https://docs.google.com/presentation/d/1ly9wQKQIlI7rlb0JNU1_P-rPDHU4xdRCCM3rxOdjcgc)
|
||||
- _Clair: A Container Image Security Analyzer @ Container Orchestration NYC_ - [Event](https://www.meetup.com/Container-Orchestration-NYC/events/229779466/) [Video](https://www.youtube.com/watch?v=wTfCOUDNV_M) [Slides](https://docs.google.com/presentation/d/1ly9wQKQIlI7rlb0JNU1_P-rPDHU4xdRCCM3rxOdjcgc)
|
||||
Clair is under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details.
|
||||
|
Loading…
Reference in New Issue
Block a user