HTTPS Configuration
It's often useful to be able to start a server with a self-signed cert. The following code starts a web-server on HTTPS port 9443 with a simple handler:
public class HttpsSelfSignedCert {
public static void main(String[] args) {
MuServer server = muServer()
.withHttpsPort(9443)
.addHandler(Method.GET, "/", (req, resp, pp) -> resp.write("This is HTTPS"))
.start();
System.out.println("Server started at " + server.uri());
}
}
(see full file)
Signed certificates
To use a signed certificate, you need to create an HttpsConfigBuilder and pass it to the withHttpsConfig
method on the MuServerBuilder class.
The HttpsConfigBuilder has a number of useful ways to create a context, for
example you can load a cert from the file system, classpath, or an InputStream
.
You can also specify which TLS protocols and ciphers you would like to use.
public class HttpsWithCert {
public static void main(String[] args) {
HttpsConfigBuilder httpsConfig = HttpsConfigBuilder.httpsConfig()
.withKeystoreType("JKS")
.withKeystorePassword("Very5ecure")
.withKeyPassword("ActuallyNotSecure")
.withKeystore(new File("src/main/java/io/muserver/docs/samples/HttpsCert.jks"))
.withProtocols("TLSv1.2", "TLSv1.3")
.withCipherFilter(new SSLCipherFilter() {
public List<String> selectCiphers(Set<String> supportedCiphers, List<String> defaultCiphers) {
return defaultCiphers;
}
});
MuServer server = muServer()
.withHttpsPort(10443)
.withHttpsConfig(httpsConfig)
.addHandler(Method.GET, "/", (req, resp, pp) -> resp.write("This is HTTPS"))
.start();
System.out.println("Server started at " + server.uri());
}
}
(see full file)
Changing certs at runtime
To perform a hot change of an HTTPS certificate, construct a new HttpsConfigBuilder
and change it
using the MuServer server reference:
server.changeHttpsConfig(httpsConfig);
HSTS Handler
HTTP Strict-Transport-Security instructs browsers to only access your website via HTTPS. This is achieved
by setting the Strict-Transport-Security
response header.
For convenience, the HttpsRedirectorBuilder class can be used to generate a handler to do this for you. Just tell it the HTTPS port to redirect to, and the amount of time the directive is valid for.
public class HSTSExample {
public static void main(String[] args) {
MuServer server = muServer()
.withHttpPort(20080)
.withHttpsPort(20443)
.addHandler(
HttpsRedirectorBuilder.toHttpsPort(20443)
.withHSTSExpireTime(365, TimeUnit.DAYS)
.includeSubDomains(true)
)
.addHandler(Method.GET, "/", (req, resp, pp) -> resp.write("This is HTTPS"))
.start();
System.out.println("Server started at " + server.httpUri());
}
}
(see full file)
If you omit the HSTS config on this builder, it will redirect to HTTPS without setting HSTS headers.
Let's Encrypt integration
Getting free, automatically renewed certificates with Let's Encrypt and other ACME-based Certificate Authorities is even simpler than providing your own SSL config.
See the Let's Encrypt integration documentation for details.
Better TLS with OpenSSL
Mu Server is based on Netty, and Netty recommends that OpenSSL is used due to it being faster and having JDK-independent ciphers. In order to support OpenSSL, please follow the netty-tcnative wiki page.
If running on a modern Linux distribution, it may be enough to add the following dependency:
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
<version>2.0.65.Final</version>
<classifier>linux-x86_64</classifier>
<scope>runtime</scope>
</dependency>
Accessing SSL Settings
The sslInfo()
method on the MuServer class returns an
SSLInfo object that can be used to get the actual values your server supports. In a handler,
this can be accessed with request.server().sslInfo()
and the following
table shows the settings from this website:
Property | Value |
---|---|
sslInfo.providerName() |
OpenSSL |
sslInfo.protocols() |
SSLv2Hello, TLSv1.2, TLSv1.3 |
sslInfo.ciphers() |
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256 |
sslInfo.certificates() |
|
To see which TLS versions and ciphers your users are connecting with, you can refer to the connection info exposed by Mu Server.
To see an SSL report for Mu Server using OpenSSL, go to the SSL Labs SSL Report for muserver.io.
Mutual TLS with Client certificates
To allow authentication with client certificates, create a Trust Manager and pass it to
withClientCertificateTrustManager(TrustManager)
on the
HttpsConfigBuilder. You can then access the client cert (if sent and valid)
with the MuRequest.connnection().clientCertificate()
method from any handler.
See the Mutual TLS documentation for a full example.