Node-RED:Руководство пользователя/Безопасность: различия между версиями
Myagkij (обсуждение | вклад) |
Myagkij (обсуждение | вклад) Нет описания правки |
||
(не показаны 3 промежуточные версии 2 участников) | |||
Строка 1: | Строка 1: | ||
{{Node-RED/Панель перехода}} | {{Node-RED/Панель перехода}} | ||
{{Перевод от Сubewriter}} | {{Перевод от Сubewriter}} | ||
{{Myagkij-редактор}} | {{Myagkij-редактор}} | ||
=Безопасность<ref>[https://nodered.org/docs/security nodered.org - Security]</ref>= | =Безопасность<ref>[https://nodered.org/docs/security nodered.org - Security]</ref>= | ||
Строка 24: | Строка 21: | ||
Чтобы добавить аутентификацию пользователя в [[API]] админа и редактора, впишите в файл '''«settings.js»''' следующее: | Чтобы добавить аутентификацию пользователя в [[API]] админа и редактора, впишите в файл '''«settings.js»''' следующее: | ||
<syntaxhighlight lang="javascript | <syntaxhighlight lang="javascript"> | ||
adminAuth: { | adminAuth: { | ||
type: "credentials", | type: "credentials", | ||
Строка 39: | Строка 36: | ||
К примеру, код выше задает только одного пользователя '''«admin»''', который имеет полномочия делать в редакторе абсолютно все, а для входа в систему использует пароль '''«password»'''. Пароль хэшируется при помощи алгоритма [[bcrypt]]. | К примеру, код выше задает только одного пользователя '''«admin»''', который имеет полномочия делать в редакторе абсолютно все, а для входа в систему использует пароль '''«password»'''. Пароль хэшируется при помощи алгоритма [[bcrypt]]. | ||
{{ | {{Примечание1|В старых версиях [[Node-RED]] для включения базовой [[HTTP-аутентификации]] в редакторе можно было использовать свойство '''«httpAdminAuth»'''. Но сейчас она устарела, и лучше ее не использовать.}} | ||
==== Генерирование хэша пароля ==== | ==== Генерирование хэша пароля ==== | ||
Строка 45: | Строка 42: | ||
Чтобы сгенерировать хороший хэш пароля, можно воспользоваться инструментом командной строки '''«node-red-admin»'''. Инструкции по его установке можно найти [https://nodered.org/docs/node-red-admin вот тут]. | Чтобы сгенерировать хороший хэш пароля, можно воспользоваться инструментом командной строки '''«node-red-admin»'''. Инструкции по его установке можно найти [https://nodered.org/docs/node-red-admin вот тут]. | ||
<syntaxhighlight lang="bash | <syntaxhighlight lang="bash"> | ||
node-red-admin hash-pw | node-red-admin hash-pw | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Строка 53: | Строка 50: | ||
В качестве альтернативы можно, находясь в папке установки [[Node-RED]], запустить команду ниже: | В качестве альтернативы можно, находясь в папке установки [[Node-RED]], запустить команду ниже: | ||
<syntaxhighlight lang="bash | <syntaxhighlight lang="bash"> | ||
node -e "console.log(require('bcryptjs').hashSync(process.argv[1], 8));" your-password-here | node -e "console.log(require('bcryptjs').hashSync(process.argv[1], 8));" your-password-here | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Строка 67: | Строка 64: | ||
В коде ниже продемонстрировано, как настроить аутентификацию через [[Twitter]] без использования соответствующего аутентификационного модуля от разработчиков [[Node-RED]]. | В коде ниже продемонстрировано, как настроить аутентификацию через [[Twitter]] без использования соответствующего аутентификационного модуля от разработчиков [[Node-RED]]. | ||
<syntaxhighlight lang="javascript | <syntaxhighlight lang="javascript"> | ||
adminAuth: { | adminAuth: { | ||
type:"strategy", | type:"strategy", | ||
Строка 105: | Строка 102: | ||
В некоторых случаях требуется настроить для всех пользователей хотя бы какой-то уровень доступа к редактору. Как правило, это доступ ''«только для чтения»''. Для этого вам нужно будет добавить в настройку '''«adminAuth»''' свойство '''«default»''' – это задаст стандартного пользователя. | В некоторых случаях требуется настроить для всех пользователей хотя бы какой-то уровень доступа к редактору. Как правило, это доступ ''«только для чтения»''. Для этого вам нужно будет добавить в настройку '''«adminAuth»''' свойство '''«default»''' – это задаст стандартного пользователя. | ||
<syntaxhighlight lang="javascript | <syntaxhighlight lang="javascript"> | ||
adminAuth: { | adminAuth: { | ||
type: "credentials", | type: "credentials", | ||
Строка 131: | Строка 128: | ||
Период действия [[токен]]а можно отредактировать с помощью свойства '''«sessionExpiryTime»''' в настройке '''«adminAuth»'''. Он задается в секундах. К примеру, если вам нужно, чтобы период действия [[токен]]а длился 1 день, вам нужно будет вписать следующее: | Период действия [[токен]]а можно отредактировать с помощью свойства '''«sessionExpiryTime»''' в настройке '''«adminAuth»'''. Он задается в секундах. К примеру, если вам нужно, чтобы период действия [[токен]]а длился 1 день, вам нужно будет вписать следующее: | ||
<syntaxhighlight lang="javascript | <syntaxhighlight lang="javascript"> | ||
adminAuth: { | adminAuth: { | ||
sessionExpiryTime: 86400, | sessionExpiryTime: 86400, | ||
Строка 150: | Строка 147: | ||
* Сохраните код ниже в файл '''«<node-red>/user-authentication.js»''' | * Сохраните код ниже в файл '''«<node-red>/user-authentication.js»''' | ||
:: <syntaxhighlight lang="javascript | :: <syntaxhighlight lang="javascript"> | ||
module.exports = { | module.exports = { | ||
type: "credentials", | type: "credentials", | ||
Строка 199: | Строка 196: | ||
* Редактируем свойство '''«adminAuth»''' в файле '''«settings.js»''', чтобы загрузить этот модуль: | * Редактируем свойство '''«adminAuth»''' в файле '''«settings.js»''', чтобы загрузить этот модуль: | ||
:: <syntaxhighlight lang="javascript | :: <syntaxhighlight lang="javascript"> | ||
adminAuth: require("./user-authentication") | adminAuth: require("./user-authentication") | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Строка 209: | Строка 206: | ||
Это можно сделать, отредактировав свойство '''«httpNodeAuth»''' в файле '''«settings.js»''' и задав там имя пользователя и пароль, дающие доступ к этим маршрутам: | Это можно сделать, отредактировав свойство '''«httpNodeAuth»''' в файле '''«settings.js»''' и задав там имя пользователя и пароль, дающие доступ к этим маршрутам: | ||
<syntaxhighlight lang="javascript | <syntaxhighlight lang="javascript"> | ||
httpNodeAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."}, | httpNodeAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."}, | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Строка 217: | Строка 214: | ||
Доступ ко всему статическому веб-контенту, заданному в свойстве '''«httpStatic»''', можно защитить с помощью свойства '''«httpStaticAuth»''', использующего тот же самый формат. | Доступ ко всему статическому веб-контенту, заданному в свойстве '''«httpStatic»''', можно защитить с помощью свойства '''«httpStaticAuth»''', использующего тот же самый формат. | ||
{{ | {{Примечание1|В старых версиях [[Node-RED]] в свойстве '''«pass»''' нужно было указать [[MD5-хэш]]. Он криптографически небезопасен, поэтому разработчики добавили возможность использования [[bcrypt-хэш]]а, используемого в '''«adminAuth»'''. В целях обратной совместимости [[MD5-хэш]] по-прежнему поддерживается, но использовать его мы не рекомендуем.}} | ||
=См.также= | =См.также= | ||
Строка 224: | Строка 221: | ||
<references /> | <references /> | ||
{{Навигационная таблица/Node-RED библиотеки}} | |||
{{Навигационная таблица/Телепорт}} |
Текущая версия от 14:20, 9 сентября 2023
Безопасность[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», использующего тот же самый формат.
См.также
Внешние ссылки