go.etcd.io/etcd@v3.3.27+incompatible/Documentation/op-guide/security.md (about)

     1  ---
     2  title: Transport security model
     3  ---
     4  
     5  etcd supports automatic TLS as well as authentication through client certificates for both clients to server as well as peer (server to server / cluster) communication. **Note that etcd doesn't enable [RBAC based authentication][auth] or the authentication feature in the transport layer by default to reduce friction for users getting started with the database. Further, changing this default would be a breaking change for the project which was established since 2013. An etcd cluster which doesn't enable security features can expose its data to any clients.**
     6  
     7  To get up and running, first have a CA certificate and a signed key pair for one member. It is recommended to create and sign a new key pair for every member in a cluster.
     8  
     9  For convenience, the [cfssl] tool provides an easy interface to certificate generation, and we provide an example using the tool [here][tls-setup]. Alternatively, try this [guide to generating self-signed key pairs][tls-guide].
    10  
    11  ## Basic setup
    12  
    13  etcd takes several certificate related configuration options, either through command-line flags or environment variables:
    14  
    15  **Client-to-server communication:**
    16  
    17  `--cert-file=<path>`: Certificate used for SSL/TLS connections **to** etcd. When this option is set, advertise-client-urls can use the HTTPS schema.
    18  
    19  `--key-file=<path>`: Key for the certificate. Must be unencrypted.
    20  
    21  `--client-cert-auth`: When this is set etcd will check all incoming HTTPS requests for a client certificate signed by the trusted CA, requests that don't supply a valid client certificate will fail. If [authentication][auth] is enabled, the certificate provides credentials for the user name given by the Common Name field.
    22  
    23  `--trusted-ca-file=<path>`: Trusted certificate authority.
    24  
    25  `--auto-tls`: Use automatically generated self-signed certificates for TLS connections with clients.
    26  
    27  **Peer (server-to-server / cluster) communication:**
    28  
    29  The peer options work the same way as the client-to-server options:
    30  
    31  `--peer-cert-file=<path>`: Certificate used for SSL/TLS connections between peers. This will be used both for listening on the peer address as well as sending requests to other peers.
    32  
    33  `--peer-key-file=<path>`: Key for the certificate. Must be unencrypted.
    34  
    35  `--peer-client-cert-auth`: When set, etcd will check all incoming peer requests from the cluster for valid client certificates signed by the supplied CA.
    36  
    37  `--peer-trusted-ca-file=<path>`: Trusted certificate authority.
    38  
    39  `--peer-auto-tls`: Use automatically generated self-signed certificates for TLS connections between peers.
    40  
    41  If either a client-to-server or peer certificate is supplied the key must also be set. All of these configuration options are also available through the environment variables, `ETCD_CA_FILE`, `ETCD_PEER_CA_FILE` and so on.
    42  
    43  `--cipher-suites`: Comma-separated list of supported TLS cipher suites between server/client and peers (empty will be auto-populated by Go). Available from v3.2.22+, v3.3.7+, and v3.4+.
    44  
    45  ## Example 1: Client-to-server transport security with HTTPS
    46  
    47  For this, have a CA certificate (`ca.crt`) and signed key pair (`server.crt`, `server.key`) ready.
    48  
    49  Let us configure etcd to provide simple HTTPS transport security step by step:
    50  
    51  ```sh
    52  $ etcd --name infra0 --data-dir infra0 \
    53    --cert-file=/path/to/server.crt --key-file=/path/to/server.key \
    54    --advertise-client-urls=https://127.0.0.1:2379 --listen-client-urls=https://127.0.0.1:2379
    55  ```
    56  
    57  This should start up fine and it will be possible to test the configuration by speaking HTTPS to etcd:
    58  
    59  ```sh
    60  $ curl --cacert /path/to/ca.crt https://127.0.0.1:2379/v2/keys/foo -XPUT -d value=bar -v
    61  ```
    62  
    63  The command should show that the handshake succeed. Since we use self-signed certificates with our own certificate authority, the CA must be passed to curl using the `--cacert` option. Another possibility would be to add the CA certificate to the system's trusted certificates directory (usually in `/etc/pki/tls/certs` or `/etc/ssl/certs`).
    64  
    65  **OSX 10.9+ Users**: curl 7.30.0 on OSX 10.9+ doesn't understand certificates passed in on the command line.
    66  Instead, import the dummy ca.crt directly into the keychain or add the `-k` flag to curl to ignore errors.
    67  To test without the `-k` flag, run `open ./fixtures/ca/ca.crt` and follow the prompts.
    68  Please remove this certificate after testing!
    69  If there is a workaround, let us know.
    70  
    71  ## Example 2: Client-to-server authentication with HTTPS client certificates
    72  
    73  For now we've given the etcd client the ability to verify the server identity and provide transport security. We can however also use client certificates to prevent unauthorized access to etcd.
    74  
    75  The clients will provide their certificates to the server and the server will check whether the cert is signed by the supplied CA and decide whether to serve the request.
    76  
    77  The same files mentioned in the first example are needed for this, as well as a key pair for the client (`client.crt`, `client.key`) signed by the same certificate authority.
    78  
    79  ```sh
    80  $ etcd --name infra0 --data-dir infra0 \
    81    --client-cert-auth --trusted-ca-file=/path/to/ca.crt --cert-file=/path/to/server.crt --key-file=/path/to/server.key \
    82    --advertise-client-urls https://127.0.0.1:2379 --listen-client-urls https://127.0.0.1:2379
    83  ```
    84  
    85  Now try the same request as above to this server:
    86  
    87  ```sh
    88  $ curl --cacert /path/to/ca.crt https://127.0.0.1:2379/v2/keys/foo -XPUT -d value=bar -v
    89  ```
    90  
    91  The request should be rejected by the server:
    92  
    93  ```
    94  ...
    95  routines:SSL3_READ_BYTES:sslv3 alert bad certificate
    96  ...
    97  ```
    98  
    99  To make it succeed, we need to give the CA signed client certificate to the server:
   100  
   101  ```sh
   102  $ curl --cacert /path/to/ca.crt --cert /path/to/client.crt --key /path/to/client.key \
   103    -L https://127.0.0.1:2379/v2/keys/foo -XPUT -d value=bar -v
   104  ```
   105  
   106  The output should include:
   107  
   108  ```
   109  ...
   110  SSLv3, TLS handshake, CERT verify (15):
   111  ...
   112  TLS handshake, Finished (20)
   113  ```
   114  
   115  And also the response from the server:
   116  
   117  ```json
   118  {
   119      "action": "set",
   120      "node": {
   121          "createdIndex": 12,
   122          "key": "/foo",
   123          "modifiedIndex": 12,
   124          "value": "bar"
   125      }
   126  }
   127  ```
   128  
   129  Specify cipher suites to block [weak TLS cipher suites](https://github.com/etcd-io/etcd/issues/8320).
   130  
   131  TLS handshake would fail when client hello is requested with invalid cipher suites.
   132  
   133  For instance:
   134  
   135  ```bash
   136  $ etcd \
   137    --cert-file ./server.crt \
   138    --key-file ./server.key \
   139    --trusted-ca-file ./ca.crt \
   140    --cipher-suites TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
   141  ```
   142  
   143  Then, client requests must specify one of the cipher suites specified in the server:
   144  
   145  ```bash
   146  # valid cipher suite
   147  $ curl \
   148    --cacert ./ca.crt \
   149    --cert ./server.crt \
   150    --key ./server.key \
   151    -L [CLIENT-URL]/metrics \
   152    --ciphers ECDHE-RSA-AES128-GCM-SHA256
   153  
   154  # request succeeds
   155  etcd_server_version{server_version="3.2.22"} 1
   156  ...
   157  ```
   158  
   159  ```bash
   160  # invalid cipher suite
   161  $ curl \
   162    --cacert ./ca.crt \
   163    --cert ./server.crt \
   164    --key ./server.key \
   165    -L [CLIENT-URL]/metrics \
   166    --ciphers ECDHE-RSA-DES-CBC3-SHA
   167  
   168  # request fails with
   169  (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
   170  ```
   171  
   172  ## Example 3: Transport security & client certificates in a cluster
   173  
   174  etcd supports the same model as above for **peer communication**, that means the communication between etcd members in a cluster.
   175  
   176  Assuming we have our `ca.crt` and two members with their own keypairs (`member1.crt` & `member1.key`, `member2.crt` & `member2.key`) signed by this CA, we launch etcd as follows:
   177  
   178  
   179  ```sh
   180  DISCOVERY_URL=... # from https://discovery.etcd.io/new
   181  
   182  # member1
   183  $ etcd --name infra1 --data-dir infra1 \
   184    --peer-client-cert-auth --peer-trusted-ca-file=/path/to/ca.crt --peer-cert-file=/path/to/member1.crt --peer-key-file=/path/to/member1.key \
   185    --initial-advertise-peer-urls=https://10.0.1.10:2380 --listen-peer-urls=https://10.0.1.10:2380 \
   186    --discovery ${DISCOVERY_URL}
   187  
   188  # member2
   189  $ etcd --name infra2 --data-dir infra2 \
   190    --peer-client-cert-auth --peer-trusted-ca-file=/path/to/ca.crt --peer-cert-file=/path/to/member2.crt --peer-key-file=/path/to/member2.key \
   191    --initial-advertise-peer-urls=https://10.0.1.11:2380 --listen-peer-urls=https://10.0.1.11:2380 \
   192    --discovery ${DISCOVERY_URL}
   193  ```
   194  
   195  The etcd members will form a cluster and all communication between members in the cluster will be encrypted and authenticated using the client certificates. The output of etcd will show that the addresses it connects to use HTTPS.
   196  
   197  ## Example 4: Automatic self-signed transport security
   198  
   199  For cases where communication encryption, but not authentication, is needed, etcd supports encrypting its messages with automatically generated self-signed certificates. This simplifies deployment because there is no need for managing certificates and keys outside of etcd.
   200  
   201  Configure etcd to use self-signed certificates for client and peer connections with the flags `--auto-tls` and `--peer-auto-tls`:
   202  
   203  ```sh
   204  DISCOVERY_URL=... # from https://discovery.etcd.io/new
   205  
   206  # member1
   207  $ etcd --name infra1 --data-dir infra1 \
   208    --auto-tls --peer-auto-tls \
   209    --initial-advertise-peer-urls=https://10.0.1.10:2380 --listen-peer-urls=https://10.0.1.10:2380 \
   210    --discovery ${DISCOVERY_URL}
   211  
   212  # member2
   213  $ etcd --name infra2 --data-dir infra2 \
   214    --auto-tls --peer-auto-tls \
   215    --initial-advertise-peer-urls=https://10.0.1.11:2380 --listen-peer-urls=https://10.0.1.11:2380 \
   216    --discovery ${DISCOVERY_URL}
   217  ```
   218  
   219  Self-signed certificates do not authenticate identity so curl will return an error:
   220  
   221  ```sh
   222  curl: (60) SSL certificate problem: Invalid certificate chain
   223  ```
   224  
   225  To disable certificate chain checking, invoke curl with the `-k` flag:
   226  
   227  ```sh
   228  $ curl -k https://127.0.0.1:2379/v2/keys/foo -Xput -d value=bar -v
   229  ```
   230  
   231  ## Notes for DNS SRV
   232  
   233  Since v3.1.0 (except v3.2.9), discovery SRV bootstrapping authenticates `ServerName` with a root domain name from `--discovery-srv` flag. This is to avoid man-in-the-middle cert attacks, by requiring a certificate to have matching root domain name in its Subject Alternative Name (SAN) field. For instance, `etcd --discovery-srv=etcd.local` will only authenticate peers/clients when the provided certs have root domain `etcd.local` as an entry in Subject Alternative Name (SAN) field
   234  
   235  ## Notes for etcd proxy
   236  
   237  etcd proxy terminates the TLS from its client if the connection is secure, and uses proxy's own key/cert specified in `--peer-key-file` and `--peer-cert-file` to communicate with etcd members.
   238  
   239  The proxy communicates with etcd members through both the `--advertise-client-urls` and `--advertise-peer-urls` of a given member. It forwards client requests to etcd members’ advertised client urls, and it syncs the initial cluster configuration through etcd members’ advertised peer urls.
   240  
   241  When client authentication is enabled for an etcd member, the administrator must ensure that the peer certificate specified in the proxy's `--peer-cert-file` option is valid for that authentication. The proxy's peer certificate must also be valid for peer authentication if peer authentication is enabled.
   242  
   243  ## Notes for TLS authentication
   244  
   245  Since [v3.2.0](https://github.com/etcd-io/etcd/blob/master/CHANGELOG-3.2.md#v320-2017-06-09), [TLS certificates get reloaded on every client connection](https://github.com/etcd-io/etcd/pull/7829). This is useful when replacing expiry certs without stopping etcd servers; it can be done by overwriting old certs with new ones. Refreshing certs for every connection should not have too much overhead, but can be improved in the future, with caching layer. Example tests can be found [here](https://github.com/coreos/etcd/blob/b041ce5d514a4b4aaeefbffb008f0c7570a18986/integration/v3_grpc_test.go#L1601-L1757).
   246  
   247  Since [v3.2.0](https://github.com/etcd-io/etcd/blob/master/CHANGELOG-3.2.md#v320-2017-06-09), [server denies incoming peer certs with wrong IP `SAN`](https://github.com/etcd-io/etcd/pull/7687). For instance, if peer cert contains any IP addresses in Subject Alternative Name (SAN) field, server authenticates a peer only when the remote IP address matches one of those IP addresses. This is to prevent unauthorized endpoints from joining the cluster. For example, peer B's CSR (with `cfssl`) is:
   248  
   249  ```json
   250  {
   251    "CN": "etcd peer",
   252    "hosts": [
   253      "*.example.default.svc",
   254      "*.example.default.svc.cluster.local",
   255      "10.138.0.27"
   256    ],
   257    "key": {
   258      "algo": "rsa",
   259      "size": 2048
   260    },
   261    "names": [
   262      {
   263        "C": "US",
   264        "L": "CA",
   265        "ST": "San Francisco"
   266      }
   267    ]
   268  }
   269  ```
   270  
   271  when peer B's actual IP address is `10.138.0.2`, not `10.138.0.27`. When peer B tries to join the cluster, peer A will reject B with the error `x509: certificate is valid for 10.138.0.27, not 10.138.0.2`, because B's remote IP address does not match the one in Subject Alternative Name (SAN) field.
   272  
   273  Since [v3.2.0](https://github.com/etcd-io/etcd/blob/master/CHANGELOG-3.2.md#v320-2017-06-09), [server resolves TLS `DNSNames` when checking `SAN`](https://github.com/etcd-io/etcd/pull/7767). For instance, if peer cert contains only DNS names (no IP addresses) in Subject Alternative Name (SAN) field, server authenticates a peer only when forward-lookups (`dig b.com`) on those DNS names have matching IP with the remote IP address. For example, peer B's CSR (with `cfssl`) is:
   274  
   275  ```json
   276  {
   277    "CN": "etcd peer",
   278    "hosts": [
   279      "b.com"
   280    ],
   281  ```
   282  
   283  when peer B's remote IP address is `10.138.0.2`. When peer B tries to join the cluster, peer A looks up the incoming host `b.com` to get the list of IP addresses (e.g. `dig b.com`). And rejects B if the list does not contain the IP `10.138.0.2`, with the error `tls: 10.138.0.2 does not match any of DNSNames ["b.com"]`.
   284  
   285  Since [v3.2.2](https://github.com/etcd-io/etcd/blob/master/CHANGELOG-3.2.md#v322-2017-07-07), [server accepts connections if IP matches, without checking DNS entries](https://github.com/etcd-io/etcd/pull/8223). For instance, if peer cert contains IP addresses and DNS names in Subject Alternative Name (SAN) field, and the remote IP address matches one of those IP addresses, server just accepts connection without further checking the DNS names. For example, peer B's CSR (with `cfssl`) is:
   286  
   287  ```json
   288  {
   289    "CN": "etcd peer",
   290    "hosts": [
   291      "invalid.domain",
   292      "10.138.0.2"
   293    ],
   294  ```
   295  
   296  when peer B's remote IP address is `10.138.0.2` and `invalid.domain` is a invalid host. When peer B tries to join the cluster, peer A successfully authenticates B, since Subject Alternative Name (SAN) field has a valid matching IP address. See [issue#8206](https://github.com/etcd-io/etcd/issues/8206) for more detail.
   297  
   298  Since [v3.2.5](https://github.com/etcd-io/etcd/blob/master/CHANGELOG-3.2.md#v325-2017-08-04), [server supports reverse-lookup on wildcard DNS `SAN`](https://github.com/etcd-io/etcd/pull/8281). For instance, if peer cert contains only DNS names (no IP addresses) in Subject Alternative Name (SAN) field, server first reverse-lookups the remote IP address to get a list of names mapping to that address (e.g. `nslookup IPADDR`). Then accepts the connection if those names have a matching name with peer cert's DNS names (either by exact or wildcard match). If none is matched, server forward-lookups each DNS entry in peer cert (e.g. look up `example.default.svc` when the entry is `*.example.default.svc`), and accepts connection only when the host's resolved addresses have the matching IP address with the peer's remote IP address. For example, peer B's CSR (with `cfssl`) is:
   299  
   300  ```json
   301  {
   302    "CN": "etcd peer",
   303    "hosts": [
   304      "*.example.default.svc",
   305      "*.example.default.svc.cluster.local"
   306    ],
   307  ```
   308  
   309  when peer B's remote IP address is `10.138.0.2`. When peer B tries to join the cluster, peer A reverse-lookup the IP `10.138.0.2` to get the list of host names. And either exact or wildcard match the host names with peer B's cert DNS names in Subject Alternative Name (SAN) field. If none of reverse/forward lookups worked, it returns an error `"tls: "10.138.0.2" does not match any of DNSNames ["*.example.default.svc","*.example.default.svc.cluster.local"]`. See [issue#8268](https://github.com/etcd-io/etcd/issues/8268) for more detail.
   310  
   311  [v3.3.0](https://github.com/etcd-io/etcd/blob/master/CHANGELOG-3.3.md) adds [`etcd --peer-cert-allowed-cn`](https://github.com/etcd-io/etcd/pull/8616) flag to support [CN(Common Name)-based auth for inter-peer connections](https://github.com/etcd-io/etcd/issues/8262). Kubernetes TLS bootstrapping involves generating dynamic certificates for etcd members and other system components (e.g. API server, kubelet, etc.). Maintaining different CAs for each component provides tighter access control to etcd cluster but often tedious. When `--peer-cert-allowed-cn` flag is specified, node can only join with matching common name even with shared CAs. For example, each member in 3-node cluster is set up with CSRs (with `cfssl`) as below:
   312  
   313  ```json
   314  {
   315    "CN": "etcd.local",
   316    "hosts": [
   317      "m1.etcd.local",
   318      "127.0.0.1",
   319      "localhost"
   320    ],
   321  ```
   322  
   323  ```json
   324  {
   325    "CN": "etcd.local",
   326    "hosts": [
   327      "m2.etcd.local",
   328      "127.0.0.1",
   329      "localhost"
   330    ],
   331  ```
   332  
   333  ```json
   334  {
   335    "CN": "etcd.local",
   336    "hosts": [
   337      "m3.etcd.local",
   338      "127.0.0.1",
   339      "localhost"
   340    ],
   341  ```
   342  
   343  Then only peers with matching common names will be authenticated if `--peer-cert-allowed-cn etcd.local` is given. And nodes with different CNs in CSRs or different `--peer-cert-allowed-cn` will be rejected:
   344  
   345  ```bash
   346  $ etcd --peer-cert-allowed-cn m1.etcd.local
   347  
   348  I | embed: rejected connection from "127.0.0.1:48044" (error "CommonName authentication failed", ServerName "m1.etcd.local")
   349  I | embed: rejected connection from "127.0.0.1:55702" (error "remote error: tls: bad certificate", ServerName "m3.etcd.local")
   350  ```
   351  
   352  Each process should be started with:
   353  
   354  ```bash
   355  etcd --peer-cert-allowed-cn etcd.local
   356  
   357  I | pkg/netutil: resolving m3.etcd.local:32380 to 127.0.0.1:32380
   358  I | pkg/netutil: resolving m2.etcd.local:22380 to 127.0.0.1:22380
   359  I | pkg/netutil: resolving m1.etcd.local:2380 to 127.0.0.1:2380
   360  I | etcdserver: published {Name:m3 ClientURLs:[https://m3.etcd.local:32379]} to cluster 9db03f09b20de32b
   361  I | embed: ready to serve client requests
   362  I | etcdserver: published {Name:m1 ClientURLs:[https://m1.etcd.local:2379]} to cluster 9db03f09b20de32b
   363  I | embed: ready to serve client requests
   364  I | etcdserver: published {Name:m2 ClientURLs:[https://m2.etcd.local:22379]} to cluster 9db03f09b20de32b
   365  I | embed: ready to serve client requests
   366  I | embed: serving client requests on 127.0.0.1:32379
   367  I | embed: serving client requests on 127.0.0.1:22379
   368  I | embed: serving client requests on 127.0.0.1:2379
   369  ```
   370  
   371  [v3.2.19](https://github.com/etcd-io/etcd/blob/master/CHANGELOG-3.2.md) and [v3.3.4](https://github.com/etcd-io/etcd/blob/master/CHANGELOG-3.3.md) fixes TLS reload when [certificate SAN field only includes IP addresses but no domain names](https://github.com/etcd-io/etcd/issues/9541). For example, a member is set up with CSRs (with `cfssl`) as below:
   372  
   373  ```json
   374  {
   375    "CN": "etcd.local",
   376    "hosts": [
   377      "127.0.0.1"
   378    ],
   379  ```
   380  
   381  In Go, server calls `(*tls.Config).GetCertificate` for TLS reload if and only if server's `(*tls.Config).Certificates` field is not empty, or `(*tls.ClientHelloInfo).ServerName` is not empty with a valid SNI from the client. Previously, etcd always populates `(*tls.Config).Certificates` on the initial client TLS handshake, as non-empty. Thus, client was always expected to supply a matching SNI in order to pass the TLS verification and to trigger `(*tls.Config).GetCertificate` to reload TLS assets.
   382  
   383  However, a certificate whose SAN field does [not include any domain names but only IP addresses](https://github.com/etcd-io/etcd/issues/9541) would request `*tls.ClientHelloInfo` with an empty `ServerName` field, thus failing to trigger the TLS reload on initial TLS handshake; this becomes a problem when expired certificates need to be replaced online.
   384  
   385  Now, `(*tls.Config).Certificates` is created empty on initial TLS client handshake, first to trigger `(*tls.Config).GetCertificate`, and then to populate rest of the certificates on every new TLS connection, even when client SNI is empty (e.g. cert only includes IPs).
   386  
   387  ## Notes for Host Whitelist
   388  
   389  `etcd --host-whitelist` flag specifies acceptable hostnames from HTTP client requests. Client origin policy protects against ["DNS Rebinding"](https://en.wikipedia.org/wiki/DNS_rebinding) attacks to insecure etcd servers. That is, any website can simply create an authorized DNS name, and direct DNS to `"localhost"` (or any other address). Then, all HTTP endpoints of etcd server listening on `"localhost"` becomes accessible, thus vulnerable to DNS rebinding attacks. See [CVE-2018-5702](https://bugs.chromium.org/p/project-zero/issues/detail?id=1447#c2) for more detail.
   390  
   391  Client origin policy works as follows:
   392  
   393  1. If client connection is secure via HTTPS, allow any hostnames.
   394  2. If client connection is not secure and `"HostWhitelist"` is not empty, only allow HTTP requests whose Host field is listed in whitelist.
   395  
   396  Note that the client origin policy is enforced whether authentication is enabled or not, for tighter controls.
   397  
   398  By default, `etcd --host-whitelist` and `embed.Config.HostWhitelist` are set *empty* to allow all hostnames. Note that when specifying hostnames, loopback addresses are not added automatically. To allow loopback interfaces, add them to whitelist manually (e.g. `"localhost"`, `"127.0.0.1"`, etc.).
   399  
   400  ## Frequently asked questions
   401  
   402  ### I'm seeing a SSLv3 alert handshake failure when using TLS client authentication?
   403  
   404  The `crypto/tls` package of `golang` checks the key usage of the certificate public key before using it.
   405  To use the certificate public key to do client auth, we need to add `clientAuth` to `Extended Key Usage` when creating the certificate public key.
   406  
   407  Here is how to do it:
   408  
   409  Add the following section to openssl.cnf:
   410  
   411  ```
   412  [ ssl_client ]
   413  ...
   414    extendedKeyUsage = clientAuth
   415  ...
   416  ```
   417  
   418  When creating the cert be sure to reference it in the `-extensions` flag:
   419  
   420  ```
   421  $ openssl ca -config openssl.cnf -policy policy_anything -extensions ssl_client -out certs/machine.crt -infiles machine.csr
   422  ```
   423  
   424  ### With peer certificate authentication I receive "certificate is valid for 127.0.0.1, not $MY_IP"
   425  Make sure to sign the certificates with a Subject Name the member's public IP address. The `etcd-ca` tool for example provides an `--ip=` option for its `new-cert` command.
   426  
   427  The certificate needs to be signed for the member's FQDN in its Subject Name, use Subject Alternative Names (short IP SANs) to add the IP address. The `etcd-ca` tool provides `--domain=` option for its `new-cert` command, and openssl can make [it][alt-name] too.
   428  
   429  ### Does etcd encrypt data stored on disk drives?
   430  No. etcd doesn't encrypt key/value data stored on disk drives. If a user need to encrypt data stored on etcd, there are some options:
   431  * Let client applications encrypt and decrypt the data
   432  * Use a feature of underlying storage systems for encrypting stored data like [dm-crypt]
   433  
   434  ### I’m seeing a log warning that "directory X exist without recommended permission -rwx------"
   435  When etcd create certain new directories it sets file permission to 700 to prevent unprivileged access as possible. However, if user has already created a directory with own preference, etcd uses the existing directory and logs a warning message if the permission is different than 700.
   436  
   437  [cfssl]: https://github.com/cloudflare/cfssl
   438  [tls-setup]: ../../hack/tls-setup
   439  [tls-guide]: https://github.com/coreos/docs/blob/master/os/generate-self-signed-certificates.md
   440  [alt-name]: http://wiki.cacert.org/FAQ/subjectAltName
   441  [auth]: authentication.md
   442  [dm-crypt]: https://en.wikipedia.org/wiki/Dm-crypt