Pull to refresh

FortNotes — онлайн менеджер паролей

Reading time10 min
Views11K
День добрый.
Хочу поделиться проектом, который недавно закончил. Надеюсь кому-то пригодится.
Все, кто пользуется интернетом длительное время, наверняка накопили большое количество различных приватных данных, таких как логины и пароли от сайтов, почтовых ящиков, серверов и баз данных. У кого-то меньше, у кого-то больше, но такие данные есть у всех. Можно хранить это на клочках бумаги, стикерах на мониторе, в блокноте на тумбочке или в файле на рабочем столе. Многие догадываются что это не очень безопасно: кто-то может подсмотреть или банально можно потерять эти драгоценные данные, но обычно редко кто пытается что-то с этим сделать.
Интернет очень плотно вошел в нашу жизнь и было бы неплохо иметь возможность упорядочить и обезопасить свои данные. Даже если не хранить в банках миллионы и не переживать, что кто-то украдет пароль от банковского счета, — это не значит, что будет приятна утеря доступа к почте, wm-киперу или фейсбуку. Личная переписка, деловые контакты, фотографии, секретная информация разного вида — всё это не должно быть доступно никому, кроме владельца.

Общее описание системы


FortNotes — это Форт Нокс для пользовательских данных. Технология в основе этого проекта — BlackBox, чёрный ящик или зашифрованный контейнер. Все записи, создаваемые на этом сайте, немедленно шифруются прямо в браузере с помощью AES (симметричный алгоритм блочного шифрования, принятый в качестве стандарта шифрования правительством США) и только после этого отправляются на сервер уже в зашифрованном виде. Это означает, что никто, кроме владельца данных, не имеет к ним доступа. Ни перехват данных интернет-соединения, ни изучение зашифрованного контейнера излишне любопытной администрацей сайта не позволят получить доступ к исходным данным. Без пользовательского пароля это будет просто бессмысленная мешанина символов. Чёрный ящик расшифровывается в реальную информацию только при входе на сайт FortNotes и вводе пароля. Таким образом пользователи не доверяют хранение своих секретных данных непонятно кому: сервер FortNotes хранит только зашифрованные чёрные ящики и ничего более, никакой информации в открытом виде. Дальше пользовательского компьютера и браузера не уходит даже логин, под которым проходит регистрация в системе. Абсолютно всё шифруется перед отправкой на сервер. Когда нужны данные — шлётся запрос, закачивается крипто-контейнер и происходит расшифровка. Процесс автоматизирован и прозрачен: требуется только предварительный ввод пароля.

Going deeper


Регистрация


Для регистрации в системе требуется только логин и пароль, которые перед отправкой на сервер преобразовываются в sha256-хеш, что по сути делает регистрацию анонимной. Вместо имен пользователей и их паролей в базе хранятся символьные последовательности вида «a9dc602f9d82bc6720b2b4bb016edcacf7da4b2b453a466b742da743f3cba15d». На сервере не хранятся никакие данные, которые могли бы идентифицировать пользователей. По этой же причине не запрашивается e-mail пользователя, так что восстановление логина и пароля невозможно. Высокий уровень безопасности накладывает определенные требования: нет никаких бекдоров, никаких «восстановлений забытых паролей». Это означает, что утеря этого пароля равнозначна утере всей базы секретных пользовательских данных. Модальное окно регистрации настойчиво акцентирует на этом внимание:



Для верификации регистрации используется капча:



После успешной регистрации происходит редирект в пользовательскую секцию. При каждом входе в эту закрытую секцию запрашивается пароль, который необходим для всех операций шифрования и расшифровки данных. Пароль хранится в оперативной памяти ограниченное (настраиваемое) время, по истечении которого очищается и вновь запрашивается у пользователя:



Перед очисткой пароля (после истечения времени его хранения), все данные, которые еще не были сохранены, шифруются и временно сохраняются в браузере без отправления на сервер. После того, как пользователь введет свой пароль, эти данные будут восстановлены, и пользователь сможет продолжить работу.

В правом верхнем углу экрана доступны две команды:
  • Lock позволяет немедленно зашифровать все открытые данные, стереть из памяти пароль и заблокировать экран до тех пор, пока не будет введен пароль. Важно помнить, что если в этот момент редактировались какие-либо данные заметки и они не были сохранены, то при данной блокировке эти изменения так и останутся только в браузере и не попадут на сервер, пока пользователь явно не сохранит заметку.
  • Exit выполняет полный выход из системы с очисткой пароля из памяти, удалением всех пользовательских кешей и сессии на сервере, после чего перенаправляет на домашнюю страницу проекта.

Создание и редактирование заметок


Основная единица информации в системе это note — заметка. Заметки могут быть разных типов. Для создания заметок имеется с десяток основных типов, оформленных в виде шаблонов. С их помощью в один клик можно получить заметку типа «почтовый ящик», «сайт», «jabber аккаунт», «ssh/ftp сервер» и т.д. Типы не статичны, но об этом чуть позже. Список типовых шаблонов для заметок:



