-
Notifications
You must be signed in to change notification settings - Fork 0
Basics of Verifying Pravega Security
Table of Contents:
- Test #1: Verify security in Pravega standalone mode cluster
- Test #2: Verify security in distributed mode cluster using Docker Compose
- Client-side tasks for verifying TLS and Auth
Say, there is a new Pravega release candidate (RC) build and you want to quickly verify that Pravega security is working. This document lists some of the tests you should run.
Note:
- We are assuming the branch/tag being tested is
v0.10.1-rc0
. Replace it with the appropriate version when running the commands mentioned in these tests when you run them against another branch. - These tests don't verify all the Security features of Pravega, but rather verify Pravega securiy at a "sanity" level only.
The goal of this test is to verify TLS and auth in Pravega standalone mode cluster. In this example, we run Pravega from the source code, but you can also use the release distribution.
-
Clone the repo.
$ git clone -b v0.10.1-rc0 https://github.com/pravega/pravega.git
-
Change directory to pravega.
$ cd pravega
-
Enable and configure TLS and auth by modifying
/path/to/pravega/config/standalone-config.properties
file.New Config (since Pravega 0.8.x):
# Enable and configure Auth: singlenode.security.auth.enable=true singlenode.security.auth.credentials.username=admin singlenode.security.auth.credentials.pwd=1111_aaaa singlenode.security.auth.pwdAuthHandler.accountsDb.location=../config/passwd # Enable and configure TLS: singlenode.security.tls.enable=true singlenode.security.tls.protocolVersion=TLSv1.2,TLSv1.3 singlenode.security.tls.privateKey.location=../config/server-key.key singlenode.security.tls.certificate.location=../config/server-cert.crt singlenode.security.tls.keyStore.location=../config/server.keystore.jks singlenode.security.tls.keyStore.pwd.location=../config/server.keystore.jks.passwd singlenode.security.tls.trustStore.location=../config/client.truststore.jks
Old Config:
# Enable and configure Auth: singlenode.enableAuth=true singlenode.userName=admin singlenode.passwd=1111_aaaa singlenode.passwdFile=../config/passwd # Enable and configure TLS: singlenode.enableTls=true singlenode.keyFile=../config/server-key.key singlenode.certFile=../config/server-cert.crt singlenode.keyStoreJKS=../config/server.keystore.jks singlenode.keyStoreJKSPasswordFile=../config/server.keystore.jks.passwd singlenode.trustStoreJKS=../config/client.truststore.jks
-
Start the Standalone mode cluster.
./gradlew startStandalone
-
Build pravega/pravega and pravega/bookkeeper Docker images locally from source code.
$ git clone -b v0.10.1-rc0 https://github.com/pravega/pravega.git $ cd pravega $ sudo ./gradlew docker
-
Ensure that the
pravega/pravega:latest
andpravega/bookkeeper:latest
images point to the newly created images, by inspecting the images manually using:$ sudo docker images
. -
Create TLS material for Controller and Segment Store. See this document for how to go about it.
-
Prepare a Docker Compose application deployment file. In this manifest, we enable TLS and Auth for both Controller and Segment Store.
version: "3"
services:
zookeeper:
image: zookeeper:3.6.3
ports:
- "2181:2181"
hdfs:
image: pravega/hdfs:2.7.7
ports:
- "2222:2222"
- "8020:8020"
- "50090:50090"
- "50010:50010"
- "50020:50020"
- "50075:50075"
- "50070:50070"
environment:
SSH_PORT: 2222
HDFS_HOST: ${HOST_IP}
bookie1:
image: pravega/bookkeeper:latest
ports:
- "3181:3181"
restart: always
environment:
ZK_URL: zookeeper:2181
bookiePort: 3181
links:
- zookeeper
bookie2:
image: pravega/bookkeeper:latest
ports:
- "3182:3182"
restart: always
environment:
ZK_URL: zookeeper:2181
bookiePort: 3182
links:
- zookeeper
bookie3:
image: pravega/bookkeeper:latest
ports:
- "3183:3183"
restart: always
environment:
ZK_URL: zookeeper:2181
bookiePort: 3183
links:
- zookeeper
controller:
image: pravega/pravega:latest
ports:
- "9090:9090"
- "10080:10080"
command: controller
environment:
WAIT_FOR: zookeeper:2181
ZK_URL: zookeeper:2181
REST_SERVER_PORT: 10080
JAVA_OPTS: |
-Dlog.level="DEBUG"
-Dcontroller.service.port=9090
-Dcontroller.auth.tlsEnabled=true
-controller.security.tls.protocolVersion=TLSv1.2,TLSv1.3
-Dcontroller.auth.tlsCertFile="/pki/server-cert.crt"
-Dcontroller.auth.tlsTrustStore="/pki/ca-cert.crt"
-Dcontroller.auth.tlsKeyFile="/pki/server-key.key"
-Dcontroller.zk.secureConnection=false
-Dcontroller.zk.tlsTrustStoreFile="/pki/zk.truststore.jks"
-Dcontroller.zk.tlsTrustStorePasswordFile="/pki/zk.truststore.jks.password"
-Dcontroller.rest.tlsKeyStoreFile="/pki/server.keystore.jks"
-Dcontroller.rest.tlsKeyStorePasswordFile="/pki/server.keystore.jks.passwd"
-Dcontroller.auth.enabled=true
-Dcontroller.auth.userPasswordFile="/opt/pravega/conf/passwd"
-Dconfig.controller.metricenableCSVReporter=false
-Dcontroller.auth.tokenSigningKey=secret
-Xmx512m
-XX:OnError="kill -9 p%"
-XX:+ExitOnOutOfMemoryError
-XX:+CrashOnOutOfMemoryError
-XX:+HeapDumpOnOutOfMemoryError
SERVICE_HOST_IP: segmentstore
volumes:
- /pravega/docker-compose/pki:/pki
links:
- zookeeper
segmentstore:
image: pravega/pravega:latest
ports:
- "12345:12345"
command: segmentstore
depends_on:
- hdfs
environment:
WAIT_FOR: bookie1:3181,bookie2:3182,bookie3:3183,hdfs:8020
TIER2_STORAGE: "HDFS"
HDFS_REPLICATION: 1
HDFS_URL: ${HOST_IP}:8020
ZK_URL: zookeeper:2181
CONTROLLER_URL: tcp://${HOST_IP}:9090
JAVA_OPTS: |
-Dlog.level="DEBUG"
-Dpravegaservice.enableTls=true
-Dpravegaservice.security.tls.protocolVersion=TLSv1.2,TLSv1.3
-Dpravegaservice.enableTlsReload=false
-Dpravegaservice.certFile="/pki/server-cert.crt"
-Dpravegaservice.keyFile="/pki/server-key.key"
-Dpravegaservice.secureZK=false
-Dpravegaservice.zkTrustStore="/pki/zk.truststore.jks"
-Dpravegaservice.zkTrustStorePasswordPath="/pki/zk.truststore.jks.password"
-Dpravegaservice.security.tls.server.keyStore.location="/pki/server.keystore.jks"
-Dpravegaservice.security.tls.server.keyStore.pwd.location="/pki/server.keystore.jks.passwd"
-DautoScale.tlsEnabled=true
-DautoScale.tlsCertFile="/pki/server-cert.crt"
-DautoScale.validateHostName=false
-DautoScale.authEnabled=true
-DautoScale.tokenSigningKey=secret
-Dbookkeeper.tlsEnabled=false
-Dbookkeeper.tlsTrustStorePath="/pki/bk.truststore.jks"
-Dmetrics.enableCSVReporter=false
-Dpravegaservice.publishedIPAddress=${HOST_IP}
-Dbookkeeper.bkEnsembleSize=2
-Dbookkeeper.bkAckQuorumSize=2
-Dbookkeeper.bkWriteQuorumSize=2
-Dpravega.client.auth.token="YWRtaW46MTExMV9hYWFh"
-Dpravega.client.auth.method="Basic"
-Xmx900m
-XX:OnError="kill -9 p%"
-XX:+ExitOnOutOfMemoryError
-XX:+CrashOnOutOfMemoryError
-XX:+HeapDumpOnOutOfMemoryError
volumes:
- /pravega/docker-compose/pki:/pki
links:
- zookeeper
- hdfs
- bookie1
- bookie2
- bookie3
-
Launch a cluster using steps described here.
Note:
- Make sure to replace
<host-ip>
withlocalhost
when running these tests against Standalone mode cluster. If you are running it against a distributed mode cluster, replace it with the host's IP address.
-
Verify that the server is responding by invoking the Controller REST API. The endpoint
/v1/scopes
should list the_system
scope.# The default REST interface port ois `9091` for Standalone mode cluster and manually # deployed distributed mode cluster. # # NOTE: If you are running this test against Docker-based # or Kubernetes-based deployments, you might need to replace the port `9091` with the # the default port on those environments: `10080`. $ curl -v -k -u admin:1111_aaaa https://<host-ip>:9091/v1/scopes Expected response: ... ... < HTTP/1.1 200 OK < Content-Type: application/json < Content-Length: 36 < * Connection #0 to host localhost left intact {"scopes":[{"scopeName":"_system"}]}
Now, we'll run a Pravega event writer and reader application to verify that the system is working properly.
-
Install the Pravega client and other libraries into the local Maven repository.
/path/to/pravega $./gradlew install
-
Note the Pravega client version.
$ ls -lrt ~/.m2/repository/io/pravega/pravega-client
. Say, the most recent version built from the last step is0.9.0
. -
Clone the Pravega samples repo.
Note: We are using the branch
r0.9
here as the server is of a similar branch. Replace it with an appropriate version, depending on the version you are trying to verify.$ git clone -b r0.9 https://github.com/pravega/pravega-samples.git
-
Change directory:
$ cd pravega-samples
-
Modify the
pravegaVersion
ingradle.properties
. (We noted version0.10.1
in the current version, earlier in this document.) -
Build Pravega samples.
$ ./gradlew clean installDist
-
Change directory.
$ cd pravega-samples/pravega-client-examples/build/install/pravega-client-examples/bin`
-
Run the writer:
$ bin/secureWriter -scope "myScope" -stream "myStream" -uri "tls://<host-ip>:9090" -routingkey "myKey" -message "hello world!" -truststore "/path/to/pravega/forked/batchclient-tokenprov/pravega/config/server-cert.crt" -username "admin" -password "1111_aaaa" Expected output: Done creating client config. Done creating a stream manager. Done creating a scope with the specified name: [myScope]. Done creating a stream configuration. Done creating a stream with the specified name: [myStream] and stream configuration. Done creating a client factory with the specified scope and client config. Done creating a writer. Done writing an event: [hello world!]. All done with writing! Exiting...
-
Run the reader:
$ bin/secureReader -scope "myScope" -stream "myStream" -uri "tls://<host-ip>:9090" -truststore "/path/to/pravega/forked/batchclient-tokenprov/pravega/config/server-cert.crt" -username "admin" -password "1111_aaaa" Expected output: Done creating a client config. Done creating a reader group config with specified scope: [myScope] and stream name: [myStream]. Done creating a reader group with specified name and config. Done creating a client factory with the specified scope and client config. Done creating a reader. Done reading an event: [hello world!]. All done with reading! Exiting...