内容はほとんどSetup Let’s Encrypt SSL on Google Appengineです。
準備
独自ドメインの設定と、LetsEncryptのインストールは割愛します。
Google App Engine Java で何らかのdeployが出来ることとします。
challenge code と response codeの取得
letsencryptが入っている端末から以下のコマンドを実行します。
sudo letsencrypt-auto -a manual certonly
challenge code と response codeが分かります。
LetsEncryptから証明書を受け取る
これを http://[カスタムドメイン]/.well-known/acme-challenge/[challenge code]
と渡してあげて、response codeを返せばOKなので
public class LetsencryptServlet extends HttpServlet {
public static final Map<String, String> challenges = new HashMap<String, String>();
static {
// challenge codeをKeyにして、response codeを返値する。
challenges.put("hflP1MkFxkoLQyrPKwblQ-BwJC67IKSA0AK2kPsOI8M",
"hflP1MkFxkoLQyrPKwblQ-BwJC67IKSA0AK2kPsOI8M.TEc9CM-bX75lCoGQwUF5BnM2K5iowriH4SOCvwuwJpk");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
if (!req.getRequestURI().startsWith("/.well-known/acme-challenge/")) {
resp.sendError(404);
return;
}
String id = req.getRequestURI().substring("/.well-known/acme-challenge/".length());
if (!challenges.containsKey(id)) {
resp.sendError(404);
return;
}
resp.setContentType("text/plain");
resp.getOutputStream().print(challenges.get(id));
}
}
<servlet>
<servlet-name>letsencrypt</servlet-name>
<servlet-class>...LetsencryptServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>letsencrypt</servlet-name>
<url-pattern>/.well-known/acme-challenge/*</url-pattern>
</servlet-mapping>
<!-- LetsEncrypt用にここはHTTP通信で行う。 -->
<security-constraint>
<web-resource-collection>
<web-resource-name>HTTP</web-resource-name>
<url-pattern>/.well-known/acme-challenge/*</url-pattern>
</web-resource-collection>
</security-constraint>
<!-- SSL Redirect -->
<security-constraint>
<web-resource-collection>
<web-resource-name>SSL Redirect</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
letsencryptと通信をする部分はhttpでdeployします。
deployして反映させた後、ターミナルから[ENTER]キーを押します。
うまくいくと、/etc/letsencrypt/live/[カスタムドメイン]配下に証明書が出来上がります。
cert.pem chain.pem fullchain.pem privkey.pem
証明書のコンバート
opensslコマンドで「復号化された PEM でエンコードされた RSA 秘密鍵」を作成します。
openssl rsa -inform pem \
-in live/[カスタムドメイン]/privkey.pem \
-outform pem > live/[カスタムドメイン]/privkey_fixed.pem
PEM でエンコードされた X.509 公開鍵証明書(fullchain.pem)と復号化された PEM でエンコードされた RSA 秘密鍵(privkey_fixed.pem)をAppEngineの「設定」→「SSL証明書」→「新しい証明書をアップロード」からアップロードします。
すぐに反映はされません。
10分ぐらいかかるような気がします。証明書反映後、証明書が有効になっている事を確認します。
今後の課題
ComputeEngineを使い、cronで90日毎にgitからmasterを取得して、challenge codeとresponse code を取得して、deployして、証明書をアップロードして…とやれば自動更新出来なくはない無いですが、障壁が多すぎてなかなか難しいです。