github.com/rkt/rkt@v1.30.1-0.20200224141603-171c416fac02/Documentation/signing-and-verification-guide.md (about)

     1  # Signing and Verification Guide
     2  
     3  This guide will walk you through signing, distributing, and verifying the hello ACI created in the [getting started guide][getting-started].
     4  
     5  ```
     6  hello-0.0.1-linux-amd64.aci
     7  ```
     8  
     9  * [Signing ACIs](#signing-acis)
    10  * [Distributing Images via Meta Discovery](#distributing-images-via-meta-discovery)
    11  * [Verifying Images with rkt](#verifying-images-with-rkt)
    12  * [Establishing Trust](#establishing-trust)
    13  * [Example Usage](#example-usage)
    14  
    15  ## Signing ACIs
    16  
    17  By default rkt requires ACIs to be signed using a gpg detached signature.
    18  The following steps will walk you through the creation of a gpg keypair suitable for signing an ACI.
    19  If you have an existing gpg signing key skip to the [Signing the ACI](#signing-the-aci) step.
    20  
    21  ### Generate a gpg signing key
    22  
    23  Create a file named `gpg-batch` with the following contents:
    24  
    25  ```
    26  %echo Generating a default key
    27  Key-Type: RSA
    28  Key-Length: 2048
    29  Subkey-Type: RSA
    30  Subkey-Length: 2048
    31  Name-Real: Carly Container
    32  Name-Comment: ACI signing key
    33  Name-Email: carly@example.com
    34  Expire-Date: 0
    35  Passphrase: rkt
    36  %pubring rkt.pub
    37  %secring rkt.sec
    38  %commit
    39  %echo done
    40  ```
    41  
    42  #### Generate the key using batch mode
    43  
    44  ```
    45  $ gpg --batch --gen-key gpg-batch
    46  ```
    47  
    48  #### List the keys
    49  
    50  ```
    51  $ gpg --no-default-keyring \
    52  --secret-keyring ./rkt.sec --keyring ./rkt.pub --list-keys
    53  ./rkt.pub
    54  ------------
    55  pub   2048R/26EF7A14 2015-01-09
    56  uid       [ unknown] Carly Container (ACI signing key) <carly@example.com>
    57  sub   2048R/B9C074CD 2015-01-09
    58  ```
    59  
    60  From the output above the level of trust for the signing key is unknown.
    61  This will cause the following warning if we attempt to validate an ACI signed with this key using the gpg cli:
    62  
    63  ```
    64  gpg: WARNING: This key is not certified with a trusted signature!
    65  ```
    66  
    67  Since we know exactly where this key came from let's trust it:
    68  
    69  ```
    70  $ gpg --no-default-keyring \
    71  --secret-keyring ./rkt.sec \
    72  --keyring ./rkt.pub \
    73  --edit-key 26EF7A14 \
    74  trust
    75  gpg (GnuPG/MacGPG2) 2.0.22; Copyright (C) 2013 Free Software Foundation, Inc.
    76  This is free software: you are free to change and redistribute it.
    77  There is NO WARRANTY, to the extent permitted by law.
    78  
    79  Secret key is available.
    80  
    81  pub  2048R/26EF7A14  created: 2015-01-09  expires: never       usage: SC
    82                       trust: unknown       validity: unknown
    83  sub  2048R/B9C074CD  created: 2015-01-09  expires: never       usage: E
    84  [ unknown] (1). Carly Container (ACI signing key) <carly@example.com>
    85  
    86  Please decide how far you trust this user to correctly verify other users' keys
    87  (by looking at passports, checking fingerprints from different sources, etc.)
    88  
    89    1 = I don't know or won't say
    90    2 = I do NOT trust
    91    3 = I trust marginally
    92    4 = I trust fully
    93    5 = I trust ultimately
    94    m = back to the main menu
    95  
    96  Your decision? 5
    97  Do you really want to set this key to ultimate trust? (y/N) y
    98  
    99  pub  2048R/26EF7A14  created: 2015-01-09  expires: never       usage: SC
   100                       trust: ultimate      validity: unknown
   101  sub  2048R/B9C074CD  created: 2015-01-09  expires: never       usage: E
   102  [ unknown] (1). Carly Container (ACI signing key) <carly@example.com>
   103  Please note that the shown key validity is not necessarily correct
   104  unless you restart the program.
   105  
   106  gpg> quit
   107  ```
   108  
   109  #### Export the public key
   110  
   111  ```
   112  $ gpg --no-default-keyring --armor \
   113  --secret-keyring ./rkt.sec --keyring ./rkt.pub \
   114  --export carly@example.com > pubkeys.gpg
   115  ```
   116  
   117  ### Signing the ACI
   118  
   119  ```
   120  $ gpg --no-default-keyring --armor \
   121  --secret-keyring ./rkt.sec --keyring ./rkt.pub \
   122  --output hello-0.0.1-linux-amd64.aci.asc \
   123  --detach-sig hello-0.0.1-linux-amd64.aci
   124  ```
   125  
   126  #### Verify the image using gpg
   127  
   128  ```
   129  $ gpg --no-default-keyring \
   130  --secret-keyring ./rkt.sec --keyring ./rkt.pub \
   131  --verify hello-0.0.1-linux-amd64.aci.asc hello-0.0.1-linux-amd64.aci
   132  gpg: Signature made Fri Jan  9 05:01:49 2015 PST using RSA key ID 26EF7A14
   133  gpg: Good signature from "Carly Container (ACI signing key) <carly@example.com>" [ultimate]
   134  ```
   135  
   136  At this point you should have the following three files:
   137  
   138  ```
   139  hello-0.0.1-linux-amd64.aci.asc
   140  hello-0.0.1-linux-amd64.aci
   141  pubkeys.gpg
   142  ```
   143  
   144  ## Distributing Images via Meta Discovery
   145  
   146  Host `example.com/hello` with the following HTML contents and meta tags:
   147  
   148  ```html
   149  <!DOCTYPE html>
   150  <html lang="en">
   151    <head>
   152      <meta charset="utf-8">
   153      <meta name="ac-discovery" content="example.com/hello https://example.com/images/{name}-{version}-{os}-{arch}.{ext}">
   154      <meta name="ac-discovery-pubkeys" content="example.com/hello https://example.com/pubkeys.gpg">
   155    </head>
   156  </html>
   157  ```
   158  
   159  Serve the following files at the locations described in the meta tags:
   160  
   161  ```
   162  https://example.com/images/example.com/hello-0.0.1-linux-amd64.aci.asc
   163  https://example.com/images/example.com/hello-0.0.1-linux-amd64.aci
   164  https://example.com/pubkeys.gpg
   165  ```
   166  
   167  ### rkt Integration
   168  
   169  Let's walk through the steps rkt takes when fetching images using Meta Discovery.
   170  The following rkt command:
   171  
   172  ```
   173  $ rkt run example.com/hello:0.0.1
   174  ```
   175  
   176  results in rkt retrieving the following URIs:
   177  
   178  ```
   179  https://example.com/hello?ac-discovery=1
   180  https://example.com/images/example.com/hello-0.0.1-linux-amd64.aci
   181  https://example.com/images/example.com/hello-0.0.1-linux-amd64.aci.asc
   182  ```
   183  
   184  The first response contains the template URL used to download the ACI and detached signature file.
   185  
   186  ```
   187  <meta name="ac-discovery" content="example.com/hello https://example.com/images/{name}-{version}-{os}-{arch}.{ext}">
   188  ```
   189  
   190  rkt populates the `{os}` and `{arch}` based on the current running system.
   191  The `{version}` will be taken from the tag given on the command line or "latest" if not supplied.
   192  The `{ext}` will be substituted appropriately depending on artifact being retrieved: .aci will be used for ACI images and .aci.asc will be used for detached signatures.
   193  
   194  Once the ACI image has been downloaded rkt will extract the image's name from the image metadata.
   195  The image's name will be used to locate trusted public keys in the rkt keystore and perform signature validation.
   196  
   197  ## Verifying Images with rkt
   198  
   199  ### Establishing Trust
   200  
   201  By default rkt does not trust any signing keys.
   202  Trust is established by storing public keys in the rkt keystore.
   203  This can be done using [`rkt trust`][rkt-trust] or manually, using the procedures described in the next section.
   204  
   205  The following directories make up the default rkt keystore layout:
   206  
   207  ```
   208  /etc/rkt/trustedkeys/root.d
   209  /etc/rkt/trustedkeys/prefix.d
   210  /usr/lib/rkt/trustedkeys/root.d
   211  /usr/lib/rkt/trustedkeys/prefix.d
   212  ```
   213  
   214  System administrators should store trusted keys under `/etc/rkt` as `/usr/lib/rkt` is designed to be used by the OS distribution.
   215  Trusted keys are saved in the desired directory named after the fingerprint of the public key.
   216  System administrators can "disable" a trusted key by writing an empty file under `/etc/rkt`.
   217  For example, if your OS distribution shipped with the following trusted key:
   218  
   219  ```
   220  /usr/lib/rkt/trustedkeys/prefix.d/coreos.com/a175e31de7e3c5b9d2c4603e4dfb22bf75ef7a23
   221  ```
   222  
   223  you can disable it by writing the following empty file:
   224  
   225  ```
   226  /etc/rkt/trustedkeys/prefix.d/coreos.com/a175e31de7e3c5b9d2c4603e4dfb22bf75ef7a23
   227  ```
   228  
   229  ### Trusting the example.com/hello key
   230  
   231  As an example, let's look at how we can trust a key used to sign images of the prefix `example.com/hello`
   232  
   233  #### Using rkt trust
   234  
   235  The easiest way to trust a key is to use the [`rkt trust`][rkt-trust] subcommand.
   236  In this case, we directly pass it the URI containing the public key we wish to trust:
   237  
   238  ```
   239  $ rkt trust --prefix=example.com/hello https://example.com/pubkeys.gpg
   240  Prefix: "example.com/hello"
   241  Key: "https://example.com/aci-pubkeys.gpg"
   242  GPG key fingerprint is: B346 E31D E7E3 C6F9 D1D4  603F 4DFB 61BF 26EF 7A14
   243  	Carly Container (ACI signing key) <carly@example.com>
   244  	Are you sure you want to trust this key (yes/no)? yes
   245  	Trusting "https://example.com/aci-pubkeys.gpg" for prefix "example.com/hello".
   246  	Added key for prefix "example.com/hello" at "/etc/rkt/trustedkeys/prefix.d/example.com/hello/b346e31de7e3c6f9d1d4603f4dfb61bf26ef7a14"
   247  ```
   248  
   249  Now the public key with fingerprint `b346e31de7e3c6f9d1d4603f4dfb61bf26ef7a14` will be trusted for all images with a name prefix of `example.com/hello`.
   250  
   251  #### Manually adding keys
   252  
   253  An alternative to using [`rkt trust`][rkt-trust] is to manually trust keys by adding them to rkt's database.
   254  We do this by downloading the key, capturing its fingerprint, and storing it in the database using the fingerprint as filename
   255  
   256  ##### Download the public key
   257  
   258  ```
   259  $ curl -O https://example.com/pubkeys.gpg
   260  ```
   261  
   262  ###### Capture the public key fingerprint
   263  
   264  ```
   265  $ gpg --no-default-keyring --with-fingerprint --keyring ./pubkeys.gpg carly@example.com
   266  pub   2048R/26EF7A14 2015-01-09
   267        Key fingerprint = B346 E31D E7E3 C6F9 D1D4  603F 4DFB 61BF 26EF 7A14
   268  uid       [ unknown] Carly Container (ACI signing key) <carly@example.com>
   269  sub   2048R/B9C074CD 2015-01-09
   270  ```
   271  
   272  Remove white spaces and convert to lowercase:
   273  
   274  ```
   275  $ echo "B346 E31D E7E3 C6F9 D1D4  603F 4DFB 61BF 26EF 7A14" | \
   276    tr -d "[:space:]" | tr '[:upper:]' '[:lower:]'
   277  ```
   278  
   279  ```
   280  b346e31de7e3c6f9d1d4603f4dfb61bf26ef7a14
   281  ```
   282  
   283  ##### Trust the key for the example.com/hello prefix
   284  
   285  ```
   286  mkdir -p /etc/rkt/trustedkeys/prefix.d/example.com/hello
   287  mv pubkeys.gpg  /etc/rkt/trustedkeys/prefix.d/example.com/hello/b346e31de7e3c6f9d1d4603f4dfb61bf26ef7a14
   288  ```
   289  
   290  Now the public key with fingerprint `b346e31de7e3c6f9d1d4603f4dfb61bf26ef7a14` will be trusted for all images with a name prefix of `example.com/hello`.
   291  
   292  #### Trusting a key globally
   293  
   294  If you would like to trust a public key for _any_ image, store the public key in one of the following "root" directories:
   295  
   296  ```
   297  /etc/rkt/trustedkeys/root.d
   298  /usr/lib/rkt/trustedkeys/root.d
   299  ```
   300  
   301  ### Example Usage
   302  
   303  #### Download, verify and run an ACI
   304  
   305  By default rkt will attempt to download the ACI detached signature and verify the image:
   306  
   307  ```
   308  # rkt run example.com/hello:0.0.1
   309  rkt: starting to discover app img example.com/hello:0.0.1
   310  rkt: starting to fetch img from http://example.com/images/example.com/hello-0.0.1-linux-amd64.aci
   311  Downloading aci: [                                             ] 7.24 KB/1.26 MB
   312  rkt: example.com/hello:0.0.1 verified signed by:
   313    Carly Container (ACI signing key) <carly@example.com>
   314  /etc/localtime is not a symlink, not updating container timezone.
   315  ^]^]Container stage1 terminated by signal KILL.
   316  ```
   317  
   318  Use the `--insecure-options=image` flag to disable image verification for a single run:
   319  
   320  ```
   321  # rkt --insecure-options=image run example.com/hello:0.0.1
   322  rkt: starting to discover app img example.com/hello:0.0.1
   323  rkt: starting to fetch img from http://example.com/images/example.com/hello-0.0.1-linux-amd64.aci
   324  rkt: warning: image signature verification has been disabled
   325  Downloading aci: [=                                            ] 32.8 KB/1.26 MB
   326  /etc/localtime is not a symlink, not updating container timezone.
   327  ^]^]Container stage1 terminated by signal KILL.
   328  ```
   329  
   330  Notice when the `--insecure-options=image` flag is used, rkt will print the following warning:
   331  
   332  ```
   333  rkt: warning: image signature verification has been disabled
   334  ```
   335  
   336  #### Download and verify an ACI
   337  
   338  Using the [`fetch`][rkt-fetch] subcommand you can download and verify an ACI without immediately running a pod.
   339  This can be useful to precache ACIs on a large number of hosts:
   340  
   341  ```
   342  # rkt fetch example.com/hello:0.0.1
   343  rkt: starting to discover app img example.com/hello:0.0.1
   344  rkt: starting to fetch img from http://example.com/images/example.com/hello-0.0.1-linux-amd64.aci
   345  Downloading aci: [                                             ] 14.5 KB/1.26 MB
   346  rkt: example.com/hello:0.0.1 verified signed by:
   347    Carly Container (ACI signing key) <carly@example.com>
   348  sha512-b3f138e10482d4b5f334294d69ae5c40
   349  ```
   350  
   351  As before, use the `--insecure-options=image` flag to disable image verification:
   352  
   353  ```
   354  # rkt --insecure-options=image fetch example.com/hello:0.0.1
   355  rkt: starting to discover app img example.com/hello:0.0.1
   356  rkt: starting to fetch img from http://example.com/images/example.com/hello-0.0.1-linux-amd64.aci
   357  rkt: warning: image signature verification has been disabled
   358  Downloading aci: [                                             ] 4.34 KB/1.26 MB
   359  sha512-b3f138e10482d4b5f334294d69ae5c40
   360  ```
   361  
   362  
   363  [getting-started]: getting-started-guide.md
   364  [rkt-fetch]: subcommands/fetch.md
   365  [rkt-trust]: subcommands/trust.md