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功能。