Каждая заметка состоит из набора полей (entry), которые представляют из себя конечные поля ввода информации, и списка тегов, разделенных пробелом. Так, например, заметка типа «skype» состоит из трех полей: skype name (имя скайп-аккаунта), password (пароль), comments (необязательное поле комментариев) и выглядит следующим образом:



Поля, в свою очередь, тоже делятся по типам: простой однострочный текст, e-mail, URI (для адресов типа сайтов), пароль, многострочный текст, html.
Деление по типам для полей позволяет добавлять различные вспомогательные операции: например, для поля типа «пароль» становится доступной функция генерации случайного пароля заданной длины, для поля адреса при вводе URL производится попытка получить описание сайта и иконки для дальнейшего использования.

Как уже было упомянуто выше, поля в заметках не статичны. В заметке типа «скайп» можно в любой момент добавить новое поле любого типа (например, e-mail) и спозиционировать его в желаемом месте, можно удалить любое уже существующее поле (восстановить удаленное), переместить выше или ниже, поменять тип или просто отредактировать текст поля и заголовок.
При наведении курсора мыши на какое-либо поле, всплывают дополнительные элементы управления:



Тип любого поля может быть изменен в любой момент с помощью соответствующего пункта. Текст заголовка (если он был изменен) и данные при этом сохраняются.



Отдельно стоит отметить просмотр истории изменений каждого поля с возможностью откатиться к ранее сохраненным значениям. Восстанавливаются и данные поля и заголовок. При выборе соответствующего пункта во всплывающем меню появляется таблица с десятью последними значениями истории и ссылкой для восстановления:



При изменении заголовка или данных уже существующей заметки модифицированные данные подсвечиваются:



После внесения изменений при сохранении заметки, визуально отображается какие поля были добавлены, а какие обновлены (плюс — новое поле, галочка — обновленное):



При редактировании заметки возможно выполнить быстрое сохранение с помощью комбинации клавиш Ctrl + Enter.
Помимо сохранения доступны две специальные команды — дублирование текущей заметки и создание новой заметки аналогичной текущей, но с пустыми полями. Это будет удобно при создании серии однотипных заметок.

Поиск и фильтрация


Поиск на серверной стороне осуществляется с помощью тегов, перечисленных через пробел в строке поиска. Использование в поиске тега со знаком минус перед ним выводит список заметок, где такой тег не встречается. Помимо пользовательских тегов, создаваемых при добавлении заметок, есть набор системных тегов для получения списка удаленных заметок, заметок без тегов или фильтрации по времени последнего доступа. Такие теги доступны в строке поиска после ввода символа двоеточия ":". В примере ниже показан результат поиска записей за последний месяц, где встречаются теги site, work и dev, но не встречается тег php:



Результирующий список отображает все удовлетворяющие условиям заметки, где каждая строка соответствует одной заметке с кратким указанием содержимого полей, датой последних изменений и полным списком тегов. При щелчке мышью на теге можно добавить его в условия поиска или убрать его из поиска, если он там уже был. При одновременно зажатой клавише Ctrl можно добавить в поиск выбранный тег со знаком минус.

Поле поиска поддерживает интеллектуальное автодополнение. Достаточно начать вводить имя тега и сразу же будет отображен список возможных вариантов с учетом уже введенных тегов. Т.е. отображаются лишь те теги, которые встречаются в паре с уже указанными.



Поиск по тегам возвращает первые 20 заметок. При необходимости получить полный список, можно воспользоваться соответствующей ссылкой load all. Там же присутствуют ссылки для выделения всех заметок, снятия выделения и инвертирования. Для того чтобы начать работу с заметкой, достаточно щёлкнуть по ней мышью, после чего строка будет отмечена галочкой и подсвечена зеленым цветом, а заметка будет открыта в режиме редактирования. Также возможно отметить галочкой одну и более заметок, щёлкнув по нужной строке с зажатой клавишей Ctrl. Аналогично работе в файловых менеджерах работает выделение заметок при нажатой клавише Shift — выделяет все элементы между двух щелчков мышью. Над выделенными галочками заметками можно проводить общие операции: удаление или восстановление удаленных. Для перехода в режим восстановления удаленных заметок можно воспользоваться системным тегом :deleted. Также возможность перейти к восстановлению присутствует в подсказке, всплывающей сразу же после удаления выбранных заметок.
Если в строке поиска будут обнаружены слова, не являющиеся тегами, то они будут использованы для дополнительной фильтрации всех загруженных в список заметок.



Техническая сторона


Языки разработки — PHP и Javascript. Второго ощутимо больше, потому как основная работа идет на клиентской стороне. Роль серверной стороны сводится к регистрации/авторизации и обработке AJAX запросов на сохранение/получение данных и их поиск. Для AES шифрования на клиенте по 256 битному ключу используется замечательная библиотека SJCL (Stanford Javascript Crypto Library).

