You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kafka.apache.org by gu...@apache.org on 2015/11/03 23:19:38 UTC

kafka git commit: KAFKA-2441: SSL/TLS in official docs

Repository: kafka
Updated Branches:
  refs/heads/trunk 5aa5f19d3 -> f413143ed


KAFKA-2441: SSL/TLS in official docs

Author: Gwen Shapira <cs...@gmail.com>

Reviewers: Guozhang Wang

Closes #406 from gwenshap/KAFKA-2441


Project: http://git-wip-us.apache.org/repos/asf/kafka/repo
Commit: http://git-wip-us.apache.org/repos/asf/kafka/commit/f413143e
Tree: http://git-wip-us.apache.org/repos/asf/kafka/tree/f413143e
Diff: http://git-wip-us.apache.org/repos/asf/kafka/diff/f413143e

Branch: refs/heads/trunk
Commit: f413143eddd713dc5f03d53fdeb10e4e7f3738b1
Parents: 5aa5f19
Author: Gwen Shapira <cs...@gmail.com>
Authored: Tue Nov 3 14:25:16 2015 -0800
Committer: Guozhang Wang <wa...@gmail.com>
Committed: Tue Nov 3 14:25:16 2015 -0800

----------------------------------------------------------------------
 docs/security.html | 145 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 145 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kafka/blob/f413143e/docs/security.html
----------------------------------------------------------------------
diff --git a/docs/security.html b/docs/security.html
index c2a9dfb..d250553 100644
--- a/docs/security.html
+++ b/docs/security.html
@@ -29,7 +29,152 @@ In release 0.9.0.0, the Kafka community added a number of features that, used ei
 The guides below explain how to configure and use the security features in both clients and brokers.
 
 <h3><a id="security_ssl">7.2 Encryption and Authentication using SSL</a></h3>
+Apache Kafka allows clients to connect over SSL. By default SSL is disabled but can be turned on as needed.
 
