Este contenido no está disponible en el idioma seleccionado.
20.7. Securing Interfaces
20.7.1. Hot Rod Interface Security
20.7.1.1. Encryption of communication between Hot Rod Server and Hot Rod client
Example 20.4. Secure Hot Rod Using SSL/TLS
import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import org.infinispan.client.hotrod.RemoteCache; import org.infinispan.client.hotrod.RemoteCacheManager; import org.infinispan.client.hotrod.configuration.ConfigurationBuilder; import org.infinispan.client.hotrod.impl.ConfigurationProperties; [...] public class SslConfiguration { public static final String ISPN_IP = "127.0.0.1"; public static final String SERVER_NAME = "node0"; public static final String SASL_MECH = "EXTERNAL"; private static final String KEYSTORE_PATH = "./keystore_client.jks"; private static final String KEYSTORE_PASSWORD = "secret"; private static final String TRUSTSTORE_PATH = "./truststore_client.jks"; private static final String TRUSTSTORE_PASSWORD = "secret"; SslConfiguration(boolean enabled, String keyStoreFileName, char[] keyStorePassword, SSLContext sslContext, String trustStoreFileName, char[] trustStorePassword) { ConfigurationBuilder builder = new ConfigurationBuilder(); builder.addServer() .host(ISPN_IP) .port(ConfigurationProperties.DEFAULT_HOTROD_PORT); //setup auth builder.security() .authentication() .serverName(SERVER_NAME) .saslMechanism(SASL_MECH) .enable() .callbackHandler(new VoidCallbackHandler()); //setup encrypt builder.security() .ssl() .enable() .keyStoreFileName(KEYSTORE_PATH) .keyStorePassword(KEYSTORE_PASSWORD.toCharArray()) .trustStoreFileName(TRUSTSTORE_PATH) .trustStorePassword(TRUSTSTORE_PASSWORD.toCharArray()); RemoteCacheManager cacheManager = new RemoteCacheManager(builder.build()); RemoteCache<Object, Object> cache = cacheManager.getCache(RemoteCacheManager.DEFAULT_CACHE_NAME); } private static class VoidCallbackHandler implements CallbackHandler { @Override public void handle(Callback[] clbcks) throws IOException, UnsupportedCallbackException { } } }
Important
20.7.1.2. Securing Hot Rod to LDAP Server using SSL
PLAIN
authentication over SSL may be used for Hot Rod client authentication against an LDAP server. The Hot Rod client sends plain text credentials to the JBoss Data Grid server over SSL, and the server subsequently verifies the provided credentials against the specified LDAP server. In addition, a secure connection must be configured between the JBoss Data Grid server and the LDAP server. Refer to the JBoss Data Grid Administration and Configuration Guide for additional information on configuring the server to communicate to an LDAP backend. The example below demonstrates configuring PLAIN
authentication over SSL on the Hot Rod client side:
Example 20.5. Hot Rod Client Authentication to LDAP Server
import static org.infinispan.demo.util.CacheOps.dumpCache; import static org.infinispan.demo.util.CacheOps.onCache; import static org.infinispan.demo.util.CacheOps.putTestKV; import static org.infinispan.demo.util.CmdArgs.LOGIN_KEY; import static org.infinispan.demo.util.CmdArgs.PASS_KEY; import static org.infinispan.demo.util.CmdArgs.getCredentials; import java.util.Map; import javax.net.ssl.SSLContext; import org.infinispan.client.hotrod.RemoteCache; import org.infinispan.client.hotrod.RemoteCacheManager; import org.infinispan.client.hotrod.configuration.ConfigurationBuilder; import org.infinispan.client.hotrod.impl.ConfigurationProperties; import org.infinispan.commons.util.SslContextFactory; import org.infinispan.demo.util.SaslUtils.SimpleLoginHandler; public class HotRodPlainAuthOverSSL { public static final String ISPN_IP = "127.0.0.1"; public static final String SERVER_NAME = "node0"; public static final String SASL_MECH = "PLAIN"; private static final String SECURITY_REALM = "ApplicationRealm"; private static final String TRUSTSTORE_PATH = "./truststore_client.jks"; private static final String TRUSTSTORE_PASSWORD = "secret"; public static void main(String[] args) { Map<String, String> userArgs = null; try { userArgs = getCredentials(args); } catch (IllegalArgumentException e) { System.err.println(e.getMessage()); System.err.println( "Invalid credentials format, plase provide credentials (and optionally cache name) with --cache=<cache> --user=<user> --password=<password>"); System.exit(1); } ConfigurationBuilder builder = new ConfigurationBuilder(); builder.addServer().host(ISPN_IP).port(ConfigurationProperties.DEFAULT_HOTROD_PORT); //set up PLAIN auth builder.security().authentication().serverName(SERVER_NAME).saslMechanism(SASL_MECH).enable().callbackHandler( new SimpleLoginHandler(userArgs.get(LOGIN_KEY), userArgs.get(PASS_KEY), SECURITY_REALM)); //set up SSL SSLContext cont = SslContextFactory.getContext(null, null, TRUSTSTORE_PATH, TRUSTSTORE_PASSWORD.toCharArray()); builder.security().ssl().sslContext(cont).enable(); RemoteCacheManager cacheManager = new RemoteCacheManager(builder.build()); RemoteCache<Object, Object> cache = cacheManager.getCache(RemoteCacheManager.DEFAULT_CACHE_NAME); onCache(cache, putTestKV.andThen(dumpCache)); cacheManager.stop(); System.exit(0); } }
Important
20.7.1.3. User Authentication over Hot Rod Using SASL
PLAIN
is the least secure mechanism because credentials are transported in plain text format. However, it is also the simplest mechanism to implement. This mechanism can be used in conjunction with encryption (SSL) for additional security.DIGEST-MD5
is a mechanism than hashes the credentials before transporting them. As a result, it is more secure than thePLAIN
mechanism.GSSAPI
is a mechanism that uses Kerberos tickets. As a result, it requires a correctly configured Kerberos Domain Controller (for example, Microsoft Active Directory).EXTERNAL
is a mechanism that obtains the required credentials from the underlying transport (for example, from aX.509
client certificate) and therefore requires client certificate encryption to work correctly.
20.7.1.3.1. Configure Hot Rod Authentication (GSSAPI/Kerberos)
Procedure 20.1. Configure SASL GSSAPI/Kerberos Authentication - Client-side Configuration
- Ensure that the Server-Side configuration has been completed. As this is configured declaratively this configuration is found in the JBoss Data Grid Administration and Configuration Guide.
- Define a login module in a login configuration file (
gss.conf
) on the client side:GssExample { com.sun.security.auth.module.Krb5LoginModule required client=TRUE; };
- Set up the following system properties:
java.security.auth.login.config=gss.conf java.security.krb5.conf=/etc/krb5.conf
Note
Thekrb5.conf
file is dependent on the environment and must point to the Kerberos Key Distribution Center. - Implement the
CallbackHandler
:public class MyCallbackHandler implements CallbackHandler { final private String username; final private char[] password; final private String realm; public MyCallbackHandler() { } public MyCallbackHandler (String username, String realm, char[] password) { this.username = username; this.password = password; this.realm = realm; } @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (Callback callback : callbacks) { if (callback instanceof NameCallback) { NameCallback nameCallback = (NameCallback) callback; nameCallback.setName(username); } else if (callback instanceof PasswordCallback) { PasswordCallback passwordCallback = (PasswordCallback) callback; passwordCallback.setPassword(password); } else if (callback instanceof AuthorizeCallback) { AuthorizeCallback authorizeCallback = (AuthorizeCallback) callback; authorizeCallback.setAuthorized(authorizeCallback.getAuthenticationID().equals( authorizeCallback.getAuthorizationID())); } else if (callback instanceof RealmCallback) { RealmCallback realmCallback = (RealmCallback) callback; realmCallback.setText(realm); } else { throw new UnsupportedCallbackException(callback); } } } }
- Configure the Hot Rod Client, as seen in the below snippet:
LoginContext lc = new LoginContext("GssExample", new MyCallbackHandler("krb_user", "krb_password".toCharArra())); lc.login(); Subject clientSubject = lc.getSubject(); ConfigurationBuilder clientBuilder = new ConfigurationBuilder(); clientBuilder.addServer() .host("127.0.0.1") .port(11222) .socketTimeout(1200000) .security() .authentication() .enable() .serverName("infinispan-server") .saslMechanism("GSSAPI") .clientSubject(clientSubject) .callbackHandler(new MyCallbackHandler()); remoteCacheManager = new RemoteCacheManager(clientBuilder.build()); RemoteCache<String, String> cache = remoteCacheManager.getCache("secured");
20.7.1.3.2. Configure Hot Rod Authentication (MD5)
- Ensure that the server has been configured for MD5 Authentication. Instructions for performing this configuration on the server are found in JBoss Data Grid's Administration and Configuration Guide.
- Implement the
CallbackHandler
:public class MyCallbackHandler implements CallbackHandler { final private String username; final private char[] password; final private String realm; public MyCallbackHandler (String username, String realm, char[] password) { this.username = username; this.password = password; this.realm = realm; } @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (Callback callback : callbacks) { if (callback instanceof NameCallback) { NameCallback nameCallback = (NameCallback) callback; nameCallback.setName(username); } else if (callback instanceof PasswordCallback) { PasswordCallback passwordCallback = (PasswordCallback) callback; passwordCallback.setPassword(password); } else if (callback instanceof AuthorizeCallback) { AuthorizeCallback authorizeCallback = (AuthorizeCallback) callback; authorizeCallback.setAuthorized(authorizeCallback.getAuthenticationID().equals( authorizeCallback.getAuthorizationID())); } else if (callback instanceof RealmCallback) { RealmCallback realmCallback = (RealmCallback) callback; realmCallback.setText(realm); } else { throw new UnsupportedCallbackException(callback); } } } }
- Connect the client to the configured Hot Rod connector as seen below:
ConfigurationBuilder clientBuilder = new ConfigurationBuilder(); clientBuilder.addServer() .host("127.0.0.1") .port(11222) .socketTimeout(1200000) .security() .authentication() .enable() .serverName("myhotrodserver") .saslMechanism("DIGEST-MD5") .callbackHandler(new MyCallbackHandler("myuser", "ApplicationRealm", "qwer1234!".toCharArray())); remoteCacheManager = new RemoteCacheManager(clientBuilder.build()); RemoteCache<String, String> cache = remoteCacheManager.getCache("secured");
20.7.2. Hot Rod C++ Client Encryption
serverCAFile
method on the SslConfigurationBuilder
. Additionally, the client's certificate may be defined with the clientCertificateFile
, allowing for client authentication.
Important
Example 20.6. Hot Rod C++ TLS Example
#include "infinispan/hotrod/ConfigurationBuilder.h" #include "infinispan/hotrod/RemoteCacheManager.h" #include "infinispan/hotrod/RemoteCache.h" #include "infinispan/hotrod/Version.h" #include "infinispan/hotrod/JBasicMarshaller.h" #include <stdlib.h> #include <iostream> #include <memory> #include <typeinfo> using namespace infinispan::hotrod; int main(int argc, char** argv) { std::cout << "TLS Test" << std::endl; if (argc < 2) { std::cerr << "Usage: " << argv[0] << " server_ca_file [client_ca_file]" << std::endl; return 1; } { ConfigurationBuilder builder; builder.addServer().host("127.0.0.1").port(11222).protocolVersion(Configuration::PROTOCOL_VERSION_24); // Enable the TLS layer and install the server public key // this ensure that the server is authenticated builder.ssl().enable().serverCAFile(argv[1]); if (argc > 2) { // Send a client certificate for authentication (optional) // without this the socket will only be encrypted std::cout << "Using supplied client certificate for authentication against the server" << std::endl; builder.ssl().clientCertificateFile(argv[2]); } // That's all. Now do business as usual RemoteCacheManager cacheManager(builder.build(), false); BasicMarshaller<std::string> *km = new BasicMarshaller<std::string>(); BasicMarshaller<std::string> *vm = new BasicMarshaller<std::string>(); RemoteCache<std::string, std::string> cache = cacheManager.getCache<std::string, std::string>(km, &Marshaller<std::string>::destroy, vm, &Marshaller<std::string>::destroy ); cacheManager.start(); cache.clear(); std::string k1("key13"); std::string v1("boron"); cache.put(k1, v1); std::unique_ptr<std::string> rv(cache.get(k1)); if (rv->compare(v1)) { std::cerr << "get/put fail for " << k1 << " got " << *rv << " expected " << v1 << std::endl; return 1; } cacheManager.stop(); } return 0; }
20.7.3. Hot Rod C# Client Encryption
ServerCAFile
method on the SslConfigurationBuilder
. Additionally, the client's certificate may be defined with the ClientCertificateFile
, allowing for client authentication.
Important
Example 20.7. Hot Rod C# TLS Example
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Infinispan.HotRod; using Infinispan.HotRod.Config; namespace TLS { /// <summary> /// This sample code shows how to perform operations over TLS using the C# client /// </summary> class TLS { static void Main(string[] args) { // Cache manager setup RemoteCacheManager remoteManager; ConfigurationBuilder conf = new ConfigurationBuilder(); conf.AddServer().Host("127.0.0.1").Port(11222).ConnectionTimeout(90000).SocketTimeout(900); SslConfigurationBuilder sslConfB = conf.Ssl(); // Retrieve the server public certificate, needed to do server authentication. Mandatory if (!System.IO.File.Exists("resources/infinispan-ca.pem")) { Console.WriteLine("File not found: resources/infinispan-ca.pem."); Environment.Exit(-1); } sslConfB.Enable().ServerCAFile("resources/infinispan-ca.pem"); // Retrieve the client public certificate, needed if the server requires client authentication. Optional if (!System.IO.File.Exists("resources/client-ca.pem")) { Console.WriteLine("File not found: resources/client-ca.pem."); Environment.Exit(-1); } sslConfB.ClientCertificateFile("resources/client-ca.pem"); // Usual business now conf.Marshaller(new JBasicMarshaller()); remoteManager = new RemoteCacheManager(conf.Build(), true); IRemoteCache<string, string> testCache = remoteManager.GetCache<string, string>(); testCache.Clear(); string k1 = "key13"; string v1 = "boron"; testCache.Put(k1, v1); } } }