仮想通貨の取引を全部無料で自動化する! (Gekko + Google Cloud Platform + Freenom + MyDNS + Let's Encrypt) その五 Google Cloud Platformでのサーバー構築の続き
俺の名を言ってみろ!!
子熊のゾルバです。
前回に引き続き、Google Cloud Platformでサーバー構築を行っていきます。
前回の記事はこちら
- Google Cloud SDKのインストール
- Google Cloud SDKからVMインスタンスへのSSH接続
- パッケージのインストール
- nginxのセットアップ
- Let's Encryptからの証明書取得
- crontabの設定
- fail2banで不要なアクセスを遮断
- トラブルシューティング
- 参考サイト
Google Cloud SDKのインストール
Google Cloud Platformの管理や、VMインスタンスへのSSHアクセスにはGoogle Cloud SDKが必要となります。ここでは、Windowsへのインストール方法について説明します。
こちらのリンクからGoogle Cloud SDKのインストーラーをダウンロードします。
Windows 用のクイックスタート | Cloud SDK のドキュメント | Google Cloud Platform
インストーラーを実行するとインストールウィザードが開始します。Nextをクリックします。
I Agreeをクリックします。
All Usersを選択し、Nextをクリックします。ユーザーアカウント制御のメッセージが表示されるので、はいを選択します。
Nextをクリックします。
Installをクリックします。
緑のバーが右まで到達したらNextをクリックします。
Finishをクリックします。
Google Cloud SDK Shellが起動し、'gcloud init'コマンドが自動的に実行されます。Yを入力しEnterキーを押すと、自動的にブラウザが起動します。
ブラウザでGoogleアカウントへのログインを行います。メールアドレスを入力します。
パスワードを入力します。
許可をクリックします。
以下の画面が表示されたら認証が完了です。ターミナルに戻りましょう。
既に作成済みのプロジェクトに接続するので、1を入力してEnterを押します。
Yを入力してEnterを押します。
デフォルトのゾーンを設定します。VMインスタンスを作成したゾーンの番号を入力し、Enterを押します。(ゾーンを忘れた人は、Google Cloud Platformの管理画面に戻り、Compute Engine > VMインスタンスから、ゾーンを確認します)
特にエラーが無くプロンプトに戻れば、Google Cloud SDKのセットアップは完了です。
Google Cloud SDKからVMインスタンスへのSSH接続
Google Cloud Platformの管理画面から、Compute Engine > VMインスタンスに移動します。プルダウンからgcloudコマンドを表示をクリックします。
コマンドラインをメモします。
Google Cloud SDK Shellに、先程メモしたコマンドを貼り付け、Enterを押します。
例)
gcloud compute --project "moonlit-dynamo-XXXXXX" ssh --zone "us-central1-c" "VMインスタンス名"
初回アクセス時にはSSH認証鍵の生成が行われます、Yをを入力してEnterを押します。
puttyが起動してSSHでのアクセスができるようになります。
もしアクセス出来ない場合、ファイアウォール設定を見直し、現在のIPアドレスがdefault-allow-sshのIP範囲に含まれているか確認します。
パッケージのインストール
インストールされているパッケージを最新にバージョンアップしましょう。
sudo apt-get update && sudo apt-get -y dist-upgrade
必要なパッケージをインストールします。
sudo apt-get -y install git build-essential nginx letsencrypt sqlite nodejs npm apache2-utils fail2ban geoip-bin geoip-database apt-file
kernel等が更新された場合は再起動されないと読み込まれないので、一旦再起動します。
sudo reboot
SSHが切断されるので、OKをクリックします。
自動では再接続してくれないので、Google Cloud SDK Shellからもう一度gcloud computerコマンドを実行します。(カーソルキーの上を押し、Enterを押す)
ログインが終わったら管理者権限(root)で作業します。
sudo su -
プロンプトが"$"から"#"に変わったことを確認します。以下の作業はこの状態でないとうまく行きません。
nginxのセットアップ
では、nginxのサイト設定ディレクトリに移動します。
cd /etc/nginx/sites-available/
初期設定ファイルのバックアップを取っておきます。
mv default default.bak
nginx用の設定ファイルを書き込みます。全部コピー&ペーストして下さい。
server_nameとssl_certificateに設定しているhogehoge.gaというドメイン名は例なので、Freenomで取得したドメイン名に変更します。
cat << '__EOF__' > default # Deny HTTP access with invalid hostname server { listen 80 default_server; server_name _; return 444; } # Accept HTTP access with valid hostname server { listen 80; root /var/www/letsencrypt; server_name hogehoge.ga; # Change domain name to yours server_tokens off; # Accept access to directory used by Let's Encrypt certificate renewal location ^~ /.well-known/acme-challenge/ { allow all; } # Otherwise deny access location / { return 444; } } __EOF__
ファイルが正しく書き込めたか確認します。
cat default
Let's Encryptの証明書生成時に使用するディレクトリを作成します。
mkdir /var/www/letsencrypt
Gekkoへのアクセス時に使用するユーザー名、パスワードを指定します。以下のUSERNAME、PASSWORDは好きな文字列でよいですが、ある程度複雑なものを設定します。
htpasswd -bc /etc/nginx/.htpasswd USERNAME PASSWORD
一度nginxの設定が正しいか確認しておきましょう。
nginx -t
設定の書式が合っていれば以下のように表示されます。
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
設定を読み込ませるため、一度nginxを再起動します。
systemctl restart nginx
Let's Encryptからの証明書取得
以下の例では、-dオプションでドメイン名にhogehoge.gaを指定していますが、Freenomで取得したドメインに変更してください。-mオプションで指定しているメールアドレス(xxx@example.com)も、使用しているメールアドレスにします。(Gmail等のアドレスでOKです)
letsencrypt certonly --webroot -w /var/www/letsencrypt -d hogehoge.ga --agree-tos -m xxx@example.com -n
成功すると以下のようにCongraturations!と表示されます。
IMPORTANT NOTES: - If you lose your account credentials, you can recover through e-mails sent to xxx@example.com. - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/hogehoge.ga/fullchain.pem. Your cert will expire on 2017-12-29. To obtain a new version of the certificate in the future, simply run Let's Encrypt again. - Your account credentials have been saved in your Let's Encrypt 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 Let's Encrypt so making regular backups of this folder is ideal. - If you like Let's Encrypt, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le
成功していたら、nginxの設定ファイルにHTTPS用の設定を追記します。
まず設定ファイルのディレクトリに移動します。
cd /etc/nginx/sites-available/
以下のコマンドをすべてコピー&ペーストし、HTTPS用の設定を追記します。
今回は">>"で追記という意味になっている事に注意して下さい。">"だと上書きとなり、今の設定が消えます。
*4
cat << '__EOF__' >> default # Gekko configuration as upstream service upstream websocket { server localhost:3000; } # HTTPS reverse proxy configuration for Gekko server { listen 443 ssl; root /var/www/html; server_name hogehoge.ga; # Change domain name to yours server_tokens off; # Set strong encryption ssl_protocols TLSv1.1 TLSv1.2; # Set Let's encrypt certificate ssl_certificate /etc/letsencrypt/live/hogehoge.ga/fullchain.pem; # Change domain name to yours ssl_certificate_key /etc/letsencrypt/live/hogehoge.ga/privkey.pem; # Change domain name to yours # Add some security related headers add_header X-Content-Type-Options nosniff; add_header X-Frame-Options "SAMEORIGIN"; add_header X-XSS-Protection "1; mode=block"; add_header X-Robots-Tag none; add_header X-Download-Options noopen; add_header X-Permitted-Cross-Domain-Policies none; # Gekko configuration # https://gekko.wizb.it/docs/installation/installing_gekko_on_a_server.html location / { proxy_buffers 8 32k; proxy_buffer_size 64k; proxy_pass http://websocket; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-NginX-Proxy true; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 86400s; proxy_send_timeout 86400s; # Authentication needed auth_basic "Restricted Content"; auth_basic_user_file /etc/nginx/.htpasswd; } } __EOF__
nginxを再起動し、HTTPSの設定と証明書を読み込ませます。
systemctl restart nginx
もし失敗する場合、トラブルシューティングを参考にしてみて下さい。
crontabの設定
MyDNSへのIPアドレス通知と、Let's Encryptの証明書更新をcronで自動的に行うための設定を行います。
crontab -e
最初にcrontabを起動するときに、どのエディターを使うか質問されます。
デフォルトのnanoを使用する場合、そのままEnterキーを押します。
no crontab for root - using an empty one Select an editor. To change later, run 'select-editor'. 1. /bin/ed 2. /bin/nano <---- easiest 3. /usr/bin/vim.basic 4. /usr/bin/vim.tiny Choose 1-4 [2]:
以下のような文字が表示されるので、カーソルキーの下を押し、一番下の行に移動します。
# Edit this file to introduce tasks to be run by cron. # # Each task to run has to be defined through a single line # indicating with different fields when the task will be run # and what command to run for the task # # To define the time you can provide concrete values for # minute (m), hour (h), day of month (dom), month (mon), # and day of week (dow) or use '*' in these fields (for 'any').# # Notice that tasks will be started based on the cron's system # daemon's notion of time and timezones. # # Output of the crontab jobs (including errors) is sent through # email to the user the crontab file belongs to (unless redirected). # # For example, you can run a backup of all your user accounts # at 5 a.m every week with: # 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/ # # For more information see the manual pages of crontab(5) and cron(8) # # m h dom mon dow command <===ココまで移動
以下の文字列をクリップボードにコピーし、ターミナル上で右クリックしてペーストします。
1行目のUSERNAMEとPASSWORDはMyDNSからメールで届いたものを入力します。
*/10 * * * * /usr/bin/curl -v --user USERNAME:PASSWORD https://ipv4.mydns.jp/login.html > /var/log/mydns.log 2>&1 48 20 * * * /usr/bin/letsencrypt renew > /var/log/letsencrypt-renew.log 2>&1 && /bin/systemctl reload nginx > /var/log/systemctl-reload-nginx.log 2>&1
ペースト後カーソル行の左側が$記号に変化し、貼り付けに失敗したように見えますが、カーソルキーの左を押すとちゃんと表示されるはずです。
*/10 * * * * /usr/bin/curl -v --user USERNAME:PASSWORD http://www.mydns.jp/login.html > /var/log/mydns.log 2>&1 $d-nginx.log 2>&1
Ctrlキー + oで保存します。画面下部に以下のように表示されるので、Enterキーを押して続行します。
File Name to Write: /tmp/crontab.96HcXA/crontab ^G Get Help M-D DOS Format M-A Append M-B Backup File ^C Cancel M-M Mac Format M-P Prepend ^T To Files
Ctrlキー + xで終了します。プロンプトに戻ります。
cronが正しく設定されたか確認します。貼り付けた文字が表示されていればOKです。
crontab -l
fail2banで不要なアクセスを遮断
nginxでGekkoへのアクセスに認証を設定しています。ここでは、認証が5回失敗したら30分間アクセスを遮断するようにします。
アクセス遮断が発動する条件を設定します。nginxのログに401(認証失敗)が出力された場合に発動するようにします。
cat << '__EOF__' > /etc/fail2ban/filter.d/nginx-401.conf [Definition] failregex = ^<HOST> -.* 401 ignoreregex = __EOF__
アクセス遮断をどのように行うか設定します。
ここでは、maxretry = 5、findtime = 120なので、120秒間の間に5回ログインが失敗したら実行します。
bantime = 1800なので、遮断時間は1800秒(30分)です。
cat << '__EOF__' > /etc/fail2ban/jail.d/nginx-401-jail.conf [nginx-401] enabled = true port = https filter = nginx-401 logpath = /var/log/nginx/access.log maxretry = 5 findtime = 120 bantime = 1800 __EOF__
HTTPに対してのファイアウォールルールは、Let's Encryptからのアクセスを受け入れるため全IPアドレスから許可しています。
Let's Encrypt以外からのしつこいアクセスもついでに禁止してしまいましょう。
HTTPへのアクセスは基本的に444(RSTを応答)がログに残るようにしています。
cat << '__EOF__' > /etc/fail2ban/filter.d/nginx-444.conf [Definition] failregex = ^<HOST> -.* 444 ignoreregex = __EOF__
こちらは300秒に2回444が発生したら1週間アクセスを遮断するというルールです。
cat << '__EOF__' > /etc/fail2ban/jail.d/nginx-444-jail.conf [nginx-444] enabled = true port = http filter = nginx-444 logpath = /var/log/nginx/access.log maxretry = 2 findtime = 300 bantime = 604800 __EOF__
fail2banに設定を読み込ませます。
systemctl reload fail2ban
だいぶ長くなってしまいましたので、今回はここまでにしておきましょう。お疲れ様でした!
CLIでの作業で手順も複雑なので、もしわかりづらければお気軽にコメント下さい。
セットアップ作業の8割位は終了しているので、もう少しお付き合いください。。
トラブルシューティング
もし証明書の取得に失敗する場合、以下のような点を確認します。
- 名前解決ができるか
- nginxが起動しているか
- ファイアウォールの設定が正しいか
①名前解決ができるか
"nslookup ドメイン名"というコマンドで、IPアドレスが解決できるか確認します。以下、hogehoge.gaというドメインの例です。
# nslookup hogehoge.ga Server: 169.254.169.254 Address: 169.254.169.254#53 Non-authoritative answer: Name: hogehoge.ga Address: xxx.xxx.xxx.xxx
xxx.xxx.xxx.xxxの部分が、Google Cloud Platformの外部IPと一致していれば問題ありません。
もし一致していない場合、FreenomでのChange Nameserversの設定が正しく行われているか確認します。
また、MyDNSでのドメイン設定が正しいか確認します。
その後以下のコマンドを実行し、MyDNSに改めてIPアドレスを通知します。USERNAME:PASSWORDには、MyDNSから届いたメールに記載のものを指定します。
curl -v --user USERNAME:PASSWORD http://www.mydns.jp/login.html
以下、実行結果例です。
# curl -v --user USERNAME:PASSWORD http://www.mydns.jp/login.html * Trying 210.197.74.203... * Connected to www.mydns.jp (210.197.74.203) port 80 (#0) * Server auth using Basic with user 'USERNAME' > GET /login.html HTTP/1.1 > Host: www.mydns.jp > Authorization: Basic XXXXXXXXXXXXXXXXX= > User-Agent: curl/7.47.0 > Accept: */* > < HTTP/1.1 200 OK <=== ココ < Date: Sun, 01 Oct 2017 11:24:38 GMT < Server: Apache < Vary: Accept-Encoding,User-Agent < Content-Length: 612 < Content-Type: text/html; charset=UTF-8 < <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>mydns776352</DD> <DT>REMOTE ADDRESS:</DT><DD>xxx.xxx.xxx.xxx</DD> <=== ココ <DT>ACCESS DAYTIME:</DT><DD>2017/10/01 20:24</DD> <DT>SERVER ADDRESS:</DT><DD>210.197.74.203</DD> <BR> </body> </html> * Connection #0 to host www.mydns.jp left intact
チェックするポイントとしては、サーバーから200 OKというレスポンスがあり、REMOTE ADDRESSにGoogle Cloud Platformの外部IPが表示されている事です。もう一度"nslookup ドメイン名"を入力すれば、IPアドレスが表示されるはずです。
②nginxが起動しているか
"systemctl status nginx"コマンドでnginxが起動している(active (running))という表示になっている事を確認します。
# systemctl status nginx ● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2017-09-30 13:05:16 UTC; 21h ago
③ファイアウォールの設定が正しいか
ファイアウォールルールを確認し、default-allow-httpのIP範囲が0.0.0.0/0となっている事を確認します。
参考サイト
Installing Gekko on a server - Gekko
____________________
以下、アフィリエイトです。もしこの記事がお役に立ちましたら、こちらから取引所口座を開設頂けると励みになります。(私のお小遣いになります)
日本では以下の3つが主要な仮想通貨取引所となります。
コインチェック
初心者でも簡単に仮想通貨が購入できます。また、ビットコイン以外の仮想通貨(オルトコイン)も12種取り扱っているのも高ポイントです。ただし、購入手数料が高いのが難点。
bitFlyer
日本で最もビットコインの取引量が多い(=売買が成立しやすい)取引所です。多額の取引をする場合におすすめ。 無難ですが、特に突出した特徴が無いのが難点と言えば難点。
私がメインで使っている取引所。手数料がマイナスなので、取引すればするほど得をします。 XEMを購入するならここ。サーバーが貧弱なのかたまに応答しなくなるのが難点。
*1:ファイアウォールルールで許可する接続元IPアドレスを自宅のみに設定しているはずなので、ブラウザウィンドウで開くのオプションは使用できません。
*2:gcloud initでデフォルトのプロジェクトやゾーンの設定が完了しているので、「gcloud compute ssh "VMインスタンス名"」だけでもアクセスができます。
*3:Linuxへのログインユーザーが接続方法により異なります。ブラウザからのSSHアクセスの場合にはGoogleアカウント(@より前の部分)、WindowsのGoogle Cloud SDKの場合Windowsでログイン中のユーザー名となります。
*4:最初にHTTPSの設定を入れなかったのは、まだHTTPS用の証明書がなく、nginxを起動しようとしてもエラーで起動しなくなるためです。
*5:上の行は、10分毎にMyDNSにIPアドレスの通知を行う設定です。下の行は、毎日20時48分(UTC)に証明書が必要か確認し、必要であれば更新を行います。それぞれ最後の実行結果は/var/log/ディレクトリの下にログを保存するようにしています。