Node-RED のダッシュボードで Basic 認証を Node-RED で生成できるハッシュ値で指定するメモ

Node-RED のダッシュボードで Basic 認証を Node-RED で生成できるハッシュ値で指定するメモです。

2021/9/7 追記

以前の設定だとpath の設定不足で一部ノードが動かなかったので、調査のうえコード修正しました。

Node-RED ダッシュボードに Basic 認証付与時に設定不足で一部ノードが動かず修正したメモ

以前は平文で指定していました

以前の記事の場合、setting.js に平文で指定していました。

Node-REDのダッシュボードだけにBasic認証をかけるメモ

ui:{
    middleware:function(req,res,next) {
        const ui_admins = {
            'username': { password: 'password' },
        };
 
        const user = auth(req);
            if (!user || !ui_admins[user.name] || ui_admins[user.name].password !== user.pass) {
                res.set('WWW-Authenticate', 'Basic realm="node-red"');
                return res.status(401).send();
            }
            return next();
        }
},

こちらでも認証は機能しますが、やはり平文だと落ち着かないです。できれば Node-RED のエディタで使われるハッシュ値での認証を共通で使えるといいなと思いました。

ちなみに、セキュリティの記事にあるように Node-RED 1.1 より node-red admin hash-pw というコマンドでハッシュ値が作成しやすくなったので、そういう意味でも便乗したかったのです。

実際の実装

ハッシュ値のままで、パスワードの一致を検証するのはこちらの記事を参考にしました。

[node.js]Expressでパスワードのハッシュ化を行おう – Qiita

bcrypt ライブラリを使って実現できることが分かりました。実際、Node-RED のエディタで使われるハッシュ値を比較してみたところバッチリ判定されました。

ということで、以前の記事をベースに改修する形ですすめていきます。

冒頭に bcrypt を呼び出せるようにする

Node-REDが動作している .node-red のフォルダに移動して、

npm i bcrypt

を実行してbcryptをインストールします。そのうえで Node-RED 設定ファイル setting.js に追記していきます。

var auth = require('basic-auth');
var bcrypt = require('bcrypt'); // 今回はこの1行を加える

すでに、Basic 認証を使えるように basic-auth を呼び出しているので、その下に bcrypt ライブラリを呼び出します。

今回のパスワードをハッシュ値で生成

セキュリティの記事を参考に

node-red admin hash-pw

というコマンドを打ち込んで、パスワードを生成します。今回は仮に HASHAAAAAAAAAABBBBBBBBBBBBBCCCCCCCCCCCCCCCC とします。

そのうえで元々の ui の設定のところで、 ui_admins[user.name].password !== user.pass だったところを、!bcrypt.compareSync(user.pass, ui_admins[user.name].password); に変更して、パスワードはそのままハッシュ値で指定します。

指定したものが以下です。

    ui:{
        middleware:function(req,res,next) {
        const ui_admins = {
            'admin': { password: 'HASHAAAAAAAAAABBBBBBBBBBBBBCCCCCCCCCCCCCCCC' },
        }
 
        const user = auth(req);
            if (!user || !ui_admins[user.name] || !bcrypt.compareSync(user.pass, ui_admins[user.name].password)) {
                res.set('WWW-Authenticate', 'Basic realm="node-red"');
                return res.status(401).send();
            }
            return next();
        },
        path:"ui"
    },

ざっくり仕組みを言うと bcrypt.compareSync のところで、ハッシュ値を bcrypt で展開して Basic 認証で入力されたパスワード値が一致しているか見ているという流れになっています。

この設定を行って保存したうえで、Node-REDを再起動すると、無事ハッシュ値のパスワードで認証をかけれるようになります!

ハッシュ値になる前のパスワード値を忘れると再現ができなくなるので、そこは今後の管理では注意しておきます!