kafka-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From guozh...@apache.org
Subject kafka git commit: KAFKA-2441: SSL/TLS in official docs
Date Tue, 03 Nov 2015 22:19:38 GMT
Repository: kafka
Updated Branches:
  refs/heads/trunk 5aa5f19d3 -> f413143ed


KAFKA-2441: SSL/TLS in official docs

Author: Gwen Shapira <cshapi@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 <cshapi@gmail.com>
Authored: Tue Nov 3 14:25:16 2015 -0800
Committer: Guozhang Wang <wangguoz@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>


Mime
View raw message