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