ねらい
本記事は、以下の目的で行った一連の遊びに関する、自分自身のためのメモです。Qiita 的にありふれた情報ばかりだとは思いますが、自分に必要な情報をまとめておきます。
- VPS (Virtual Private Server) の勉強
- Linux (CentOS 7) の勉強
- パーソナル認証局でのお遊びからの卒業
前回(1/2)は、ConoHa で VPS を借りて、CentOS 7 の各種設定をして、SSH、SCP、VNC によるセキュアなリモート接続環境を構築したうえで、Web サーバ(Apache)を動かすところまででした。
前回の記事:ConoHa で VPS を借りて Node.js で HTTPS サーバを建てるまでのメモ(1/2)
今回(2/2)は、オリジナルのドメインを取得し、DNS に登録し、Let's Encrypt を使って SSL (HTTPS) に対応した Web サイトに仕立てたうえで、Node.js でも HTTPS サーバを建てます。
前回、Apache で Web サーバを動かし、https で接続させましたが、素の状態では、ブラウザに「安全な接続ではありません」と表示され、例外として追加しないとアクセスできません。これは、電子証明書が信頼できる認証局により発行されたものではないからです。
無償で電子証明書を発行してくれる Let's Encrypt で証明書を取得します。また、その前提として、オリジナルのドメインを取得します。その後、まずは Apache を SSL 対応させ、さらに、Node.js でも HTTPS サーバを建てます。
独自ドメインの取得
ドメインの取得方法
独自のドメイン(hogehoge.com や hogehoge.net のような、hogehoge の部分)を取得するには「レジストラ」というサイトでドメインを買う。以下はレジストラの例。
あるいは、レンタルサーバやホスティングサービスを提供しているところでも買える。
今回は、MuuMuu Domain で取得。ドメインの検索方法や結果が個人的に最も分かりやすいと感じた。サイトのトップページで取得したいドメイン名(.com や .net などより前の部分)を入れて検索すると、空いているか(先に取られていないか)と、値段(取得費用)が表示される。
※ 実際には取得費用以外に、更新費用が毎年かかるので、価格一覧ページで確認。
「カートに追加」して、普通のネット通販同様の手順で、すぐに取得できる。
これ以降は、「hogehoge.com」というドメインを取得したという架空の設定とする。ちなみに「.com」ドメインは、取得費用が 799 円、1年ごとに更新料が 1,480 円。
WHOIS 検索でドメインの登録確認
取得したドメインの登録情報は WHOIS 検索サイトや、whois コマンド(要インストール)で確認できる。
Verisign のサイトで確認
- Verisign の Whois サイトにアクセス
- 「Search Whois」にて、「Domain」を選び、ドメイン名を入力して、「SEARCH」をクリック
- ただし、Verisign で Whois 検索できるドメインは限定的
whois コマンドで確認
- whois をインストール
- whois ドメイン名
$ su
# yum install whois
# whois hogehoge.com
:
Domain Name: HOGEHOGE.COM
Registry Domain ID: xxxxxxxxxx_DOMAIN_NET-VRSN
Registrar WHOIS Server: whois.discount-domain.com
Registrar URL: http://gmo.jp
:
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Name Server: DNS01.MUUMUU-DOMAIN.COM
Name Server: DNS02.MUUMUU-DOMAIN.COM
DNSSEC: unsigned
URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/
:
マシンにホスト名を設定
マシン(VPS)にホスト名を設定する。hostnamectl の set-hostname を使う。
$ su
# hostnamectl set-hostname hogehoge.com
ホスト名の情報は /etc/hostname に書かれている。
# cat /etc/hostname
hogehoge.com
ドメインを DNS に登録する
ドメインは、取得しただけでは機能しない。そのドメインが、どのマシンやサービス(IP アドレス等)と対応するかを紐づける必要がある。それが DNS (Domain Name System) への登録。以下の3種類の選択肢を試した。
- 選択肢1:今回ドメインを買った MuuMuu Domain の ムームーDNS に登録
- 選択肢2:ConoHa の DNS に登録
- 選択肢3:ダイナミック DNS サービス MyDNS.jp に登録
なお現在は「選択肢1:ムームーDNS に登録」で運用中。サーバ管理は ConoHa、ドメイン管理はムームー、という棲み分けがシンプルかと。
選択肢1:ドメインを ムームーDNS に登録
DNS への登録
- MuuMuu Domain のサイトにログインした状態で、ページ上部のユーザのアイコンをクリック -> コントロールパネルに移行
- 左側の「ドメイン管理」メニューから「ムームー DNS」をクリック
- 取得したドメイン名の横にある「変更」ボタンをクリック
「カスタム設定」に移行
ここで、ムームー DNS は通常は、GMO が提供している各種サービス(ロリポップ等)とドメイン名との紐づけを目的にしているので、デフォルトでは、ムームー以外のサービス(今回のような VPS や自宅サーバ等)は登録できない。しかし、「カスタム設定」を使うことで、VPS や自宅サーバも登録できる。
- ページ最下部の「カスタム設定」ボタンをクリック
- 以降、「設定2」の欄で作業する
登録
- 「サブドメイン」欄は空白のまま
- 「種別」は「A」を選択(A は IPv4 アドレスを対応付けるという意味)
- 「内容」欄に VPS の IPv4 アドレスを入力
- 最後に「セットアップ情報変更」ボタンをクリックして、完了
ネームサーバの指定
MuuMuu Domain 側に「DNS は ムームーDNS を使う」という指定をする。
- コントロールパネル左側の「ドメイン管理」メニューから「ネームサーバ設定変更」をクリック
- 取得したドメイン名の横にある「ネームサーバ設定変更」ボタンをクリック
- 「(●) ムームードメインのネームサーバ(ムームーDNS)を使用する」を選択
- ページ最下部の「ネームサーバ設定変更」ボタンをクリック
- ちなみに、以下の2個のネームサーバが指定されるようだ
- dns01.muumuu-domain.com
- dns02.muumuu-domain.com
選択肢2:ドメインを ConoHa の DNS に登録
DNS への登録
ConoHa VPS のコントロールパネルでドメインを登録する。
- 左側のメニューから「DNS」を選択
- 「+ドメイン」をクリック
- 「ドメイン名」欄に取得したドメインを入力(例えば hogehoge.com)
- 「保存」をクリック → ドメインリストに追加される
- リストに追加されたドメイン名をクリック
- 鉛筆アイコンをクリック
- 「+」アイコンをクリックし、以下のように設定
- タイプ:A(通常) ←(A は IPv4 アドレスを対応付けるという意味)
- 名称:(空欄のまま)
- 値:VPS の IPv4 アドレス
- 「保存」をクリック
- 表示されている3個のネームサーバをメモする(例えば以下)
- ns-a1.conoha.io
- ns-a2.conoha.io
- ns-a3.conoha.io
ネームサーバの指定
MuuMuu Domain 側に「DNS は ConoHa を使う」という指定をする。
- MuuMuu Domain のサイトにログインした状態で、ページ上部のユーザのアイコンをクリック -> コントロールパネルに移行
- 左側の「ドメイン管理」メニューから「ネームサーバ設定変更」をクリック
- 取得したドメイン名の横にある「ネームサーバ設定変更」ボタンをクリック
- 「(●) GMOペパボ以外 のネームサーバを使用する」を選択
- 「ネームサーバを設定してください」の欄に以下を入力(ConoHa のネームサーバ)
- ネームサーバ1: ns-a1.conoha.io
- ネームサーバ2: ns-a2.conoha.io
- ネームサーバ3: ns-a3.conoha.io
- ページ最下部の「ネームサーバ設定変更」ボタンをクリック
選択肢3:ドメインを MyDNS に登録
DNS への登録
- MyDNS.jp を使うのが初めてなら、ページ上部の「JOIN US」からユーザ登録
- ログイン後…
- ページ左側の「DOMAIN INFO」にて、取得したドメイン(今回は hogehoge.com)を登録
- Domain 欄にドメイン名を(今回は hogehoge.com)
- MX 欄にも同じくドメイン名を(今回は hogehoge.com)(省略も可)
- Hostname 欄の最上段には「*」と入力
- 最後に「CHECK」ボタンをクリック
- 以上の設定により、*.hogehoge.com というアドレスを、hogehoge.com に関連付けた
- ページ左側の「IP ADDR DIRECT」にて、上記で設定したドメイン(hogehoge.com)と IP アドレスを紐づけ
- IPv4 Address 欄にサーバの IPv4アドレスを入力、固定IP を選択
- IPv6 Address 欄はデフォルトのままで OK(使う予定がないので)
- 最後に「CHECK」ボタンをクリック
- 以上の設定により、hogehoge.com とサーバの IP アドレスが紐づけられた
ネームサーバの指定
MuuMuu Domain 側に「DNS は MyDNS を使う」という指定をする。
- MuuMuu Domain のサイトにログインした状態で、ページ上部のユーザのアイコンをクリック -> コントロールパネルに移行
- 「ドメイン管理」メニューから「ネームサーバ設定変更」をクリック
- 取得したドメイン名の横にある「ネームサーバ設定変更」ボタンをクリック
- 「(●) 取得したドメインで使用する ※上級者向け」を選択
- 「ネームサーバを設定してください」の欄に以下を入力(MyDNS のネームサーバ)
- ネームサーバ1: ns0.mydns.jp
- ネームサーバ2: ns1.mydns.jp
- ネームサーバ3: ns2.mydns.jp
- ページ最下部の「ネームサーバ設定変更」ボタンをクリック
MyDNS への登録の更新方法
MyDNS は、もともと自宅サーバのような「動的 IP」を紐づけるサービス(DDNS; Dynamic DNS)であるため、定期的に登録情報を更新する必要がある(最長でも約1週間ごとに)。たとえ「固定 IP」として登録しても更新が必要な仕様。ちなみに、1ヶ月以上、更新もログインも無いと、アカウント自体が削除されるようだ。
更新方法は以下のように様々な選択肢がある。
- POP3(s)
- IMAP4(s)
- FTP(s)
- HTTP(s)-BASIC
- HTTP(s)-DIRECT
- 更新用アプリケーション(DiCE 等)を使う
今回は、本記事末尾の参考書籍に従って、fetchmail というメール取得・転送パッケージを使い、POP3(つまりメール)で定期的に更新する方法を試した。
fetchmail のインストール
- サーバに SSH 等でログイン
- 以下のコマンドを実行
$ su
# yum install fetchmail
fetchmail の設定
- /root/.fetchmailrc に設定値を書く(例えば nano エディタで)
# nano /root/.fetchmailrc
defaults
no rewrite
no mimedecode
poll mail.mydns.jp
protocol pop3
username {MyDNS.jp の MasterID}
password {MyDNS.jp のパスワード}
- /root/.fetchmailrc に書いたパスワードが見られないようにパーミッションを設定(おそらく最初から 700 だと思うが念のため)
# chmod 700 /root/.fetchmailrc
cron による fetchmail での更新の自動化
- crontab(自動実行テーブル)に定期実行の設定を書く(例えば nano エディタを使って)
# EDITOR=nano crontab -e
- 例えば30分ごとに自動実行するなら以下のように書く
*/30 * * * * /usr/bin/fetchmail --all >/dev/null 2>&1
- 例えば毎日昼の12時00分に自動実行するなら以下のように書く
0 12 * * * /usr/bin/fetchmail --all >/dev/null 2>&1
- crontab の頭は、分 時 日 月 曜日 を半角スペースで区切って書く
- */x と書くと x 分ごとに実行する
DNS の設定確認
DNS の設定は実際に反映されるまで時間がかかり、すぐにはドメイン名で Web ページなどは見られない。そのため、うまく設定できたかどうかが分かりにくい。設定が問題ないか確認する方法は以下(上記「選択肢1:ドメインを ムームーDNS に登録」の場合を例に)。
dig コマンドで確認する方法
- dig ドメイン名 @DNSサーバ any
- 「ANSWER SECTION」に、設定したネームサーバと、設定した IPv4 アドレスが表示されれば OK
- @以下の DNS サーバを省略すると、自分が一番近いところに問い合わせる(出力の「;; SERVER」欄に問い合わせたサーバの IP アドレスが表示される)
- @以下の DNS サーバに任意の DNS サーバを指定して、各所への浸透具合を確認できる(例えば Google の 8.8.8.8 等を指定)
$ dig hogehoge.com @dns01.muumuu-domain.com any
:
;; ANSWER SECTION:
hogehoge.com. 3600 IN NS dns01.muumuu-domain.com.
hogehoge.com. 3600 IN NS dns02.muumuu-domain.com.
hogehoge.com. 3600 IN A xxx.xx.xx.xxx
:
CMAN サイトで確認する方法
サーバ監視サービスを提供してくれている株式会社シーマンのサイトで、同じことができる。
- 左側のメニューから「DNS チェック」を選択
- 「ホスト名(FQDN)を指定してください」欄にドメインを入力(例:hogehoge.com)
- 「dig実行」ボタンをクリック
- 「ANSWER SECTION」にドメインと IP アドレスの対応が出る
- 「AUTHORITY SECTION」にネームサーバの設定が出る
浸透待ち
上記で設定が問題なければ、あとはしばらく待てば、ドメイン名でアクセスできるようになる。かかる時間はケースバイケースで、数時間とか、数日とか。
しばらくの間は、スマホでは大丈夫でも PC ではまだダメ(またはその逆)ということもある。スマホ(のキャリア)が参照している DNS と、PC(のプロバイダ)が参照している DNS が違うから。あちこちの DNS のキャッシュが更新されるのを、ただ待つしかない(俗に言う「浸透待ち」)。
Let's Encrypt で証明書を得る
独自ドメインを取得して、DNS に登録したことで、ようやく電子証明書を発行してもらう準備ができた。様々な証明書発行機関(とその代理店)があるが、原則有料で、高価。そこで、無償の Let's Encrypt を使う。
必要なパッケージのインストール
- epel-release, certbot, certbot-apache をインストールする
$ su
# yum install epel-release
# yum install certbot certbot-apache
仮想 Web サーバを建てる
- 証明書の発行には、仮想 Web サーバ(Virtual Host)を設置してポート 80 でアクセスできる必要があるらしい
- 前回(1/2)の Apache の設定時にポート 80 は開けてある前提
- その名も「VirtualHost」という名前の仮想 Web サーバを作る
- /etc/httpd/conf.d/virtualhost80.conf というファイルを作る(例えば nano エディタで)
- その中に以下のように書く
$ su
# nano /etc/httpd/conf.d/virtualhost80.conf
NameVirtualHost *:80
<VirtualHost *:80>
ServerAdmin root@hogehoge.com # 環境に応じて書き換えること
DocumentRoot /var/www/html # 環境に応じて書き換えること
ServerName hogehoge.com # 環境に応じて書き換えること
</VirtualHost>
- Apache を再起動する
# systemctl restart httpd.service
証明書を取得
- 証明書を取得する
$ su
# certbot run --apache -d hogehoge.com
-
メールアドレスを聞かれたら、実在するメールアドレスを入力
-
途中で「(A)gree / (C)ancel」と聞かれたら「A」
-
途中で「(Y)es / (N)o」と聞かれたら「Y」
-
最後に、1か2を選べと言われたら、以下から判断して入力(通常は2で問題ない)
- 1: http と https の両方でアクセスできるようにする
- 2: https のみでアクセスできるようにする
-
最後に、ローカルマシンやスマホから「**https://**サーバのアドレス」でアクセスしてみて、何の警告も出ずに表示されて、かつ、アドレスバーに×印や!マークなどが出ていないことを確認する
証明書の更新
Let's Encrypt の証明書の有効期限は3ヶ月のため、定期的に更新する必要がある。
手動で更新する方法
- コマンドで単発的に更新する方法は以下(期限切れの30日前から更新できるらしい)
$ su
# certbot renew
自動で更新する方法
- 自動更新の設定は以下
$ su
# systemctl enable --now certbot-renew.timer
- (念のため)タイマーが動いているか確認する方法
$ su
# systemctl list-timers
NEXT LEFT LAST PASSED UNIT
水 2019-03-13 04:12:48 JST 10h left 火 2019-03-12 05:13:13 JST 12h ago certbot-renew.timer
Node.js を準備する(nvm 利用)
Let's Encrypt で取得した証明書は、なにも Apache でしか使えないわけではない。証明書と鍵は特定の場所に保存されているので、それを読むようにすれば、Node.js の https モジュールでも問題なく https 接続できる。
その実験の前に、まずは Node.js を設定する。今後のため、Node.js のバージョン管理ツール nvm (node version manager) を使って、複数のバージョンの中から必要なバージョンを使えるように設定しておく。
nvm のインストール
- Node.js を使うユーザにて
- nvm のページの通りにコマンドを打つだけ
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
$ source .bashrc
Node.js のインストール
- インストール可能な Node.js のバージョンを確認する
$ nvm ls-remote
- たいていは LTS (Long-Term Support) の中から、新しいのを入れれば良いと思われる
- 例えばこの記事を書いている時点の最新 LTS (Dubnium) の 10.15.3 を入れるなら
$ nvm install 10.15.3
あるいは、バージョン番号指定ではなく「最新の LTS」を入れるなら
$ nvm install --lts
- インストール済の Node.js のバージョンや現在選択されているバージョンなどを見るには
$ nvm ls
- 特定のバージョン(例えば 8.15.1)に切り替えるには
$ nvm use 8.15.1
- しかしこの nvm use だと、ログインするたびにバージョンが戻ってしまう(一番最初に入れたバージョンがデフォルトとして扱われる仕様)
- そこで、デフォルトバージョンを変えるには…(以下はデフォルトを 8.15.1 にする場合)
$ nvm alias default 8.15.1
- ログインし直せば、default で指定したバージョンに固定されている
Node.js で SSL (HTTPS) 対応サイトを作る
証明書のありかの確認とパーミッションの設定
-
Let's Encrypt で取得した証明書の類は /etc/letsencrypt/live/{ドメイン名}/ にある
- cert.pem ・・・ 証明書
- privkey.pem ・・・ 秘密鍵
- chain.pem ・・・ 中間証明書
- fullchain.pem ・・・ 証明書と中間証明書をつないだファイル
-
これらはシンボリックリンクで、実体は /etc/letsencrypt/archive/{ドメイン名}/ にある(更新されても大丈夫なように)
-
Node.js の https モジュールでこれらを指定すればよいのだが、この場所は root でないと使えないため、以下のようにパーミッションを変更する(あまり好ましくないとは思うが…)
$ su
# chmod 755 /etc/letsencrypt/live/
# chmod 755 /etc/letsencrypt/live/{ドメイン名}/privkey.pem
# chmod 755 /etc/letsencrypt/archive/
準備
サイトを作る場所やモジュールの準備をする。
- 例えば「hoge」というユーザだとして…
- /home/hoge/test/ をルートにするとする
$ mkdir test
$ cd test
- express モジュールくらいは入れておく
$ npm install express
アプリを作る
JavaScript(サーバ)
- Node.js で実行する JavaScript を、上で作った /home/hoge/test フォルダ内に作る(例えば以下のような感じ)
- 例:ポート 10443 をリッスンする設定
"use strict"
const express = require("express"); // express モジュールを使う
const app = express(); // app という名前で
app.use(express.static(__dirname)); // ホームディレクトリ以下の静的ファイルへのアクセスを許可
app.get("/", (req, res) => { // アクセス要求があったら
res.sendFile(__dirname + "/index.html"); // index.html を送る
});
const fs = require("fs"); // fs モジュールを使う
const opt = { // 証明書などのファイルを読み込む
key: fs.readFileSync("/etc/letsencrypt/live/hogehoge.com/privkey.pem"),
cert: fs.readFileSync("/etc/letsencrypt/live/hogehoge.com/cert.pem"),
ca: [fs.readFileSync("/etc/letsencrypt/live/hogehoge.com/chain.pem"),
fs.readFileSync("/etc/letsencrypt/live/hogehoge.com/fullchain.pem")]
};
const https = require("https"); // https モジュールを使う
const svr = https.createServer(opt, app); // https サーバを作成
svr.listen(10443); // ポート 10443 をリッスン
HTML(ユーザインタフェース)
- index.html を、上で作った /home/hoge/test フォルダ内に作る(例えば以下のような感じ)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Welcome!</title>
</head>
<body>
<h1>hogehoge.com Node.js https server</h1>
<p>This is the test page.</p>
</body>
</html>
ポートを開ける
- ポート 10443 を使うことにしたので、10443/tcp を開ける
$ su
# firewall-cmd --add-port=10443/tcp --zone=public --permanent
# firewall-cmd --reload
# firewall-cmd --list-all
動作確認
- app.js を Node.js で実行
$ node app.js
- ローカルマシンやスマホのブラウザで **https://**hogehoge.com:10443 でアクセスできることを確認する
- ただしこの実行方法だと、ログアウトや再起動したら止まってしまう
Node アプリの自動実行(サービス)化
ログアウト後や、マシンが再起動したりしても、Node.js アプリを自動実行できるようにする。systemd (systemctl) を使う。
node のありかを確認
- 普通に Node.js を入れると node の場所は /usr/bin/node だが、nvm で入れると…
$ which node
~/.nvm/versions/node/v10.15.3/bin/node
- つまり /home/hoge/.nvm/versions/node/v10.15.3/bin/node
- ユーザのホームディレクトリ内、かつ、使っているバージョンごとのフォルダ内にあることに注意
- nvm は、node の PATH を変更するタイプのバージョン管理
- このあたり、n という npm パッケージを使ってバージョン管理すると、/usr/local/bin/node に固定できるが、n は n で少しクセがある
サービスを作る
- 例えばサービス名を node-app に決めたとして…
- 新しくサービス(ファイル)を作り、中に以下のように書く(例えば nano エディタで)
$ su
# nano /etc/systemd/system/node-app.service
[Unit]
# 任意のサービス名
Description=node-app service
[Service]
# node の場所と実行する js の指定
ExecStart=/home/hoge/.nvm/versions/node/v10.15.3/bin/node /home/hoge/test/app.js
# 停止したら再始動する
Restart=always
# 10秒待って再始動する
RestartSec=10
# ログを syslog に記録する(識別子として "node-app" を指定)
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=node-app
[Install]
WantedBy=multi-user.target
サービス開始、自動実行、停止、再起動、設定ファイル修正後の措置
$ su
# systemctl start node-app.service
# systemctl enable node-app.service
# systemctl stop node-app.service
# systemctl restart node-app.service
# systemctl daemon-reload
# systemctl restart node-app.service
ログの確認方法
$ journalctl -u node-app
↓
例えば以下のようにログが確認できる
3月 13 21:38:00 hogehoge.com systemd[1]: Started node-app service.
3月 15 13:21:25 hogehoge.com systemd[1]: Stopping node-app service...
3月 15 13:21:25 hogehoge.com systemd[1]: Stopped node-app service.
3月 15 13:21:25 hogehoge.com systemd[1]: Started node-app service.
まとめ
ConoHa で借りた VPS に対して、オリジナルのドメインを取得し、DNS に登録し、Let's Encrypt を使って SSL (HTTPS) に対応した Web サイトに仕立てたうえで、Node.js でも HTTPS サーバを建てました。
長々と書きましたが、あくまで自分のメモです。もしご自身の環境で動かない場合は、どうかご容赦ください。
ただ、私も勉強中の身です。ご助言ありましたら(お手柔らかに)コメントをいただけますと幸いです m(_ _)m
参考
- 福田和宏 (2018). 実践!CentOS7 サーバー徹底構築 改訂第二版 CentOS7(1708)対応, ソーテック社.
- @tkykmw さん (2016). Let's encrypt運用のベストプラクティス, Qiita.
- @seiketkm さん (2016). let's encrypt を node.js でつかう, Qiita.
- @Akira_Kido_N さん (2018). Let's Encrypt + Node.js で HTTPS サーバ, Qiita.
- axllent (Ralph Slooten) (2015). Run node.js service with systemd, Axllent.org