さくらのVPSのサイトをHTTPS化

さくらの VPS で運用しているサイト(Railsアプリ)を Let’s Encrypt で HTTPS 化した。言っとくけどこのブログじゃないよ。

HTTPのポートを開放

まず、HTTPS のポート 443 を開放する。/etc/sysconfig/iptables ファイルを編集。

[takatoh@tk2-254-36564 ~]$ cd /etc/sysconfig
[takatoh@tk2-254-36564 sysconfig]$ sudo vim iptables

つぎの行を追加。

-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT

iptables を再起動。

[takatoh@tk2-254-36564 sysconfig]$ sudo service iptables restart
iptables: Setting chains to policy ACCEPT: filter [ OK ]
iptables: Flushing firewall rules: [ OK ]
iptables: Unloading modules: [ OK ]
iptables: Applying firewall rules: [ OK ]
iptables: Loading additional modules: ip_conntrack_ftp [ OK ]

certbot-auto のセットアップと証明書の自動生成

「certbot-auto」は Let’s Encrypt が提供しているクライントツールで、SSL証明書を取得したり延長したりできる。ここでは、最新版を取得する。

[takatoh@tk2-254-36564 bin]$ sudo wget https://dl.eff.org/certbot-auto
--2019-01-13 09:41:36-- https://dl.eff.org/certbot-auto
dl.eff.org をDNSに問いあわせています… 151.101.72.201, 2a04:4e42:36::201
dl.eff.org|151.101.72.201|:443 に接続しています… 接続しました。
HTTP による接続要求を送信しました、応答を待っています… 200 OK
長さ: 63562 (62K) [application/octet-stream]
`certbot-auto' に保存中

100%[======================================>] 63,562 --.-K/s 時間 0.002s

2019-01-13 09:41:39 (24.3 MB/s) - `certbot-auto' へ保存完了 [63562/63562]

[takatoh@tk2-254-36564 bin]$ sudo chmod 700 /usr/bin/certbot-auto

いまインストールした certbot-auto を使って、証明書を自動生成する。

[takatoh@tk2-254-36564 ~]$ sudo certbot-auto certonly --webroot -w /var/www/lathercraft/public -d www.lathercraft.net --email lathercraft@gmail.com

途中、いろんなパッケージをインストールしたりするのでy(yes)を入力する。しばらくすると利用規約が表示されるので、A(agree)を入力。最後に↓こんなメッセージが出ればOK。

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/www.lathercraft.net/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/www.lathercraft.net/privkey.pem
Your cert will expire on 2019-04-12. To obtain a new or tweaked
version of this certificate in the future, simply run certbot-auto
again. To non-interactively renew all of your certificates, run
"certbot-auto renew"
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
- 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

- We were unable to subscribe you the EFF mailing list because your
e-mail address appears to be invalid. You can try again later by
visiting https://act.eff.org.

……じゃないな、e-mail が invalid だと言ってる。あとから試せるとも言ってるので、とりあえず先に進む。この時点で証明書類はこんな感じになっている。

[takatoh@tk2-254-36564 ~]$ sudo ls -l /etc/letsencrypt/live/www.lathercraft.net/
合計 4
-rw-r--r-- 1 root root 692 1月 13 09:53 2019 README
lrwxrwxrwx 1 root root 43 1月 13 09:53 2019 cert.pem -> ../../archive/www.lathercraft.net/cert1.pem
lrwxrwxrwx 1 root root 44 1月 13 09:53 2019 chain.pem -> ../../archive/www.lathercraft.net/chain1.pem
lrwxrwxrwx 1 root root 48 1月 13 09:53 2019 fullchain.pem -> ../../archive/www.lathercraft.net/fullchain1.pem
lrwxrwxrwx 1 root root 46 1月 13 09:53 2019 privkey.pem -> ../../archive/www.lathercraft.net/privkey1.pem

Nginxの設定

SSL 対応にする。こんなふうに書き換える。

    #listen      80;
    listen      443 ssl;

    ssl_certificate      /etc/letsencrypt/live/www.lathercraft.net/cert.pem;
    ssl_certificate_key  /etc/letsencrypt/live/www.lathercraft.net/privkey.pem;

