Commit 483a69fed1981ee07e14b9b00f15f6f515828b82
1 parent
330ff094
Use SSL credentials configuration to setup HTTPS. Enable Lwm2m credentials by default.
Showing
12 changed files
with
225 additions
and
65 deletions
@@ -31,6 +31,7 @@ import java.util.Arrays; | @@ -31,6 +31,7 @@ import java.util.Arrays; | ||
31 | "org.thingsboard.server.service.install", | 31 | "org.thingsboard.server.service.install", |
32 | "org.thingsboard.server.dao", | 32 | "org.thingsboard.server.dao", |
33 | "org.thingsboard.server.common.stats", | 33 | "org.thingsboard.server.common.stats", |
34 | + "org.thingsboard.server.common.transport.config.ssl", | ||
34 | "org.thingsboard.server.cache"}) | 35 | "org.thingsboard.server.cache"}) |
35 | public class ThingsboardInstallApplication { | 36 | public class ThingsboardInstallApplication { |
36 | 37 |
@@ -23,14 +23,30 @@ server: | @@ -23,14 +23,30 @@ server: | ||
23 | ssl: | 23 | ssl: |
24 | # Enable/disable SSL support | 24 | # Enable/disable SSL support |
25 | enabled: "${SSL_ENABLED:false}" | 25 | enabled: "${SSL_ENABLED:false}" |
26 | - # Path to the key store that holds the SSL certificate | ||
27 | - key-store: "${SSL_KEY_STORE:classpath:keystore/keystore.p12}" | ||
28 | - # Password used to access the key store | ||
29 | - key-store-password: "${SSL_KEY_STORE_PASSWORD:thingsboard}" | ||
30 | - # Type of the key store | ||
31 | - key-store-type: "${SSL_KEY_STORE_TYPE:PKCS12}" | ||
32 | - # Alias that identifies the key in the key store | ||
33 | - key-alias: "${SSL_KEY_ALIAS:tomcat}" | 26 | + # Server SSL credentials |
27 | + credentials: | ||
28 | + # Server credentials type (PEM - pem certificate file; KEYSTORE - java keystore) | ||
29 | + type: "${SSL_CREDENTIALS_TYPE:PEM}" | ||
30 | + # PEM server credentials | ||
31 | + pem: | ||
32 | + # Path to the server certificate file (holds server certificate or certificate chain, may include server private key) | ||
33 | + cert_file: "${SSL_PEM_CERT:server.pem}" | ||
34 | + # Path to the server certificate private key file (optional) | ||
35 | + key_file: "${SSL_PEM_KEY:server_key.pem}" | ||
36 | + # Server certificate private key password (optional) | ||
37 | + key_password: "${SSL_PEM_KEY_PASSWORD:server_key_password}" | ||
38 | + # Keystore server credentials | ||
39 | + keystore: | ||
40 | + # Type of the key store | ||
41 | + type: "${SSL_KEY_STORE_TYPE:PKCS12}" | ||
42 | + # Path to the key store that holds the SSL certificate | ||
43 | + store_file: "${SSL_KEY_STORE:classpath:keystore/keystore.p12}" | ||
44 | + # Password used to access the key store | ||
45 | + store_password: "${SSL_KEY_STORE_PASSWORD:thingsboard}" | ||
46 | + # Key alias | ||
47 | + key_alias: "${SSL_KEY_ALIAS:tomcat}" | ||
48 | + # Password used to access the key | ||
49 | + key_password: "${SSL_KEY_PASSWORD:thingsboard}" | ||
34 | log_controller_error_stack_trace: "${HTTP_LOG_CONTROLLER_ERROR_STACK_TRACE:false}" | 50 | log_controller_error_stack_trace: "${HTTP_LOG_CONTROLLER_ERROR_STACK_TRACE:false}" |
35 | ws: | 51 | ws: |
36 | send_timeout: "${TB_SERVER_WS_SEND_TIMEOUT:5000}" | 52 | send_timeout: "${TB_SERVER_WS_SEND_TIMEOUT:5000}" |
@@ -679,10 +695,10 @@ transport: | @@ -679,10 +695,10 @@ transport: | ||
679 | store_file: "${COAP_DTLS_KEY_STORE:coapserver.jks}" | 695 | store_file: "${COAP_DTLS_KEY_STORE:coapserver.jks}" |
680 | # Password used to access the key store | 696 | # Password used to access the key store |
681 | store_password: "${COAP_DTLS_KEY_STORE_PASSWORD:server_ks_password}" | 697 | store_password: "${COAP_DTLS_KEY_STORE_PASSWORD:server_ks_password}" |
682 | - # Password used to access the key | ||
683 | - key_password: "${COAP_DTLS_KEY_PASSWORD:server_key_password}" | ||
684 | # Key alias | 698 | # Key alias |
685 | key_alias: "${COAP_DTLS_KEY_ALIAS:serveralias}" | 699 | key_alias: "${COAP_DTLS_KEY_ALIAS:serveralias}" |
700 | + # Password used to access the key | ||
701 | + key_password: "${COAP_DTLS_KEY_PASSWORD:server_key_password}" | ||
686 | x509: | 702 | x509: |
687 | # Skip certificate validity check for client certificates. | 703 | # Skip certificate validity check for client certificates. |
688 | skip_validity_check_for_client_cert: "${TB_COAP_X509_DTLS_SKIP_VALIDITY_CHECK_FOR_CLIENT_CERT:false}" | 704 | skip_validity_check_for_client_cert: "${TB_COAP_X509_DTLS_SKIP_VALIDITY_CHECK_FOR_CLIENT_CERT:false}" |
@@ -702,7 +718,7 @@ transport: | @@ -702,7 +718,7 @@ transport: | ||
702 | # Server X509 Certificates support | 718 | # Server X509 Certificates support |
703 | credentials: | 719 | credentials: |
704 | # Whether to enable LWM2M server X509 Certificate/RPK support | 720 | # Whether to enable LWM2M server X509 Certificate/RPK support |
705 | - enabled: "${LWM2M_SERVER_CREDENTIALS_ENABLED:false}" | 721 | + enabled: "${LWM2M_SERVER_CREDENTIALS_ENABLED:true}" |
706 | # Server credentials type (PEM - pem certificate file; KEYSTORE - java keystore) | 722 | # Server credentials type (PEM - pem certificate file; KEYSTORE - java keystore) |
707 | type: "${LWM2M_SERVER_CREDENTIALS_TYPE:PEM}" | 723 | type: "${LWM2M_SERVER_CREDENTIALS_TYPE:PEM}" |
708 | # PEM server credentials | 724 | # PEM server credentials |
@@ -721,10 +737,10 @@ transport: | @@ -721,10 +737,10 @@ transport: | ||
721 | store_file: "${LWM2M_SERVER_KEY_STORE:lwm2mserver.jks}" | 737 | store_file: "${LWM2M_SERVER_KEY_STORE:lwm2mserver.jks}" |
722 | # Password used to access the key store | 738 | # Password used to access the key store |
723 | store_password: "${LWM2M_SERVER_KEY_STORE_PASSWORD:server_ks_password}" | 739 | store_password: "${LWM2M_SERVER_KEY_STORE_PASSWORD:server_ks_password}" |
724 | - # Password used to access the key | ||
725 | - key_password: "${LWM2M_SERVER_KEY_PASSWORD:server_key_password}" | ||
726 | # Key alias | 740 | # Key alias |
727 | key_alias: "${LWM2M_SERVER_KEY_ALIAS:server}" | 741 | key_alias: "${LWM2M_SERVER_KEY_ALIAS:server}" |
742 | + # Password used to access the key | ||
743 | + key_password: "${LWM2M_SERVER_KEY_PASSWORD:server_ks_password}" | ||
728 | # Only Certificate_x509: | 744 | # Only Certificate_x509: |
729 | skip_validity_check_for_client_cert: "${TB_LWM2M_SERVER_SECURITY_SKIP_VALIDITY_CHECK_FOR_CLIENT_CERT:false}" | 745 | skip_validity_check_for_client_cert: "${TB_LWM2M_SERVER_SECURITY_SKIP_VALIDITY_CHECK_FOR_CLIENT_CERT:false}" |
730 | bootstrap: | 746 | bootstrap: |
@@ -738,7 +754,7 @@ transport: | @@ -738,7 +754,7 @@ transport: | ||
738 | # Bootstrap server X509 Certificates support | 754 | # Bootstrap server X509 Certificates support |
739 | credentials: | 755 | credentials: |
740 | # Whether to enable LWM2M bootstrap server X509 Certificate/RPK support | 756 | # Whether to enable LWM2M bootstrap server X509 Certificate/RPK support |
741 | - enabled: "${LWM2M_BS_CREDENTIALS_ENABLED:false}" | 757 | + enabled: "${LWM2M_BS_CREDENTIALS_ENABLED:true}" |
742 | # Server credentials type (PEM - pem certificate file; KEYSTORE - java keystore) | 758 | # Server credentials type (PEM - pem certificate file; KEYSTORE - java keystore) |
743 | type: "${LWM2M_BS_CREDENTIALS_TYPE:PEM}" | 759 | type: "${LWM2M_BS_CREDENTIALS_TYPE:PEM}" |
744 | # PEM server credentials | 760 | # PEM server credentials |
@@ -757,15 +773,15 @@ transport: | @@ -757,15 +773,15 @@ transport: | ||
757 | store_file: "${LWM2M_BS_KEY_STORE:lwm2mserver.jks}" | 773 | store_file: "${LWM2M_BS_KEY_STORE:lwm2mserver.jks}" |
758 | # Password used to access the key store | 774 | # Password used to access the key store |
759 | store_password: "${LWM2M_BS_KEY_STORE_PASSWORD:server_ks_password}" | 775 | store_password: "${LWM2M_BS_KEY_STORE_PASSWORD:server_ks_password}" |
760 | - # Password used to access the key | ||
761 | - key_password: "${LWM2M_BS_KEY_PASSWORD:server_key_password}" | ||
762 | # Key alias | 776 | # Key alias |
763 | key_alias: "${LWM2M_BS_KEY_ALIAS:bootstrap}" | 777 | key_alias: "${LWM2M_BS_KEY_ALIAS:bootstrap}" |
778 | + # Password used to access the key | ||
779 | + key_password: "${LWM2M_BS_KEY_PASSWORD:server_ks_password}" | ||
764 | security: | 780 | security: |
765 | # X509 trust certificates | 781 | # X509 trust certificates |
766 | trust-credentials: | 782 | trust-credentials: |
767 | # Whether to load X509 trust certificates | 783 | # Whether to load X509 trust certificates |
768 | - enabled: "${LWM2M_TRUST_CREDENTIALS_ENABLED:false}" | 784 | + enabled: "${LWM2M_TRUST_CREDENTIALS_ENABLED:true}" |
769 | # Trust certificates store type (PEM - pem certificates file; KEYSTORE - java keystore) | 785 | # Trust certificates store type (PEM - pem certificates file; KEYSTORE - java keystore) |
770 | type: "${LWM2M_TRUST_CREDENTIALS_TYPE:PEM}" | 786 | type: "${LWM2M_TRUST_CREDENTIALS_TYPE:PEM}" |
771 | # PEM certificates | 787 | # PEM certificates |
@@ -27,27 +27,36 @@ import java.net.URL; | @@ -27,27 +27,36 @@ import java.net.URL; | ||
27 | @Slf4j | 27 | @Slf4j |
28 | public class ResourceUtils { | 28 | public class ResourceUtils { |
29 | 29 | ||
30 | + public static final String CLASSPATH_URL_PREFIX = "classpath:"; | ||
31 | + | ||
30 | public static boolean resourceExists(Object classLoaderSource, String filePath) { | 32 | public static boolean resourceExists(Object classLoaderSource, String filePath) { |
31 | return resourceExists(classLoaderSource.getClass().getClassLoader(), filePath); | 33 | return resourceExists(classLoaderSource.getClass().getClassLoader(), filePath); |
32 | } | 34 | } |
33 | 35 | ||
34 | public static boolean resourceExists(ClassLoader classLoader, String filePath) { | 36 | public static boolean resourceExists(ClassLoader classLoader, String filePath) { |
35 | - File resourceFile = new File(filePath); | ||
36 | - if (resourceFile.exists()) { | ||
37 | - return true; | ||
38 | - } else { | ||
39 | - InputStream classPathStream = classLoader.getResourceAsStream(filePath); | ||
40 | - if (classPathStream != null) { | 37 | + boolean classPathResource = false; |
38 | + String path = filePath; | ||
39 | + if (path.startsWith(CLASSPATH_URL_PREFIX)) { | ||
40 | + path = path.substring(CLASSPATH_URL_PREFIX.length()); | ||
41 | + classPathResource = true; | ||
42 | + } | ||
43 | + if (!classPathResource) { | ||
44 | + File resourceFile = new File(path); | ||
45 | + if (resourceFile.exists()) { | ||
41 | return true; | 46 | return true; |
42 | - } else { | ||
43 | - try { | ||
44 | - URL url = Resources.getResource(filePath); | ||
45 | - if (url != null) { | ||
46 | - return true; | ||
47 | - } | ||
48 | - } catch (IllegalArgumentException e) {} | ||
49 | } | 47 | } |
50 | } | 48 | } |
49 | + InputStream classPathStream = classLoader.getResourceAsStream(path); | ||
50 | + if (classPathStream != null) { | ||
51 | + return true; | ||
52 | + } else { | ||
53 | + try { | ||
54 | + URL url = Resources.getResource(path); | ||
55 | + if (url != null) { | ||
56 | + return true; | ||
57 | + } | ||
58 | + } catch (IllegalArgumentException e) {} | ||
59 | + } | ||
51 | return false; | 60 | return false; |
52 | } | 61 | } |
53 | 62 | ||
@@ -56,32 +65,40 @@ public class ResourceUtils { | @@ -56,32 +65,40 @@ public class ResourceUtils { | ||
56 | } | 65 | } |
57 | 66 | ||
58 | public static InputStream getInputStream(ClassLoader classLoader, String filePath) { | 67 | public static InputStream getInputStream(ClassLoader classLoader, String filePath) { |
68 | + boolean classPathResource = false; | ||
69 | + String path = filePath; | ||
70 | + if (path.startsWith(CLASSPATH_URL_PREFIX)) { | ||
71 | + path = path.substring(CLASSPATH_URL_PREFIX.length()); | ||
72 | + classPathResource = true; | ||
73 | + } | ||
59 | try { | 74 | try { |
60 | - InputStream keyStoreInputStream; | ||
61 | - File keyStoreFile = new File(filePath); | ||
62 | - if (keyStoreFile.exists()) { | ||
63 | - log.info("Reading key store from file {}", filePath); | ||
64 | - keyStoreInputStream = new FileInputStream(keyStoreFile); | 75 | + if (!classPathResource) { |
76 | + File resourceFile = new File(path); | ||
77 | + if (resourceFile.exists()) { | ||
78 | + log.info("Reading resource data from file {}", filePath); | ||
79 | + return new FileInputStream(resourceFile); | ||
80 | + } | ||
81 | + } | ||
82 | + InputStream classPathStream = classLoader.getResourceAsStream(path); | ||
83 | + if (classPathStream != null) { | ||
84 | + log.info("Reading resource data from class path {}", filePath); | ||
85 | + return classPathStream; | ||
65 | } else { | 86 | } else { |
66 | - InputStream classPathStream = classLoader.getResourceAsStream(filePath); | ||
67 | - if (classPathStream != null) { | ||
68 | - log.info("Reading key store from class path {}", filePath); | ||
69 | - keyStoreInputStream = classPathStream; | ||
70 | - } else { | ||
71 | - URI uri = Resources.getResource(filePath).toURI(); | ||
72 | - log.info("Reading key store from URI {}", filePath); | ||
73 | - keyStoreInputStream = new FileInputStream(new File(uri)); | 87 | + URL url = Resources.getResource(path); |
88 | + if (url != null) { | ||
89 | + URI uri = url.toURI(); | ||
90 | + log.info("Reading resource data from URI {}", filePath); | ||
91 | + return new FileInputStream(new File(uri)); | ||
74 | } | 92 | } |
75 | } | 93 | } |
76 | - return keyStoreInputStream; | ||
77 | } catch (Exception e) { | 94 | } catch (Exception e) { |
78 | if (e instanceof NullPointerException) { | 95 | if (e instanceof NullPointerException) { |
79 | log.warn("Unable to find resource: " + filePath); | 96 | log.warn("Unable to find resource: " + filePath); |
80 | } else { | 97 | } else { |
81 | log.warn("Unable to find resource: " + filePath, e); | 98 | log.warn("Unable to find resource: " + filePath, e); |
82 | } | 99 | } |
83 | - throw new RuntimeException("Unable to find resource: " + filePath); | ||
84 | } | 100 | } |
101 | + throw new RuntimeException("Unable to find resource: " + filePath); | ||
85 | } | 102 | } |
86 | 103 | ||
87 | public static String getUri(Object classLoaderSource, String filePath) { | 104 | public static String getUri(Object classLoaderSource, String filePath) { |
@@ -90,10 +107,10 @@ public class ResourceUtils { | @@ -90,10 +107,10 @@ public class ResourceUtils { | ||
90 | 107 | ||
91 | public static String getUri(ClassLoader classLoader, String filePath) { | 108 | public static String getUri(ClassLoader classLoader, String filePath) { |
92 | try { | 109 | try { |
93 | - File keyStoreFile = new File(filePath); | ||
94 | - if (keyStoreFile.exists()) { | ||
95 | - log.info("Reading key store from file {}", filePath); | ||
96 | - return keyStoreFile.getAbsolutePath(); | 110 | + File resourceFile = new File(filePath); |
111 | + if (resourceFile.exists()) { | ||
112 | + log.info("Reading resource data from file {}", filePath); | ||
113 | + return resourceFile.getAbsolutePath(); | ||
97 | } else { | 114 | } else { |
98 | URL url = classLoader.getResource(filePath); | 115 | URL url = classLoader.getResource(filePath); |
99 | return url.toURI().toString(); | 116 | return url.toURI().toString(); |
No preview for this file type
@@ -71,6 +71,7 @@ public abstract class AbstractSslCredentials implements SslCredentials { | @@ -71,6 +71,7 @@ public abstract class AbstractSslCredentials implements SslCredentials { | ||
71 | String alias = e.nextElement(); | 71 | String alias = e.nextElement(); |
72 | privateKeyEntry = tryGetPrivateKeyEntry(this.keyStore, alias, this.keyPasswordArray); | 72 | privateKeyEntry = tryGetPrivateKeyEntry(this.keyStore, alias, this.keyPasswordArray); |
73 | if (privateKeyEntry != null) { | 73 | if (privateKeyEntry != null) { |
74 | + this.updateKeyAlias(alias); | ||
74 | break; | 75 | break; |
75 | } | 76 | } |
76 | } | 77 | } |
@@ -88,6 +89,11 @@ public abstract class AbstractSslCredentials implements SslCredentials { | @@ -88,6 +89,11 @@ public abstract class AbstractSslCredentials implements SslCredentials { | ||
88 | } | 89 | } |
89 | 90 | ||
90 | @Override | 91 | @Override |
92 | + public KeyStore getKeyStore() { | ||
93 | + return this.keyStore; | ||
94 | + } | ||
95 | + | ||
96 | + @Override | ||
91 | public PrivateKey getPrivateKey() { | 97 | public PrivateKey getPrivateKey() { |
92 | return this.privateKey; | 98 | return this.privateKey; |
93 | } | 99 | } |
@@ -123,12 +129,10 @@ public abstract class AbstractSslCredentials implements SslCredentials { | @@ -123,12 +129,10 @@ public abstract class AbstractSslCredentials implements SslCredentials { | ||
123 | 129 | ||
124 | protected abstract boolean canUse(); | 130 | protected abstract boolean canUse(); |
125 | 131 | ||
126 | - protected abstract String getKeyPassword(); | ||
127 | - | ||
128 | - protected abstract String getKeyAlias(); | ||
129 | - | ||
130 | protected abstract KeyStore loadKeyStore(boolean isPrivateKeyRequired, char[] keyPasswordArray) throws IOException, GeneralSecurityException; | 132 | protected abstract KeyStore loadKeyStore(boolean isPrivateKeyRequired, char[] keyPasswordArray) throws IOException, GeneralSecurityException; |
131 | 133 | ||
134 | + protected abstract void updateKeyAlias(String keyAlias); | ||
135 | + | ||
132 | private static X509Certificate[] asX509Certificates(Certificate[] certificates) { | 136 | private static X509Certificate[] asX509Certificates(Certificate[] certificates) { |
133 | if (null == certificates || 0 == certificates.length) { | 137 | if (null == certificates || 0 == certificates.length) { |
134 | throw new IllegalArgumentException("certificates missing!"); | 138 | throw new IllegalArgumentException("certificates missing!"); |
@@ -49,4 +49,9 @@ public class KeystoreSslCredentials extends AbstractSslCredentials { | @@ -49,4 +49,9 @@ public class KeystoreSslCredentials extends AbstractSslCredentials { | ||
49 | } | 49 | } |
50 | return keyStore; | 50 | return keyStore; |
51 | } | 51 | } |
52 | + | ||
53 | + @Override | ||
54 | + protected void updateKeyAlias(String keyAlias) { | ||
55 | + this.keyAlias = keyAlias; | ||
56 | + } | ||
52 | } | 57 | } |
@@ -17,6 +17,7 @@ package org.thingsboard.server.common.transport.config.ssl; | @@ -17,6 +17,7 @@ package org.thingsboard.server.common.transport.config.ssl; | ||
17 | 17 | ||
18 | import lombok.Data; | 18 | import lombok.Data; |
19 | import lombok.EqualsAndHashCode; | 19 | import lombok.EqualsAndHashCode; |
20 | +import lombok.Getter; | ||
20 | import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; | 21 | import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; |
21 | import org.bouncycastle.cert.X509CertificateHolder; | 22 | import org.bouncycastle.cert.X509CertificateHolder; |
22 | import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; | 23 | import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; |
@@ -48,10 +49,11 @@ import java.util.stream.Collectors; | @@ -48,10 +49,11 @@ import java.util.stream.Collectors; | ||
48 | @EqualsAndHashCode(callSuper = false) | 49 | @EqualsAndHashCode(callSuper = false) |
49 | public class PemSslCredentials extends AbstractSslCredentials { | 50 | public class PemSslCredentials extends AbstractSslCredentials { |
50 | 51 | ||
52 | + private static final String DEFAULT_KEY_ALIAS = "server"; | ||
53 | + | ||
51 | private String certFile; | 54 | private String certFile; |
52 | private String keyFile; | 55 | private String keyFile; |
53 | private String keyPassword; | 56 | private String keyPassword; |
54 | - private final String keyAlias = "serveralias"; | ||
55 | 57 | ||
56 | @Override | 58 | @Override |
57 | protected boolean canUse() { | 59 | protected boolean canUse() { |
@@ -125,8 +127,17 @@ public class PemSslCredentials extends AbstractSslCredentials { | @@ -125,8 +127,17 @@ public class PemSslCredentials extends AbstractSslCredentials { | ||
125 | CertPath certPath = factory.generateCertPath(certificates); | 127 | CertPath certPath = factory.generateCertPath(certificates); |
126 | List<? extends Certificate> path = certPath.getCertificates(); | 128 | List<? extends Certificate> path = certPath.getCertificates(); |
127 | Certificate[] x509Certificates = path.toArray(new Certificate[0]); | 129 | Certificate[] x509Certificates = path.toArray(new Certificate[0]); |
128 | - keyStore.setKeyEntry(this.keyAlias, privateKey, keyPasswordArray, x509Certificates); | 130 | + keyStore.setKeyEntry(DEFAULT_KEY_ALIAS, privateKey, keyPasswordArray, x509Certificates); |
129 | } | 131 | } |
130 | return keyStore; | 132 | return keyStore; |
131 | } | 133 | } |
134 | + | ||
135 | + @Override | ||
136 | + public String getKeyAlias() { | ||
137 | + return DEFAULT_KEY_ALIAS; | ||
138 | + } | ||
139 | + | ||
140 | + @Override | ||
141 | + protected void updateKeyAlias(String keyAlias) { | ||
142 | + } | ||
132 | } | 143 | } |
@@ -19,6 +19,7 @@ import javax.net.ssl.KeyManagerFactory; | @@ -19,6 +19,7 @@ import javax.net.ssl.KeyManagerFactory; | ||
19 | import javax.net.ssl.TrustManagerFactory; | 19 | import javax.net.ssl.TrustManagerFactory; |
20 | import java.io.IOException; | 20 | import java.io.IOException; |
21 | import java.security.GeneralSecurityException; | 21 | import java.security.GeneralSecurityException; |
22 | +import java.security.KeyStore; | ||
22 | import java.security.KeyStoreException; | 23 | import java.security.KeyStoreException; |
23 | import java.security.NoSuchAlgorithmException; | 24 | import java.security.NoSuchAlgorithmException; |
24 | import java.security.PrivateKey; | 25 | import java.security.PrivateKey; |
@@ -30,6 +31,12 @@ public interface SslCredentials { | @@ -30,6 +31,12 @@ public interface SslCredentials { | ||
30 | 31 | ||
31 | void init(boolean trustsOnly) throws IOException, GeneralSecurityException; | 32 | void init(boolean trustsOnly) throws IOException, GeneralSecurityException; |
32 | 33 | ||
34 | + KeyStore getKeyStore(); | ||
35 | + | ||
36 | + String getKeyPassword(); | ||
37 | + | ||
38 | + String getKeyAlias(); | ||
39 | + | ||
33 | PrivateKey getPrivateKey(); | 40 | PrivateKey getPrivateKey(); |
34 | 41 | ||
35 | PublicKey getPublicKey(); | 42 | PublicKey getPublicKey(); |
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.transport.config.ssl; | ||
17 | + | ||
18 | +import org.springframework.beans.factory.annotation.Autowired; | ||
19 | +import org.springframework.beans.factory.annotation.Qualifier; | ||
20 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | ||
21 | +import org.springframework.boot.autoconfigure.web.ServerProperties; | ||
22 | +import org.springframework.boot.context.properties.ConfigurationProperties; | ||
23 | +import org.springframework.boot.web.server.Ssl; | ||
24 | +import org.springframework.boot.web.server.SslStoreProvider; | ||
25 | +import org.springframework.boot.web.server.WebServerFactoryCustomizer; | ||
26 | +import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; | ||
27 | +import org.springframework.context.annotation.Bean; | ||
28 | +import org.springframework.stereotype.Component; | ||
29 | + | ||
30 | +import java.security.KeyStore; | ||
31 | + | ||
32 | +@Component | ||
33 | +@ConditionalOnExpression("'${spring.main.web-environment:true}'=='true' && '${server.ssl.enabled:false}'=='true'") | ||
34 | +public class SslCredentialsWebServerCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> { | ||
35 | + | ||
36 | + @Bean | ||
37 | + @ConfigurationProperties(prefix = "server.ssl.credentials") | ||
38 | + public SslCredentialsConfig httpServerSslCredentials() { | ||
39 | + return new SslCredentialsConfig("HTTP Server SSL Credentials", false); | ||
40 | + } | ||
41 | + | ||
42 | + @Autowired | ||
43 | + @Qualifier("httpServerSslCredentials") | ||
44 | + private SslCredentialsConfig httpServerSslCredentialsConfig; | ||
45 | + | ||
46 | + private final ServerProperties serverProperties; | ||
47 | + | ||
48 | + public SslCredentialsWebServerCustomizer(ServerProperties serverProperties) { | ||
49 | + this.serverProperties = serverProperties; | ||
50 | + } | ||
51 | + | ||
52 | + @Override | ||
53 | + public void customize(ConfigurableServletWebServerFactory factory) { | ||
54 | + SslCredentials sslCredentials = this.httpServerSslCredentialsConfig.getCredentials(); | ||
55 | + Ssl ssl = serverProperties.getSsl(); | ||
56 | + ssl.setKeyAlias(sslCredentials.getKeyAlias()); | ||
57 | + ssl.setKeyPassword(sslCredentials.getKeyPassword()); | ||
58 | + factory.setSsl(ssl); | ||
59 | + factory.setSslStoreProvider(new SslStoreProvider() { | ||
60 | + @Override | ||
61 | + public KeyStore getKeyStore() { | ||
62 | + return sslCredentials.getKeyStore(); | ||
63 | + } | ||
64 | + | ||
65 | + @Override | ||
66 | + public KeyStore getTrustStore() { | ||
67 | + return null; | ||
68 | + } | ||
69 | + }); | ||
70 | + } | ||
71 | +} |
@@ -118,10 +118,10 @@ transport: | @@ -118,10 +118,10 @@ transport: | ||
118 | store_file: "${COAP_DTLS_KEY_STORE:coapserver.jks}" | 118 | store_file: "${COAP_DTLS_KEY_STORE:coapserver.jks}" |
119 | # Password used to access the key store | 119 | # Password used to access the key store |
120 | store_password: "${COAP_DTLS_KEY_STORE_PASSWORD:server_ks_password}" | 120 | store_password: "${COAP_DTLS_KEY_STORE_PASSWORD:server_ks_password}" |
121 | - # Password used to access the key | ||
122 | - key_password: "${COAP_DTLS_KEY_PASSWORD:server_key_password}" | ||
123 | # Key alias | 121 | # Key alias |
124 | key_alias: "${COAP_DTLS_KEY_ALIAS:serveralias}" | 122 | key_alias: "${COAP_DTLS_KEY_ALIAS:serveralias}" |
123 | + # Password used to access the key | ||
124 | + key_password: "${COAP_DTLS_KEY_PASSWORD:server_key_password}" | ||
125 | x509: | 125 | x509: |
126 | # Skip certificate validity check for client certificates. | 126 | # Skip certificate validity check for client certificates. |
127 | skip_validity_check_for_client_cert: "${TB_COAP_X509_DTLS_SKIP_VALIDITY_CHECK_FOR_CLIENT_CERT:false}" | 127 | skip_validity_check_for_client_cert: "${TB_COAP_X509_DTLS_SKIP_VALIDITY_CHECK_FOR_CLIENT_CERT:false}" |
@@ -19,6 +19,34 @@ server: | @@ -19,6 +19,34 @@ server: | ||
19 | address: "${HTTP_BIND_ADDRESS:0.0.0.0}" | 19 | address: "${HTTP_BIND_ADDRESS:0.0.0.0}" |
20 | # Server bind port | 20 | # Server bind port |
21 | port: "${HTTP_BIND_PORT:8081}" | 21 | port: "${HTTP_BIND_PORT:8081}" |
22 | + # Server SSL configuration | ||
23 | + ssl: | ||
24 | + # Enable/disable SSL support | ||
25 | + enabled: "${SSL_ENABLED:false}" | ||
26 | + # Server SSL credentials | ||
27 | + credentials: | ||
28 | + # Server credentials type (PEM - pem certificate file; KEYSTORE - java keystore) | ||
29 | + type: "${SSL_CREDENTIALS_TYPE:PEM}" | ||
30 | + # PEM server credentials | ||
31 | + pem: | ||
32 | + # Path to the server certificate file (holds server certificate or certificate chain, may include server private key) | ||
33 | + cert_file: "${SSL_PEM_CERT:server.pem}" | ||
34 | + # Path to the server certificate private key file (optional) | ||
35 | + key_file: "${SSL_PEM_KEY:server_key.pem}" | ||
36 | + # Server certificate private key password (optional) | ||
37 | + key_password: "${SSL_PEM_KEY_PASSWORD:server_key_password}" | ||
38 | + # Keystore server credentials | ||
39 | + keystore: | ||
40 | + # Type of the key store | ||
41 | + type: "${SSL_KEY_STORE_TYPE:PKCS12}" | ||
42 | + # Path to the key store that holds the SSL certificate | ||
43 | + store_file: "${SSL_KEY_STORE:classpath:keystore/keystore.p12}" | ||
44 | + # Password used to access the key store | ||
45 | + store_password: "${SSL_KEY_STORE_PASSWORD:thingsboard}" | ||
46 | + # Key alias | ||
47 | + key_alias: "${SSL_KEY_ALIAS:tomcat}" | ||
48 | + # Password used to access the key | ||
49 | + key_password: "${SSL_KEY_PASSWORD:thingsboard}" | ||
22 | 50 | ||
23 | # Zookeeper connection parameters. Used for service discovery. | 51 | # Zookeeper connection parameters. Used for service discovery. |
24 | zk: | 52 | zk: |
@@ -283,4 +311,4 @@ management: | @@ -283,4 +311,4 @@ management: | ||
283 | web: | 311 | web: |
284 | exposure: | 312 | exposure: |
285 | # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). | 313 | # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). |
286 | - include: '${METRICS_ENDPOINTS_EXPOSE:info}' | ||
314 | + include: '${METRICS_ENDPOINTS_EXPOSE:info}' |
@@ -114,7 +114,7 @@ transport: | @@ -114,7 +114,7 @@ transport: | ||
114 | # Server X509 Certificates support | 114 | # Server X509 Certificates support |
115 | credentials: | 115 | credentials: |
116 | # Whether to enable LWM2M server X509 Certificate/RPK support | 116 | # Whether to enable LWM2M server X509 Certificate/RPK support |
117 | - enabled: "${LWM2M_SERVER_CREDENTIALS_ENABLED:false}" | 117 | + enabled: "${LWM2M_SERVER_CREDENTIALS_ENABLED:true}" |
118 | # Server credentials type (PEM - pem certificate file; KEYSTORE - java keystore) | 118 | # Server credentials type (PEM - pem certificate file; KEYSTORE - java keystore) |
119 | type: "${LWM2M_SERVER_CREDENTIALS_TYPE:PEM}" | 119 | type: "${LWM2M_SERVER_CREDENTIALS_TYPE:PEM}" |
120 | # PEM server credentials | 120 | # PEM server credentials |
@@ -133,10 +133,10 @@ transport: | @@ -133,10 +133,10 @@ transport: | ||
133 | store_file: "${LWM2M_SERVER_KEY_STORE:lwm2mserver.jks}" | 133 | store_file: "${LWM2M_SERVER_KEY_STORE:lwm2mserver.jks}" |
134 | # Password used to access the key store | 134 | # Password used to access the key store |
135 | store_password: "${LWM2M_SERVER_KEY_STORE_PASSWORD:server_ks_password}" | 135 | store_password: "${LWM2M_SERVER_KEY_STORE_PASSWORD:server_ks_password}" |
136 | - # Password used to access the key | ||
137 | - key_password: "${LWM2M_SERVER_KEY_PASSWORD:server_key_password}" | ||
138 | # Key alias | 136 | # Key alias |
139 | key_alias: "${LWM2M_SERVER_KEY_ALIAS:server}" | 137 | key_alias: "${LWM2M_SERVER_KEY_ALIAS:server}" |
138 | + # Password used to access the key | ||
139 | + key_password: "${LWM2M_SERVER_KEY_PASSWORD:server_ks_password}" | ||
140 | # Only Certificate_x509: | 140 | # Only Certificate_x509: |
141 | skip_validity_check_for_client_cert: "${TB_LWM2M_SERVER_SECURITY_SKIP_VALIDITY_CHECK_FOR_CLIENT_CERT:false}" | 141 | skip_validity_check_for_client_cert: "${TB_LWM2M_SERVER_SECURITY_SKIP_VALIDITY_CHECK_FOR_CLIENT_CERT:false}" |
142 | bootstrap: | 142 | bootstrap: |
@@ -150,7 +150,7 @@ transport: | @@ -150,7 +150,7 @@ transport: | ||
150 | # Bootstrap server X509 Certificates support | 150 | # Bootstrap server X509 Certificates support |
151 | credentials: | 151 | credentials: |
152 | # Whether to enable LWM2M bootstrap server X509 Certificate/RPK support | 152 | # Whether to enable LWM2M bootstrap server X509 Certificate/RPK support |
153 | - enabled: "${LWM2M_BS_CREDENTIALS_ENABLED:false}" | 153 | + enabled: "${LWM2M_BS_CREDENTIALS_ENABLED:true}" |
154 | # Server credentials type (PEM - pem certificate file; KEYSTORE - java keystore) | 154 | # Server credentials type (PEM - pem certificate file; KEYSTORE - java keystore) |
155 | type: "${LWM2M_BS_CREDENTIALS_TYPE:PEM}" | 155 | type: "${LWM2M_BS_CREDENTIALS_TYPE:PEM}" |
156 | # PEM server credentials | 156 | # PEM server credentials |
@@ -169,15 +169,15 @@ transport: | @@ -169,15 +169,15 @@ transport: | ||
169 | store_file: "${LWM2M_BS_KEY_STORE:lwm2mserver.jks}" | 169 | store_file: "${LWM2M_BS_KEY_STORE:lwm2mserver.jks}" |
170 | # Password used to access the key store | 170 | # Password used to access the key store |
171 | store_password: "${LWM2M_BS_KEY_STORE_PASSWORD:server_ks_password}" | 171 | store_password: "${LWM2M_BS_KEY_STORE_PASSWORD:server_ks_password}" |
172 | - # Password used to access the key | ||
173 | - key_password: "${LWM2M_BS_KEY_PASSWORD:server_key_password}" | ||
174 | # Key alias | 172 | # Key alias |
175 | key_alias: "${LWM2M_BS_KEY_ALIAS:bootstrap}" | 173 | key_alias: "${LWM2M_BS_KEY_ALIAS:bootstrap}" |
174 | + # Password used to access the key | ||
175 | + key_password: "${LWM2M_BS_KEY_PASSWORD:server_ks_password}" | ||
176 | security: | 176 | security: |
177 | # X509 trust certificates | 177 | # X509 trust certificates |
178 | trust-credentials: | 178 | trust-credentials: |
179 | # Whether to load X509 trust certificates | 179 | # Whether to load X509 trust certificates |
180 | - enabled: "${LWM2M_TRUST_CREDENTIALS_ENABLED:false}" | 180 | + enabled: "${LWM2M_TRUST_CREDENTIALS_ENABLED:true}" |
181 | # Trust certificates store type (PEM - pem certificates file; KEYSTORE - java keystore) | 181 | # Trust certificates store type (PEM - pem certificates file; KEYSTORE - java keystore) |
182 | type: "${LWM2M_TRUST_CREDENTIALS_TYPE:PEM}" | 182 | type: "${LWM2M_TRUST_CREDENTIALS_TYPE:PEM}" |
183 | # PEM certificates | 183 | # PEM certificates |