Node-REDをOracleの無料VPSサービスで使う

後記: ここでやったことと同じことについて “Installing Node-RED In An Always Free VM On Oracle Cloud | Oracle Developers Blog” に解説があった。この記事のほぼ1年前に出てたようなのになぜ気づかなかったのか。


Node-RED and Its Android Versions” で調べてみたNode-RED (Wikipedia) を自分でも使ってみたくなった。制限があるにしろパッと無料で使える,Node-REDをホストしたサービスがあるのだが,そういった可能性が当初思いつけなかった。VPSサービスではなくWebホスティングサービスでNode.jsを使う奇策もあるが,ここは無難にVPSを使う。

幸い,Oracle Cloudを期限なく無料で使える「Always Free」が1年ほど前から提供されている。この他にもクラウドコンピューティングサービスを提供する各社が無料枠を提供しているが,VPSだけに見るとOracleのそれが最も太っ腹。

サインアップしてVMを作成しSSHで外部から接続する

VMを作成するまでは以下を参照した。

サインアップ時にホームリージョン (home region)を選択しなくてはならなかった。なんでも一度選択すると変えることができないということだったので,慎重になった。同じ日本でも東京と大阪の選択肢があったが,1サービスを除いて,提供されるサービスは東京のものが大阪のものを内包しているので,東京センターを選択した。レスポンスの速さがクリティカルになる使い方をする予定は今のところないので,それならばより多くの可能性が残るほうが良かろう,と。

上記の記事にあるVM作成の流れと違ったのは,SSHのキーを自分で作成するだけではなく,作ってくれる選択肢も与えられたこと(上のスクリーンショット)。自分はそれを選択した。

ちなみにVMイメージとしてはUbuntu 20.04を選択。~Minimalで用が済むのならそれを選びたかったが,悲しいかなそれすら自分では判断できない。

Connecting to an Instance” のPuTTYの項を参照しつつ,WindowsからPuTTYでSSH接続しようとすると秘密鍵が “old PEM format” なのが駄目と怒られる…ように見える。 “Convert Pem to Ppk File Using PuTTYgen” を参照して,PuttyGenを利用してPpk形式に変換…がうまくいかない。 “Couldn’t load private key (unrecognized key type)” とPuTTYgenに怒られる。 “Change Private Key Format to Use with PuTTY” を読んでも手順に関して本質的に異なることは書かれていない。 “Use SSH Keys with PuTTY on Windows | IONOS DevOps Central

PuTTYでの対処はさておくとして,今度は “Connecting to an Instance” のOpenSSHの項を参照してsshコマンドでアクセスすると成功した。そこに説明があるように,秘密鍵のファイルパーミッションを正しく設定しないとsshコマンドは無視してしまう。ちなみに,OpenSSHはChocolateyでインストール。

ちなみに、あまりに簡単にSSHコネクションが切られてしまうので、 “How to Increase SSH Connection Timeout in Linux” を参照してタイムアウトまでの時間を伸ばした。

Node.jsをインストールしNode-REDをインストール

Running on Raspberry Pi : Node-RED” にコマンド一発でNode-REDをインストールする手段が掲載されている。表題ではRaspberry Pi用としているがUbuntuを含めDebianの派生Linuxでこれが利用できる。これによりhttp://パブリックIPアドレス:1880でNode-REDにアクセスできるようになる…はずなんだがそうは問屋が卸さない。VMなんだから,ま,想定内。

Running on Raspberry Pi : Node-REDの “Autostart on boot” の項にあるように,以下でVMが立ち上がる際自動的にNode-REDが起動されるように。

$ sudo systemctl enable nodered.service

ここで “Installing Node-RED In An Always Free VM On Oracle Cloud | Oracle Developers Blog” の存在に気づいた。Oracle自身による解説なので信頼が置ける。基本今まで自分がたどってきたことと基本同じなのだが(ただしNode-REDインストールスクリプトがUbuntu (Debian)用ではない),VM作成時の “Modifying Your Security List” の項に説明されているSecurity Listの変更をしてみたが,これだけではWANからアクセスできない。コメントでも同様にできないと言ってる人がいるので,自分だけの問題ではなさそうだ。イマイチ信頼できない文書だったか…。

Node-REDが外部からアクセスできるように

Free Tier: Install Apache and PHP on an Ubuntu VM” では先にVCNの設定をやってからVMインスタンス生成,という流れになっている。実は多くの解説記事でそうなってる。そのVCNの設定でもやはりSecurity Listの変更は行っている。ただしそこで設定する igress ruleとしてstatelessを選ぶことになっているが, “Security Rules” を読むとstatefulでよいように思うのでそうしている。確信はない。

いずれにせよ,VMインスタンス生成後に以下のステップが必要としている。

Update firewall settings.

The Ubuntu firewall is disabled by default. However, it is still necessary to update your iptables configuration to allow HTTP traffic. Execute the following commands to update iptables.

$ sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 80 -j ACCEPT
$ sudo netfilter-persistent save

The commands add a rule to allow HTTP traffic and saves the changes to the iptables configuration files.

Node-RED用ポートは1880なのでそこを読み替えて上記を行うと無事外部から http://ドメイン名:1880 でアクセスできるようになった。

Oracle Cloudが永遠に無料らしいので開発環境を作ってみたかった (ネットワーク編) – Qiita” でちゃんとOracle Cloudでのネットワーク絡みの事情を説明してくれているので後で読み直そう。

Node-REDへの接続をセキュアに

この時点ではNode-REDにはHTTPSで接続するようにもなってなければ,アカウント制御も行われていない。

HTTPSのための公開鍵証明書作成

以下を参照した。ただ,そこで使用することになっているcertbot-autoがUbuntu 20.04で走らないといった問題があり,後知恵としてはCertbotのドキュメントを直接参照した方がよかった。

ここでも,公開鍵証明書発行のプロセスで必要になるドメイン名に対するポート80でのHTTPアクセスを可能にするため,Security Listの編集とiptablesの操作が必要。後者のためこの記事で例示されているfirewall-cmdは,Ubuntu 20.04ではデフォルトではインストールされていない。インストールしてもいいんだが,上のiptablesコマンドで実行。

certbot-autoを実行する段でpython-virtualenvがない,と怒られる。 “Ubuntu 20.04 fails to install jitsi via install-letsencrypt-cert.sh · Issue #6341 · jitsi/jitsi-meet · GitHub” を見ると,どうやらUbuntu 20.04で普遍的に見られる問題のようだ。

上の議論中にあるように,解決策は certbot-auto を利用するのではなく,Ubuntuが公式に提供するcertbotを利用すること。

$ sudo apt install certbot
$ sudo /usr/bin/certbot certonly --standalone

でプロンプトにしたがって進めると

IMPORTANT NOTES:
– Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/ドメイン名/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/ドメイン名/privkey.pem
Your cert will expire on 2021-01-14. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
“certbot renew”

と表示された上で,公開鍵証明書が作成される。Certbot本家ではUbuntu 20.04上ではaptではなくsnapを利用するよう指示している…が面倒なのでaptで進めることにする。

/etc/letsencrypt/live/ドメイン名/には以下のファイルができている。

README cert.pem chain.pem fullchain.pem privkey.pem

*.pemファイルはシンボリックリンクであり

/etc/letsencript/live/ドメイン名/fullchain.pem -> /etc/letsencript/archive/ドメイン名/fullchain1.pem

といったシンボリックリンクになっている。 “1” 部分は更新ごとに増えていくのであろうと想像する。

Node-REDをHTTPS対応に

Free SSL Certificates In The Oracle Cloud Using CertBot And Let’s Encrypt | Oracle Developers Blog” では.pemファイルを~/.node-red/certsディレクトリにコピーするよう指示しているが,これらファイルは相対的パスで実体を指しているシンボリックリンクなので違うパスにコピーしたところで実体は参照できない。むしろ,/etc/letsencript/live/ドメイン名/{privkey,cert}.pemを直接Node-REDの設定ファイルで参照したほうがいい。今後証明書を更新しても,これらファイルはシンボリックリンクなのであるから,実体が置き換わっても問題ない。

ただし,パーミッションのせいでrootでなければこれらファイルを見ることはできない。これに関しては, “User Guide — Certbot 1.10.0.dev0 documentation” で

For historical reasons, the containing directories are created with permissions of 0700 meaning that certificates are accessible only to servers that run as the root user. If you will never downgrade to an older version of Certbot, then you can safely fix this using chmod 0755 /etc/letsencrypt/{live,archive}.

For servers that drop root privileges before attempting to read the private key file, you will also need to use chgrp and chmod 0640 to allow the server to read /etc/letsencrypt/live/$domain/privkey.pem.

とあるのでこれに従う。Chgrpでどのグループにすべきかはよくわからないが,ubuntuにした。

その上で, “Securing Node-RED : Node-RED” を参照して,~/.node-red/settings.js で以下のような変更を加える:

    https: {
      key:  require("fs").readFileSync('/etc/letsencrypt/live/ドメイン名/privkey.pem'),
      cert: require("fs").readFileSync('/etc/letsencrypt/live/ドメイン名/cert.pem')
    },
...
    requireHttps: true, // HTTPでアクセスしても自動的にHTTPSに切り替える

これでさしあたってのHTTPS化は完了。HTPSでアクセスする際もポート番号は変わらず,https://ドメイン名:1880

公開鍵証明書の自動更新対策

certbotにより,/etc/cron.d/certbot に自動更新スクリプトが作成されている。この内容は以下のコメントがある:

# Important Note! This cronjob will NOT be executed if you are
# running systemd as your init system. If you are running systemd,
# the cronjob.timer function takes precedence over this cronjob. For
# more details, see the systemd.timer manpage, or use systemctl show
# certbot.timer.