Nginx を再起動。

[takatoh@tk2-254-36564 conf.d]$ sudo service nginx restart
Stopping nginx: [ OK ]
Starting nginx: [ OK ]

これでOKのはず。まだアプリが SSL 対応していないのでバナー画像に https でアクセスしてみたら、ちゃんと表示された。なのでここまではOKのようだ。

RailsアプリのSSL対応

これは簡単。config/envronments/production.rb ファイルのつぎの箇所を修正すればいい。

  # config.force_ssl = true
  config.force_ssl = true

コメントアウトしてあるのを外すだけだ。そして再起動。

[takatoh@tk2-254-36564 environments]$ sudo service unicorn_lathercraft restart
reloaded OK

OK。大丈夫そうだ。

httpをhttpsにリダイレクト

最後に、http でのアクセスを https にリダイレクトする設定をする。Nginx の設定に戻ってつぎの設定を追加する。

server {
    listen       80;
    server_name  www.lathercraft.net;
    return       301 https://www.lathercraft.net;
}

Nginx を再起動して完了。

証明書の自動更新設定

Let’s Encrypt の証明書は有効期限が3ヶ月と短いので、自動更新するように設定する。更新は certbot-auto renew コマンドでできるので、これを root ユーザの cron に登録する。

[takatoh@tk2-254-36564 ~]$ sudo -s
[root@tk2-254-36564 takatoh]# crontab -l
no crontab for root
[root@tk2-254-36564 takatoh]# crontab -e
0 4 * * 0 certbot-auto renew --post-hook "service unicorn_lathercraft restart" > /dev/null 2> /dev/null

これで毎週月曜日の午前4時に更新するようになる。

[追記]

上の、Nginx のリダイレクトの設定では、http でのアクセスはどんなパスでも全て https のルートにリダイレクトされてしまう。なので、つぎのように変更した。

server {
    listen       80;
    server_name  www.lathercraft.net;

    location ~ ^/(.*)$ {
        return 301 https://www.lathercraft.net/$1;
    }
}

これで各ページも https にリダイレクトされるようになった。

iTunes Storeにつながらない

Windows10 のセットアップが終わって、一息ついたと思ったら、iTunes Store につながらない。「ネットワークの接続を確認して、やり直してください。」と言われる。CD からインポートした曲は聴けるんだけど(当然)、Store から購入した曲が聴けない。これじゃ、何のために Windows の再インストールをしたんだかわからないじゃないか。

たしか昨日、Windows のインストールが終わったあと、最初にインストールしたのが iTunes だ。その時はちゃんとつながったはずだ。ということは、そのあとにインストールしたアプリが悪さをしてるか、何か設定が変わってしまったか。

はぁ、一つずつ消して確かめてみるか……

[追記]

iTunes 以外のアプリを一つずつ消しながら確かめてみた。結果、iTunes 以外の、あとからインストールしたアプリを全部消しても、さらには iTunes 自体を再インストールしてもつながらなかった。たぶん、アプリのインストールをしてるどこかで何かの設定が変わっちゃったんだ。

結局、Windows の再インストールしかないか。

Gem in a Boxでオレオレgemサーバをたてる

自分でしか使わない、外部には公開できないような gem がいくつかあるので、gem サーバをたてることにした。Gem in a Box (geminabox)は、プライベートな gem サーバだ。gem コマンドでインストールして、ちょっと設定ファイルを書くだけで使えるようになる。

じゃ、いってみよう。

環境

  • Ubuntu 16.04 LTS
  • Ruby 2.3.1p112

インストールと設定

前述したように gem コマンドでインストールできる。

takatoh@wplj $ sudo gem install geminabox

~/geminabox ディレクトリを作って、設定ファイルを書く。

takatoh@wplj $ mkdir ~/geminabox
takatoh@wplj $ cd ~/geminabox
takatoh@wplj $ vim config.ru

設定ファイルはこんな感じ、っていうかこれだけ。

require "geminabox"