Клиентская сторона представляет собой по сути веб-приложение, работающее без перезагрузок, и состоит из набора js классов. Активно используется библиотека JQuery и модули для неё: jquery-autocomplete и SimpleModal. Имеется ядро системы, основная функция которого сводится к хранению и получению пароля, а также шифрованию и расшифровке данных с помощью этого пароля. Все остальные модули системы (используя шаблон observer) уведомляются о получении пароля от пользователя или же об истечении времени его хранения. В зависимости от этого происходит расшифровка закрытых данных с дальнейшим отображением, либо же очистка/шифрование и блокировка.
Все коммуникации между клиентом и сервером осуществляются данными в JSON-формате. При старте веб-приложения все справочные данные уже присутствуют на странице в виде JS массивов и объектов. Дальнейшие запросы выполняются с помощью фоновых AJAX запросов.

Для серверной стороны был разработан микро-фреймворк с поддержкой ЧПУ и абсолютно минимальным функционалом. Подход «ничего лишнего» и максимальное кеширование (общие данные — APC, пользовательские — JSON в gzипованных файлах на RAMFS разделе в оперативной памяти) позволил добиться весьма внушительных показателей быстродействия. Так, к примеру, генерация страницы закрытой пользовательской секции занимает 5-7ms на старой машине уровня Athlon 2800+.

В качестве веб-сервера используется Lighttpd. PHP-FPM как FastCGI процесс-менеджер.
База данных — MySql. Доступ осуществляется с помощью своей реализации подхода, аналогичного библиотеке MeekroDB. Разница заключается в использовании PDO и встроенной валидации таблиц и полей. Данная библиотека выделена в отдельный проект. Использование PDO в теории означает возможность работы с другими базами (помимо MySql), но это не тестировалось.

Для минимизации обращений к сереверу, все JS файлы упакованы в один собирательный файл all.js, а все CSS файлы — в all.css. При модификации любого исходного файла в отладочном режиме происходит автоматическа пересборка.

В системе присутствуют два шелл-скрипта init.sh и halt.sh, выполняемые при старте и выключении сервера соответственно:
  • init.sh создает директорию для кеша (если необходимо) и монтирует ее как RAMFS. Если имеется бекап ранее кешированных данных, то они переносятся в кеш. Дополнительно происходит проверка и создание (если необходимо) вложенных директорий кеша, отвечающих за разные данные. Устанавливаются требуемые права доступа. Генерируется структура базы данных для использования в последующей верификации имен таблиц и полей. Проверка и создание папки логов, её содержимого и установка прав. Подготовка собирательных файлов для JS и CSS файлов. Запуск php-fpm и lighttpd.
  • halt.sh завершает работу lighttpd и php-fpm. Осуществляет бекап всех кешированных данных и отключает кеш.

В заключение


Система бесплатная и открыта для всех. Более того, распространяется с открытыми исходными текстами, так что любой желающий может лично провести аудит кода или, если потребуется, установить эту систему на свой личный домашний или корпоративный сервер. Полные исходные коды находятся в публичном mercurial репозитории, а подробные инструкции по установке — в вики.
В планах: добавить импорт/экспорт данных, детальный аудит, управление сессиями, настройки и многоязычность.
Адрес сайта — http://fortnotes.com/
Или защищённое шифрованное соединение — https://fortnotes.com/
Проект на ohloh.net.
Конструктивные комментарии и пожелания приветствуются.
Приятной и безопасной работы :)

Update (2013.02.10):
Проведена чистка кода и документации, правка мелких багов.
Добавлена возможность запуска с использованием web-сервера Apache.
Добавлена поддержка встроенного PHP web-сервера. Это снимает обязательную зависимость от Apache или Lighttpd.
Добавлена поддержка sqlite баз. Это дает возможность быстрой установки системы вообще без внешних баз данных (типа Mysql).
Созданы представительства в различных соц-сетях: Google+, Facebook, ВКонтакте.

Update (2013.03.30):
Очередная порция мелких правок, оптимизаций и обновлений документации исходного кода.
Активация и поддержка механизма SJCL генерации энтропии для улучшения качества и криптостойкости генерируемых случайных паролей.
Долгожданная реализация восстановления бекапа. Пользователь и пароль в бекапе должны совпадать с логином и паролем аккаунта где производится восстановление. Все старые данные будут удалены, а данные из файла бекапа импортированы.
При экспорте предлагается более удобное имя, появилась возможность полностью выйти из системы в окне запроса пароля.
Добавлено детальное пошаговое руководство по установке проекта (система windows, база Sqlite, встроенный веб сервер php) и подробное описание архитектуры на английском языке.

Update (2013.11.13):
Ведется полная переработка системы. Упор на масштабируемость, поддержку многих платформ, простоту установки и работы. Приглашаются все желающие.

Update (2018.06.05):
Выпущены тестовые Docker образы текущей версии с небольшими косметическими изменениями и серьезной внутренней переработкой.
Подробности — github.com/fortnotes/legacy/tree/master/docker

Update (2019.05.01):
Проект переехал на собственный выделенный сервер. Должна сильно увеличиться бесперебойность работы и отзывчивость сервиса. Все подсистемы переведены на Docker контейнеры. Сайт разбит на две части: fortnotes.com с общей информацией и приложение для работы с шифрованными данными — app.fortnotes.com. Само приложение было значительно доработано и оптимизировано.
Tags:
Hubs:
+4
Comments21

Articles

Change theme settings