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.jks
keystore.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を参照してください。