Setting Up Security for a Standalone Mode Server¶
Security in Pravega is off by default. You may start Pravega Standalone mode server with security enabled by modifying the security configuration before launching it.
Depending on how you configure security, either or both of the following occurs:
- Client-server and internal communications are encrypted using SSL/TLS
- Server authenticates and authorizes client requests
For standalone mode servers, you may enable SSL/TLS, and/ auth
(short for Authentication and Authorization). We recommend that you enable both. The subsections below describe how to enable them.
Enabling SSL/TLS and Auth¶
The configuration parameter singlenode.enableTls
determines whether SSL/TLS is enabled in a standalone mode server. Its default value is false
, and therefore, SSL/TLS is disabled by default.
Similarly, the configuration parameter singlenode.enableAuth
determines whether auth
is enabled. It is disabled by default as well.
The following steps explain how to enable and configure SSL/TLS and/ auth
:
- Locate the
standalone-config.properties
file.
If you are running standalone mode server from source, you can find it under the /path/to/pravega/config
directory.
If you are running it from the distribution instead, you can find it under the /path/to/pravega-<version>/conf
directory.
- If enabling SSL/TLS, optionally prepare the certificates and keys for SSL/TLS.
In the same directory as the standalone-config.properties
file, you'll find default/provided PKI material. You may use these material for SSL/TLS.
If you'd like to create your own material instead, you may follow similar steps as those used for creating the supplied material.
- If enabling SSL/TLS, configure SSL/TLS parameters.
If you are using custom material, replace the paths of the files accordingly.
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
- If enabling
auth
, configureauth
parameters.
singlenode.enableAuth=true singlenode.userName=admin singlenode.passwd=1111_aaaa singlenode.passwdFile=../config/passwd
Note:
* The default Password Auth Handler supports Basic
authentication for client-server communications. You may deploy additional Auth Handler plugins by placing them in the classpath.
-
The default handler's configuration file shown above -
passwd
file - contains a single user with credentials containing usernameadmin
and password1111_aaaa
. -
To create additional users or change the password for the default
admin
user:a) Create a file containing 1 or more entries of the form
<user>:<password>:<acl>;
.For example: `jdoe:strong-password:*,READ_UPDATE;`
b) Use the PasswordCreatorTool to create a new file with the passwords encrypted. Configure this new file instead of the supplied
passwd
file. -
If enabling SSL/TLS, ensure that the server's certificate is trusted.
Note: This step is only needed the first time you run SSL/TLS-enabled standalone mode with a certificate. If you have already imported the certificate earlier, you don't need to do it again the next time you launch the server.
A server certificate can be rendered trusted via either Chain of Trust or via Direct Trust.
-
Chain of Trust: A chain of trust, which is the standard SSL/TLS certificate trust model, is established by verifying that the certificate is issued and signed by a trusted CA. To establish chain of trust for a certificate signed by a custom CA, we need to import the certificate of the CA into the JVM's truststore. The provided
server-cert.crt
is signed using a CA represented by another provided certificateca-cert.crt
: so, when using those certificate, you should importca-cert.crt
file. -
Direct Trust: This type of trust is established by adding the server's certificate to the truststore. It is a non-standard way of establishing trust, which is useful when using self-signed certificates.
Here's how to import the provided CA certificate file ca-cert.crt
to Java's system truststore, for establishing 'Chain of Trust':
a) Change directory to Standalone mode config directory.
```bash $ cd /path/to/pravega/config ``` or ```bash $ cd /path/to/pravega-<version>/conf ```
b) Convert the X.509 PEM (ASCII) encoded ca-cert.crt
file to DER (Binary) encoded format:
```bash $ openssl x509 -in server-cert.crt -inform pem -out ca-cert.der -outform der ```
c) Import the certificate into the local JVM's trust store:
```bash $ sudo keytool -importcert -alias local-CA \ -keystore /path/to/jre/lib/security/cacerts -file ca-cert.der ``` When prompted for keystore password, use the default JRE keystore password `changeit` or the custom one that you might have configured for the JRE.
Note: If you want to use a custom truststore instead of adding the certificate to the system truststore, create a new truststore using Java keytool utility, add the certificate to it and configure the JVM to use it by setting the system properties javax.net.ssl.trustStore
and javax.net.ssl.trustStorePassword
.
Now that you have enabled and configured security, restart the standalone mode server and verify that security is working.
Verifying Security¶
- Verify that the controller REST API is responding properly:
# If both TLS and Auth are enabled $ curl -v -k -u admin:1111_aaaa https://<host-name-or-ip/localhost>:9091/v1/scopes # If only Auth is enabled $ curl -v -u admin:1111_aaaa http://<host-name-or-ip/localhost>:9091/v1/scopes
Note: -k
in the command above avoids hostname verification and is needed only if you are enabling SSL/TLS. If you are using the provided certificate, the host's DNS name/IP isn't the subject (in CN
or SAN
), and therefore hostname verification will fail. -k
lets the command to return data successfully. You can find details about curl's options here.
- Optionally, run security-enabled Reader/Writer from Pravega sample applications against the standalone server to verify it is responding appropriately to
Read/Write
requests.
To do so, configure security in the client application and run it. The example below assumes both TLS and auth
are enabled. If TLS is disabled, modify the Controller URI scheme to tcp
instead of tls
and remove the lines that add
TLS-related client-side configuration.
ClientConfig clientConfig = ClientConfig.builder() .controllerURI(URI.create("tls://localhost:9090")) // TLS-related client-side configuration .trustStore("/path/to/ca-cert.crt") .validateHostName(false) // Auth-related client-side configuration .credentials(new DefaultCredentials(this.password, this.username)) .build();
You can find a client example with security enabled here.
Note:
* Remember that clients can access standalone mode servers through the localhost interface only. Therefore, the hostname in the Controller URI should be specified as localhost
in client applications when accessing standalone mode servers.
* .validateHostName(false)
disables hostname verification for client-to-segment-store communications.