Geminabox.data = "/home/takatoh/geminabox/data"
run Geminabox::Server

gem ファイルが格納される data ディレクトリを作る。

takatoh@wplj $ mkdir data

これで Gem in a Box 自体のインストールと設定は完了。

Supervisord で管理

さて、これをデーモンにする必要があるんだけど、昨日 Supvervisord を試したので今日も同じようにしてみる。設定ファイル /etc/supervisord.d/geminabox.ini をつぎのように書いた。

[program:geminabox]
command=/usr/local/bin/rackup -p 9999
process_name=geminabox
user=takatoh
directory=/home/takatoh/geminabox
autostart=true
autorestart=true
stdout_logfile=/home/takatoh/geminabox/geminabox.log
stdout_logfile_maxbytes=1M
stdout_logfile_backups=7
stdout_capture_maxbytes=1M
redirect_stderr=true

これで OK のはず。動かしてみよう。

takatoh@wplj $ supervisorctl reload
Restarted supervisord
takatoh@wplj $ supervisorctl status
geminabox RUNNING pid 26835, uptime 0:00:08
sulaiman RUNNING pid 26836, uptime 0:00:08

ちゃんと動いてるようだ。

Nginxのバーチャルホスト設定

gembox というホスト名でアクセスできるように Nginx を設定する。/etc/nginx/sites-available/gembox が設定ファイルだ。

upstream geminabox {
    server 127.0.0.1:9999;
}

server {
    # port
    listen      80;

    # server name
    server_name gembox;

    # document root
    root        /home/takatoh/geminabox;

    # index
    #index       index.php index.html index.htm;

    # log files
    access_log /var/log/nginx/gembox/access.log combined;
    error_log  /var/log/nginx/gembox/error.log  warn;

    keepalive_timeout     60;
    proxy_connect_timeout 60;
    proxy_read_timeout    60;
    proxy_send_timeout    60;

 
    location / {
        proxy_set_header Host $http_host;
        proxy_pass http://geminabox;
    }
}

/etc/nginx/sites-enabled/gembox にリンクをはる。

takatoh@wplj $ sudo ln -s /etc/nginx/sites-available/gembox sites-enabled/gembox

ログファイル用のディレクトリを作成。

takatoh@wplj $ sudo mkdir /var/log/nginx/gembox

そして、Ngixn をリロード。

takatoh@wplj $ sudo systemctl reload nginx

これで完了。ほかのマシンからブラウザで http://gembox/ にアクセスすると、期待どおり Gem in a Box のページにアクセスできた。

[追記]

アクセスはできたけど、試しに gem ファイルを1つアップロードしてみたら「uninitialized constant Gem::Util」というエラーが出てしまった。なんだこりゃ?

[追記2]

解決編。rubygems 自体が古いのが原因だったようだ。

takatoh@wplj $ sudo gem update --system
takatoh@wplj $ gem -v
3.0.1

念のため、データ置き場を作りなおす。

takatoh@wplj $ cd ~/geminabox
takatoh@wplj $ rm -rf data
takatoh@wplj $ mkdir data

リスタート。

takatoh@wplj $ supervisorctl restart geminabox
geminabox: stopped
geminabox: started

これで無事、オレオレgemをアップロードできるようになった。

Supervisorで自作プログラムをデーモン化

自作のプログラムやスクリプトをデーモン化したい場合がある。でも、デーモンとして動作するようには作っていない……そういう時には Supervisor の出番だ。

Supervisor は Python 製のツールで、デーモンとして動作するように作られていないプログラムでもデーモン化できる。Supervisor 自体は root 権限でデーモンとして動かす必要があるけど、その下にぶら下がるプログラムはユーザー権限で管理できるのがいい点だ。

今日は、Ubuntu マシンの wplj に Supervisor をインストールして、以前 Go で作った画像アップローダを動かしてみる。

環境

  • Ubuntu 16.04 LTS
  • Python 2.7.12

Supervisorのインストールといろいろ下準備

Supervisor 自体は pip でインストールできる。

takatoh@wplj $ sudo pip install supervisor

