...

суббота, 12 августа 2017 г.

Проклятые Земли — Улучшаем бег и опыт с напарниками



Многие играли в эту замечательную игру. Интересный сюжет, хорошая музыка, неплохой геймплей. Только есть пара моментов, которые мне не нравятся. Бег персонажей очень ограниченный, буквально несколько секунд, а запас сил восстанавливается долго. Система начисления опыта не стимулирует брать напарников, потому что опыт распределяется на всех поровну, и лучше бегать одному, чтобы забирать весь опыт себе. Возьмем отладчик и попробуем это исправить.

Нам понадобятся ArtMoney, IDA, Hiew.

В действиях ничего сложного нет, здесь главное результат. Смещения приведены для версии 1.07.

Запускаем IDA, загружаем файл game.exe, ждем пока завершится анализ.
Запускаем стартер, убираем настройку «Полноэкранный режим».
Запускаем игру в отладчике, загружаем сохранение где уже можно взять напарника.
Берем напарника, выходим на карту.

Бег

Смотрим, сколько запаса сил у персонажа. Здесь это 54.
Запускаем ArtMoney. Ищем это значение. Тип «С точкой 4 байта».
Пробегаем сколько-нибудь и отсеиваем новое значение.
Повторяем сколько нужно, у меня сразу осталось одно значение.

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

Ставим на этот адрес брейкпойнт на запись в IDA. Перед этим обязательно надо сделать 'Pause process', иначе случаются вылеты.
Переключаемся на игру, отправляем персонажа в какую-нибудь точку, снимаем с паузы.

Брейкпойнт срабатывает.

.text:00548315 loc_548315:
.text:00548315                 fld     dword ptr [edi+14h]
.text:00548318                 fld     dword ptr [edi+18h]
.text:0054831B                 fmul    ds:dbl_73F088
.text:00548321                 fsubp   st(1), st
.text:00548323                 fst     dword ptr [edi+14h]
.text:00548326 >               fcomp   ds:flt_73B858
.text:0054832C                 fnstsw  ax
.text:0054832E                 test    ah, 1
.text:00548331                 jz      short loc_548388

Запись происходит в инструкции fst dword ptr [edi+14h]. Можно поставить Operand type — Floating point на этот адрес и на соседний [edi+18h].

Судя по значениям, там хранится:
[edi+14h] — текущее значение
[edi+18h] — максимальное значение

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

.rdata:0073F088 dbl_73F088      dq 6.666666666666666e-3
; 6.666666666666666e-3 = 0.006666666666666666 = 1/150


То есть персонаж может пробежать примерно 150 «шагов», но это не совсем шаги, которые видно на анимации, потому что вычитание происходит гораздо чаще. Полный запас сил расходуется за 9-10 секунд, значит вычитание вызывается 15 — 16.66 раз в секунду.
Скорее всего это зеленые точки, обозначающие путь.

В байтах эта константа записывается так:

4E 1B E8 B4 81 4E 7B 3F

Открываем game.exe в Hiew и переходим на адрес ".73F088".

Других констант с таким значением нет, ссылка на нее есть только в рассмотренном коде.

Можно ее поменять на любое значение, которое вам нужно. Я сделал себе в 3 раза меньше.
(1/150)/3 = 1/450 = 0.0022222222222222222

Для конвертации float/double в hex-представление можно воспользоваться онлайн-конвертером, например этим.

для справки
0.0066666666666666667 - 0x3F7B4E81B4E81B4F
0.006666666666666666  - 0x3F7B4E81B4E81B4E
0.0022222222222222222 - 0x3F623456789ABCDF
0.002222222222222222  - 0x3F623456789ABCDE



Получается красивое число 0x3F623456789ABCDF
DF BC 9A 78 56 34 62 3F


Заменяем, сохраняем, запускаем. Вот, так гораздо лучше.

Опыт

Тут немного сложнее. Он не хранится в явном виде. Нужно искать через связанные значения. Начинаем, впрочем, так же.

Смотрим, сколько опыта отображается у персонажа. Это можно сделать в режиме между картами. У меня это 116.


Ищем это значение. Здесь нужен тип «Целое 4 байта».

Это не исходная переменная, а вычисляемое значение, приведенное к int. Сам опыт хранится во float, но там другое значение, об этом ниже.

Теперь можно с кем-нибудь подраться. Выходить с карты чтобы посмотреть опыт нельзя, перезагружаться тоже, потому что память выделяется заново, и при повторном заходе на карту будут другие адреса. Надо прибавлять в уме. При этом надо учитывать округление. То есть, если за противника дается 5 очков опыта, и в команде 2 персонажа, то на экране будет отображаться опыт 2, но прибавлять надо 2.5 и брать целую часть.

После пары повторений у меня осталось 6 значений, которые изменяются синхронно.

Попробуем поставить брейкпойнты на запись на каждый адрес. Не забываем про «Pause process».

Подходит первый адрес. Остальные срабатывают по rep movsd.

.text:00522D00                 fld     dword ptr [ebx+700h]
.text:00522D06                 fadd    dword ptr [ebx+4]
.text:00522D09                 fsub    dword ptr [ebx+8]
.text:00522D0C                 fstp    [ebp+var_10]
.text:00522D0F                 fld     [ebp+var_10]
.text:00522D12                 fistp   [ebp+var_C]
.text:00522D15                 mov     edx, [ebp+var_C]
.text:00522D18                 mov     [edi+8], edx
.text:00522D1B >               mov     eax, [ebx+10h]
.text:00522D1E                 mov     [ebp+var_10], eax

Он срабатывает при беге или при бое любого из персонажей. Поэтому здесь лучше управлять только одним, а не группой, чтобы не путаться. В ebx находится адрес объекта персонажа. В [ebx+700h] находится 0.

Посмотрим значения.

387 — 271 = 116
Можно предположить, что это полученный и потраченный опыт, а текущий рассчитывается как их разность.

Уберем этот брейкпойнт и поставим новый на [ebx+4].

Выбираем всю группу и нападаем на противника.

Брейкпойнт срабатывает до того, как это будет видно на экране.

.text:005239D7                 fld     ds:dbl_73E128
.text:005239DD                 fld     dword ptr [esi+20h]
.text:005239E0                 fsub    ds:flt_73E124
.text:005239E6                 call    __CIpow
.text:005239EB                 fmul    [ebp+arg_4]
.text:005239EE                 fadd    dword ptr [esi+700h]
.text:005239F4                 fcom    ds:flt_73B858
.text:005239FA                 fst     dword ptr [esi+700h]
.text:00523A00                 fnstsw  ax
.text:00523A02                 test    ah, 41h
.text:00523A05                 jnz     short loc_523A19
.text:00523A07                 fadd    dword ptr [esi+4]
.text:00523A0A                 mov     dword ptr [esi+700h], 0
.text:00523A14                 fstp    dword ptr [esi+4]
.text:00523A17 >               jmp     short loc_523A1B

В [esi+4] новое значение опыта. В [ebp+arg_4] число 2.0. За молодого кабана дается 4.0, значит деление находится до вызова функции.

Выходим из функции через Ctrl+F7. Это обертка, выходим еще раз.

Смотрим чуть выше, там находится такой код.

.text:00591521 loc_591521:
.text:00591521                 fild    [ebp+var_18]
.text:00591524                 xor     esi, esi
.text:00591526                 cmp     eax, edi
.text:00591528                 mov     [ebp+var_14], esi
.text:0059152B                 fdivr   [ebp+arg_4]
.text:0059152E                 fstp    [ebp+arg_4]
.text:00591531                 jle     short loc_5915A5
.text:00591533                 jmp     short loc_591537


Поставим брейкпойнт на 00591521 и поучаствуем в битве еще раз.
fdivr делит аргумент на st(0) и результат записывает в st(0): st(0) = arg / st(0). В st(0) находится значение [ebp+var_18], в котором находится 2 — число персонажей. В [ebp+arg_4] находится 4.0 — опыт за противника. При выполнении миссии начисление тоже происходит здесь.

Также деление на число участников есть выше:

.text:00591324                 fdiv    [ebp+var_18]


Но я не нашел, когда выполняется этот код. Там трогать не будем.

Теперь через Hiew можно убрать код для деления. Из-за особенностей fdivr заменяем на nop все 3 команды (9 байт).

; было
.00591521: DB45E8                         fild        d,[ebp][-018]
.00591524: 33F6                           xor         esi,esi
.00591526: 3BC7                           cmp         eax,edi
.00591528: 8975EC                         mov         [ebp][-014],esi
.0059152B: D87D0C                         fdivr       d,[ebp][00C]
.0059152E: D95D0C                         fstp        d,[ebp][00C]
.00591531: 7E72                           jle        .0005915A5
.00591533: EB02                           jmps       .000591537

; стало
.00591521: 909090                         nop
.00591524: 33F6                           xor         esi,esi
.00591526: 3BC7                           cmp         eax,edi
.00591528: 8975EC                         mov         [ebp][-014],esi
.0059152B: 909090                         nop
.0059152E: 909090                         nop
.00591531: 7E72                           jle        .0005915A5
.00591533: EB02                           jmps       .000591537

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

Поехали!

