KtorサーバーにおけるSSLと証明書
必須の依存関係: io.ktor:ktor-network-tls-certificates
ほとんどの場合、KtorサービスはNginxやApacheなどのリバースプロキシの背後に配置されます。 これは、リバースプロキシサーバーがSSLを含むセキュリティ上の懸念を処理することを意味します。
必要に応じて、証明書へのパスを提供することで、Ktorが直接SSLを提供するように設定できます。 Ktorは証明書のストレージ施設としてJava KeyStore (JKS)を使用します。 KeyStoreに保存されている証明書を変換および管理するには、keytoolを使用できます。 これは、認証局によって発行されたPEM証明書をKtorがサポートするJKS形式に変換する必要がある場合に役立ちます。
_Let's Encrypt_を使用すると、Ktorで
https://およびwss://のリクエストを提供するための無料の証明書を取得できます。
自己署名証明書を生成する
コードで証明書を生成する
Ktorは、テスト目的で自己署名証明書を生成する機能を提供しており、これはbuildKeyStore関数を呼び出すことで可能で、この関数はKeyStoreインスタンスを返します。 この関数を使用するには、ビルドスクリプトにktor-network-tls-certificatesアーティファクトを追加する必要があります。
以下のコードスニペットは、証明書を生成してキーストアファイルに保存する方法を示しています。
private fun ApplicationEngine.Configuration.envConfig() {
val keyStoreFile = File("build/keystore.jks")
val keyStore = buildKeyStore {
certificate("sampleAlias") {
password = "foobar"
domains = listOf("127.0.0.1", "0.0.0.0", "localhost")
}
}
keyStore.saveToFile(keyStoreFile, "123456")
}Ktorは起動時に証明書を要求するため、サーバーを起動する前に証明書を作成する必要があります。 完全な例は、ssl-embedded-serverで確認できます。
keytoolを使用して証明書を生成する
keytoolを使用して、自己署名証明書を生成できます。
keytool -keystore keystore.jks -alias sampleAlias -genkeypair -keyalg RSA -keysize 4096 -validity 3 -dname 'CN=localhost, OU=ktor, O=ktor, L=Unspecified, ST=Unspecified, C=US'このコマンドを実行すると、keytoolはキーストアのパスワードを指定するように促し、JKSファイルを生成します。
PEM証明書をJKSに変換する
認証局がPEM形式で証明書を発行する場合、KtorでSSLを設定する前にJKS形式に変換する必要があります。 これにはopensslとkeytoolユーティリティを使用できます。 例えば、key.pemファイルに秘密鍵があり、cert.pemに公開証明書がある場合、変換プロセスは次のようになります。
opensslを使用してPEMをPKCS12形式に変換します。以下のコマンドを使用します。Bashopenssl pkcs12 -export -in cert.pem -inkey key.pem -out keystore.p12 -name "sampleAlias"key.pemのパスフレーズとkeystore.p12の新しいパスワードの入力を求められます。keytoolを使用してPKCS12をJKS形式に変換します。Bashkeytool -importkeystore -srckeystore keystore.p12 -srcstoretype pkcs12 -destkeystore keystore.jkskeystore.p12ファイルのパスワードとkeystore.jksの新しいパスワードの入力を求められます。keystore.jksが生成されます。
KtorでSSLを設定する
KtorでのSSL設定の指定は、Ktorサーバーの設定方法(設定ファイルを使用するか、embeddedServer関数をコードで使用するか)によって異なります。
設定ファイル
サーバーがapplication.confまたはapplication.yamlの設定ファイルで設定されている場合、以下のプロパティを使用してSSLを有効にできます。
ktor.deployment.sslPortプロパティを使用してSSLポートを指定します。shellktor { deployment { sslPort = 8443 } }yamlktor: deployment: sslPort: 8443別の
securityグループでキーストア設定を提供します。shellktor { security { ssl { keyStore = keystore.jks keyAlias = sampleAlias keyStorePassword = foobar privateKeyPassword = foobar } } }yamlktor: security: ssl: keyStore: keystore.jks keyAlias: sampleAlias keyStorePassword: foobar privateKeyPassword: foobar
完全な例は、ssl-engine-mainを参照してください。
embeddedServer
embeddedServer関数を使用してサーバーを実行する場合、ApplicationEngine.Configurationでカスタム環境を設定し、そこでsslConnectorを使用してSSL設定を提供する必要があります。
import io.ktor.network.tls.certificates.*
import io.ktor.server.application.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import org.slf4j.*
import java.io.*
import java.security.KeyStore
fun main() {
embeddedServer(Netty, applicationEnvironment { log = LoggerFactory.getLogger("ktor.application") }, {
envConfig()
}, module = Application::module).start(wait = true)
}
private fun ApplicationEngine.Configuration.envConfig() {
val keyStoreFile = File("build/keystore.jks")
val keyStore = buildKeyStore {
certificate("sampleAlias") {
password = "foobar"
domains = listOf("127.0.0.1", "0.0.0.0", "localhost")
}
}
keyStore.saveToFile(keyStoreFile, "123456")
connector {
port = 8080
}
sslConnector(
keyStore = keyStore,
keyAlias = "sampleAlias",
keyStorePassword = { "123456".toCharArray() },
privateKeyPassword = { "foobar".toCharArray() }) {
port = 8443
keyStorePath = keyStoreFile
}
}完全な例は、ssl-embedded-serverを参照してください。
