セットアップの流れ
本家サイトにもスタートアップガイドはありますが、記載は必要最低限になっており、初めての方だと迷われるかもしれません。
そこで、初めての方でも迷わないよう、以下のステップに沿ってVPS WebARENA (Indigo) の簡単なセットアップ手順を紹介したいと思います。
以下の手順を確認する際は、サインアップだけでも実施しておくことをおすすめします。
サインアップだけなら料金は発生しないのでご安心ください。
実際の画面を見ながらの方が、断然理解が進むと思います。
SSLとは
SSL(Secure Socket Layer)とは、インターネット上でデータを暗号化して送受信する仕組みのひとつです。
クレジットカード番号や、一般に秘匿すべきとされる個人に関する情報を取り扱うWebサイトで、これらの情報が盗み取られるのを防止するため、広く利用されています。
たとえば、インターネットバンキングで利用者登録する場合などは、このSSLを使ったホームページが使われます。
Let’s Encryptを使うと無料でSSL化
通常SSLを発行するには費用が発生しますが、Let’s Encryptを使うと無料でSSL化することが出来ます。
Let’s Encryptは、非営利団体の Internet Security Research Group (ISRG) が提供する自動化されたフリーでオープンな認証局です。
Let’s Encrypt は、認証局(CA)として「SSL/TLSサーバ証明書」を無料で発行するとともに、証明書の発行・インストール・更新のプロセスを自動化することにより、
TLS や HTTPS(TLSプロトコルによって提供されるセキュアな接続の上でのHTTP通信)を普及させることを目的としているプロジェクトです。2016年4月12日 に正式サービスが開始されました。非営利団体の ISRG (Internet Security Research Group) が運営しており、
シスコ(Cisco Systems)、Akamai、電子フロンティア財団(Electronic Frontier Foundation)、モジラ財団(Mozilla Foundation)などの大手企業・団体が、
ISRG のスポンサーとして Let’s Encrypt を支援しています。
更新は3か月毎に必要
無料でサーバ証明書を発行してくれるLet’s Encryptですが、有効期限は3ヶ月しか無く、そのたびにSSL証明書を更新するという手間が面倒です。
そのため、自動更新のための仕組みを取りいてることで省力化したいと思います。
VPS ( WebARENA Indigo ) でLet’s Encryptを自動更新
参考にさせて頂いたサイト
Docker環境で簡単にSSL化する方法を解説 【失敗しない初心者でもできる方法】
ファイヤーウォールの設定
今回はWebARENA Indigoを使ってHTTPS化したRedmineを構築したいと思います。
VPS側のファイヤーウォール設定でポートを開放します。ファイヤーウォール作成を参考にして頂ければと思います。
ドメイン(サブドメイン)の取得
もし、まだドメインを未取得の場合は「お名前ドットコム」で取得します。
dfsa初年度であれば1円のドメインも多くあります。
サブドメインの作成は以下のサイトを参考にさせて頂きました。
(なぜお名前ドットコム本家のサイトは、あんなに分かりづらいのか。。。)
ドメインの設定
今回は試しにRedmineをLet’s EncryptでSSL化し、httpsでアクセスしたいと思います。
構成
今回のサーバ側の構成です。
docker環境の構築がまだの場合は、docker環境構築を参考にして頂ければと思います。
├── redmine
│ └── docker-compose.yml
└── ssl
└── docker-compose.yml
また、dockerイメージは3つ利用しています。
- Redmine
- jwilder/nginx-proxy
- jrcs/letsencrypt-nginx-proxy-companion
Redmineの説明は割愛して、残りの2つのイメージについて説明します。
jwilder/nginx-proxy とは
簡単に言うと、リバースプロキシです。
以下の環境変数を設定することで、サイトへのアクセスを適切にルーティングするWEBサーバになります。このDockerイメージではWEBサーバにNginxを利用しています。
- VIRTUAL_HOST
Nginxで(動的に)リバースプロキシを設定し、別コンテナ側(今回はRedmine)で設定した「VIRTUAL_HOSTのURL」をもとに、
アクセス可能にさせてくれるDockerイメージが jwilder/nginx-proxy になります。
設定は簡単で、今回の構成では「ssl/docker-compose.yml」に、jwilder/nginx-proxyをリバースプロキシとして追加します。
それとは別に、各コンテナ(今回はRedmine)に環境変数VIRTUAL_HOSTを与えてあげるだけです。
jrcs/letsencrypt-nginx-proxy-companion とは
簡単にいうと、Let’s Encryptを使ったSSL証明書の自動更新コンテナです。
次の環境変数を設定して、プロキシされるコンテナのLet’sEncryptサポートを有効にすることで、
Let’s Encryptサービスを使用して、仮想ホストの有効な証明書を自動的に作成します。
- LETSENCRYPT_HOST
- LETSENCRYPT_EMAIL
ほとんどの場合、変数LETSENCRYPT_HOSTは変数と同じであるVIRTUAL_HOST必要があり、
公的に到達可能なドメインである必要があります。
docker-compose.yml の設定内容
具体的な設定を確認していきます。
redmine/docker-compose.yml
まずはRedmineです。
本家のdocker-compose.ymlをもとに、SSL化に必要な設定を追加していきます。
version: '3.1'
services:
redmine:
image: redmine
restart: always
ports:
- 8080:3000
environment:
REDMINE_DB_MYSQL: db
REDMINE_DB_PASSWORD: example
REDMINE_SECRET_KEY_BASE: supersecretkey
db:
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: redmine
ここに以下の設定を追加します。
port → exposeへ変更
#ports:
# - 8080:3000
expose:
- 3000
リバースプロキシのフックになる環境変数の追加
ここは自分で取得したドメイン/サブドメインを設定。
またポートは上でexposeしたポート番号(今回は3000)を指定します。
environment:
VIRTUAL_HOST: ********************(techwalk.net のようなドメインを指定)
VIRTUAL_PORT: 3000
LETSENCRYPT_HOST: ********************(techwalk.net のようなドメインを指定)
LETSENCRYPT_EMAIL: ********************(info@gmai.com のようなメールアドレスを指定)
ネットワークの追加
SSL と Redmine は別yamlで起動しているため、ネットワークを追記して同一ネットワークとなるようにします。
networks:
- container-link
networks:
default:
external:
name: bridge
container-link:
name: container_network
最終的な設定は以下の通りです。
version: '3.1'
services:
redmine:
image: redmine
restart: always
#ports:
# - 8080:3000
expose:
- 3000
environment:
REDMINE_DB_MYSQL: db
REDMINE_DB_PASSWORD: example
REDMINE_SECRET_KEY_BASE: supersecretkey
VIRTUAL_HOST: ********************(techwalk.net のようなドメインを指定)
VIRTUAL_PORT: 3000
LETSENCRYPT_HOST: ********************(techwalk.net のようなドメインを指定)
LETSENCRYPT_EMAIL: ********************(info@gmai.com のようなメールアドレスを指定)
networks:
- container-link
db:
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: redmine
networks:
- container-link
networks:
default:
external:
name: bridge
container-link:
name: container_network
また、「jwilder/nginx-proxy」「jrcs/letsencrypt-nginx-proxy-companion」の設定は以下の通りです。
こちらはアプリによって変える記載はありません。
version: '3.7'
services:
nginx-proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy-test
privileged: true
environment:
- "DHPARAM_GENERATION=false"
ports:
- 80:80
- 443:443
tty: true
networks:
- container-link
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- proxy:/usr/share/nginx/html
- proxy:/etc/nginx/vhost.d
- ./docker/encrypt/certs:/etc/nginx/certs:ro
# - ./conf.d/proxy.conf:/etc/nginx/conf.d/proxy.conf:ro # 設定を上書きするときはconf.d内に「.conf」拡張子で追加する
restart: always
labels:
com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: "true"
letsencrypt-nginx:
image: jrcs/letsencrypt-nginx-proxy-companion
container_name: letsencrypt-nginx-test
privileged: true
environment:
- NGINX_PROXY_CONTAINER=nginx-proxy-test # volume_fromを使わない時はコンテナを指定する必要がある
networks:
- container-link
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- proxy:/etc/nginx/vhost.d
- proxy:/usr/share/nginx/html
- ./docker/encrypt/certs:/etc/nginx/certs:rw
restart: always
depends_on:
- nginx-proxy
networks:
default:
external:
name: bridge
container-link:
name: container_network
volumes:
proxy:
SSL化
それでは、それぞれのフォルダ内でdoker-compose upを実行します。
redmine
まずはRedmineです。
[rocky@ redmine]$ docker-compose up
Creating redmine_db_1 ... done
Creating redmine_redmine_1 ... done
ssl
次に「jwilder/nginx-proxy」「jrcs/letsencrypt-nginx-proxy-companion」を起動します。
[rocky@ ssl]$ docker-compose up
Creating nginx-proxy-test ... done
Creating letsencrypt-nginx-test ... done
正常に動くと、以下のログが表示され、証明書の発行と次回チェックまでの待機時間が表示されます。
letsencrypt-nginx-test | [Sat Jun 25 13:03:27 UTC 2022] Using CA: https://acme-v02.api.letsencrypt.org/directory
letsencrypt-nginx-test | [Sat Jun 25 13:03:27 UTC 2022] Creating domain key
letsencrypt-nginx-test | [Sat Jun 25 13:03:28 UTC 2022] The domain key is here: /etc/acme.sh/********************/********************/********************.key
letsencrypt-nginx-test | [Sat Jun 25 13:03:28 UTC 2022] Single domain='********************'
letsencrypt-nginx-test | [Sat Jun 25 13:03:28 UTC 2022] Getting domain auth token for each domain
letsencrypt-nginx-test | [Sat Jun 25 13:03:30 UTC 2022] Getting webroot for domain='********************'
letsencrypt-nginx-test | [Sat Jun 25 13:03:30 UTC 2022] Verifying: ********************
nginx-proxy-test | nginx.1 | ******************** 52.41.228.68 - - [25/Jun/2022:13:03:31 +0000] "GET /.well-known/acme-challenge/XXXXXXXXXXXXXXXXXXXXXXXXXXXXX HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"
nginx-proxy-test | nginx.1 | ******************** 3.19.120.239 - - [25/Jun/2022:13:03:31 +0000] "GET /.well-known/acme-challenge/XXXXXXXXXXXXXXXXXXXXXXXXXXXXX HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"
nginx-proxy-test | nginx.1 | ******************** 66.133.109.36 - - [25/Jun/2022:13:03:32 +0000] "GET /.well-known/acme-challenge/XXXXXXXXXXXXXXXXXXXXXXXXXXXXX HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"
nginx-proxy-test | nginx.1 | ******************** 18.156.79.179 - - [25/Jun/2022:13:03:32 +0000] "GET /.well-known/acme-challenge/XXXXXXXXXXXXXXXXXXXXXXXXXXXXX HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"
letsencrypt-nginx-test | [Sat Jun 25 13:03:34 UTC 2022] Success
letsencrypt-nginx-test | [Sat Jun 25 13:03:34 UTC 2022] Verify finished, start to sign.
letsencrypt-nginx-test | [Sat Jun 25 13:03:34 UTC 2022] Lets finalize the order.
letsencrypt-nginx-test | [Sat Jun 25 13:03:34 UTC 2022] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/604767096/100935554236'
letsencrypt-nginx-test | [Sat Jun 25 13:03:35 UTC 2022] Downloading cert.
letsencrypt-nginx-test | [Sat Jun 25 13:03:35 UTC 2022] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/03732059b76b0fb68cedb55d29440dff2aa9'
letsencrypt-nginx-test | [Sat Jun 25 13:03:36 UTC 2022] Cert success.
letsencrypt-nginx-test | -----BEGIN CERTIFICATE-----
letsencrypt-nginx-test | MIIGKDCCBRCgAwIBAgISA3MgWbdrD7aM7bVdKUQN/yqpMA0GCSqGSIb3DQEBCwUA
letsencrypt-nginx-test | MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
......
letsencrypt-nginx-test | Bt6WDhrIol4LiERJCrFH/7VE48QMUQpZifHC5uRS1aVqESlRtS87eIHN/mLKca6U
letsencrypt-nginx-test | faWBLtHlsSSV1Nmc4WSYVt+sAOgH3vnQuW/0t+qZ+aab5IJKI+WnlwHQuag=
letsencrypt-nginx-test | -----END CERTIFICATE-----
letsencrypt-nginx-test | [Sat Jun 25 13:03:36 UTC 2022] Your cert is in /etc/acme.sh/********************/********************/********************.cer
letsencrypt-nginx-test | [Sat Jun 25 13:03:36 UTC 2022] Your cert key is in /etc/acme.sh/********************/********************/********************.key
letsencrypt-nginx-test | [Sat Jun 25 13:03:36 UTC 2022] The intermediate CA cert is in /etc/acme.sh/********************/********************/ca.cer
letsencrypt-nginx-test | [Sat Jun 25 13:03:36 UTC 2022] And the full chain certs is there: /etc/acme.sh/********************/********************/fullchain.cer
letsencrypt-nginx-test | [Sat Jun 25 13:03:36 UTC 2022] Installing cert to:/etc/nginx/certs/********************/cert.pem
letsencrypt-nginx-test | [Sat Jun 25 13:03:36 UTC 2022] Installing CA to:/etc/nginx/certs/********************/chain.pem
letsencrypt-nginx-test | [Sat Jun 25 13:03:36 UTC 2022] Installing key to:/etc/nginx/certs/********************/key.pem
letsencrypt-nginx-test | [Sat Jun 25 13:03:36 UTC 2022] Installing full chain to:/etc/nginx/certs/********************/fullchain.pem
letsencrypt-nginx-test | Reloading nginx proxy (c19734260fee101db799873b6a2d36b39e22db13fc38633e51e7c0dfca2f3456)...
nginx-proxy-test | nginx.1 | 2022/06/25 13:03:38 [notice] 13#13: signal 1 (SIGHUP) received from 57, reconfiguring
nginx-proxy-test | nginx.1 | 2022/06/25 13:03:38 [notice] 13#13: reconfiguring
nginx-proxy-test | nginx.1 | 2022/06/25 13:03:38 [notice] 13#13: using the "epoll" event method
nginx-proxy-test | nginx.1 | 2022/06/25 13:03:38 [notice] 13#13: start worker processes
nginx-proxy-test | nginx.1 | 2022/06/25 13:03:38 [notice] 13#13: start worker process 58
nginx-proxy-test | nginx.1 | 2022/06/25 13:03:38 [notice] 47#47: gracefully shutting down
nginx-proxy-test | nginx.1 | 2022/06/25 13:03:38 [notice] 47#47: exiting
nginx-proxy-test | nginx.1 | 2022/06/25 13:03:38 [notice] 47#47: exit
letsencrypt-nginx-test | 2022/06/25 13:03:38 Generated '/etc/nginx/conf.d/default.conf' from 4 containers
nginx-proxy-test | nginx.1 | 2022/06/25 13:03:38 [notice] 13#13: signal 17 (SIGCHLD) received from 47
nginx-proxy-test | nginx.1 | 2022/06/25 13:03:38 [notice] 13#13: worker process 47 exited with code 0
nginx-proxy-test | nginx.1 | 2022/06/25 13:03:38 [notice] 13#13: signal 29 (SIGIO) received
letsencrypt-nginx-test | 2022/06/25 13:03:38 [notice] 57#57: signal process started
letsencrypt-nginx-test | Sleep for 3600s
HTTPS化した証明書の確認
証明書の確認を行います。アドレスバーに鍵マークが表示され、接続が保護されていることが分かります。
また、証明書の詳細をみると、有効期限が3か月後になっており、発行者はR3となっています。
このR3はLet’sEncryptになります。
以上、となります。
ここで紹介した手順は、Redmine以外でも同じように応用可能になります。