概要
前回からの続きです.
今回はDNSサーバの構築とサーバ証明書を発行して,HTTPS通信,ドメイン名でWebサイトにアクセスできるようにします.
前提知識
DNSサーバ:「ドメイン名」と「IPアドレス」を結びつける役割を持つサーバー.これによってサーバにドメイン名でアクセスできるようになる.ドメイン名からIPアドレスを調べることを名前解決と呼ぶ.
HTTPS通信:「HTTP」を「SSL/TLS」という暗号化技術で保護した、安全な通信プロトコル.
DNSサーバ
こちらの記事を参考にしました
準備
構築するDNSサーバを名前解決に使用してもらうため,アプリケーションをデプロイしたサーバのネットワークの設定を変えておきます.
network:
version: 2
ethernets:
enp1s0:
dhcp4: no
addresses:
- 192.168.11.50/24
routes:
- to: default
via: 192.168.11.1
nameservers:
addresses:
- 192.168.11.50 自分のdnsのip
- 8.8.8.8
- 1.1.1.1
nameserversの設定を変えておきます.
DNSサーバの構築
bindをインストールします.
sudo apt-get install bind9 bind9utils bind9-doc
インストールできたら設定ファイルに移動
cd /etc/bind/named.conf.default-zones
上側がフォワードルックアップの設定で下側がリバースルックアップの設定をする.
zone “example.home” {
type master;
file "/etc/bind/db.example.home";
};
zone “11.168.192.in-addr.arpa" {
type master;
file "/etc/bind/db.11.168.192";
};
ここでexample.homeというドメイン名を設定.
次に、/etc/bind/db.example.homeを編集する
このファイルはデフォルトでは作成されないので、適当なdb.~ファイルをコピペして作る.
シリアルは適当に増やす
$TTL 604800
@ IN SOA home.local. root.localhost. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS localhost.
cd-server IN A 192.168.11.50
/etc/bind/db.11.168.192も作成する
$TTL 604800
@ IN SOA home.local. root.localhost. (
3 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS localhost.
1 IN PTR cd-server.example.home
bindをリスタート
sudo systemctl restart bind9
DNSの設定がしっかりできているかチェック
sudo named-checkzone example.home /etc/bind/db.example.home
sudo named-checkzone 11.168.192 /etc/bind/db.11.168.192
ファイアーウォールでdnsのポートを許可する
sudo ufw allow 53/tcp
sudo ufw allow 53/udp
dns設定がnetplanで正しく出来ていればdnsの指定がなくとも名前解決できる
#下記で名前解決するか確認する
nslookup 192.168.11.50
nslookup cd-server.example.home
Webアプリにドメイン名でアクセス
前回の記事で設定したNginxに関するファイルを編集します.
server {
listen 80;
server_name cd-server.example.home;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:8080;
}
}
server_nameをドメイン名に変更しました.これでアクセスする準備が完了しました.
実際にアクセスしてみる
最後にPCで設定されているDNSサーバを今回作成したDNSサーバのIPに変更します.
Macの人は↓の順で設定画面に移動.
左上のアップルマーク>システム設定>Wi-Fi>接続しているWi-Fiの詳細ボタン

このように設定画面で作成したDNSサーバのIPアドレスをセットしてOKをクリック.
http://cd-server.exmaple.comにアクセスできるようになりました.