Ubuntu 20.04ではsystemdが走っているようなので,ここに警告されているようにこのスクリプトは実行されないことになる。ただ,以下によりsystemdにより定期的に更新が試みられるようになっているようだ。

$ systemctl list-timers | grep certbot
Sat 2020-10-17 00:20:25 UTC 8h left Fri 2020-10-16 12:50:40 UTC 2h 50min ago certbot.timer certbot.service

Securing Node-RED : Node-RED” の “Refreshing HTTPS certificates” の項にはsettings.js内のhttpsを関数として適切に定義することで,証明書の更新時,新たな証明書を読み込ませるためにNode-REDを再起動しなくてはならないことを避けられるとしている。ただ,具体的な定義のしかたがわからない。このようにCertbotと組み合わせて運用するようなことは典型的に起こると思うので,例を提示してくれてもいいようなもんだが…。

次善策として “User Guide — Certbot 1.10.0.dev0 documentation” で紹介されている以下のフックを利用して,更新後自動的にNode-REDが再起動されるようにする。

You can also specify hooks by placing files in subdirectories of Certbot’s configuration directory. Assuming your configuration directory is /etc/letsencrypt, any executable files found in /etc/letsencrypt/renewal-hooks/pre/etc/letsencrypt/renewal-hooks/deploy, and /etc/letsencrypt/renewal-hooks/post will be run as pre, deploy, and post hooks respectively when any certificate is renewed with the renew subcommand. These hooks are run in alphabetical order and are not run for other subcommands. (The order the hooks are run is determined by the byte value of the characters in their filenames and is not dependent on your locale.)

/usr/bin/node-read-reloadがNode-REDを停止し,再起動するシェルスクリプトのようなので,最初はそれに対するシンボリックリンクを/etc/letsencrypt/renewal-hooks/postに置いてみた。その上で $sudo certbot renew --dry-run を実行してみると,どうもnode-red-reloadの実行でタイム・アウトしてしまう模様。なので以下のようにバックグラウンド実行するスクリプトnode-red-reload-bg.shに置き換えた。ドライランで見る限り問題なさそうだ。

#! /bin/sh
sudo /usr/bin/node-red-reload &

ユーザ名とパスワードによる認証

Securing Node-RED : Node-RED” ページの “Username/password based authentication” の項にユーザ名とパスワードによる認証を行う方法が出ているのでそれを行う。

これで最低限のセキュリティー対策はできた。

お遊びフロー作成

この記事冒頭のスクリーンショットにあるような簡単なテストフローを作成。MQTTブローカの特定トピックをサブスクライブし,値がパブリッシュされるたび,Lineで通知を送る,というもの。デバッグノードを除いて2つのノードからなる極めて単純なもの。

カスタムノードなどはWeb上で検索できるが,それらをインストールするのは,Node-REDの画面右上のハンバーガーメニュー中から起動できるPalette Managerを使って行うのが簡便だろう。

シンプルなフローだが,Mi Floraを購入すると決めてから実現を目指してきた自動化のためのお膳立てがこれでやっと整ったと思うと感慨深い。

広告

Node-REDをOracleの無料VPSサービスで使う」への13件のフィードバック

  1. ピンバック: Node-RED and Its Android Versions | あくまで暫定措置としてのブログ
  2. ピンバック: IFTTT代替自動化システム | あくまで暫定措置としてのブログ
  3. ピンバック: ホストされたNode-RED | あくまで暫定措置としてのブログ
  4. ピンバック: Sonoff Micro USBスマートアダプタ | あくまで暫定措置としてのブログ
  5. ピンバック: SONOFF MICRO USBスマートアダプタをMQTT経由で操作できるように | あくまで暫定措置としてのブログ
  6. ピンバック: Tuyaのスマート機器をNode-REDからアクセスする | あくまで暫定措置としてのブログ
  7. ピンバック: Node-REDでSmartLife Airカスタムノードで給電がコントロールできないTuya製プラグをなんとか | あくまで暫定措置としてのブログ
  8. ピンバック: TuyaがOEM提供した電力計機能つきのスマートプラグをNode-REDでコントロール…できなかった | あくまで暫定措置としてのブログ
  9. ピンバック: JSONata | あくまで暫定措置としてのブログ
  10. ピンバック: TermuxをAndroidTV準拠ストリーミング・メディア・プレーヤAmig 7xJPで | あくまで暫定措置としてのブログ
  11. ピンバック: SSHトンネルでLAN内のAndroid TVに外部からアクセス | あくまで暫定措置としてのブログ
  12. ピンバック: Androidスマホへの電力消費の少ないメッセージ通知法 | あくまで暫定措置としてのブログ
  13. ピンバック: 電子書籍の管理方針 | あくまで暫定措置としてのブログ

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください