Skip to content
Server Plugin

KtorサーバーにおけるSSLと証明書

必須の依存関係: io.ktor:ktor-network-tls-certificates

コード例: ssl-engine-main, ssl-embedded-server

ほとんどの場合、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アーティファクトを追加する必要があります。

Kotlin
Groovy
XML

以下のコードスニペットは、証明書を生成してキーストアファイルに保存する方法を示しています。

kotlin
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を使用して、自己署名証明書を生成できます。

Bash
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形式に変換する必要があります。 これにはopensslkeytoolユーティリティを使用できます。 例えば、key.pemファイルに秘密鍵があり、cert.pemに公開証明書がある場合、変換プロセスは次のようになります。

  1. opensslを使用してPEMをPKCS12形式に変換します。以下のコマンドを使用します。

    Bash
    openssl pkcs12 -export -in cert.pem -inkey key.pem -out keystore.p12 -name "sampleAlias"

    key.pemのパスフレーズとkeystore.p12の新しいパスワードの入力を求められます。

  2. keytoolを使用してPKCS12をJKS形式に変換します。

    Bash
    keytool -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を有効にできます。

  1. ktor.deployment.sslPortプロパティを使用してSSLポートを指定します。

    shell
    ktor {
        deployment {
            sslPort = 8443
        }
    }
    yaml
    ktor:
        deployment:
            sslPort: 8443
  2. 別のsecurityグループでキーストア設定を提供します。

    shell
    ktor {
        security {
            ssl {
                keyStore = keystore.jks
                keyAlias = sampleAlias
                keyStorePassword = foobar
                privateKeyPassword = foobar
            }
        }
    }
    yaml
    ktor:
        security:
            ssl:
                keyStore: keystore.jks
                keyAlias: sampleAlias
                keyStorePassword: foobar
                privateKeyPassword: foobar

完全な例は、ssl-engine-mainを参照してください。

embeddedServer

embeddedServer関数を使用してサーバーを実行する場合、ApplicationEngine.Configurationカスタム環境を設定し、そこでsslConnectorを使用してSSL設定を提供する必要があります。

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