6、Ktor學習-證書;

Melrose發表於2019-03-04

JKS檔案格式

  JKS(Java KeyStore)是Java和Ktor使用的證照格式。

  你可以使用keytool來轉換和管理這些證照。

CER檔案格式

keytool -import -v -trustcacerts -alias keyAlias -file server.cer -keystore cacerts.jks -keypass changeit
複製程式碼

SSL

  您可以購買證照並配置Ktor使用它,或者您可以使用Let's Encrypt自動獲取免費證照以使用Ktor提供https://和wss://請求。

  將Ktor配置為直接為單個域提供SSL證照,或者使用Docker和nginx輕鬆地在單個計算機上的不同容器中提供不同的應用程式。

使用Ktor直接提供的SSL

  首先,您必須將域或子域配置為指向要用於證照的計算機的IP。 你必須在這裡放置機器的公共IP。 如果該計算機位於路由器後面,則需要將路由器配置為使用主機對機器進行DMZ,或者至少將埠80(HTTP)重定向到該計算機,稍後您可能需要配置埠443(HTTPS )也是。

注:即使您將Ktor配置為繫結到另一個埠,Let’s Encrypt也將始終訪問公共IP的PORT 80,您必須配置路由以將埠80重定向到託管ktor的計算機的正確本地IP和埠。

  • 生成證照

      要Ktor伺服器能執行,您必須執行以下命令(changing my.example.com, root@example.com and 8889)。 此命令將啟動指定埠中的HTTP Web伺服器(必須在公共網路中作為埠80使用,或者您可以將路由器中的埠轉發到80:8889,並且域必須指向您的公共IP),它 然後將請求,使用適當的內容公開/.well-known/acme-challenge/file,生成域私鑰,並檢索證照鏈:

    export DOMAIN=my.example.com
    export EMAIL=root@example.com
    export PORT=8889
    export ALIAS=myalias
    certbot certonly -n -d $DOMAIN --email "$EMAIL" --agree-tos --standalone --preferred-challenges http --http-01-port $PORT
    複製程式碼

      配置正常後會生成如下資訊:

    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Plugins selected: Authenticator standalone, Installer None
    Obtaining a new certificate
    Performing the following challenges:
    http-01 challenge for my.example.com
    Waiting for verification...
    Cleaning up challenges
    
    IMPORTANT NOTES:
    - Congratulations! Your certificate and chain have been saved at:
    /etc/letsencrypt/live/my.example.com/fullchain.pem
    Your key file has been saved at:
    /etc/letsencrypt/live/my.example.com/privkey.pem
    Your cert will expire on 2018-09-27. To obtain a new or tweaked
    version of this certificate in the future, simply run certbot
    again. To non-interactively renew *all* of your certificates, run
    "certbot renew"
    - If you like Certbot, please consider supporting our work by:
    
    Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
    Donating to EFF:                    https://eff.org/donate-le
    複製程式碼
  • 轉換Ktor的私鑰和證照

    現在,您必須將certbot編寫的私鑰和證照轉換為Ktor可以理解的格式。 鏈和私鑰儲存在/etc/letsencrypt/live/$DOMAIN中,作為fullchain.pem和privkey.pem。

     openssl pkcs12 -export -out /etc/letsencrypt/live/$DOMAIN/keystore.p12 -inkey /etc/letsencrypt/live/$DOMAIN/privkey.pem -in /etc/letsencrypt/live/$DOMAIN/fullchain.pem -name $ALIAS
    複製程式碼

    這將為匯出請求密碼(您需要提供一個用於下一步工作的密碼):

    Enter Export Password: mypassword
    Verifying - Enter Export Password: mypassword
    複製程式碼

    使用p12檔案,我們可以使用keytool cli生成JKS檔案:

    keytool -importkeystore -alias $ALIAS -destkeystore /etc/letsencrypt/live/$DOMAIN/keystore.jks -srcstoretype PKCS12 -srckeystore /etc/letsencrypt/live/$DOMAIN/keystore.p12
    複製程式碼
  • 配置Ktor以使用生成的JKS

    現在,您必須更新application.conf HOCON檔案,以配置SSL埠,keyStore,別名和密碼。 您必須為特定情況設定正確的值:

    ktor {
      deployment {
          port = 8889
          port = ${?PORT}
          sslPort = 8890
          sslPort = ${?PORT_SSL}
      }
      application {
          modules = [ com.example.ApplicationKt.module ]
      }
      security {
          ssl {
              keyStore = /etc/letsencrypt/live/mydomain.com/keystore.jks
              keyAlias = myalias
              keyStorePassword = mypassword
              privateKeyPassword = mypassword
          }
      }
    }
    複製程式碼

    如果一切順利,Ktor應該在HTTP中偵聽埠8889並在HTTPS中偵聽埠8890。

