-
Notifications
You must be signed in to change notification settings - Fork 25.8k
[DOCS] Refine full verification mode requirements for Transport layer TLS #32729
Description
Relates: https://discuss.elastic.co/t/elasticsearch-tls-with-wildcard-san/139972/7
The documentation for configuring TLS on the Transport layer could be improved to provide additional detail when configuring full verification mode for TLS on the Transport layer.
When specifying the hostname as network.publish_host or (network.host), the publish address resolves to the IP address on the network. For example, in config
network.host: ["data-0"]
results in
[2018-07-02T00:45:20,095][INFO ][o.e.t.TransportService ] [data-0] publish_address {10.0.0.6:9300}, bound_addresses {10.0.0.6:9300}
and it looks like NetworkService always resolves a string host to an InetAddress:
elasticsearch/server/src/main/java/org/elasticsearch/common/network/NetworkService.java
Lines 133 to 176 in 9b00f09
| public InetAddress resolvePublishHostAddresses(String publishHosts[]) throws IOException { | |
| if (publishHosts == null || publishHosts.length == 0) { | |
| for (CustomNameResolver customNameResolver : customNameResolvers) { | |
| InetAddress addresses[] = customNameResolver.resolveDefault(); | |
| if (addresses != null) { | |
| return addresses[0]; | |
| } | |
| } | |
| // we know it's not here. get the defaults | |
| publishHosts = new String[] {DEFAULT_NETWORK_HOST}; | |
| } | |
| InetAddress addresses[] = resolveInetAddresses(publishHosts); | |
| // TODO: allow publishing multiple addresses | |
| // for now... the hack begins | |
| // 1. single wildcard address, probably set by network.host: expand to all interface addresses. | |
| if (addresses.length == 1 && addresses[0].isAnyLocalAddress()) { | |
| HashSet<InetAddress> all = new HashSet<>(Arrays.asList(NetworkUtils.getAllAddresses())); | |
| addresses = all.toArray(new InetAddress[all.size()]); | |
| } | |
| // 2. try to deal with some (mis)configuration | |
| for (InetAddress address : addresses) { | |
| // check if its multicast: flat out mistake | |
| if (address.isMulticastAddress()) { | |
| throw new IllegalArgumentException("publish address: {" + NetworkAddress.format(address) + "} is invalid: multicast address"); | |
| } | |
| // check if its a wildcard address: this is only ok if its the only address! | |
| // (if it was a single wildcard address, it was replaced by step 1 above) | |
| if (address.isAnyLocalAddress()) { | |
| throw new IllegalArgumentException("publish address: {" + NetworkAddress.format(address) + "} is wildcard, but multiple addresses specified: this makes no sense"); | |
| } | |
| } | |
| // 3. if we end out with multiple publish addresses, select by preference. | |
| // don't warn the user, or they will get confused by bind_host vs publish_host etc. | |
| if (addresses.length > 1) { | |
| List<InetAddress> sorted = new ArrayList<>(Arrays.asList(addresses)); | |
| NetworkUtils.sortAddresses(sorted); | |
| addresses = new InetAddress[]{sorted.get(0)}; | |
| } | |
| return addresses[0]; | |
| } |
What this ultimately means is that a certificate with only a DNS Subject Alternative Name can't be used with full verification mode for the Transport layer, without also specifying an IP SAN, since communication on the Transport layer with other nodes will be using the IP address.
I think the documentation should include a NOTE admonition or similar against xpack.security.transport.ssl.verification_mode under https://www.elastic.co/guide/en/elasticsearch/reference/6.3/security-settings.html#transport-tls-ssl-settings to indicate that a certificate must include an ipAddress SAN to be used with full verification mode for the Transport layer.
It may also be worth calling this out in the certutil docs too at https://www.elastic.co/guide/en/elasticsearch/reference/current/configuring-tls.html#node-certificates ?