Комментарии (0)

    Let's block ads! (Why?)

    [Из песочницы] Разработка telegram бота с использованием Spring

    [Перевод] Практический бизнес онтологии: рассказ c передовой

    Информационная экономика: почему стоимость технологических компаний так высока

    Инвесторы всё чаще предпочитают вкладываться в нематериальные активы (intangible investment), а не в компании, производящие промышленное оборудование, оснащение и другие материальные ценности (tangibles). Компании в США владеют нематериальными активами, общая сумма которых превышает $8 трлн. Это почти половина стоимости индекса S&P 500 на момент проведения исследования.

    image

    Нематериальные активы состоят из прав, отношений и интеллектуальной собственности. Но среди них выделяется особая форма – разработки, появившиеся в результате расходов на НИОКР. Они составляют основной доход любой современной организации. Это сбивает с толку инвестора. Дело в том, что действующий механизм не может адекватно связать такие блага с ценой компани.
    Способы ведения бухучета и методы оценки, использующиеся в XXI веке, плохо подходят для нематериальных активов и искажают их стоимость.

    Издание The Market Mogul опубликовало интересную статью о том, почему капитализации технологических компаний в последние годы находятся на очень высоких уровнях. Мы подготовили адаптированную версию этого материала.

    Как формируется оценка бизнеса в 21 веке


    Учетные политики, которые организации используют для управления своими экономическими процессами, не подходят для современных нематериальных активов. Это создает причину для беспокойства при оценки акций. Регулирующие инструменты, такие как МСФО, признают нематериальные активы только в момент совершения сделки, например покупки. Такой стандарт не учитывает нематериальные активы компании, которые формируют ее акционерную стоимость. Значимость возрастает, когда из $89 трлн цены предприятия $30,1 трлн считается «нераскрытой стоимостью».

    Кроме того, классификация затрат может неточно отображать определенные показатели, непосредственно влияющие на оценку, такие как дисконтированный денежный поток. Основными расходами, которые стимулируют информационное развитие, являются НИОКР. В бухгалтерской отчетности они отражаются как операционные затраты, хотя по своей сути создают долгосрочные экономические выгоды. Если вручную переконфигурировать отчетность о прибылях и убытках и проводить расходы на НИОКР в качестве капитальных затрат, создается более точное представление о доходах компании.

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

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

    Основная проблема


    Фундаментальная проблема заключается в неспособности ценового механизма работать с чем-то неограниченным. Современная экономическая система не учитывает, что затраты на данные, необходимые для производства товаров, будут стремиться к нулю. Компаниям ничего не стоит воссоздать несколько строк кода и скопировать информацию. Следовательно, естественные рыночные механизмы не могут создать цену.

    Хотя некоторые исследования показывают, что данные потребляют вычислительную мощность при удалении «одного бита», для фиксации значения требуется более надежная система.

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

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

    Вывод


    В краткосрочной перспективе текущие подходы к бухгалтерской оценке компаний, скорее всего, не изменятся. Но некоторые страны начинают признавать ценность нематериальных активов в рамках отчетности. Например, Китай постепенно переходит от капиталоемких отраслей промышленности к технологиям и услугам.

    В результате внедряются новые установки, которые позволяют фиксировать внешние факторы, связанные с нематериальными активами. Это обеспечивает ясность, но не создает надежной системы ценообразования, которую требует текущая бизнес-среда. Может ли следующий длительный экономический цикл обеспечить то, что требуется?

    Другие материалы по теме финансов и фондового рынка от ITinvest:


    Комментарии (0)

      Let's block ads! (Why?)

      пятница, 11 августа 2017 г.

      [Перевод] Создаем самодостаточный Docker-кластер

      Пятничное: к сообществу

      Автономный способ обхода DPI и эффективный способ обхода блокировок сайтов по IP-адресу

      Провайдеры Российской Федерации, в большинстве своем, применяют системы глубокого анализа трафика (DPI, Deep Packet Inspection) для блокировки сайтов, внесенных в реестр запрещенных. Не существует единого стандарта на DPI, есть большое количество реализации от разных поставщиков DPI-решений, отличающихся по типу подключения и типу работы.

      Существует два распространенных типа подключения DPI: пассивный и активный.

      Пассивный DPI

      Пассивный DPI — DPI, подключенный в провайдерскую сеть параллельно (не в разрез) либо через пассивный оптический сплиттер, либо с использованием зеркалирования исходящего от пользователей трафика. Такое подключение не замедляет скорость работы сети провайдера в случае недостаточной производительности DPI, из-за чего применяется у крупных провайдеров. DPI с таким типом подключения технически может только выявлять попытку запроса запрещенного контента, но не пресекать ее. Чтобы обойти это ограничение и заблокировать доступ на запрещенный сайт, DPI отправляет пользователю, запрашивающему заблокированный URL, специально сформированный HTTP-пакет с перенаправлением на страницу-заглушку провайдера, словно такой ответ прислал сам запрашиваемый ресурс (подделывается IP-адрес отправителя и TCP sequence). Из-за того, что DPI физически расположен ближе к пользователю, чем запрашиваемый сайт, подделанный ответ доходит до устройства пользователя быстрее, чем настоящий ответ от сайта.

      Выявляем и блокируем пакеты пассивного DPI

      Поддельные пакеты, формируемые DPI, легко обнаружить анализатором трафика, например, Wireshark.
      Пробуем зайти на заблокированный сайт:
      Wireshark

      Мы видим, что сначала приходит пакет от DPI, с HTTP-перенаправлением кодом 302, а затем настоящий ответ от сайта. Ответ от сайта расценивается как ретрансмиссия и отбрасывается операционной системой. Браузер переходит по ссылке, указанной в ответе DPI, и мы видим страницу блокировки.

      Рассмотрим пакет от DPI подробнее:
      image

      HTTP/1.1 302 Found
      Connection: close
      Location: http://ift.tt/2vMf4co
      

      В ответе DPI не устанавливается флаг «Don't Fragment», и в поле Identification указано 1. Серверы в интернете обычно устанавливают бит «Don't Fragment», и пакеты без этого бита встречаются нечасто. Мы можем использовать это в качестве отличительной особенности пакетов от DPI, вместе с тем фактом, что такие пакеты всегда содержат HTTP-перенаправление кодом 302, и написать правило iptables, блокирующее их:
      # iptables -A FORWARD -p tcp --sport 80 -m u32 --u32 "0x4=0x10000 && 0x60=0x7761726e && 0x64=0x696e672e && 0x68=0x72742e72" -m comment --comment "Rostelecom HTTP" -j DROP
      

      Что это такое? Модуль u32 iptables позволяет выполнять битовые операции и операции сравнения над 4-байтовыми данными в пакете. По смещению 0x4 хранится 2-байтное поле Indentification, сразу за ним идут 1-байтные поля Flags и Fragement Offset.
      Начиная со смещения 0x60 расположен домен перенаправления (HTTP-заголовок Location).
      Если Identification = 1, Flags = 0, Fragment Offset = 0, 0x60 = «warn», 0x64 = «ing.», 0x68 = «rt.ru», то отбрасываем пакет, и получаем настоящий ответ от сайта.

      В случае с HTTPS-сайтами, DPI присылает TCP Reset-пакет, тоже с Identification = 1 и Flags = 0.

      Активный DPI

      Активный DPI — DPI, подключенный в сеть провайдера привычным образом, как и любое другое сетевое устройство. Провайдер настраивает маршрутизацию так, чтобы DPI получал трафик от пользователей к заблокированным IP-адресам или доменам, а DPI уже принимает решение о пропуске или блокировке трафика. Активный DPI может проверять как исходящий, так и входящий трафик, однако, если провайдер применяет DPI только для блокирования сайтов из реестра, чаще всего его настраивают на проверку только исходящего трафика.

      Системы DPI разработаны таким образом, чтобы обрабатывать трафик с максимально возможной скоростью, исследуя только самые популярные и игнорируя нетипичные запросы, даже если они полностью соответствуют стандарту.

      Изучаем стандарт HTTP

      Типичные HTTP-запросы в упрощенном виде выглядят следующим образом:
      GET / HTTP/1.1
      Host: habrahabr.ru
      User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/50.0
      Accept-Encoding: gzip, deflate, br
      Connection: keep-alive
      
      Запрос начинается с HTTP-метода, затем следует один пробел, после него указывается путь, затем еще один пробел, и заканчивается строка протоколом и переносом строки CRLF.
      Заголовки начинаются с большой буквы, после двоеточия ставится символ пробела.

      Давайте заглянем в последнюю версию стандарта HTTP/1.1 от 2014 года. Согласно RFC 7230, HTTP-заголовки не зависят от регистра символов, а после двоеточия может стоять произвольное количество пробелов (или не быть их вовсе).

         Each header field consists of a case-insensitive field name followed
         by a colon (":"), optional leading whitespace, the field value, and
         optional trailing whitespace.
      
           header-field   = field-name ":" OWS field-value OWS
      
           field-name     = token
           field-value    = *( field-content / obs-fold )
           field-content  = field-vchar [ 1*( SP / HTAB ) field-vchar ]
           field-vchar    = VCHAR / obs-text
      
           obs-fold       = CRLF 1*( SP / HTAB )
                          ; obsolete line folding
      

      OWS — опциональный один или несколько символов пробела или табуляции, SP — одинарный символ пробела, HTAB — табуляция, CRLF — перенос строки и возврат каретки (\r\n).

      Это значит, что запрос ниже полностью соответствует стандарту, его должны принять многие веб-серверы, придерживающиеся стандарта:

      GET / HTTP/1.1
      hoSt:habrahabr.ru
      user-agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/50.0
      Accept-Encoding:           gzip, deflate, br
      coNNecTion:     keep-alive      ← здесь символ табуляции между двоеточием и значением
      

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

      Старый стандарт, RFC 2616, рекомендует снисходительно парсить запросы и ответы сломанных веб-северов и клиентов, и раздешать произвольное количество пробелов в самой первой строке HTTP-запросов и ответов в тех местах, где требуется только один:

      Clients SHOULD be tolerant in parsing the Status-Line and servers tolerant when parsing the Request-Line. In particular, they SHOULD accept any amount of SP or HT characters between fields, even though only a single SP is required.
      Этой рекомендации придерживаются далеко не все веб-серверы. Из-за двух пробелов между методом и путем ломаются некоторые сайты.

      Спускаемся на уровень TCP

      Соединение TCP начинается с SYN-запроса и SYN/ACK-ответа. В запросе клиент, среди прочей информации, указывает размер TCP-окна (TCP Window Size) — количество байт, которые он готов принимать без подтверждения передачи. Сервер тоже указывает это значение. В интернете используется значение MTU 1500, что позволяет отправить до 1460 байтов данных в одном TCP-пакете.
      Если сервер указывает размер TCP-окна менее 1460, клиент отправит в первом пакете данных столько, сколько указано в этом параметре.

      Если сервер пришлет TCP Window Size = 2 в SYN/ACK-пакете (или мы его изменим на это значение на стороне клиента), то браузер отправит HTTP-запрос двумя пакетами:

      Пакет 1:

      GE
      
      Пакет 2:
      T / HTTP/1.1
      Host: habrahabr.ru
      User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/50.0
      Accept-Encoding: gzip, deflate, br
      Connection: keep-alive
      

      Используем особенности HTTP и TCP для обхода активного DPI

      Многие решения DPI ожидают заголовки только в стандартном виде.
      Для блокировки сайтов по домену или URI, они ищут строку "Host: " в теле запроса. Стоит заменить заголовок «Host» на «hoSt» или убрать пробел после двоеточия, и перед вами открывается запрошенный сайт.
      Не все DPI можно обмануть таким простым трюком. DPI некоторых провайдеров корректно анализируют HTTP-заголовки в соответствии со стандартом, но не умеют собирать TCP-поток из нескольких пакетов. Для таких DPI подойдет «фрагментирование» пакета, путем искусственного уменьшения TCP Window Size.

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

      Программа для обхода DPI


      Я написал программу для обхода DPI под Windows: GoodbyeDPI.
      Она умеет блокировать пакеты с перенаправлением от пассивного DPI, заменять Host на hoSt, удалять пробел между двоеточием и значением хоста в заголовке Host, «фрагментировать» HTTP и HTTPS-пакеты (устанавливать TCP Window Size), и добавлять дополнительный пробел между HTTP-методом и путем.
      Преимущество этого метода обхода в том, что он полностью автономный: нет внешних серверов, которые могут заблокировать.

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

      goodbyedpi.exe -1 -a
      
      Если заблокированные сайты стали открываться, DPI вашего провайдера можно обойти.
      Попробуйте запустить программу с параметром -2 и зайти на заблокированный HTTPS-сайт. Если все продолжает работать, попробуйте режим -3 и -4 (наиболее быстрый).
      Некоторые провайдеры, например, Мегафон и Yota, не пропускают фрагментированные пакеты по HTTP, и сайты перестают открываться вообще. С такими провайдерами используйте опцию -3 -a

      Эффективное проксирование для обхода блокировок по IP

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

      ReQrypt

      Долгое время разработка была заморожена из-за того, что автор не мог найти сервер с возможностью спуфинга. Спуфинг IP-адресов часто используется для амплификации атак через DNS, NNTP и другие протоколы, из-за чего он запрещен у подавляющего большинства провайдеров. Но сервер все-таки был найден, хоть и не самый удачный. Разработка продолжается.

      Заключение и TL;DR

      GoodbyeDPI — программа под Windows, позволяющая обходить пассивные и активные DPI. Просто скачайте и запустите ее, и заблокированные сайты станут снова доступны.
      Для Linux есть аналогичная программа — zapret.

      Используйте кроссплатформенную программу ReQrypt, если ваш провайдер блокирует сайты по IP-адресу.

      Определить тип блокировки сайтов можно программой Blockcheck. Если в тестах DPI вы видите, что сайты открываются, или видите строку «обнаружен пассивный DPI», то GoodbyeDPI вам поможет. Если нет, используйте ReQrypt.

      Комментарии (0)

        Let's block ads! (Why?)

        Как настроить командную работу и сохранять спокойствие в чатах Телеграма, если всё горит, и все в аду

        Учим робота готовить пиццу. Часть 1: Получаем данные

        Digest MBLTdev — свежак для iOS-разработчиков

        Сегодня вышел 130-й выпуск дайджеста. Решили поделиться с общественностью небольшой круглой датой полезным контентом. Спасибо, что читаете нас. А если ещё не читаете, то пора начать.

        The Ultimate Guide to Branch Products
        Если вы что-то слышали про Branch, то, возможно, знаете, что они предоставляют систему дип линков. На самом деле у Branch сейчас есть целый арсенал продуктов для любой стадии развития приложения.
        BRANCH.APP.LINK

        HomePod firmware provides detailed look at iPhone 8 screen layout
        Скандалы, интриги, расследования. Вопрос один: это вообще законно? Скоро узнаем. Ждать осталось недолго.
        9TO5MAC.COM

        Apple releases fourth iOS 11 public beta for iPhone and iPad
        Паблик бета 4 в бою. Хуже не стало. И это хорошо.
        9TO5MAC.COM

        Неделя для подачи доклада на MBLTdev 2017
        Точнее, 9 дней. Но дедлайн близко (ждём заявки до 20.08).
        MBLTDEV.RU

        iOS.Ninja
        Новый канал для iOS-разработчиков, объединённый. Если вдруг подзабылось, каналов целый ворох на http://ios-channels.ru.
        T.ME

        Не CoreML единым
        Нейросеть на Swift, реализующая XOR, но без использования CoreML, а через BNNS.
        COCOA-BEANS.RU

        MAChineLearning
        Ещё один заход по ML. Специально для macOS-разработчиков. Вторую неделю подряд появляется что-то специфическое для macOS. Так, глядишь, и синхронизацию CoreData через iCloud починят.
        GITHUB.COM

        Disk
        Предлагается абстракция над некоторыми дисковыми операциями.
        GITHUB.COM

        Managing view controller complexity in tvOS and iOS projects
        В процессе работы над своим AVPlayerViewController ребята сделали правильные выводы насчёт архитектуры. Стейт надо изолировать!
        MEDIUM.COM

        Enforce Exclusive Access to Memory (Swift-evolution)
        Concurrency — это непросто. Если вам интересно узнать, что такое overlapping accesses, чем он плох и как с ним предлагают жить, читайте этот proposal.
        GITHUB.COM

        UI-тесты для iOS
        Мобильные проекты обычно небольшие и недолго живущие, люди уже начинают забывать, как выглядит Objective-C, а некоторые его даже не видели. И вот прекрасная статья про проект, которому уже 6 лет. 99% кода написано на Objective-C, много чего подкручено это здорово! Конечно, такую кодовую базу надо покрывать тестами, и парни поделились тем, как они тестируют UI. Если коротко, то это XCTest и добавление JSON с описанием UI-элементов в accessibilityValue.
        HABRAHABR.RU

        TamTam: как мы делали новый мессенджер
        Немного про то, как устроен мессенджер от Одноклассников.
        HABRAHABR.RU

        Sequel Pro
        А вот немножечко UI для работы с mySQL, MariaDB. Можно, конечно, и образ с сайта скачать, но из исходников-то правомернее будет.
        GITHUB.COM

        SQLite.viewer
        Поднимает сервер который позволяет работать с SQLite базой приложения из браузера. Напомнило PonyDebugger.
        GITHUB.COM

        App Store Insights
        Немного занимательных фактов о магазинах приложений.
        BLOG.APPFIGURES.COM

        Digest MBLTDEV — это собрание самой полезной и свежей информации для iOS-разработчиков с просторов мирового интернета. Выпуск выходит каждую пятницу. Подписка бесплатная. И никакого спама, честно!

        Комментарии (0)

          Let's block ads! (Why?)

          История торговых кассовых аппаратов

          Современную торговлю невозможно представить без использования контрольно-кассовой техники. Кассы с нами повсюду: в супермаркетах, кафе, на заправках и на почте. С 1 июля 2017 года кассовые аппараты обязательно должны использоваться даже при оплате товаров в интернет-магазинах. А кто и когда первым придумал вести учет финансовых поступлений при помощи кассы? Вся история торговых кассовых аппаратов – в нашем материале.


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

          1871-1884: первые кассы Джеймса Якоба Ритти


          Первым человеком, который задумался о необходимости контроля денежных поступлений, был Джеймс Якоб Ритти. Будущий изобретатель кассового аппарата в 1871 году открыл в городе Дайтон (штат Огайо) бар под названием Pony House. Несмотря на немалое число посетителей, денег бизнес не приносил, так как персонал заведения постоянно утаивал выручку от владельца. Решить проблему увольнением нечистых на руку продавцов не получалось – с новыми людьми происходило то же самое.

          Джеймс Ритти – изобретатель первого кассового аппарата

          Решение пришло неожиданно, во время морского путешествия Ритти из США в Европу. Джеймс зашел в машинное отделение корабля и увидел там тахометр – круглый датчик, который отсчитывал число оборотов гребного вала. Глядя на этот датчик, Джеймс подумал, что можно собрать похожее устройство, которое бы точно так же отсчитывало деньги, принимаемые от клиентов Pony House. Вернувшись домой, воодушевленный Джеймс сконструировал прототип кассового аппарата.

          Это устройство было совершенно не похоже на привычные для нас кассы. Для индикации суммы дохода использовался круглый циферблат, из-за чего устройство издалека можно было принять за обычные часы в деревянном корпусе. Тем более что у первой кассы, как и у часов, были стрелки: длинная («минутная») показывала центы, а короткая («часовая») отображала доллары. Под этим циферблатом располагались кнопки, каждая из которых соответствовала цене на тот или иной товар. Например, если посетитель приобретал выпивку на 35 центов, кассир должен был нажать на кнопку с этим значением, после чего счетчик корректировал положение стрелок на циферблате.


          Первая рабочая модель кассового аппарата

          Первая модель кассового аппарата оказалась несовершенной. Хитрый продавец мог лишь сделать вид, что использует кассу, или нажать на кнопку с меньшим номиналом. А когда никто не видел, он поступал еще проще – переводил стрелки обратно. Поэтому Джеймс внес изменения в конструкцию – в кассе появились колесики с цифрами, а их движение было синхронизировано передаточным механизмом. Благодаря «сумматору» аппарат научился подсчитывать общую сумму заказа, а также приобрел форму, которая впоследствии не менялась в течение многих лет.

          Чтобы приучить посетителей заведения к кассе, Ритти повесил на устройство колокольчик, который издавал звон после расчета посетителя. Эта модель получила прозвище «Неподкупный кассир Ритти».

          Однако и во второй модификации кассового аппарата со временем обнаружился существенный недостаток. Как-то раз в заведении разразился сильный скандал – недовольный посетитель обвинил бармена в том, что тот его обсчитал. Доказательств, понятное дело, не было – кассовый аппарат показывал новую сумму выручки, и только. Тогда Джеймс решил доработать свое детище, наделив его специальной бумажной лентой, на которой фиксировалась каждая операция, проведенная кассиром.

          Так в третьей модификации кассового аппарата все операции сопровождались перфорацией бумаги, по которой можно было отследить действия кассира. Вероятно, с той поры и появилось хорошо известное выражение «пробить чек».

          Кроме того, под кассой теперь в обязательном порядке находился ящик для денег – поначалу самый простой выдвижной, поделенный на секции для разного номинала. Также в нем имелись прижимные ролики для купюр. Со временем в ящике появился и замок. Интересно, что за более чем сто лет ящик для наличности практически не изменился.

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


          Джеймс Ритти с братом создают первые образцы кассовых аппаратов

          Первые кассы современности: «Национальная кассовая компания» Джона Паттерсона


          В 1884 году права на изготовление кассовых аппаратов выкупил Джон Паттерсон, которого по праву называют человеком, создавшим современную технологию продаж. Получив патент на производство перспективного устройства, бизнесмен создал компанию The National Cash Register Company (которая, кстати, и сегодня выпускает POS-оборудование).

          В 1906 году в NCR был изобретен первый кассовый аппарат на электромоторе с кнопочным приводом. Его создал один из самых талантливых инженеров NCR – Чарльз Кеттеринг, который всего за пять лет работы в компании получил более двадцати патентов на разные изобретения. Команда инженеров NCR вносила все новые усовершенствования в кассовые аппараты, и именно под началом Джона Паттерсона эти устройства стали такими, какими мы их привыкли видеть.


          Классический кассовый аппарат фирмы The National Cash Register Company

          Когда Паттерсон занялся кассовыми аппаратами, ему пришлось влезть в долги и полагаться на свою интуицию предпринимателя. Но он твердо верил в то, что за кассовыми аппаратами будущее. Интересно, что Паттерсон не навязывал покупателям сами кассовые аппараты, а работал над созданием потребности в кассовых чеках (то есть по сути продавал не сам продукт, а выгоду от его использования). Для продавцов NCR был написан целый учебник, который они обязаны были выучить наизусть, прежде чем идти к потенциальным клиентам. В итоге с 1884 по 1911 год в мире было продано более миллиона кассовых аппаратов, а к 1917 году The National Cash Register Company контролировала около 95% рынка.

          Некоторые методы, которые использовал в своей бизнес-стратегии Джон Паттерсон, были действительно новаторскими (и применяются по сей день). Так, компания NCR часто попросту скупала своих конкурентов. Как только Джон видел в продаже модель кассового аппарата с функциями, которых недоставало в собственной продукции, он тут же делал все, чтобы выкупить производителя или вынудить его свернуть бизнес.

          Во-вторых, в компании дотошно изучали кассы конкурентов, чтобы лучше понять их недостатки. Так, например, достоверно известно, что в феврале 1892 года внутри компании было распространен циркуляр с инструкциями по взлому денежного ящика кассового аппарата конкурирующей марки – Simplex Cash Register.

          Эта касса работала достаточно необычно. У нее не было кнопок, зато имелись отверстия под шарики. Каждое отверстие соответствовало определенной сумме. После установки шариков в нужное положение в небольшом окне поднимался флажок с ценником. Так покупатель мог увидеть выставленный ему счет. Попав внутрь кассы, шарики накапливались, и в конце дня владелец мог сравнить выручку с числом шариков.


          Альтернативный тип кассового аппарата от Simplex Cash Register

          Продавцы NCR получили от руководства подробную инструкцию, разъясняющую, насколько легко можно обмануть эту кассу и достать оттуда наличность. К инструкции прилагалась свинцовая пуля и конский волос. Трюк был прост – вместо шарика можно было вставить в отверстие пулю, а потянув за заранее подложенный под ящик конский волос, без проблем выдвинуть ящик и достать деньги из кассы. Конечно же, после такой демонстрации многие владельцы подобных кассовых аппаратов спешили заменить их на устройства от NCR.

          К несчастью для компании Паттерсона, эта инструкция послужила поводом для иска к NCR со стороны федерального правительства и в соответствии с антимонопольным законодательством в 1913 году компания была признана виновной в нечестном ведении продаж.

          Впрочем, Паттерсон не боялся судебных процессов и активно спорил в суде с конкурентами. Забавный случай произошел в 1894 году. Обратив внимание на растущую популярность кассовых устройств, некий Майкл Хайнц из Детройта создал компанию Heintz Cash Register, которая выпустила свой кассовый аппарат. Отличительной особенностью этой модели было то, что вместо привычного звона колокольчика об окончании операции сообщала… кукушка. Да-да, механическая кукушка, которая высовывала голову из кассы и куковала.

          Мимо такого Паттерсон пройти не мог. Он подал иск на Хайнц Кэш Реджистер, обвинив конкурента в нарушении авторских прав. В суде представители «кассы с кукушкой» заявили, что сделали принципиально новый продукт, заменив классический колокольчик на птичку. Но Джон настаивал на том, что это не так, а в доказательство предъявил текст оригинального патента. И действительно в патенте Джеймса Ритти не был прописан именно колокольчик — в нем указывалось «звуковое устройство для оповещения». Решение суда постановило заставить кукушку замолчать навсегда. Хотя, наверное, было бы забавно услышать на кассе, что твои деньги «ку-ку».

          Кассовые аппараты в СССР


          В Советском Союзе контрольно-кассовые устройства собственного производства появились не сразу. Долгое время в ресторанах и торговых точках использовались импортные образцы, в основном, устаревшей конструкции. Отдельные довоенные разработки, как, например, выпускаемые Киевским заводом имени 13-летия Октября, не получили особого распространения — главным образом по причине низкой надежности.

          Более того, в стране даже толком не было мест, где можно было бы отремонтировать поврежденную импортную технику. В 1923 году открылось единственное на тот момент предприятие по ремонту пишущих машин, счётных и кассовых аппаратов – «Бюро точной механики 1-го МГУ».

          Первые более или менее удачные варианты кассовых аппаратов отечественного производства, такие как А1Т или линейка устройств КИМ, появились во второй половине прошлого века. Изначально эти модели были исключительно механическими и приводились в действие поворотной ручкой. Позже их конструкция стала электромеханической, они работали от обычной сети. Но даже когда во второй половине 70-х в универмагах и продуктовых магазинах появились электрифицированные образцы, на боковой стенке кассового аппарата все еще можно было видеть ручку «для завода», которая использовалась в экстренных случаях при отсутствии электричества.


          Кассовый аппарат КИМ-2

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

          Ранние модели советских касс имели ограниченный набор регистров. Каждый регистр вводился своим набором цифр. Для десятков рублей использовался первый вертикальный столбец кнопок от «1» до «9», для единиц рублей – второй вертикальный столбец и т.д. Цифры «ноль» не было вообще, вместо нее ставился крест – это была своеобразная защита от подделок чека. Также на клавиатуре находился короткий столбец кнопок – «1», «2», «3», «4». Это были номера отделов, для которых выбивался товар.

          Еще одна хитрая особенность, предназначенная для защиты от мошенников, – буквенный код. Чтобы человек не мог получить товар по поддельному чеку, кассир должен был регулярно договариваться с продавцом и менять контрольную букву чека. Таким образом, если человек вручает продавцу чек, и тот не видит «секретную букву», он знает, что чек – подделка.

          Кнопки имели фиксацию, и чек пробивался — с помощью кнопки ввода — лишь тогда, когда вся информация была набрана. Если же кассир ошибался, он мог сделать «сброс», отжав текущую комбинацию клавиш специальной кнопкой.


          Модель КИМ-3-СП

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


          Контрольно-кассовый аппарат «Ока 4401»

          С начала 80-х годов прошлого века такая касса стояла практически в каждом советском магазине. Она заправлялась сразу двумя рулонами лент: одна – для покупателя, вторая – для ведения контрольного протокола. Контрольная лента показывалась под окошком на панели рядом с кнопками, так что кассир мог оперативно увидеть свою ошибку или просмотреть историю действий.

          К кассе прилагался целый комплект ключей. Первый позволял включить кассовый аппарат, второй служил для обнуления датчиков, а третий – для снятия показаний счетчиков. А «визитной карточкой» отечественного кассового аппарата стал ящик для наличности, который по окончанию расчета буквально вылетал из основного корпуса.

          В восьмидесятых же появились и первые электронные кассовые аппараты. Наиболее популярной среди них была Искра-302А. Она была похожа на гигантский калькулятор и имела встроенную память на магнитных сердечниках. Такая касса часто использовалась в Сбербанке и на почте.


          Советский кассовый аппарат Искра-302А

          Наше время


          В наш век «умных вещей» кассовые аппараты стали настоящими маленькими компьютерами. Современная касса, отвечающая всем требованиям законодательства, состоит из следующих компонентов:
          • корпуса, внутри которого должны быть часы реального времени.
          • фискального накопителя (ФН) – криптографического средства защиты фискальных данных, которое записывает данные в некорректируемом виде, хранит их и передает в контролирующие органы. Именно передача накопленных данных является отличием ФН от ЭКЛЗ (электронной защищенной контрольной ленты), которая использовалась в более ранних версиях кассовых аппаратов для некорректируемого накопления информации обо всех оформленных на устройстве платежных документах и отчетах закрытия смены.
          • устройства для печати чеков. Впрочем, в эпоху онлайн-расчетов печать бумажного чека для некоторых видов торговли уже необязательна. Поэтому сегодня уже есть онлайн-кассы, которые генерируют только электронный чек и не печатают его на бумаге.

          Для того чтобы разобраться в разнообразии современных касс, можно ориентироваться на буквенные обозначения в названиях моделей:

          • «ФС» – кассы только для расчетов в интернете (не содержат внутри корпуса устройство для печати);
          • «ФА» – кассы только для встраивания в автоматические устройства (вендинг, платежные терминалы);
          • «ФБ» – автоматизированные системы БСО;
          • «Ф» – все остальные, которые могут применяться в любом из вариантов.

          Современные онлайн-кассы для торговых точек обычно оснащаются встроенным модемом, обеспечивающим онлайн-передачу данных в ФНС, слотом для SIM-карты, влагозащищенной клавиатурой, Li-ion аккумулятором (на случай перебоев с электропитанием).


          Касса АТОЛ 90Ф

          Есть и портативные кассы, предназначенные специально для курьеров. Они более легкие и компактные (иногда – весом до 300 грамм), могут в течение длительного времени работать автономно, оснащены интерфейсами передачи данных Bluetooth и Wi-Fi.

          А вот современные многофункциональные POS-терминалы по внешнему виду больше напоминают классический десктоп, чем контрольно-кассовый аппарат. В любом POS-терминале можно безошибочно распознать знакомые компоненты – системный блок, монитор, клавиатуру, принтер. Однако в отличие от обычного ПК, терминал, конечно же, не используется для игр и веб-серфинга, а предназначен для применения в различных торговых точках.


          Многофункциональный POS-терминал «АТОЛ Магазин у дома»

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

          В итоге


          Контрольно-кассовые аппараты, выпущенные за последние сто пятьдесят лет, сильно отличаются внешне и функционально. Но есть кое-что, что объединяет первые кассы Джеймса Ритти и современные POS-терминалы. Это – простота в обращении.

          Главный пользователь подобных устройств – обычный кассир, который зачастую имеет очень смутное представление о том, как функционирует кассовый аппарат. Поэтому производители касс всегда уделяли большое внимание простоте их использования и придавали им сходство с узнаваемыми предметами. В разные времена дизайн кассового аппарата напоминал часы, печатную машинку, настольный калькулятор и т.д. И чем сложнее становилась «начинка» кассовой техники, тем важнее было сделать аппарат более дружелюбным и надежным. И какую бы форму ни принимало устройство, его главная функция остается неизменной – помогать человеку вести контрольный учет денежных операций. Ведь кассовые чеки — это единственная составляющая бизнеса, суть которой не изменилась за последние сто лет.

          Комментарии (0)

            Let's block ads! (Why?)

            Мониторинг как сервис: модульная система для микросервисной архитектуры

            Сегодня на нашем проекте, помимо монолитного кода, функционируют десятки микросервисов. Каждый из них требует того, чтобы его мониторили. Делать это в таких объемах силами DevOps проблематично. Мы разработали систему мониторинга, которая работает как сервис для разработчиков. Они могут самостоятельно писать метрики в систему мониторинга, пользоваться ими, строить на их основании дашборды, прикручивать к ним алерты, которые будут срабатывать при достижении пороговых значений. С DevOps — только инфраструктура и документация.
            Этот пост — расшифровка моего выступления с нашей секции на РИТ++. Многие просили нас сделать текстовые версии докладов оттуда. Если вы были на конференции или смотрели видео, то не найдете ничего нового. А всем остальным — добро пожаловать под кат. Расскажу, как мы пришли к такой системе, как она работает и как мы планируем её обновлять.

            Прошлое: схемы и планы


            Как мы пришли к существующей системе мониторинга? Для того, чтобы ответить на этот вопрос, нужно отправиться в 2015 год. Вот как это выглядело тогда:

            У нас существовало порядка 24 узлов, которые отвечали за мониторинг. Здесь есть целая пачка различных кронов, скриптов, демонов, которые что-то где-то каким-то образом мониторят, отправляют сообщения, выполняют функции. Мы подумали, что чем дальше, тем менее такая система будет жизнеспособна. Развивать её нет смысла: слишком громоздкая.
            Мы решили выбрать те элементы мониторинга, которые мы оставим и будем развивать, и те, от каких откажемся. Их оказалось 19. Остались только графиты, агрегаторы и Grafana в качестве дашборда. Но как же будет выглядеть новая система? Вот так:

            У нас есть хранилище метрик: это графиты, которые будут базироваться на быстрых SSD-дисках, это определенные агрегаторы для метрик. Далее — Grafana для вывода дашбордов и Moira в качестве алертинга. Также мы хотели разработать систему для поиска аномалий.

            Стандарт: Мониторинг 2.0


            Так выглядели планы в 2015. Но нам надо было готовить не только инфраструктуру и сам сервис, но и документацию к нему. Мы для себя разработали корпоративный стандарт, который назвали мониторинг 2.0. Какие требования были к системе?
            • постоянная доступность;
            • интервал хранения метрик = 10 секунд;
            • структурированное хранение метрик и дашбордов;
            • SLA > 99,99%
            • cбор ивентовых метрик по UDP (!).

            Нам был необходим UDP, так как у нас большой поток трафика и событий, которые генерируют метрики. Если их все сразу писать в графит, хранилище ляжет. Также мы выбрали префиксы первого уровня для всех метрик.

            Каждый из префиксов носит какое-то свойство. Есть метрики по серверам, сетям, контейнерам, ресурсам, приложениям и так далее. Реализована четкая, строгая, типизированная фильтрация, где мы принимаем метрики первого уровня, а остальные просто дропаем. Вот как мы планировали эту систему в 2015 году. Что же в настоящем?

            Настоящее: схема взаимодействия компонентов мониторинга


            В первую очередь мы мониторим аппликейшны: наш PHP-код, приложения и микросервисы — словом, все, что пишут наши разработчики. Все аппликейшны через UDP отправляют метрики в агрегатор Brubeck (statsd, переписанный на С). Он оказался самым быстрым по итогам синтетических тестов. И он отправляет уже агрегированные метрики в Graphite через TCP.

            У него есть такой тип метрик, как таймеры. Это очень удобная штука. Например, на каждое соединение пользователя с сервисом вы отправляете в Brubeck метрику с responce time. Пришел миллион ответов, а агрегатор выдал всего 10 метрик. У вас есть количество пришедших людей, максимальное, минимальное и среднее время отклика, медиана и 4 персентиля. Потом данные передаются в Graphite и мы видим их все вживую.

            Также у нас есть агрегация для метрик по железу, софту, системных метрик и нашей старой системы мониторинга Munin (она работала у нас до 2015 года). Все это мы собираем через C'ишный демон CollectD (в него вшита целая пачка различных плагинов, он умеет опрашивать все ресурсы хостовой системы, на которой он установлен, просто укажите в конфигурации, куда писать данные) и пишем через него данные в Graphite. Также он поддерживает плагины python и shell скрипты, так что вы можете писать свои кастомные решения: CollectD будет собирать эти данные с локального или удаленного хоста (предположим, есть Curl) и отправлять их в Graphite.

            Дальше все метрики, которые мы собрали, отправляем в Carbon-c-relay. Это решение Carbon Relay от Graphite, доработанное на C. Это роутер, который собирает в себе все метрики, которые мы отправляем с наших агрегаторов, и маршрутизирует их по нодам. Также на стадии маршрутизации он проверяет валидность метрик. Они, во-первых, должны соответствовать той схеме с префиксами, которую я показал раньше и, во-вторых, валидны для графита. Иначе они дропаются.

            Потом Carbon-c-relay отправляет метрики в кластер Graphite. Мы используем в качестве основного хранилища метрик Carbon-cache, переписанные на Go. Go-carbon по причине его многопоточности намного превосходит по производительности Carbon-cache. Он принимает данные в себя и записывает их на диски с помощью пакета whisper (стандартный, написан на python). Для того, чтобы прочитать данные с наших хранилищ, мы используем Graphite API. Он работает намного быстрее, чем стандартный Graphite WEB. Что происходит с данными дальше?

            Они идут в Grafana. В качестве основного источника данных мы используем наши кластеры графитов, плюс у нас есть Grafana как веб-интерфейс, для отображения метрик, построения дэшбордов. На каждый свой сервис разработчики заводят собственный дэшборд. Далее они строят по ним графики, на которых отображаются метрики, которые они пишут со своих приложений. Помимо Grafana у нас есть еще SLAM. Это питонячий демон, который считает SLA на основании данных из графита. Как я уже говорил, у нас есть несколько десятков микросервисов, у каждого из которых есть свои требования. С помощью SLAM мы ходим в документацию и сравниваем её с тем что есть в Graphite и сравниваем, насколько требования соответствуют доступности наших сервисов.

            Идем далее: алертинг. Он организован с помощью сильной системы — Moira. Она независимая потому, что у нее под капотом — свой собственный Graphite. Разработана ребятами из СКБ контура, написана на python и Go, полностью опенсорсная. Moira получает в себя весь тот же поток, что уходит в графиты. Если по какой-то причине у вас умрет хранилище, то ваш алертинг будет работать.

            Moira мы развернули в Kubernetes, в качестве основной базы данных она использует кластер Redis-серверов. В итоге получилась отказоустойчивая система. Она сравнивает поток метрик со списком триггеров: если в нем нет упоминаний, то дропает метрику. Так она способна переварить гигабайты метрик в минуту.

            Еще мы к ней прикрутили корпоративный LDAP, с помощью которого каждый пользователь корпоративной системы может создавать для себя нотификации по существующим (или вновь созданным) триггерам. Так как Moira содержит в себе Graphite, она поддерживает все его функции. Поэтому вы сначала берете строчку и копируете ее в Grafana. Смотрите, как отображаются данные на графиках. А потом берете эту же строчку и копируете ее в Moira. Обвешиваете ее лимитами и получаете на выходе алертинг. Чтобы все это делать, вам не нужны никакие специфические знания. Moira умеет алертить по смс, email, в Jira, Slack… Также она поддерживает выполнение кастомных скриптов. Когда у нее случается триггер, и она подписана на кастомный скрипт или бинарник, она его запускает, и отдает на stdin этому бинарнику JSON. Соответственно, ваша программа должна его распарсить. Что вы будете с этим JSONом делать — решайте сами. Хотите — отправляйте в Telegram, хотите — открывайте таски в Jira, делайте что угодно.

            У нас для алертинга используется ещё и собственная разработка — Imagotag. Мы адаптировали панель, которая применяется обычно для электронных ценников в магазинах, под наши задачи. Мы вывели на нее триггеры из Moira. Там указано, в каком они состоянии, когда произошли. Часть ребят из разработки отказались от уведомлений в Slack и в почту в пользу вот этой панельки.

            Ну и так как мы — прогрессивная компания, то замониторили в этой системе еще и Kubernetes. Включили его в систему с помощью Heapster, который мы установили в кластер, он собирает данные и отправляет их в Graphite. В итоге схема выглядит вот так:

            Компоненты мониторинга

            Вот список ссылок на те компоненты, которые мы использовали для этой задачи. Все они — опенсорсные.

            Graphite:


            Carbon-c-relay:


            http://ift.tt/2kK9FwW

            Brubeck:


            http://ift.tt/1BJUAiW

            Collectd:


            collectd.org

            Moira:


            http://ift.tt/2vVBw3u

            Grafana:


            grafana.com

            Heapster:


            http://ift.tt/2vVo3ZA

            Статистика


            И вот немного цифр о том, как система работает у нас.

            Aggregator (brubeck)


            Количество метрик: ~ 300 000 / sec
            Интервал отправки метрик в Graphite: 30 sec
            Использование ресурсов сервера: ~ 6% CPU (речь идет о полноценных серверах); ~ 1Gb DDR; ~ 3 Mbps LAN

            Graphite (go-carbon)


            Количество метрик: ~ 1 600 000 / min
            Интервал обновления метрик: 30 sec
            Схема хранения метрик: 30sec 35d, 5min 90d, 10min 365d (дает понимание что происходит с сервисом на продолжительном этапе времени)
            Использование ресурсов сервера: ~ 10% CPU; ~ 20Gb DDR; ~ 30 Mbps LAN

            Гибкость


            Мы в Avito очень ценим в нашем сервисе мониторинга гибкость. Почему, он собственно получился таким? Во первых, его составные части взаимозаменяемы: как сами компоненты, так и их версии. Во-вторых — поддерживаемость. Так как весь проект построен на опенсорсе, вы сами можете править код, вносить изменения, можете реализовывать функции, недоступные из коробки. Используются достаточно распространенные стеки, в основном, Go и Python, поэтому это делается достаточно просто.

            Вот пример реально возникшей проблемы. Метрика в Graphite — это файл. У него есть название. Имя файла = имя метрики. И есть путь до него. Названия файлов в Linux ограничены 255 символами. А у нас есть (в качестве “внутренних заказчиков”) ребята из отдела баз данных. Они нам говорят: “Мы хотим мониторить наши SQL-запросы. А они — не 255 символов, а 8 МБ каждый. Мы их хотим отображать в Grafana, видеть параметры по этому запросу, а еще лучше, мы хотим видеть топ таких запросов. Будет здорово, если он будет отображаться в реальном времени. А совсем круто было бы запихнуть их в алертинг”.


            Пример SQL-запроса взят в качестве примера с сайта postgrespro.ru

            Мы поднимаем сервер Redis и нашими Collectd-плагинами, которые ходят в Postgres и берут оттуда все данные, отправляем метрики в Graphite. Но заменяем имя метрики на хэши. Этот же хэш одновременно отправляем в Redis в качестве ключа, и весь SQL-запрос в качестве значения. Нам осталось сделать так, чтобы Grafana умела ходить в Redis и брать эту информацию. Мы открываем Graphite API, т.к. это основной интерфейс взаимодействия всех компонентов мониторинга с графитом, и вписываем туда новую функцию, которая называется aliasByHash() — от Grafana получаем имя метрики, и используем его в запросе к Redis как ключ, в ответ получаем значение ключа, которым является наш “SQL запрос”. Таким образом, мы вывели в Grafana отображение SQL-запроса, который по идее отобразить там было никак нельзя, вместе со статистикой по нему (calls, rows, total_time, ...).

            Итоги


            Доступность. Наш сервис мониторинга доступен 24 на 7 из любого аппликейшна и любого кода. Если у вас есть доступ к хранилищам, вы можете писать в сервис данные. Язык неважен, решения не важны. Вам нужно только знать как открыть сокет, закинуть туда метрику и закрыть сокет.

            Надежность. Все компоненты отказоустойчивы и справляются с нашими нагрузками хорошо.

            Низкий порог вхождения. Для того, чтобы пользоваться этой системой, вам не надо изучать языки программирования и запросы в Grafana. Просто открываете ваше приложение, вписываете в него сокет, который будет отправлять метрики в Graphite, закрываете его, открываете Grafana, создаете там дэшборды и смотрите на поведение ваших метрик, получая уведомления через Moira.

            Самостоятельность. Все это можно делать самим, без использования DevOps. И это оверфича, потому что вы можете мониторить свой проект прямо сейчас, никого не надо просить — ни для начала работы, ни для изменений.

            К чему мы стремимся?


            Все перечисленное ниже — это не просто абстрактные мысли, а то, к чему сделаны хотя бы первые шаги.
            1. Детектор аномалий. Хотим запилить у себя сервис, который будет ходить в наши Graphite-хранилища и каждую метрику проверять по различным алгоритмам. Уже есть алгоритмы, которые мы хотим просматривать, есть данные, мы умеем с ними работать.
            2. Метаданные. У нас много сервисов, со временем они меняются, так же как и люди, которые с ними работают. Постоянно вести документацию вручную — не вариант. Поэтому сейчас в наши микросервисы встраиваются метаданные. Там прописано, кто его разработал, языки, с которыми он взаимодействует, требования по SLA, куда и кому высылать нотификации. При деплое сервиса все данные сущности создаются самостоятельно. В итоге вы получаете две ссылки — одна на триггеры, другая — на дэшборды в Grafana.
            3. Мониторинг в каждый дом. Мы считаем, что подобной системой должны пользоваться все разработчики. В этом случае вы всегда понимаете, где ваш трафик, что с ним происходит, где он падает, где у него слабые места. Если, допустим, придёт нечто и завалит ваш сервис, то вы узнаете об этом не во время звонка от менеджера, а от алерта, и сразу сможете открыть свежие логи и посмотреть, что там произошло.
            4. Высокая производительность. Наш проект постоянно растет, и сегодня в нём обрабатывается около 2 000 000 значений метрик в минуту. Год назад этот показатель составлял 500 000. А рост продолжается, и это значит, что через какое-то время Graphite (whisper) начнет очень сильно нагружать дисковую подсистему. Как я уже говорил, эта система мониторинга довольно универсальна за счёт взаимозаменяемости компонентов. Кто-то специально под Graphite обслуживает и постоянно расширяет свою инфраструктуру, но мы решили пойти другим путем: использовать ClickHouse в качестве хранилища наших метрик. Этот переход практически завершен, и совсем скоро я расскажу поподробнее, как это было сделано: какие были трудности и как они были преодолены, как проходил процесс миграции, опишу выбранные в качестве обвязки компоненты и их конфигурации.

            Спасибо за внимание! Задавайте свои вопросы по теме, постараюсь ответить здесь или в следующих постах. Возможно, у кого-то есть опыт построения подобной системы мониторинга или перехода на Clickhouse в сходной ситуации — делитесь им в комментариях.

            Комментарии (0)

              Let's block ads! (Why?)

              [Перевод] Аутентификация в Node.js. Учебные руководства и возможные ошибки

              Однажды я отправился на поиск учебных руководств по аутентификации в Node.js/Express.js, но, к сожалению, не смог найти ни одного, которое меня бы полностью устроило. Некоторые были неполными, некоторые содержали ошибки в сфере безопасности, вполне способные навредить неопытным разработчикам.

              Сразу скажу, что я всё ещё нахожусь в поиске надёжного, всеобъемлющего решения для аутентификации в Node/Express, которое способно составить конкуренцию Devise для Rails. Однако, удручающая ситуация в сфере руководств подвигла меня на подготовку этого материала. Тут я разберу некоторые наиболее распространённые ошибки в области аутентификации и расскажу о том, как их избежать.

              image

              Выше я говорил о «неопытных разработчиках». Кто они? Например — это тысячи фронтенд-программистов, брошенных в водоворот серверного JS, которые пытаются набраться практического опыта из руководств, либо просто копипастят всё, что попадётся под руку и устанавливают всё подряд с помощью npm install. Почему бы им не вложить время в серьёзное изучение вопроса? Дело в том, что они копипастят не от хорошей жизни, им приходится из кожи вон лезть, чтобы уложиться в сроки, установленные аутсорс-менеджерами, или кем-то вроде креативных директоров рекламных агентств.

              На самом деле, пока я искал подходящее руководство по аутентификации, я проникся ощущением, что каждый Node-программист, у которого есть блог, опубликовал собственный тьюториал, посвящённый тому, как «делать это правильно», или, точнее, о том, «как это делается».

              Ещё одна неоднозначная вещь в разработке для Node.js заключается в отсутствии некоего всеобъемлющего, надёжного решения для аутентификации. Этот вопрос, в основном, рассматривается в качестве чего-то вроде упражнения для программиста. Стандартом де-факто для Express.js является Passport, однако, это решение предлагает лишь набор стратегий аутентификации. Если вам нужно надёжное решение для Node, вроде Platformatec Devise для Ruby on Rails, вам, вероятно, придётся обратиться к Auth0 — стартапу, который предлагает аутентификацию как сервис.

              Passport, в отличие от полномасштабного Devise, представляет собой промежуточный программный слой, который, сам по себе, не охватывает все части процесса аутентификации. Используя Passport, Node-разработчику придётся создать собственное API для механизма токенов и для сброса пароля. Ему придётся подготовить маршруты и конечные точки аутентификации пользователей. На нём же лежит и создание интерфейсов с использованием, например, некоего популярного языка шаблонов. Именно поэтому существует множество учебных руководств, которые направлены на помощь в установке Passport для Express.js-приложений. Практически все они содержат те или иные ошибки. Ни одно из них не позволяет создать полномасштабное решение, необходимое для работающего веб-приложения.

              Хотелось бы отметить, что я не собираюсь нападать на конкретных создателей этих руководств, скорее я использую их ошибки для того, чтобы продемонстрировать проблемы с безопасностью, связанные с развёртыванием ваших собственных систем аутентификации. Если вы — автор подобного руководства — дайте мне знать, если после чтения этого материала внесёте в своё руководство правки. Сделаем экосистему Node/Express безопаснее и доступнее для новых разработчиков.

              Ошибка первая: хранилище учётных данных


              Начнём с хранилища учётных данных. Запись и чтение учётных данных — это вполне обычные задачи в сфере управления аутентификацией, и традиционный способ решения этих задач заключается в использовании собственной базы данных. Passport является промежуточным программным обеспечением, которое просто сообщает нашему приложению: «этот пользователь прошёл проверку», или: «этот пользователь проверку не прошёл», требуя модуля passport-local для работы с хранилищем паролей в локальной базе данных. Этот модуль написан тем же разработчиком, что и сам Passport.js.

              Прежде чем мы спустимся в эту кроличью нору учебных руководств, вспомним об отличной шпаргалке по хранению паролей, подготовленной OWASP, которая сводится к тому, что нужно хранить высокоэнтропийные пароли с уникальной «солью» и c применением односторонних адаптивных функций хэширования. Тут можно вспомнить и bcrypt-мем с codahale.com, даже несмотря на то, что по данному вопросу имеются некоторые разногласия.

              Я, в поиске того, что мне нужно, повторяя путь нового пользователя Express.js и Passport, сначала заглянул в примеры к самому passport-local. Там оказался шаблон приложения Express 4.0., который я мог скопировать и расширить под свои нужды. Однако, после простого копирования этого кода, я получал не так уж и много полезностей. Например, здесь не оказалось подсистемы поддержки базы данных. Пример подразумевал простое использование некоторого набора аккаунтов.

              На первый взгляд всё вроде бы нормально. Перед нами — обычное интранет-приложение. Разработчик, который воспользуется им, загружен донельзя, у него нет времени что-то серьёзно улучшать. Неважно, что пароли в примере не хэшируются. Они хранятся в виде обычного текста прямо рядом с кодом логики валидации. А хранилище учётных данных здесь даже не рассматривается. Чудная получится система аутентификации.

              Поищем ещё одно учебное руководство по passport-local. Например, мне попался этот материал от RisingStack, который входит в серию руководств «Node Hero». Однако, и эта публикация мне совершенно не помогла. Она тоже давала пример приложения на GitHub, но имела те же проблемы, что и официальное руководство. Тут, однако, надо отметить, что 8-го августа стало известно о том, что RisingStack теперь использует bcrypt в своём демонстрационном приложении.

              Далее, вот ещё один результат из Google, выданный по запросу express js passport-local tutorial. Руководство написано в 2015-м. Оно использует Mongoose ODM и читает учётные данные из базы данных. Тут есть всё, включая интеграционные тесты, и, конечно, ещё один шаблон, который можно использовать. Однако, Mongoose ODM хранит пароли, используя тип данных String, как и в предыдущих руководствах, в виде обычного текста, только на этот раз в экземпляре MongoDB. А всем известно, что экземпляры MongoDB обычно очень хорошо защищены.

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

              Возьмём теперь материал с самого верха страницы результатов поиска — руководство по passport-local от TutsPlus. Это руководство лучше, тут используют bcrypt с коэффициентом трудоёмкости 10 для хэширования паролей и замедляют синхронные проверки хэша, используя process.nextTick.

              Самый верхний результат в Google, это руководство от scotch.io, в котором так же используется bcrypt с меньшим коэффициентом трудоёмкости, равным 8. И 8, и 10 — это мало, но 8 — это очень мало. Большинство современных bcrypt-библиотек используют 12. Коэффициент трудоёмкости 8 был хорош для административных учётных записей восемнадцать лет назад, сразу после выпуска первой спецификации bcrypt.

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

              Ошибка вторая: система сброса паролей


              Схожая проблема в области безопасности — сброс пароля. Ни одно из руководств, находящихся в верхней части поисковой выдачи, совершенно ничего не говорит о том, как делать это с использованием Passport. Чтобы это узнать, придётся искать что-то другое.

              В деле сброса пароля есть тысячи способов всё испортить. Вот наиболее распространённые ошибки в решении этой задачи, которые мне довелось видеть:

              1. Предсказуемые токены. Токены, основанные на текущем времени — хороший пример. Токены, построенные на базе плохого генератора псевдослучайных чисел, хотя и выглядят лучше, проблему не решают.
              2. Неудачное хранилище данных. Хранение незашифрованных токенов сброса пароля в базе данных означает, что если она будет взломана, эти токены равносильны паролям, хранящимся в виде обычного текста. Создание длинных токенов с помощью криптографически стойкого генератора псевдослучайных чисел позволяет предотвратить удалённые атаки на токены сброса пароля методом грубой силы, но не защищает от локальных атак. Токены для сброса пароля следует воспринимать как учётные данные и обращаться с ними соответственно.
              3. Токены, срок действия которых не истекает. Если срок действия токенов не истекает, у атакующего есть время для того, чтобы воспользоваться временным окном сброса пароля.
              4. Отсутствие дополнительных проверок. Дополнительные вопросы при сбросе пароля — это стандарт верификации данных де-факто. Конечно, это работает как надо лишь в том случае, если разработчики выбирают хорошие вопросы. У подобных вопросов есть собственные проблемы. Тут стоит сказать и об использовании электронной почты для восстановления пароля, хотя рассуждения об этом могут показаться излишней перестраховкой. Ваш адрес электронной почты — это то, что у вас есть, а не то, что вы знаете. Он объединяет различные факторы аутентификации. Как результат, адрес почты становится ключом к любой учётной записи, которая просто отправляет на него токен сброса пароля.

              Если вы со всем этим никогда не сталкивались, взгляните на шпаргалку по сбросу паролей, подготовленную OWASP. Теперь, обсудив общие вопросы, перейдём к конкретике, посмотрим, что может предложить экосистема Node.

              Ненадолго обратимся к npm и посмотрим, сделал ли кто-нибудь библиотеку для сброса паролей. Вот, например, пакет пятилетней давности от в целом замечательного издателя substack. Учитывая скорость развития Node, этот пакет напоминает динозавра, и если бы мне хотелось попридираться к мелочам, то я мог бы сказать, что функция Math.random()предсказуема в V8, поэтому её не следует использовать для создания токенов. Кроме того, этот пакет не использует Passport, поэтому мы идём дальше.

              Stack Overflow здесь тоже особенно не помог. Как оказалось, разработчики из компании Stormpath любят писать о своём IaaS-стартапе в любом посте, хоть как-то связанным с этой темой. Их документация тоже всплывает повсюду, они также продвигают свой блог, где есть материалы по сбросу паролей. Однако, чтение всего этого — пустая трата времени. Stormpath — проект нерабочий, 17 августа 2017-го он закрывается.

              Ладно, возвращаемся к поиску в Google. На самом деле, такое ощущение, что интересующая нас тема раскрыта в единственном материале. Возьмём первый результат, найденный по запросу express passport password reset. Тут снова встречаем нашего старого друга bcrypt, с даже меньшим коэффициентом трудоёмкости, равным 5, что значительно меньше, чем нужно в современных условиях.

              Однако, это руководство выглядит довольно-таки целостным по сравнению с другими, так как оно использует crypto.randomBytes для создания по-настоящему случайных токенов, срок действия которых истекает, если они не были использованы. Однако, пункты 2 и 4 из вышеприведённого списка ошибок при сбросе пароля в этом серьёзном руководстве не учтены. Токены хранятся ненадёжно — вспоминаем первую ошибку руководств по аутентификации, связанную с хранением учётных данных.

              Хорошо хотя бы то, что украденные из такой системы токены имеют ограниченный срок действия. Однако, работать с этими токенами очень весело, если у атакующего есть доступ к объектам пользователей в базе данных через BSON-инъекцию, или есть свободный доступ к Mongo из-за неправильной настройки СУБД. Атакующий может просто запустить процесс сброса пароля для каждого пользователя, прочитать незашифрованные токены из базы данных и создать собственные пароли для учётных записей пользователей, вместо того, чтобы заниматься ресурсоёмкой атакой по словарю на хэши bcrypt с использованием мощного компьютера с несколькими видеокартами.

              Ошибка третья: токены API


              Токены API — это тоже учётные данные. Они так же важны, как пароли и токены сброса паролей. Практически все разработчики знают это и стараются очень надёжно хранить свои ключи AWS, коды доступа к Twitter и другие подобные вещи, однако, к программам, которые они пишут, это часто не относится.

              Воспользуемся системой JSON Web Tokens (JWT) для создания учётных данных доступа к API. Применение токенов без состояния, которые можно добавлять в чёрные списки и нужно запрашивать, это лучше, чем старый шаблон API key/secret, который использовался в последние годы. Возможно, наш начинающий Node.js-разработчик где-то слышал о JWT, или даже видел пакет passport-jwt и решил реализовать в своём проекте стратегию JWT. В любом случае, JWT — это то место, где кажется, что все попадают в сферу влияния Node.js. (Почтенный Томас Пташек заявит, что JWT — это плохо, но я сомневаюсь, что его кто-нибудь услышит).

              Поищем по словам express js jwt в Google и откроем первый материал в поисковой выдаче, руководствоСони Панди об аутентификации пользователей с применением JWT. К несчастью, этот материал нам ничем не поможет, так как в нём не используется Passport, но пока мы на него смотрим, отметим некоторые ошибки в хранении учётных данных:

              1. Ключи JWT хранятся в виде обычного текста в GitHub-репозитории.
              2. Для хранения паролей используется симметричный шифр. Это означает, некто может завладеть ключом шифрования и расшифровать все пароли. К тому же, тут наблюдаются неправильные взаимоотношения между ключом шифрования и секретным ключом JWT.
              3. Здесь, для шифрования данных в хранилище паролей, используется алгоритм AES-256-CTR. AES вообще не стоит использовать, и данный его вариант ничего не меняет. Я не знаю, почему был выбран именно этот алгоритм, но только одно это делает зашифрованные данные уязвимыми.

              Да уж… Вернёмся к Google и поищем ещё руководств. Ресурс scotch.io, который, в руководстве по passport-local, проделал замечательную работу, касающуюся хранилища паролей, просто игнорирует свои же идеи и хранит пароли в новом примере в виде обычного текста.

              Однако, я решил дать этому руководству шанс, хотя его нельзя рекомендовать любителям копипастить. Это из-за одной интересной особенности, которая заключается в том, что тут выполняется сериализация объекта пользователя Mongoose в JWT.

              Клонируем репозиторий этого руководства, следуя инструкциям развернём и запустим приложение. После нескольких DeprecationWarning от Mongoose можно будет перейти на http://localhost:8080/setup и создать пользователя. Затем, отправив на /api/authenticate учётные данные — «Nick Cerminara» и «password», мы получим токен, Просмотрим его в Postman.


              JWT-токен, полученный из программы, описанной в руководстве scotch.io

              Обратите внимание на то, что JWT-токен подписан, но не зашифрован. Это означает, что большой фрагмент двоичных данных между двумя точками — это объект в кодировке Base64. По-быстрому его раскодируем и перед нами откроется кое-что интересное.


              Что может быть лучше пароля в виде обычного текста

              Теперь любой, у кого есть токен, даже такой, срок действия которого истёк, имеет пароль пользователя, а заодно и всё остальное, что хранится в модели Mongoose. Учитывая то, что токен передаётся по HTTP, завладеть им можно с помощью обычного сниффера.

              Как насчёт ещё одного руководства? Оно рассчитано на новичков и посвящено аутентификации с использованием Express, Passport и JWT. В нём наблюдается та же уязвимость, связанная с раскрытием информации. Следующее руководство, подготовленное стартапом SlatePeak, выполняет такую же сериализацию. На данном этапе я прекратил поиски.

              Ошибка четвёртая: ограничение числа попыток аутентификации


              Я не нашёл упоминаний об ограничении числа попыток аутентификации или о блокировке аккаунта ни в одном из рассмотренных руководств.

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

              Помните о том, что ограничение числа попыток аутентификации способствует доступности сервиса. Так, использование bcrypt создаёт серьёзную нагрузку на процессор. Без ограничений, функции, в которых вызывают bcrypt, становятся вектором отказа в обслуживании уровня приложения, особенно при использовании высоких значений коэффициента трудоёмкости. В результате обработка множества запросов на регистрацию пользователей или на вход в систему с проверкой пароля создаёт высокую нагрузку на сервер.

              Хотя подходящего учебного руководства на эту тему у меня нет, есть множество вспомогательных библиотек для ограничения числа запросов, таких, как express-rate-limit, express-limiter, и express-brute. Не могу говорить об уровне безопасности этих модулей, я их даже не изучал. В целом, я порекомендовал бы использовать в рабочих системах обратный прокси и передавать обработку ограничения числа запросов nginx или любому другому балансировщику нагрузки.

              Итоги: аутентификация — задача непростая


              Скорее всего авторы учебных руководств будут защищать себя со словами: «Это лишь объяснение основ! Уверены, никто не будет использовать этого в продакшне!». Однако, я не могу не указать на то, что эти слова не соответствуют действительности. Это особенно справедливо, если к учебным руководствам прилагается код. Люди верят словам авторов руководств, у которых гораздо больше опыта, чем у тех, кто руководства читает.

              Если вы — начинающий разработчик — не доверяйте учебным руководствам. Копипастинг кода из таких материалов, наверняка, приведёт вас, вашу компанию, и ваших клиентов, к проблемам в сфере Node.js-аутентификации. Если вам действительно нужны надёжные, готовые к использованию в продакшне, всеобъемлющие библиотеки для аутентификации, взгляните на что-то, чем вам удобно будет пользоваться, на что-то, что обладает большей стабильностью и лучше испытано временем. Например — на связку Rails/Devise.

              Экосистема Node.js, несмотря на свою доступность, всё ещё таит множество опасностей для JS-разработчиков, которым нужно срочно написать веб-приложение для решения реальных задач. Если ваш опыт ограничивается фронтендом, и ничего кроме JavaScript вы не знаете, лично я уверен в том, что легче взять Ruby и встать на плечи гигантов, вместо того, чтобы быстро научиться тому, как не отстрелить себе ногу, программируя подобные решения с нуля для Node.

              Если вы — автор учебного руководства, пожалуйста, обновите его, в особенности это касается шаблонного кода. Этот код попадёт в продакшн.

              Если вы — убеждённый Node.js-разработчик, надеюсь, вы нашли в моём рассказе что-нибудь полезное, касающееся того, чего лучше не делать в вашей системе аутентификации, основанной на Passport. Наверняка, если такая система у вас уже есть, что-то в ней сделано неправильно. Я не говорю о том, что мой материал покрывает все возможные ошибки аутентификации. Создание системы аутентификации для Express-приложения — это задача разработчика, который понимает все тонкости конкретного проекта. В результате получиться у него должно что-то качественное и надёжное. Если вы хотите обсудить вопросы защиты веб-приложений на Node.js — отправьте мне сообщение в Twitter.
              Автор публикации сообщает, что 7-го августа, с ним связались представители RisingStack. Они сообщили о том, что в их учебных руководствах пароли больше не хранятся в виде обычного текста. Теперь в коде и руководствах они используют bcrypt.

              Кроме того, он, вдохновлённый откликами на свой материал, создал этот документ, в котором намеревается собрать всё лучшее из области аутентификации в Node.js.

              Уважаемые читатели! Что вы можете сказать об организации системы аутентификации в веб-приложениях, основанных на Node.js?

              Комментарии (0)

                Let's block ads! (Why?)

                Узники системы

                OpenDataScience и Mail.Ru Group проведут открытый курс по машинному обучению

                6 сентября 2017 года стартует 2 запуск открытого курса OpenDataScience по анализу данных и машинному обучению. На этот раз будут проводиться и живые лекции, площадкой выступит московский офис Mail.Ru Group.



                Если коротко, то курс состоит из серии статей на Хабре (вот первая), воспроизводимых материалов (Jupyter notebooks, вот github-репозиторий курса), домашних заданий, соревнований Kaggle Inclass, тьюториалов и индивидуальных проектов по анализу данных. Здесь можно записаться на курс, а тут — вступить в сообщество OpenDataScience, где будет проходить все общение в течение курса (канал #mlcourse_open в Slack ODS). А если поподробней, то это вам под кат.


                План статьи



                В чем особенность курса



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


                Большой плюс именно этого курса — активная жизнь на форуме (Slack сообщества OpenDataScience). В двух словах, OpenDataScience — это крупнейшее русскоязычное сообщество DataScientist-ов, которое делает множество классных вещей, в том числе организует Data Fest. При этом сообщество активно живет в Slack’e, где любой участник может найти ответы на свои DS-вопросы, найти единомышленников и коллег для проектов, найти работу и т.д. Для открытого курса создан отдельный канал, в котором 3-4 сотни людей, изучающих то же, что и ты, помогут в освоении новых тем.


                Выбирая формат подачи материала, мы остановились на статьях на Хабре и тетрадках Jupyter. Теперь еще добавятся "живые" лекции и их видеозаписи.


                На кого рассчитан курс и как к нему подготовиться


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


                Если вам не хватает знаний или скиллов, то в первой статье серии мы описываем, как повторить математику и освежить (либо приобрести) навыки программирования на Python.


                Да, еще не помешает знание английского, а также хорошее чувство юмора.



                Что в себя включает курс


                Статьи


                Мы сделали ставку на Хабр и подачу материала в форме статьи. Так можно в любой момент быстро и легко найти нужную часть материала. Статьи уже готовы, за сентябрь-ноябрь они будут частично обновлены, а также добавится еще одна статья про градиентный бустинг.


                Список статей серии:


                1. Первичный анализ данных с Pandas
                2. Визуальный анализ данных c Python
                3. Классификация, деревья решений и метод ближайших соседей
                4. Линейные модели классификации и регрессии
                5. Композиции: бэггинг, случайный лес
                6. Построение и отбор признаков. Приложения в задачах обработки текста, изображений и геоданных
                7. Обучение без учителя: PCA, кластеризация
                8. Обучение на гигабайтах c Vowpal Wabbit
                9. Анализ временных рядов с помощью Python
                10. Градиентный бустинг

                Лекции


                Лекции будут проходить в московском офисе Mail.Ru Group по средам с 19.00 до 22.00, с 6 сентября по 8 ноября. На лекциях будет разбор теории в целом по тому же плану, что описан в статье. Но также будут разборы задач лекторами вживую, а последний час каждой лекции будет посвящен практике — слушатели сами будут анализировать данные (да, прямо писать код), а лекторы — помогать им в этом. Посетить лекцию смогут топ-30 участников курса по текущему рейтингу. На рейтинг будут влиять домашние задания, соревнования и проекты по анализу данных. Также будут организованы трансляции лекций.



                Лекторы:


                • Юрий Кашницкий. Программист-исследователь Mail.Ru Group и старший преподаватель факультета компьютерных наук ВШЭ, а также преподаватель в годовой программе дополнительного образования по анализу данных в ВШЭ.
                • Алексей Натекин. Основатель сообщества OpenDataScience и DM Labs, Chief Data Officer в Diginetica. В прошлом — глава отдела аналитики Deloitte. Идейный лидер сообщества OpenDataScience, организатор DataFest.
                • Дмитрий Сергеев. Data Scientist в Zeptolab, лектор в Центре Математических Финансов МГУ.

                Про всех авторов статей курса при желании можно прочитать здесь.


                Домашние задания


                Каждая из 10 тем сопровождается домашним заданием, на которое дается 1 неделя. Задание — в виде тетрадки Jupyter, в которую надо дописать код и на основе этого выбрать правильный ответ в форме Google. Домашние задания — это первое, что начнет влиять на рейтинг участников курса и, соответственно, на то, кто сможет вживую посещать лекции.


                Сейчас в репозитории курса вы можете видеть 10 домашних заданий с решениями. В новом запуске курса домашние задания будут новыми.


                Тьюториалы


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


                Соревнования Kaggle Inclass



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


                • Идентификация взломщика по его поведению в сети Интернет. Имелись реальные данные о посещении пользователями различных сайтов, и надо было по последовательности из посещенных за 30 минут сайтов понять, была ли это некто Элис или кто-то другой.
                • Прогноз популярности статьи на Хабре. В этом задании по тексту, времени и прочим признакам публикации на Хабре надо было предсказать популярность этой статьи — число добавлений в избранное.

                Индивидуальные проекты



                Из паблика Вконтакте "Мемы про машинное обучение для взрослых мужиков".


                Курс рассчитан на 2.5 месяца, а активностей запланировано немало. Но обязательно рассмотрите возможность выполнить собственный проект по анализу данных, от начала до конца, по плану, предложенному преподавателями, но с собственными данными. Проекты можно обсуждать с коллегами, а по окончании курса будет устроена peer-review проверка проектов.
                Подробности про проекты будут позже, а пока вы можете подумать, какие бы данные вам взять, чтобы "что-то для них прогнозировать". Но если идей не будет, не страшно, мы посоветуем какие-нибудь интересные задачи и данные для анализа, причем они могут быть разными по уровню сложности.


                Как мне записаться на курс?


                Для участия в курсе заполните этот опрос, а также вступите в сообщество OpenDataScience (в графе "Откуда вы узнали об OpenDataScience?" ответьте "mlcourse_open"). В основном общение в течение курса будет проходить в Slack OpenDataScience в канале #mlcourse_open.


                Как прошел первый запуск курса


                Первый запуск прошел с февраля по июнь 2017 года, записалось около тысячи человек, первую домашку сделали 520, а последнюю — 150 человек. Жизнь на форуме просто кипела, в соревнованиях Kaggle было сделано несколько тысяч посылок, участники курса написали с десяток тьюториалов. И, судя по отзывам, получили отличный опыт, с помощью которого дальше можно окунаться в нейронные сети, соревнования на Kaggle или в теорию машинного обучения.


                Бонусом для топ-100 финалистов курса был митап в московском офисе Mail.Ru Group, на котором было 3 лекции по актуальным в современном DS темам:


                • Обработка больших данных при помощи Apache Spark (Виталий Худобахшов, "Одноклассники"). Видео: часть1, часть2;
                • Основы нейронных сетей и Deep Learning (Алексей Озерин, Reason8.ai), видео;
                • Deep Learning в решении задач сентимент анализа (Виталий Радченко, Ciklum), видео.

                Бонус: совместное прохождение курса cs231n


                И последнее, чем пока порадуем: с середины ноября 2017 года, сразу по окончании вводного курса по машинному обучению, там же в канале #mlcourse_open в Slack ODS будем вместе проходить один из лучших курсов по нейронным сетям — стэнфордский курс cs231n “Convolutional Neural Networks for Visual Recognition”.


                Успехов вам в изучении этой прекрасной дисциплины — машинного обучения! И вот эти два товарища тут — для мотивации.



                Andrew Ng берет интервью у Andrej Karpathy в рамках специализации по Deep Learning.

                Комментарии (0)

                  Let's block ads! (Why?)