使用Docker和Nginx作為反向代理

  使用具有多個域的Docker時,您可能希望使用nginx-proxy映像和letsencrypt-nginx-proxy-companion映像在單個計算機/ip上提供多個域/子域,並使用Let's Encrypt自動提供HTTPS。

  在這種情況下,您使用NGINX建立一個容器,可能會偵聽埠80和443,內部網路只能在容器之間訪問,因此nginx可以連線和反向代理您的網站(包括websockets),以及NGINX通過處理域證照 配置Docker容器。

  • 建立內部docker網路

  第一步是建立一個我們將使用的橋接網路,以便nginx可以連線到其他容器以反向代理使用者的HTTP,HTTPS,WS和WSS請求:

docker network create --driver bridge reverse-proxy
複製程式碼
  • 建立一個Nginx容器

    現在我們必須建立一個執行NGINX的容器來執行反向代理:

     docker rm -f nginx
     docker run -d -p 80:80 -p 443:443 \
      --name=nginx \
      --restart=always \
      --network=reverse-proxy \
      -v /home/virtual/nginx/certs:/etc/nginx/certs:ro \
      -v /home/virtual/nginx/conf.d:/etc/nginx/conf.d \
      -v /home/virtual/nginx/vhost.d:/etc/nginx/vhost.d \
      -v /home/virtual/nginx/html:/usr/share/nginx/html \
      -v /var/run/docker.sock:/tmp/docker.sock:ro \
      -e NGINX_PROXY_CONTAINER=nginx \
      --label com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true \
      jwilder/nginx-proxy
    複製程式碼

    --restart=always 當重新啟動機器時,docker守護程式會重新啟動容器。 --network=reverse-proxy NGINX在該網路中,可以連線到同一網路中的其他容器。 -v certs:ro 此卷將與letsencrypt-companion共享,以訪問每個域的證照。 -v conf, vhost 如果您需要進行一些調整,這種配置是持久的,可以從外部訪問。 -v /var/run/docker.sock 這允許此image獲得有關在守護程式中執行的新容器的通知。 -e --label 由同伴使用,將此image標識為NGINX。

    注:您可以將/home/virtual/nginx *路徑調整為您喜歡的路徑。

  • 使用Let’s Encrypt來建立Nginx容器

     docker rm -f nginx-letsencrypt
     docker run -d \
     --name nginx-letsencrypt \
     --restart=always \
     --network=reverse-proxy \
     --volumes-from nginx \
     -v /home/virtual/nginx/certs:/etc/nginx/certs:rw \
     -v /var/run/docker.sock:/var/run/docker.sock:ro \
     jrcs/letsencrypt-nginx-proxy-companion
    複製程式碼
  • 建立服務

  現在我們用Let’s Encrypt配置了NGINX,這樣他們就會根據環境變數VIRTUAL_HOST,VIRTUAL_PORT和LETSENCRYPT_HOST,LETSENCRYPT_EMAIL自動反向代理您的網站,併為他們請求和提供證照。

  使用docker-compose,您可以建立一個docker-compose.yml檔案(無需其他服務),如下所示:


docker-compose.yml

version: '2'
services:
  web:
    build:
      context: ./
      dockerfile: Dockerfile
    expose:
      - 8080
    environment:
      - VIRTUAL_HOST=mydomain.com
      - VIRTUAL_PORT=8080
      - LETSENCRYPT_HOST=mydomain.com
      - LETSENCRYPT_EMAIL=myemail@mydomain.com
    networks:
      - reverse-proxy
    restart: always

networks:
  backend:
  reverse-proxy:
    external:
      name: reverse-proxyv
複製程式碼

Dockerfile

FROM openjdk:8-jre-alpine

ENV APPLICATION_USER ktor
RUN adduser -D -g '' $APPLICATION_USER

RUN mkdir /app
RUN chown -R $APPLICATION_USER /app

USER $APPLICATION_USER

COPY ./build/libs/my-application.jar /app/my-application.jar
WORKDIR /app

CMD ["java", "-server", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCGroupMemoryLimitForHeap", "-XX:InitialRAMFraction=2", "-XX:MinRAMFraction=2", "-XX:MaxRAMFraction=2", "-XX:+UseG1GC", "-XX:MaxGCPauseMillis=100", "-XX:+UseStringDeduplication", "-jar", "my-application.jar"]
複製程式碼

XForwardedHeaderSupport功能

  在這種情況下,您使用nginx作為請求的反向代理。 如果要獲取有關原始請求的資訊,而不是代理的nginx請求,則必須使用XForwardedHeaderSupport功能。

相關文章