+<ol>
+    <li><h4>Generate SSL key and certificate for each Kafka broker</h4>
+        The first step of deploying HTTPS is to generate the key and the certificate for each machine in the cluster. You can use Java’s keytool utility to accomplish this task.
+        We will generate the key into a temporary keystore initially so that we can export and sign it later with CA.
+        <pre>$ keytool -keystore server.keystore.jks -alias localhost -validity {validity} -genkey</pre>
+
+        You need to specify two parameters in the above command:
+        <ol>
+            <li>keystore: the keystore file that stores the certificate. The keystore file contains the private key of the certificate; therefore, it needs to be kept safely.</li>
+            <li>validity: the valid time of the certificate in days.</li>
+        </ol>
+        Ensure that common name (CN) matches exactly with the fully qualified domain name (FQDN) of the server. The client compares the CN with the DNS domain name to ensure that it is indeed connecting to the desired server, not the malicious one.</li>
+
+    <li><h4>Creating your own CA</h4>
+        After the first step, each machine in the cluster has a public-private key pair, and a certificate to identify the machine. The certificate, however, is unsigned, which means that an attacker can create such a certificate to pretend to be any machine.<p>
+        Therefore, it is important to prevent forged certificates by signing them for each machine in the cluster. A certificate authority (CA) is responsible for signing certificates. CA works likes a government that issues passports—the government stamps (signs) each passport so that the passport becomes difficult to forge. Other governments verify the stamps to ensure the passport is authentic. Similarly, the CA signs the certificates, and the cryptography guarantees that a signed certificate is computationally difficult to forge. Thus, as long as the CA is a genuine and trusted authority, the clients have high assurance that they are connecting to the authentic machines.
+        <pre>openssl req <b>-new</b> -x509 -keyout ca-key -out ca-cert -days 365</pre>
+
+        The generated CA is simply a public-private key pair and certificate, and it is intended to sign other certificates.<br>
+
+        The next step is to add the generated CA to the **clients’ truststore** so that the clients can trust this CA:
+        <pre>keytool -keystore server.truststore.jks -alias CARoot <b>-import</b> -file ca-cert</pre>
+
+        <b>Note:</b> If you configure Kafka brokers to require client authentication by setting ssl.client.auth to be "requested" or "required" on <a href="#config_broker">Kafka broker config</a> then you must provide a truststore for kafka broker as well and it should have all the CA certificates that clients keys signed by.
+        <pre>keytool -keystore client.truststore.jks -alias CARoot -import -file ca-cert</pre>
+
+        In contrast to the keystore in step 1 that stores each machine’s own identity, the truststore of a client stores all the certificates that the client should trust. Importing a certificate into one’s truststore also means that trusting all certificates that are signed by that certificate. As the analogy above, trusting the government (CA) also means that trusting all passports (certificates) that it has issued. This attribute is called the chains of trust, and it is particularly useful when deploying SSL on a large Kafka cluster. You can sign all certificates in the cluster with a single CA, and have all machines share the same truststore that trusts the CA. That way all machines can authenticate all other machines.</li>
+
+        <li><h4>Signing the certificate</h4>
+        The next step is to sign all certificates generated by step 1 with the CA generated in step 2. First, you need to export the certificate from the keystore:
+        <pre>keytool -keystore server.keystore.jks -alias localhost -certreq -file cert-file</pre>
+
+        Then sign it with the CA:
+        <pre>openssl x509 -req -CA ca-cert -CAkey ca-key -in cert-file -out cert-signed -days {validity} -CAcreateserial -passin pass:{ca-password}</pre>
+
+        Finally, you need to import both the certificate of the CA and the signed certificate into the keystore:
+        <pre>
+            $ keytool -keystore server.keystore.jks -alias CARoot -import -file ca-cert
+            $ keytool -keystore server.keystore.jks -alias localhost -import -file cert-signed
+        </pre>
+
+        The definitions of the parameters are the following:
+        <ol>
+            <li>keystore: the location of the keystore</li>
+            <li>ca-cert: the certificate of the CA</li>
+            <li>ca-key: the private key of the CA</li>
+            <li>ca-password: the passphrase of the CA</li>
+            <li>cert-file: the exported, unsigned certificate of the server</li>
+            <li>cert-signed: the signed certificate of the server</li>
+        </ol>
+
+        Here is an example of a bash script with all above steps. Note that one of the commands assumes a password of `test1234`, so either use that password or edit the command before running it.
+            <pre>
+        #!/bin/bash
+        #Step 1
+        keytool -keystore server.keystore.jks -alias localhost -validity 365 -genkey
+        #Step 2
+        openssl req -new -x509 -keyout ca-key -out ca-cert -days 365
+        keytool -keystore server.truststore.jks -alias CARoot -import -file ca-cert
+        keytool -keystore client.truststore.jks -alias CARoot -import -file ca-cert
+        #Step 3
+        keytool -keystore server.keystore.jks -alias localhost -certreq -file cert-file
+        openssl x509 -req -CA ca-cert -CAkey ca-key -in cert-file -out cert-signed -days 365 -CAcreateserial -passin pass:test1234
+        keytool -keystore server.keystore.jks -alias CARoot -import -file ca-cert
+        keytool -keystore server.keystore.jks -alias localhost -import -file cert-signed
+                </pre></li>
+    <li><h4><a name="config_broker">Configuring Kafka Broker</a></h4>
+        Kafka Broker comes with the feature of listening on multiple ports thanks to [KAFKA-1809](https://issues.apache.org/jira/browse/KAFKA-1809).
+        We need to configure the following property in server.properties, which must have one or more comma-separated values:
+        <pre>listeners</pre>
+
+        If SSL is not enabled for inter-broker communication (see below for how to enable it), both PLAINTEXT and SSL ports will be necessary.
+        <pre>listeners=PLAINTEXT://host.name:port,SSL://host.name:port</pre>
+
+        Following SSL configs are needed on the broker side
+        <pre>
+        ssl.keystore.location = /var/private/ssl/kafka.server.keystore.jks
+        ssl.keystore.password = test1234
+        ssl.key.password = test1234
+        ssl.truststore.location = /var/private/ssl/kafka.server.truststore.jks
+        ssl.truststore.password = test1234
+        </pre>
+
+        Optional settings that are worth considering:
+        <ol>
+            <li>ssl.client.auth = none ("required" => client authentication is required, "requested" => client authentication is requested and client without certs can still connect when this option chosen")</li>
+            <li>ssl.cipher.suites = A cipher suite is a named combination of authentication, encryption, MAC and key exchange algorithm used to negotiate the security settings for a network connection using TLS or SSL network protocol. (Default is an empty list)</li>
+            <li>ssl.enabled.protocols = TLSv1.2,TLSv1.1,TLSv1 (list out the SSL protocols that you are going to accept from clients. Do note SSL is deprecated and using that in production is not recommended)</li>
+            <li> ssl.keystore.type = JKS</li>
+            <li>ssl.truststore.type = JKS</li>
+        </ol>
+        If you want to enable SSL for inter-broker communication, add the following to the broker properties file (it defaults to PLAINTEXT)
+        <pre>security.inter.broker.protocol = SSL</pre>
+
+        If you want to enable any cipher suites other than the defaults that comes with JVM like the ones listed here:
+        <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html">https://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html</a> you will need to install <b><a href="http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html">Unlimited Strength Policy files</a></b><br>
+
+        Once you start the broker you should be able to see in the server.log
+        <pre>with addresses: PLAINTEXT -> EndPoint(192.168.64.1,9092,PLAINTEXT),SSL -> EndPoint(192.168.64.1,9093,SSL)</pre>
+
+        To check quickly if  the server keystore and truststore are setup properly you can run the following command
+        <pre>openssl s_client -debug -connect localhost:9093 -tls1</pre> (Note: TLSv1 should be listed under ssl.enabled.protocols)<br>
+        In the output of this command you should see server's certificate:
+        <pre>
+        -----BEGIN CERTIFICATE-----
+        {variable sized random bytes}
+        -----END CERTIFICATE-----
+        subject=/C=US/ST=CA/L=Santa Clara/O=org/OU=org/CN=Sriharsha Chintalapani
+        issuer=/C=US/ST=CA/L=Santa Clara/O=org/OU=org/CN=kafka/emailAddress=test@test.com
+            </pre>
+        If the certificate does not show up or if there are any other error messages than your keystore is not setup properly.</li>
+
+        <li><h4>Configuring Kafka Clients</h4>h4>
+        SSL is supported only for new Kafka Producer & Consumer, the older API is not supported. The configs for SSL will be same for both producer & consumer.<br>
+        If client authentication is not required in the broker, then the following is a minimal configuration example:
+        <pre>
+        security.protocol = SSL
+        ssl.truststore.location = "/var/private/ssl/kafka.client.truststore.jks"
+        ssl.truststore.password = "test1234"
+            </pre>
+
+        If client authentication is required, then a keystore must be created like in step 1 and the following must also be configured:
+            <pre>
+        ssl.keystore.location = "/var/private/ssl/kafka.client.keystore.jks"
+        ssl.keystore.password = "test1234"
+        ssl.key.password = "test1234"
+                </pre>
+        Other configuration settings that may also be needed depending on our requirements and the broker configuration:\
+            <ol>
+                <li>ssl.provider (Optional). The name of the security provider used for SSL connections. Default value is the default security provider of the JVM.</li>
+                <li>ssl.cipher.suites (Optional). A cipher suite is a named combination of authentication, encryption, MAC and key exchange algorithm used to negotiate the security settings for a network connection using TLS or SSL network protocol.</li>
+                <li>ssl.enabled.protocols=TLSv1.2,TLSv1.1,TLSv1 **Should list at least one of the protocols configured on the broker side</li>
+                <li>ssl.truststore.type = "JKS"</li>
+                <li>ssl.keystore.type = "JKS"</li>
+            </ol>
+<br>
+        Examples using console-producer and console-consumer:
+        <pre>
+            kafka-console-producer.sh --broker-list localhost:9093 --topic test --new-producer --producer-property "security.protocol=SSL"  --producer-property "ssl.truststore.location=client.truststore.jks" --producer-property "ssl.truststore.password=test1234"
+
+            kafka-console-consumer.sh --bootstrap-server localhost:9093 --topic test --new-consumer --consumer.config client-ssl.properties
+            </pre>
+    </li>
+</ol>
 <h3><a id="security_sasl">7.3 Authentication using SASL</a></h3>
 
 <ol>