Issue
I have figured out on how to start a ktor with embeddedServer Jetty and serving https/ssl/tls using my own signed Certificate (signed by my own self-signed rootCA certificate).
Now ktor sslConnector needs to have the keyStorePath
as File
, but I'd prefer to serve the keystore from the/a file inside the final fat jar (mainly for being able to run it inside a kubernetes cluster)
Is there a way to tell ktor to take/read a resource embedded in its jar file as keyStore?
// openssl pkcs12 -export -nodes -passout pass:${keystorePW} -in "domain.cert" -inkey "domain.key" -certfile "intermediateAndRootCAchain.ca" -name "aliasName" -out "webserverKeystore.p12"
val keystore: KeyStore = KeyStore.getInstance(keystoreFile, keystorePW.toCharArray())
@Suppress("UNUSED_PARAMETER")
fun doIt(args: Array<String>) {
val server = embeddedServer(Jetty, applicationEngineEnvironment {
module {
configureRouting()
configureHTTP(sslPort)
configureSerialization()
}
connector {
this.host = host // redirected to https
this.port = port // redirected to sslPort
}
sslConnector(keystore,
keyAlias = certAlias, // alias name inside keystore: keytool -v -list -keystore certs/keystore.jks
keyStorePassword = { keystorePW.toCharArray() },
privateKeyPassword = { keystorePW.toCharArray() } // somehow this is the same as keystorePW if using openssl pkcs12 -export from above
) {
this.port = sslPort
keyStorePath = keystoreFile
}
})
server.start(wait = true)
}
Is there a way to tell ktor to take/read a resource embedded in its jar file as keyStore?
(also wondering why sslConnector
still needs the keystore as File
if it already got the whole keystore as first parameter, but that's probably to be independant from the actual web container that's being used)
a second question: is it possible to enable mutual tls, so that the ktor server refuses a connection if the client cannot present a valid certificate? if yes, how would I configure that?
Solution
For Netty
and Jetty
engines, a keystore
that you pass as a first parameter for sslConnector
is actually used. The keyStorePath
property is used only for the Tomcat
engine.
Unfortunately, there is no way to configure mutual TLS authentication in Ktor but as a workaround, you can do it manually by adding a connector to the underlying Jetty server. This article may be useful for you. Here is an incomplete example:
embeddedServer(
Jetty,
applicationEngineEnvironment {
module {
// ...
}
}
) {
configureServer = {
val factory = SslConnectionFactory(
SslContextFactory.Server().apply {
// keyStore = ...
// setKeyManagerPassword(...)
// setKeyStorePassword(...)
needClientAuth = true
},
HttpVersion.HTTP_1_1.asString()
)
val connector = ServerConnector(this, factory).apply {
// host = ...
// port = ...
}
addConnector(connector)
}
}
Answered By - Aleksei Tirman
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.