In my last article, I showed how we can use Java to access StorageGRID Webscale's S3 API endpoint. In this post, we'll look into configuring self-signed SSL certificates to secure the connection between the API clients and the StorageGRID Webscale system.
As a first step, we need to generate our private key and the certificate itself. If you already have an certificate you want to use, you may skip this step.
> openssl genrsa -out server.key 2048
Generating RSA private key, 2048 bit long modulus .................+++ ...........................................................+++ e is 65537 (0x10001)
> openssl req -new -x509 -key server.key -out server.crt -days 3650
You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:DE State or Province Name (full name) [Some-State]:BY Locality Name (eg, city) :Munich Organization Name (eg, company) [Internet Widgits Pty Ltd]:MyCompany Organizational Unit Name (eg, section) :IT Common Name (e.g. server FQDN or YOUR name) :*.storagegrid.mycompany.com Email Address :firstname.lastname@example.org
Note, that setting up the correct hostname is important, so that hostname verification can function properly. In order to achieve that, make sure that the client can resolve the gateway and storage nodes' names properly via DNS (more specifically, all nodes that run CLB or LDR services). For the certificate, use wildcards, e.g., *.storagegrid.mycompany.com, given that, e.g., your gateway nodes are gw1.storagegrid.mycompany.com and gw2.storagegrid.mycompany.com. As a side note, hostnames with wildcards need at least 2 dots (e.g., *.mycompany.com).
Next, we'll log into the NMS node (the admin interface), where we navigate to Grid Management -> Grid Configuration -> Configuration Tab
There, we'll paste the contents of server.crt into the "Custom Server Certificate" section and the server.key into the "Custom Private Key" section. Once done, click "Apply Changes". All API endpoints will now have the new certificate.
S3 via Java
Now that we have our certificate set up, we need to make our JRE aware of the new certificate. Since the certificate is not signed by an external certification authority (CA), our JRE doesn't trust it, and also has no way to verify it. Therefore, we need to add it manually to the list of trusted certificates.
Either, we can do this JVM wide:
sudo keytool -importcert -file server.crt -alias grid_certificate -keystore $JAVA_HOME/jre/lib/security/cacerts
The default password for the store is "changeit". This means all applications using this JRE installation are now able to establish trusted HTTPS connections to the StorageGRID API endpoint (they still require S3 credentials though!).
The other option is to create a new JRE truststore and pass it into the JVM during startup via the -Djavax.net.ssl.trustStore=store.jks flag.
For setting up the S3 user in StorageGRID and accessing StorageGRID's S3 endpoint, see my other blog post: Accessing StorageGRID Webscale throught its S3 API
S3 via Ruby
Firstly, set up a S3 user in StorageGRID (see first part of Accessing StorageGRID Webscale throught its S3 API) and also create a profile with the S3 credentials under ~/.aws/credentials as explained in the referenced blog post. In this example, I was using the following version of the AWS SDK for Ruby (Version 1):
> gem list aws-sdk *** LOCAL GEMS *** aws-sdk-v1 (1.59.1)
In this example we'll use the AWS Ruby SDK in Version 1. For using Version 2, please see this post. Code wise, we need to reference our credential profile 'webscale' and a gateway node address. Since Ruby doesn't know about the self-signed certificate we created, we need to manually specify the public part of the certificate. Otherwise, we'll see SSL certificate errors: `connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError)
require 'aws-sdk-v1' s3 = AWS::S3::Client.new( credential_provider: AWS::Core::CredentialProviders::SharedCredentialFileProvider.new(profile_name: 'webscale'), endpoint: 'site1-gw1.storagegrid.poc.com:8082', s3_force_path_style: true, ssl_ca_file: 'server.crt', ssl_verify_peer: true ) # Standard S3 code starts here... puts s3.list_buckets()
That's it, you should now be able to access StorageGRID via HTTPS in a secure fashion. If you have any questions, please let me know!
Follow me on Twitter: @clemenssiebler