brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aleds...@apache.org
Subject [1/2] brooklyn-library git commit: Support proxying with TLS client certificates in Nginx
Date Fri, 29 Jul 2016 15:16:43 GMT
Repository: brooklyn-library
Updated Branches:
  refs/heads/master a06cb1554 -> 532f373f7


Support proxying with TLS client certificates in Nginx


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-library/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-library/commit/835ba7e9
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-library/tree/835ba7e9
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-library/diff/835ba7e9

Branch: refs/heads/master
Commit: 835ba7e92e277524ed8f6e566b4bfa8774fe8e58
Parents: 7b1a9f7
Author: Andrew Donald Kennedy <andrew.kennedy@cloudsoftcorp.com>
Authored: Thu Jul 14 18:12:36 2016 +0100
Committer: Andrew Donald Kennedy <andrew.kennedy@cloudsoftcorp.com>
Committed: Fri Jul 29 16:09:19 2016 +0100

----------------------------------------------------------------------
 .../brooklyn/entity/proxy/ProxySslConfig.java   | 51 ++++++++++++++++++-
 .../nginx/NginxDefaultConfigGenerator.java      | 52 ++++++++++++++++++--
 2 files changed, 99 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/835ba7e9/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/ProxySslConfig.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/ProxySslConfig.java
