Node-RED:Руководство пользователя/Безопасность
Безопасность[1]
По умолчанию редактор Node-RED никак не защищен, поэтому любой, кто знает IP-адрес и порт, может получить доступ к редактору, внести свои изменений и выполнить их развертку. Поэтому этот вариант подходит только в том случае, если вы работаете с Node-RED в проверенной сети.
Поэтому в этой статье мы опишем, как можно защитить Node-RED. Она будет поделена на 2 части:
- Защита админского и редакторского API
- Защита HTTP-нод, панели управления и статического веб-контента
Защита админского и редакторского API
Админский и редакторский API поддерживают два типа аутентификации:
- Аутентификация с помощью имени пользователя и пароля
- Аутентификация через любого поставщика OAuth/OpenID вроде Twitter или GitHub (добавлена в версии 0.17)
Аутентификация через имя пользователя и пароль
Чтобы добавить аутентификацию пользователя в API админа и редактора, впишите в файл «settings.js» следующее:
adminAuth: {
type: "credentials",
users: [{
username: "admin",
password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.",
permissions: "*"
}]
}
Свойство «users» – это массив объектов, каждый из которых представляет собой данные об одном пользователе. Соответственно, в нем можно задать несколько разных пользователей, у каждого из которых могут быть разные полномочия.
К примеру, код выше задает только одного пользователя «admin», который имеет полномочия делать в редакторе абсолютно все, а для входа в систему использует пароль «password». Пароль хэшируется при помощи алгоритма bcrypt.
Генерирование хэша пароля
Чтобы сгенерировать хороший хэш пароля, можно воспользоваться инструментом командной строки «node-red-admin». Инструкции по его установке можно найти вот тут.
node-red-admin hash-pw
Этот инструмент запросит у вас пароль, который вы хотите использовать, а затем напечатает хэш, который затем можно скопировать и вставить в файл настроек.
В качестве альтернативы можно, находясь в папке установки Node-RED, запустить команду ниже:
node -e "console.log(require('bcryptjs').hashSync(process.argv[1], 8));" your-password-here
Аутентификация через OAuth/OpenID
Была добавлена в версии 0.17.
Если вы хотите настроить аутентификацию через внешний ресурс, то можете воспользоваться для этого большим диапазоном аутентификационных стратегий библиотеки «passport.js».
У Node-RED есть аутентификационные модули и для Twitter, и для GitHub. Поскольку эти стратегии предусматривают некоторый специфический код, разработчики сделали для него «обертку», чтобы ими было легче пользоваться. Но эти модули также можно использовать в качестве шаблона для аутентификации с помощью других похожих стратегий.
В коде ниже продемонстрировано, как настроить аутентификацию через Twitter без использования соответствующего аутентификационного модуля от разработчиков Node-RED.
adminAuth: {
type:"strategy",
strategy: {
name: "twitter",
label: 'Sign in with Twitter',
icon:"fa-twitter",
strategy: require("passport-twitter").Strategy,
options: {
consumerKey: TWITTER_APP_CONSUMER_KEY,
consumerSecret: TWITTER_APP_CONSUMER_SECRET,
callbackURL: "http://example.com/auth/strategy/callback",
verify: function(token, tokenSecret, profile, done) {
done(null, profile);
}
},
},
users: [
{ username: "knolleary",permissions: ["*"]}
]
};
В свойстве «strategy» имеются следующие опции:
- «name» – название используемой passport-стратегии
- «strategy» – модуль passport-стратегии
- «label» и «icon» – надпись и иконка для страницы залогинивания. В свойстве «icon» можно вписать название любой иконки с FontAwesome
- «options» – объект «options», который передается passport-стратегии при ее создании. О том, что для него нужно, читайте в документации используемой стратегии. О свойстве «callbackURL» читайте ниже.
- «verify» – функция верификации, используемая стратегией. Если данные пользователя верны, она должна вызвать done(), где вторым параметром должен быть профиль пользователя. В нем должно быть свойство «username», используемое для сверки со списком корректных пользователей. Разработчики «passport.js» стараются стандартизировать объекты для профиля пользователя, поэтому это свойство должно быть у большинства стратегий.
Свойство «callbackURL» – это URL, на который аутентификационный поставщик перенаправит пользователя после завершения процесса аутентификации. Первой частью этого URL должен быть URL вашего редактора Node-RED, а затем должно идти «/auth/strategy/callback». К примеру, если доступ к редактору осуществляется по ссылке «http://localhost:1880», то в свойстве «callbackURL» нужно вписать «http://localhost:1880/auth/strategy/callback».
Как задать стандартного пользователя
Код ниже не будет пускать пользователя в редактор, пока он не залогинится.
В некоторых случаях требуется настроить для всех пользователей хотя бы какой-то уровень доступа к редактору. Как правило, это доступ «только для чтения». Для этого вам нужно будет добавить в настройку «adminAuth» свойство «default» – это задаст стандартного пользователя.
adminAuth: {
type: "credentials",
users: [ /* список пользователей */ ],
default: {
permissions: "read"
}
}
Полномочия пользователей
До выхода версии 0.14 для пользователей можно было задать только два вида полномочий:
- «*» – полный доступ
- «read» – только для чтения
Но с выходом версии 0.14 появились новые возможности для настройки полномочий. Теперь значением в этом свойстве может быть и одна строка (как раньше), и массив с несколькими полномочиями.
У каждого метода в админском API есть полномочия, необходимые для доступа к нему. Модель полномочий – ресурсо-ориентированная. К примеру, чтобы прочесть данные текущего потока, пользователю понадобится полномочие «flows.read», а для обновления потока ему понадобится полномочие «flows.write».
Истечение срока действия аутентификационного токена
По умолчанию срок действия токена доступа истекает через 7 дней после его создания. Увеличение этого периода сейчас не поддерживается.
Период действия токена можно отредактировать с помощью свойства «sessionExpiryTime» в настройке «adminAuth». Он задается в секундах. К примеру, если вам нужно, чтобы период действия токена длился 1 день, вам нужно будет вписать следующее:
adminAuth: {
sessionExpiryTime: 86400,
...
}
Доступ к админскому API
Теперь, задав настройку «adminAuth», мы можем получить доступ к админскому API. О том, как это сделать, читайте тут.
Аутентификация пользователей с помощью собственного кода
Вместо того, чтобы «хардкодить» данные о пользователях в файл настроек, вы также можете задать аутентификацию пользователей при помощи собственного кода. Кроме того, ваш метод можно будет встроить в уже имеющиеся аутентификационные схемы.
Пример ниже показывает, как можно использовать внешний модуль, чтобы задать собственный аутентификационный код:
- Сохраните код ниже в файл «<node-red>/user-authentication.js»
module.exports = { type: "credentials", users: function(username) { return new Promise(function(resolve) { // Пишем здесь код, проверяющий, // корректно ли это имя пользователя: if (valid) { // Если корректно, возвращаем объект «user». // В нем должны находиться // свойства «username» и «permissions». var user = { username: "admin", permissions: "*" }; resolve(user); } else { // Если не корректно, возвращаем «null», // чтобы показать, что такого пользователя нет. resolve(null); } }); }, authenticate: function(username,password) { return new Promise(function(resolve) { // Пишем здесь код, проверяющий, // корректны ли имя пользователя и пароль: if (valid) { // Если корректны, возвращаем объект «user». // Это эквивалентно вызову функции users(username). var user = { username: "admin", permissions: "*" }; resolve(user); } else { // Если не корректны, возвращаем «null», // чтобы показать, что таких // имени пользователя и пароля не существует: resolve(null); } }); }, default: function() { return new Promise(function(resolve) { // Возвращаем объект «user» для стандартного пользователя. // Если стандартных пользователей нет, возвращаем «null». resolve({anonymous: true, permissions:"read"}); }); } }
- Редактируем свойство «adminAuth» в файле «settings.js», чтобы загрузить этот модуль:
adminAuth: require("./user-authentication")
Защита HTTP-нод
Маршруты, которые становятся уязвимы в результате использования нод «http in», можно защитить с помощью базовой аутентификации.
Это можно сделать, отредактировав свойство «httpNodeAuth» в файле «settings.js» и задав там имя пользователя и пароль, дающие доступ к этим маршрутам:
httpNodeAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."},
При редактировании свойства «pass» используется тот же формат, что и в свойстве «adminAuth». Более подробно читайте выше в разделе «Генерирование хэша пароля».
Доступ ко всему статическому веб-контенту, заданному в свойстве «httpStatic», можно защитить с помощью свойства «httpStaticAuth», использующего тот же самый формат.
См.также
Внешние ссылки