/etc/supervisord.conf にデフォルトの設定ファイルを生成。

takatoh@wplj $ sudo echo_supervisord_conf > /etc/supervisord.conf
-bash: /etc/supervisord.conf: 許可がありません

あれ、sudo つけてるのになんでだ?よくわからないけど sudo -s してからやってみよう。

takatoh@wplj $ sudo -s
root@wplj # echo_supervisord_conf > /etc/supervisord.conf

今度はできた。つぎ、include 設定ファイル用のディレクトリを作成。

root@wplj # mkdir /etc/supervisord.d

supervisord 自体のはくログ周りの設定。デフォルトでは /tmp/supervisord.log に吐き出すことになっているので、設定ファイル /etc/supervisord.conf を修正して /var/log/supervisord.log に吐くようにする。

[supervisord]
;logfile=/tmp/supervisord.log ; main log file; default $CWD/supervisord.log
logfile=/var/log/supervisord.log

PID ファイルの設定。/var/run 以下に置くように変更。

;pidfile=/tmp/supervisord.pid ; supervisord pidfile; default supervisord.pid
pidfile=/var/run/supervisord.pid

/etc/supervisord.d 以下のファイルを include するように変更。これで設定ファイルの修正は終了。

[include]
files = supervisord.d/*.ini

supervisord自体のサービス登録

/etc/systemd/system/supervisord.service ファイルを作成する。

[Unit]
Description=Supervisor process control system for UNIX
Documentation=http://supervisord.org/
After=network.target

[Service]
ExecStart=/usr/local/bin/supervisord -n -c /etc/supervisord.conf
ExecStop=/usr/local/bin/supervisorctl $OPTIONS shutdown
ExecReload=/usr/local/bin/supervisorctl $OPTIONS reload
KillMode=process
Restart=on-failure
RestartSec=50s

[Install]
WantedBy=multi-user.target

起動と自動起動の登録

root@wplj # systemctl start supervisord
root@wplj # systemctl enable supervisord.service
Created symlink from /etc/systemd/system/multi-user.target.wants/supervisord.service to /etc/systemd/system/supervisord.service.

自作プログラムの配置

Go で作った画像アップローダ sulaiman を配置する。こんなふうにした。

takatoh@wplj $ tree ~/sulaiman
/home/takatoh/sulaiman
├── config.json
├── photos
│   ├── img
│   └── thumb
├── static
│   ├── css
│   │   └── style.css
│   ├── html
│   │   └── index.html
│   └── js
│   └── sulaiman.js
└── sulaiman

試しに動かしてみる。

takatoh@wplj $ ./sulaiman
_ _ / // /
/ // / \/ _ \
//__////_/ v3.3.5
High performance, minimalist Go web framework
https://echo.labstack.com
_________________________________O/_

O\
⇨ http server started on [::]:9099

大丈夫そうだ。

プロセス管理登録と起動確認

配置したプログラムを supervisord の管理下に登録する。/etc/supervisord.d 以下に設定ファイル sulaiman.ini を作る。

[program:sulaiman]
command=/home/takatoh/sulaiman/sulaiman
process_name=sulaiman
user=takatoh
directory=/home/takatoh/sulaiman
autostart=true
autorestart=true
stdout_logfile=/home/takatoh/sulaiman/sulaiman.log
stdout_logfile_maxbytes=1MB
stdout_logfile_backups=7
stdout_capture_maxbytes=1MB
redirect_stderr=true

これで OK のはずだ。確認してみよう。

takatoh@wplj $ supervisorctl start sulaiman
error: , [Errno 13] Permission denied: file: /usr/lib/python2.7/socket.py line: 228

はぁ?どういうこと?

問題解決

ソケット周りでエラーが出てるようだ。権限がないとかいってる。supervisord の設定ファイルを眺めてみると、ソケットファイルのモードを設定する項目が見つかった。これを変更してみよう。

[unix_http_server]
file=/tmp/supervisor.sock ; the path to the socket file
;chmod=0700 ; socket file mode (default 0700)
chmod=0777

supervisord をリロード。

takatoh@wplj $ sudo systemctl reload supervisord

確認。

takatoh@wplj $ supervisorctl status sulaiman
sulaiman RUNNING pid 19356, uptime 0:00:22

こんどは OK。

これで、プログラムやスクリプトを簡単にデーモン化できるようになった。

参考ページ

 cf. Supervisorで簡単にデーモン化 – Qiita

MyDNS.JPを利用してDDNSを設定した

昨日はグローバル IP での接続に成功した。今日はDDNS(ダイナミック DNS)を使ってドメイン名で接続することに挑戦する。

無料の DDNS にはいくつか選択肢があるけど、日本語であること、更新に専用のクライアントソフトが不要であること、が決め手となって MyDNS.JP を利用することにした。

ユーザ登録(マスターIDの発行)

まずはユーザ登録。↓このページの JOIN US から登録ページに入る。

 cf. https://www.mydns.jp/

名前とかメールアドレスとかを入力して CHECK をクリックすると、確認画面になる。登録するドメイン名は1つなので子 ID の数は 0 のまま OK をクリック。すると登録したメールアドレスにマスター ID とパスワードが送られてくる。

ドメインの登録

送られてきたマスター ID とパスワードでログイン。DOMAIN INFO からドメインの登録ページに進んで、登録する。Domain 欄には希望するドメイン名(FQDN)、MX 欄は空欄、その下にはホスト名、A、マスター IDを設定。ドメインは無料で使える mydns.jp のサブドメインにした。CHECK →OK とクリックして登録完了。

IPアドレスの通知

ドメインの登録はできたはずなので、使用している IP アドレスの通知をする。通知の方法はいくつかあるけど、HTTP-BASIC を利用することにした。

[takatoh@bigswifty ~]$ wget -O - --http-user マスターID --http-password パスワード http://www.mydns.jp/login.html

↓こんな感じのレスポンスが返ってくれば OK。

<html>
<head>
<title>Free Dynamic DNS (DDNS) for Home Server and VPS etc  | MyDNS.JP</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<LINK href="./site.css" rel=stylesheet type=text/css>
</head>
<BODY BGCOLOR="#FFFFFF"
      TEXT="#304040"
      leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">

Login and IP address notify OK.<BR>
login_status = 1.<BR>
<BR>
<DT>MASTERID :</DT><DD>mydnsxxxxxx</DD>
<DT>REMOTE ADDRESS:</DT><DD>xxx.xxx.xxx.xxx</DD>
<DT>ACCESS DAYTIME:</DT><DD>2018/12/12 19:42:26 UTC</DD>
<DT>SERVER ADDRESS:</DT><DD>168.235.75.38</DD>
<BR>

</body>
</html>

確認

他のマシンから、ドメイン名でアクセスできるか確認したところ、ちゃんとアクセスできた。

cronで自動通知

最後に、cron を使って自動でアドレスを通知するようにする。とりあえず↓こんなスクリプトをかいて、

#!/usr/bin/sh

wget -O - --http-user マスターID --http-password パスワード http://www.mydns.jp/login.html > /dev/null 2> /dev/null

実行権限を付与、毎時 0 分と 30 分に実行するように cron を設定した。

[takatoh@bigswifty ~]$ crontab -l
0,30 * * * * /home/takatoh/bin/mydns_update.sh

これで完了。

WiMAX端末が届いたのでセットアップした

接続

クレードルも一緒に届いたので、クレードルに差して、bigswifty を有線で接続。クレードルには有線 LAN のポートがあるのだ。bigswifty を再起動してやると、自動的に IP アドレスが割り振られて接続できた。ちゃんとインターネットも閲覧できる。カンタン。

グローバルIPの設定

WiMAX 端末にグローバル IP を割り当てる設定をする。WiMAX では、通常は IP アドレス節約のためにプライベートアドレスが割り当てられるようだ。だけど今回はサーバを公開しようとしているので、グローバルなアドレスを割り当ててもらう必要がある。これはそのための設定。

まずは、ブラウザで 192.168.100.1 にアクセス。端末の設定ツールのページになるので、ユーザー名とパスワードを入力してログイン。ユーザー名は「admin」、パスワードは端末本体の背面に書いてある IMEI という番号の下5桁だ。

ログインしたら、設定→WAN設定→プロファイル設定と進んで、新しいプロファイルを Global という名前で作成する。設定の内容は↓このページの通りにしたらうまくいった。

 cf. https://www.uqwimax.jp/service/price/files/GIPOP_manual_HW.pdf

ここで一つ注意。上の設定でグローバル IP を割り当てられるようになるけど、固定ではないということ。これについては後でダイナミック DNS をつかう。

ポートマッピング

bitswifty を WEB サーバとして公開するので、引き続きポートマッピングの設定。設定→ファイアウォール設定→ポートマッピングと進んで、HTTP(80 番ポート)を bitswifty (のアドレス)に転送するように設定する。これで完了のはず。

試してみよう。実際にどんなアドレスが割り当てられているかは、↓このページでわかる。

 cf. https://www.cman.jp/network/support/go_access.cgi

上のページで確かめたアドレスに、他のマシンからブラウザでアクセスしたところ、無事ページが表示された。成功だ!

というわけで、今日のところはここまで。

CentOS7でNginxを動かす

OS のインストールが終わった bigswifty、Web サーバにするので Nginx をインストールする。と言っても、過去記事があるのでそこにリンクするだけにしておく。

cf. CentOS 7にNginxをインストールする

上の記事に、インストールからファイアウォールの設定、Nginx の起動まで書いてある。

別のマシンからブラウザでアクセスしてみて、ちゃんと動いているのを確認した。

新しいノートPCにCentOS7をインストールした

新しいといっても中古だけど。
インターネットに公開してるサーバのバックアップにしようと思って、HP のノートPCを中古で買ったんだ。4年落ちくらいの Windows7 Pro がインストールされてるやつ。で、サーバにするので、Windows はサクッと消して CentOS をインストールしようというわけ。

修復ディスクの作成

万が一、CentOS がインストールできなくても Windows PC として使えるように、修復ディスクを作っておく。USB メモリを買っておいたんだけど、Windows 7 では DVD にしか作れないようだ。無駄になった。
それはさておき、コントロールパネル → システムとセキュリティ → バックアップと復元 とたどって開いたウィンドウの左側にある、「システム修復ディスクの作成」を選んで修復ディスクを作成した。

CentOS 7のインストール

9月に、nightschool にインストールしたのと同じ CentOS 7.5 1804 のディスクを使う。
ノートPC の電源を入れ、起動の途中で ESC キーを押してセットアップメニューに入る。F9 のブートオプションから USB CD/DVD ブートを選んで起動する。ソフトウェアの選択では「サーバ(GUI使用)」を選んだ。ユーザー takatoh を管理者として作成。ホスト名は bigswifty。
後はインストールが済むのを待つ。
終わると再起動して、ライセンスに同意。これでインストール終了。

日本語入力

左上のメニューから、アプリケーション → システムツール → 設定 → 地域と言語 とたどって、入力ソースのところで + ボタンを押し、「日本語(かな漢字)」を追加する。これで、Windowsキー + スペースキーで日本語入力に切り替えられるようになった。

パッケージのアップデート

[takatoh@bigswifty ~]$ sudo yum update

361個のパッケージがアップデートされた。

さて、ひとまずここまで。

Dropboxに接続できなくなった

メインの Windows 10 マシン(montana)で、Dropbox に接続できなくなった。
いつからかはわからないけどファイルの同期ができなくなっていて、それで仕方がなく再インストールするも、インストール自体はできるけど、その後の設定の場面で「ご使用のコンピュータは現在オフラインです。ネットワーク設定をご確認ください。」のメッセージが出て接続できない。

ブラウザでは問題なく Dropbox のサイトに接続できているし、ほかの Windows 10 マシン(sofa と flambay)でも Dropbox に接続(っていうか同期)できている。なぜか montana だけができない状態。

目下のところ打つ手なし。お手上げ状態。どうすりゃいいんだ。