Chromeを使ってWebサイトを表示しました.
上のアドレスバーのところに「保護されていない通信」と表示されています.
これはhttp通信だと表示される警告です.
HTTPS通信
こちらのQiitaを参考にしました.
ざっくりHTTPS通信について
HTTPSは基本的に TLS(旧SSL) という暗号化技術を使います。 通信の流れは簡単にいうと以下のようになります:
- クライアント(ブラウザ)がサーバーに接続要求
- サーバーが証明書を送信
- 証明書にはサーバーの公開鍵と認証情報が含まれる
- クライアントが証明書を検証
- 証明書が正当であれば、公開鍵を使って セッションキー を生成
- 以降の通信を暗号化
- このセッションキーを使い、対称鍵暗号で効率よく通信
ネットで調べてみると詳しく図で解説しているものがたくさんあるので,詳しいことは各自で調べてみてください.
実装
ディレクトリを作成する.アプリケーションを作成したサーバにログインしてコマンドを実行する.
sudo mkdir /etc/nginx/ssl
- /etc/nginx/ssl というディレクトリを作成しています。
- sudo は管理者権限で作成するため。
- SSL証明書や秘密鍵を格納する場所を作っています。
続いて秘密鍵の作成
sudo openssl genrsa -out /etc/nginx/ssl/server.key 2048
- openssl genrsa → RSA形式の秘密鍵を生成
- -out /etc/nginx/ssl/server.key → 出力先ファイル
- 2048 → 鍵の長さ(ビット長)。2048ビットは最低限の安全性を確保する標準的な値。
- 秘密鍵はサーバだけが持つ重要な情報で、他人に見られてはいけません。
証明書署名要求(CSR)の作成
sudo openssl req -new -key /etc/nginx/ssl/server.key -out /etc/nginx/ssl/server.csr
- openssl req -new → 新しい証明書署名要求(CSR)を作る
- -key /etc/nginx/ssl/server.key → 先ほど作った秘密鍵を使う
- -out /etc/nginx/ssl/server.csr → 出力先ファイル
- CSR には「このサーバの情報(ドメイン名や組織名など)」が入ります。
- 通常は CA に送って署名してもらうためのファイルですが、自己署名証明書でも作ります。
最後文章について補足します.通常この証明書というのは公的な機関によって発行されるモノです.その機関を認証局(CA)といいます.そのCAも証明書を持っており,その証明書はさらに上位のCAによって署名されています.このように階層型で証明書の正当性を担保しています.この階層を証明書チェーンと呼びます.
これは無限に続くように思えますが,ルート証明書という絶対的な権威を持つ証明書が存在し,これは誰にも署名されなくても大丈夫なため,ここが証明書チェーンの頂点になります.
今回は個人開発のため,CAの署名を受けずに発行できるルート証明書もどき,つまり自己署名証明書を作成しています.オレオレ証明書とも呼ばれます.
ちなみに,実際に使われているルート証明書はみなさんのPC,ブラウザにすでにインストール済みです.Macの方は後でルート署名書がみれる場所を教えますが,それ以外の方やブラウザに保存されているルート署名書をみたい人は調べてみてください.
最後に自己署名証明書を作成します.
sudo openssl x509 -days 3650 -req -signkey /etc/nginx/ssl/server.key -in /etc/nginx/ssl/server.csr -out /etc/nginx/ssl/server.crt -extfile SAN.txt
- openssl x509 → X.509形式の証明書を作る
- -days 3650 → 有効期間を 3650 日(約10年)に設定
- -req → 入力は CSR 形式
- -signkey /etc/nginx/ssl/server.key → 自己署名するため、秘密鍵で署名
- -in /etc/nginx/ssl/server.csr → CSR を入力
- -out /etc/nginx/ssl/server.crt → 出力する証明書ファイル
- Chromeは、ドメイン名のチェックをCommon Nameで行わず、SAN(Subject Alternative Name)を参照しているとのこと。(Chromeの人のみ必須)
- 従って、SAN.txtに適用するホスト名を指定する。
subjectAltName = DNS:cd-server.example.home
これで 自己署名証明書 server.crt ができあがります。
一応ちゃんとファイルが作られているか確認します.
ls /etc/nginx/ssl/
- ディレクトリ内のファイルを確認
- server.key → 秘密鍵
- server.csr → 証明書署名要求
- server.crt → 作成された自己署名証明書
Nginxの設定
NginxにTLSに対応した通信ができるように設定をします.
sudo vi /etc/nginx/conf.d/registersite.conf
server {
listen 443 ssl;
server_name cd-server.example.home;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:8080;
}
}
TLSのポート番号443,暗号化通信に必要な鍵を設定します.
Nginxが鍵などのファイルを操作できるようにパーミッションを設定します.
ファイルの所有者の権限をnginxのユーザ(www-data)にする
sudo chown root:www-data /etc/nginx/ssl/server.key
sudo chmod 640 /etc/nginx/ssl/server.key
二つ目のコマンドは,所有者rootが読み書きグループwww-data が読み取り可能、他はアクセス不可
ディレクトリに入れるのは所有者とグループだけにして,nginxを再起動
sudo chown root:www-data /etc/nginx/ssl
sudo chmod 755 /etc/nginx/ssl
systemctl restart nginx
自己証明書のダウンロードと必要な設定
ローカルのPCにはルート証明書が元々設定されているので,ユーザ側で特に設定をする必要がなく,WebサイトにHTTPSでアクセスできます.
ただ,自己証明書の場合,もちろん標準ではインストールされていないので,その設定を行う必要があります.
まず,証明書をPCにダウンロードします.
以下のコマンドをPCで実行してください.
scp ubuntu@192.168.11.50:/etc/nginx/ssl/server.crt ~/Desktop/server.crt
ダウンロード場所はどこでもいいですが,後でドラッグ&ドロップする関係でデスクトップにしました.
次に,Macosのキーチェーンアクセスを開いて,左のダブからシステムをクリック
その後,右の画面で証明書を選択.
↓画面に対して先ほどダウンロードした鍵をドラッグ&ドロップ.
追加した鍵をダブルクリックして,信頼タブを開く.常に信頼を選択

その後,https://~でアクセスするとHTTPSでアクセスできます.

先ほどの警告が消えているのがわかります.
まとめ
今回はDNSサーバとHTTPS通信をローカルで実現してみました.
今はオンプレでこういったシステムを構築する機会は少なく,業務ではAWS,GCPなどのパブリッククラウドで実装することが多いと思いますが,基本的な原理は今回紹介したことと同じなので一度自分で1から構築してみる経験を積むことは今後大いに役立つと思います.
一旦こちらの個人開発は今回で以上です!
最後までご覧いただきありがとうございました!