b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/ProxySslConfig.java
index 71a8bf1..95bfdf8 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/ProxySslConfig.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/ProxySslConfig.java
@@ -41,8 +41,11 @@ public class ProxySslConfig implements Serializable {
     public static class Builder {
         @SetFromFlag protected String certificateSourceUrl;
         @SetFromFlag protected String keySourceUrl;
+        @SetFromFlag protected String clientCertificateSourceUrl;
         @SetFromFlag protected String certificateDestination;
         @SetFromFlag protected String keyDestination;
+        @SetFromFlag protected String clientCertificateDestination;
+        @SetFromFlag protected boolean verifyClient = false;
         @SetFromFlag protected boolean targetIsSsl = false;
         @SetFromFlag protected boolean reuseSessions = false;
 
@@ -52,12 +55,21 @@ public class ProxySslConfig implements Serializable {
         public Builder keySourceUrl(String val) {
             keySourceUrl = val; return this;
         }
+        public Builder clientCertificateSourceUrl(String val) {
+            clientCertificateSourceUrl = val; return this;
+        }
         public Builder certificateDestination(String val) {
             certificateDestination = val; return this;
         }
         public Builder keyDestination(String val) {
             keyDestination = val; return this;
         }
+        public Builder clientCertificateDestination(String val) {
+            clientCertificateDestination = val; return this;
+        }
+        public Builder verifyClient(boolean val) {
+            verifyClient = val; return this;
+        }
         public Builder targetIsSsl(boolean val) {
             targetIsSsl = val; return this;
         }
@@ -79,8 +91,11 @@ public class ProxySslConfig implements Serializable {
 
     private String certificateSourceUrl;
     private String keySourceUrl;
+    private String clientCertificateSourceUrl;
     private String certificateDestination;
     private String keyDestination;
+    private String clientCertificateDestination;
+    private boolean verifyClient = false;
     private boolean targetIsSsl = false;
     private boolean reuseSessions = false;
 
@@ -89,8 +104,11 @@ public class ProxySslConfig implements Serializable {
     protected ProxySslConfig(Builder builder) {
         certificateSourceUrl = builder.certificateSourceUrl;
         keySourceUrl = builder.keySourceUrl;
+        clientCertificateSourceUrl = builder.clientCertificateSourceUrl;
         certificateDestination = builder.certificateDestination;
         keyDestination = builder.keyDestination;
+        clientCertificateDestination = builder.clientCertificateDestination;
+        verifyClient = builder.verifyClient;
         targetIsSsl = builder.targetIsSsl;
         reuseSessions = builder.reuseSessions;
     }
@@ -131,6 +149,14 @@ public class ProxySslConfig implements Serializable {
         this.keySourceUrl = keySourceUrl;
     }
 
+    public String getClientCertificateSourceUrl() {
+        return clientCertificateSourceUrl;
+    }
+
+    public void setClientCertificateSourceUrl(String clientCertificateSourceUrl) {
+        this.clientCertificateSourceUrl = clientCertificateSourceUrl;
+    }
+
     /**
      * Sets the {@code ssl_certificate_path} to be used within the generated
      * {@link LoadBalancer} configuration.
@@ -171,6 +197,25 @@ public class ProxySslConfig implements Serializable {
         this.keyDestination = keyDestination;
     }
 
+    public String getClientCertificateDestination() {
+        return clientCertificateDestination;
+    }
+
+    public void setClientCertificateDestination(String clientCertificateDestination) {
+        this.clientCertificateDestination = clientCertificateDestination;
+    }
+
+    /**
+     * Whether to verify the client using certificates; default false.
+     */
+    public boolean getVerifyClient() {
+        return verifyClient;
+    }
+
+    public void setVerifyClient(boolean verifyClient) {
+        this.verifyClient = verifyClient;
+    }
+
     /**
      * Whether the downstream server (if mapping) also expects https; default false.
      */
@@ -197,7 +242,8 @@ public class ProxySslConfig implements Serializable {
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(certificateSourceUrl, keySourceUrl, certificateDestination,
keyDestination, reuseSessions, targetIsSsl);
+        return Objects.hashCode(certificateSourceUrl, keySourceUrl, certificateDestination,
keyDestination,
+                clientCertificateSourceUrl, clientCertificateDestination, verifyClient, reuseSessions,
targetIsSsl);
     }
 
     @Override
@@ -212,6 +258,9 @@ public class ProxySslConfig implements Serializable {
                 Objects.equal(certificateDestination, other.certificateDestination) &&
                 Objects.equal(keyDestination, other.keyDestination) &&
                 Objects.equal(keySourceUrl, other.keySourceUrl) &&
+                Objects.equal(clientCertificateSourceUrl, other.clientCertificateSourceUrl)
&&
+                Objects.equal(clientCertificateDestination, other.clientCertificateDestination)
&&
+                Objects.equal(verifyClient, other.verifyClient) &&
                 Objects.equal(reuseSessions, other.reuseSessions) &&
                 Objects.equal(targetIsSsl, other.targetIsSsl);
     }

http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/835ba7e9/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxDefaultConfigGenerator.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxDefaultConfigGenerator.java
b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxDefaultConfigGenerator.java
index 0d82cc4..bbe81aa 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxDefaultConfigGenerator.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxDefaultConfigGenerator.java
@@ -78,6 +78,7 @@ public class NginxDefaultConfigGenerator implements NginxConfigFileGenerator
{
             config.append("  }\n");
             config.append("  server {\n");
             config.append(getCodeForServerConfig());
+            appendCodeForProxySSLConfig(nginx.getId(), config, "    ", globalSslConfig);
             config.append("    listen "+nginx.getPort()+";\n");
             if (nginx.getDomain()!=null)
                 config.append("    server_name "+nginx.getDomain()+";\n");
@@ -146,6 +147,7 @@ public class NginxDefaultConfigGenerator implements NginxConfigFileGenerator
{
             }
             if (localSslConfig != null) {
                 appendSslConfig(domain, config, "    ", localSslConfig, true, true);
+                appendCodeForProxySSLConfig(domain, config, "    ", localSslConfig);
             }
 
             for (UrlMapping mappingInDomain : mappingsByDomain.get(domain)) {
@@ -188,7 +190,7 @@ public class NginxDefaultConfigGenerator implements NginxConfigFileGenerator
{
 
     protected String getCodeForServerConfig() {
         // See http://wiki.nginx.org/HttpProxyModule
-        return ""+
+        return "" +
             // this prevents nginx from reporting version number on error pages
             "    server_tokens off;\n"+
 
@@ -203,6 +205,37 @@ public class NginxDefaultConfigGenerator implements NginxConfigFileGenerator
{
             "    proxy_set_header X-Real-IP $remote_addr;\n";
     }
 
+    protected void appendCodeForProxySSLConfig(String id, StringBuilder out, String prefix,
ProxySslConfig ssl) {
+        if (ssl.getTargetIsSsl() && ssl.getVerifyClient()) {
+            // Send 403 if not verified, otherwise pass on the client certificate we received
+            out.append(prefix).append("if ($ssl_client_verify != SUCCESS) { return 403; }\n");
+            out.append(prefix).append("proxy_set_header ssl.client_cert $ssl_client_cert;\n");
+
+            // Use the configured SSL certificate and key for the proxied server
+            String cert;
+            if (Strings.isEmpty(ssl.getCertificateDestination())) {
+                cert = "" + id + ".crt";
+            } else {
+                cert = ssl.getCertificateDestination();
+            }
+            out.append(prefix);
+            out.append("proxy_ssl_certificate " + cert + ";\n");
+
+            String key;
+            if (!Strings.isEmpty(ssl.getKeyDestination())) {
+                key = ssl.getKeyDestination();
+            } else if (!Strings.isEmpty(ssl.getKeySourceUrl())) {
+                key = "" + id + ".key";
+            } else {
+                key = null;
+            }
+            if (key != null) {
+                out.append(prefix);
+                out.append("proxy_ssl_certificate_key " + key + ";\n");
+            }
+        }
+    }
+
     protected String getCodeFor404() {
         return "    return 404;\n";
     }
@@ -231,7 +264,6 @@ public class NginxDefaultConfigGenerator implements NginxConfigFileGenerator
{
             } else {
                 cert = ssl.getCertificateDestination();
             }
-
             out.append(prefix);
             out.append("ssl_certificate " + cert + ";\n");
 
@@ -243,12 +275,26 @@ public class NginxDefaultConfigGenerator implements NginxConfigFileGenerator
{
             } else {
                 key = null;
             }
-
             if (key != null) {
                 out.append(prefix);
                 out.append("ssl_certificate_key " + key + ";\n");
             }
 
+            if (ssl.getVerifyClient()) {
+                out.append("ssl_verify_client on;\n");
+
+                String client;
+                if (Strings.isEmpty(ssl.getClientCertificateDestination())) {
+                    client = "" + id + ".cli";
+                } else {
+                    client = ssl.getClientCertificateDestination();
+                }
+                if (client != null) {
+                    out.append(prefix);
+                    out.append("ssl_client_certificate " + client + ";\n");
+                }
+            }
+
             out.append("ssl_protocols TLSv1 TLSv1.1 TLSv1.2;\n");
         }
         return true;


Mime
View raw message