Магазин открыл 110 000 банковских карт своих покупателей и 6 месяцев не хотел закрывать уязвимость

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

В ноябре 2016 года компании специалисты по безопасности из Kromtech Security Research Center обнаружили базу данных с полной информацией о покупателях одного из крупнейших онлайновых зоомагазинов в США — всего более 110 000 записей о банковских карточках, некоторые с кодами CVV.

Сотрудники Kromtech Security Research Center немедленно отправили владельцам магазина уведомление о неправильно сконфигурированной базе данных на сервере, из-за которой в онлайне всем желающим доступна информация из базы данных. Синхронизация данных между серверами магазина по протоколу Rsync осуществляется без пароля, то есть кто угодно с клиентом Rsync и подключением к интернету может скачать базу данных целиком.

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

Специалисты не нашли другого выхода, кроме как разгласить факт уязвимости, хотя не назвали конкретного названия компании и названия сайта. Впрочем, шила в мешке не утаишь, и коллеги быстро раскопали, что речь идёт о техасском магазине FuturePets.com (в данный момент сервер отключен, выдаёт HTTP Error 404). Магазин разработан техасской веб-студией DataWeb Inc., которая разработала много других похожих сайтов с товарами для животных. Портфолио представлено у них на главной странице. Вполне вероятно, что на этих сайтах можно искать аналогичные уязвимости. Компания DataWeb владеет платёжной платформой PegasusCart. Эта платформа обслуживает сайты магазинов, разработанных DataWeb.

Представители MacKeeper предупреждают, что за подобное безалаберное обращение с финансовыми данными клиентов компания не только рискует репутацией, но и несёт конкретную юридическую ответственность. Они нарушают Стандарт безопасности данных в индустрии платёжных карт (PCI DSS). За его нарушение предусмотрено наказание. Кроме того, что финансовая информация не защищена должным образом, нарушено ещё одно правило: номера CVC, CVV и CVV2 не должны храниться в системе, даже в зашифрованном виде. Об этом ясно сказано в пунктах 3.2 и 3.4 стандарта PCI DSS.


В базе 193 337 записей, содержащих имена, адреса, почтовые адреса и другие идентификационные данные о покупателях, телефоны, номера банковских карточек, сроки действия карточек, имена владельцев карт и т. д. Хотя в базе нет поля CVV как такового, но некоторые поля содержат этот код, вероятно, по ошибке.

Общее количество доступных банковских карт — 110 429. В базе присутствуют записи с 2002 года, так что большое количество карт уже с истёкшим сроком действия, но есть много карт, добавленных в 2015 и 2016 годах, в некоторых случаях с кодами CVV.

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

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

В интернете есть способы обналичить деньги с чужой карты даже без знания CVV, только по номеру из 16 цифр, имени владельца и сроку действия. Например, таким образом можно оплачивать номера в гостиницах, покупать товары на Amazon и в других магазинах (лучше всего покупать гифт-карты, которые анонимны и их потом легко продать). Так что утечка действительно серьёзная

Специалисты по безопасности говорят, что именно сайты небольших интернет-магазинов сейчас стали самой привлекательной мишенью для взломов по сочетанию выгоды и лёгкости взлома. У них просто меньше ресурсов и квалификации, чтобы защититься. Согласно опросу SecurityMagazine, только 31% представителей малого бизнеса «предприняли активные действия для защиты от взломов системы безопасности, а 41% вообще не осведомлены о таких рисках». Похоже, за неосведомлённость кое-кому придётся платить.
ссылка на оригинал статьи https://geektimes.ru/post/288726/

MeteorJS, Nginx, mongodb, iptables… продакшен

Здравствуйте, меня зовут Александр Зеленин, и я веб-разработчик сисадмин.

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

Разворачивать будем на Ubuntu 16, но, в целом, схема на 99% совпадает и для Debian 8.

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

В качестве файловой системы при установке выбираем XFS — монга с ней хорошо дружит.

Готовим SSH

Если доступ у нас рутовый, то первое что надо сделать — создать пользователя.

adduser zav # Используйте свой %username% вместо zav apt-get install sudo  usermod -aG sudo zav # Добавляем нашего пользователя в группу sudo,                       # что бы иметь возможность далее всё делать из-под него vi /etc/ssh/sshd_config # Если вы совсем не можете в vi — используйте тут nano вместо vi.                          # Если он не установлен — apt-get install nano

Нам надо изменить порт на случайный, по вашему выбору — это сразу защитит от части атак на ssh сервера.

Port 355 # Обычно изначально стоит Port 22 PermitRootLogin no # Запрещаем вход под рутом

Перезагружаем SSH

/etc/init.d/ssh restart

Теперь переподключаемся по SSH на новый порт (355) на нового, свежесозданного пользователя.

Подготавливаем второй диск и tmpfs (что бы разместить монгу в памяти)

Я использую 2 раздельных физических диска что бы минимизировать шанс отказа.
Вы можете размещать всё на 1 на свой страх и риск, схема от этого не изменится.
В этом случае можете точно так же использовать папку /secondary, но не монтировать в неё диск.

sudo cfdisk /dev/sdb # имя второго диска (sdb) может отличаться.                      # Выбираем создать новый, 100% места, запись sudo mkfs.xfs /dev/sdb1 # создаем ФС на втором диске sudo mkdir /secondary sudo vi /etc/fstab # делаем авто-монтирование при запуске системы

Добавляем в конец (если второго диска нет — первую строку опускаем)
tmpfs — файловая система будет расположена в оперативной памяти. Т.е. запись в раздел /data/inmemory будет делать запись в оперативную память, а не на диск. Надо понимать что при перезагрузке оно очищается. size задает размер данной области. Ваша задача что бы её хватило на размещение монги со всеми индексами. В моём случае оперативной памяти 128Gb, соответственно под tmpfs выделено 32 гигабайта.

/dev/sdb1       /secondary      xfs     defaults        0       2 tmpfs           /data/inmemory  tmpfs   size=25%        0       0

Ставим монгу, настраиваем реплику, подготавливаем реалтайм бекап

Актуальный способ установки можно посмотреть на официальном сайте.
В данном примере идёт установка версии 3.4 на Ubuntu 16.

Устанавливаем:

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6 echo "deb [ arch=amd64,arm64 ] http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list sudo apt-get update sudo apt-get install mongodb-org

Создаем папки, конфиги и ставим права:

sudo mkdir /data sudo mkdir /data/db sudo mkdir /data/inmemory sudo mkdir /secondary/data sudo mkdir /secondary/data/db sudo vi /data/mongod-memory.conf

Подход, в котором primary в памяти может быть опасен, т.к. в случае внезапного выключения питания данные, которые не успели перейти в реплики — теряются. В моём случае потеря 1-2 секунд не страшна, т.к. всё приложение пишется с учетом возможности восстановления из любой позиции. Финансовые данные пишутся с параметром, подтверждающим что данные уже есть на реплике (т.е. на диске).
Если ваше приложение к такому не готово — вы можете отказаться от memory раздела и делать всё классически. В целом для этого достаточно будет убрать монтирование tmpfs и немного изменить конфиг, сделав его схожим с mongod-sec-d1.conf

mongod-memory.conf — primary, in memory

processManagement:   fork: true    pidFilePath: "/data/inmemory/mongod.pid"  storage:   dbPath: "/data/inmemory"   journal:     enabled: false # Отключаем журналирование                    # т.к. в памяти в случае падения оно нас всё равно не спасёт   indexBuildRetry: true   wiredTiger:     engineConfig:       cacheSizeGB: 8 # Ограничиваем размер кеша.                       # Я, честно говоря, не уверен, но его можно убрать полностью,                      # т.к. это то, что монга для оптимизации поместить                       # в оперативную память, а данный инстанс уже весь в ней  systemLog:   destination: "file"   path: "/var/log/mongodb/mongodb.log" # Для всех экземпляров указываем один инстанс.                                        # Теоретически тут можно получить просадку,                                         # если монга в памяти начнёт писать                                        # на диск, но при нормальном функционировании                                         # эти события редки (ошибки, медленный запросы)   logAppend: true   quiet: false   verbosity: 0   logRotate: "reopen"   timeStampFormat: "iso8601-local"  net:   bindIp: 127.0.0.1 # Делаем монгу доступной только для локального интерфейса                     # в случае если настраиваем реалтайм бекап добавляем внешний интерфейс   port: 27000 # указываем на каких портах будем размещать,                # они должны быть разные для разных инстансов в пределах сервера   http:     enabled: false # отключаем доступ по http и прочим интерфейсам     JSONPEnabled: false     RESTInterfaceEnabled: false   ssl: # ssl нам тоже не нужен в данном случае     mode: disabled  security: # Мы будем настраивать корректный доступ по правам,            #что бы клиенты видели только то, что им надо   authorization: "enabled"   keyFile: "/data/mongod-keyfile" # Это ключ для общения реплик между собой   javascriptEnabled: false # Запрещаем исполнение JS в БД.  replication:   oplogSizeMB: 4096 # Указываем максимальный размер oplog'а.                      # случае падения реплик их восстановление будет быстрым                     # только если они отстали не более чем на размер oplog'a.                      # Корректный размер можно определить                     # в зависимости от приложения — как часто идёт изменение БД?   replSetName: "consulwar"   enableMajorityReadConcern: false # указываем что мы НЕ дожидаемся подтверждение                                     # от реплики на запись для возврата значений поиска.  operationProfiling:   slowOpThresholdMs: 30 # указываем сколько максимум может выполнятся запрос,                          # после чего будет считаться медленным                         # и записан в лог, для последующей ручной обработки   mode: "slowOp"

sudo vi /data/mongod-sec-d1.conf

mongod-sec-d1.conf — secondary, disk 1

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

processManagement:   fork: true   pidFilePath: "/data/db/mongod.pid"  storage:   dbPath: "/data/db"   journal:     enabled: true # Обращаем внимание что тут журнал уже включен,                    # диск у нас считается надёным источником   indexBuildRetry: true   wiredTiger:     engineConfig:       cacheSizeGB: 8 # Фактически, даже если по какой-то причине Primary упадёт,                       # secondary будет использовать память но только для чтения  systemLog:   destination: "file"   path: "/var/log/mongodb/mongodb.log"   logAppend: true   quiet: false   verbosity: 0   logRotate: "reopen"   timeStampFormat: "iso8601-local"  net:   bindIp: 127.0.0.1   port: 27001   http:     enabled: false     JSONPEnabled: false     RESTInterfaceEnabled: false   ssl:     mode: disabled  security:   authorization: "enabled"   keyFile: "/data/mongod-keyfile"   javascriptEnabled: false  replication:   oplogSizeMB: 4096   replSetName: "consulwar"   enableMajorityReadConcern: false  operationProfiling:   slowOpThresholdMs: 30   mode: "slowOp"

sudo vi /data/mongod-sec-d2.conf

mongod-sec-d2.conf — secondary, disk 2

Разница, по сути, только в пути до БД и в зависимости от используемого порта.

processManagement:   fork: true   pidFilePath: "/secondary/data/db/mongod.pid"  storage:   dbPath: "/secondary/data/db"   journal:     enabled: true   indexBuildRetry: true   wiredTiger:     engineConfig:       cacheSizeGB: 8  systemLog:   destination: "file"   path: "/var/log/mongodb/mongodb.log"   logAppend: true   quiet: false   verbosity: 0   logRotate: "reopen"   timeStampFormat: "iso8601-local"  net:   bindIp: 127.0.0.1   port: 27002   http:     enabled: false     JSONPEnabled: false     RESTInterfaceEnabled: false   ssl:     mode: disabled  security:   authorization: "enabled"   keyFile: "/data/mongod-keyfile"   javascriptEnabled: false  replication:   oplogSizeMB: 4096   replSetName: "consulwar"   enableMajorityReadConcern: false  operationProfiling:   slowOpThresholdMs: 30   mode: "slowOp"

Добавляем ключ для корректной работы реплики, устанавливаем права на папки

sudo openssl rand -base64 741 > ~/mongod-keyfile sudo mv mongod-keyfile /data/mongod-keyfile sudo chmod 600 /data/mongod-keyfile sudo chown mongodb:mongodb -R /data sudo chown mongodb:mongodb -R /secondary/data

Создаем скрипты автозапуска

sudo apt-get install numactl sudo mv /lib/systemd/system/mongod.service /lib/systemd/system/mongod@.service sudo vi /lib/systemd/system/mongod@.service

mongod@.service

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

[Unit] Description= Mongo Database on %i After=network.target  [Service] Type=forking ExecStartPre=/bin/sh -c '/bin/echo never > /sys/kernel/mm/transparent_hugepage/enabled' ExecStartPre=/bin/sh -c '/bin/echo never > /sys/kernel/mm/transparent_hugepage/defrag' User=mongodb Group=mongodb PermissionsStartOnly=true ExecStart=/usr/bin/numactl --interleave=all /usr/bin/mongod --config /data/mongod-%i.conf LimitFSIZE=infinity LimitCPU=infinity LimitAS=infinity LimitNOFILE=64000 LimitNPROC=64000 TasksMax=infinity TasksAccounting=false  [Install] WantedBy=multi-user.target

Говорим БД запускаться при старте системы и так же запускаем экземпляры прямо сейчас.
Наш параметр устанавливается после @, например, memory укажет использовать при запуске /data/mongod-memory.conf

sudo systemctl enable mongod@memory sudo systemctl enable mongod@sec-d1 sudo systemctl enable mongod@sec-d2 sudo service start mongod@memory sudo service start mongod@sec-d1 sudo service start mongod@sec-d2

Подключаемся к монге, инициализируем реплику, устанавливаем пользователей

mongo localhost:27000/admin

Выполняем в консоли монги

rs.initiate({   _id: "consulwar", // название реплики   version: 1,   protocolVersion: 1,   writeConcernMajorityJournalDefault: false, // Говорим что бы реплика не дожидалась                                               // подтверждения о записи от других   configsvr: false, // Указываем, что это не конфигурационный сервер для кластера                      // (кластер — тема отдельной статьи)   members: [     {       _id: 0, // id начинаем от нуля и далее инкрементим       host: 'localhost:27000', // по какому адресу доступна данная монга       arbiterOnly: false, // может ли отдавать и хранить данные       buildIndexes: true, // указываем что строить индексы надо       hidden: false, // не скрытая, т.е. приложение к ней может подключиться       priority: 100, // приоритет при выборе Primary — чем больше, тем приоритетнее       slaveDelay: 0, // задержка репликации. Нам задержка не нужна.       votes: 1 // может ли голосовать при выборе Primary     },     {       _id: 1,       host: 'localhost:27001',       arbiterOnly: false,       buildIndexes: true,       hidden: false,       priority: 99, // Приоритет ниже       slaveDelay: 0,       votes: 1     },     {       _id: 2,       host: 'localhost:27002',       arbiterOnly: false,       buildIndexes: true,       hidden: false,       priority: 98,       slaveDelay: 0,       votes: 1     }   ],   settings: {     chainingAllowed : true, // Разрешаем репликам читать друг с друга, а не только с мастера     electionTimeoutMillis : 5000, // Указываем время на переголосование,                                    // в случае падения одной из БД. ~7 секунд.                                    // Если все экземпляры у нас на 1 машине                                    // можем уменьшить до 500мс, скажем     catchUpTimeoutMillis : 2000   } });  // Создаем первого пользователя, он должен иметь права root'а db.createUser({user: 'zav', pwd: '7Am9859dcb82jJh', roles: ['root']});  // Выходим - ctrl+c, ctrl+c

Подключаемся под нашим пользователем

mongo localhost:27000/admin -u zav -p '7Am9859dcb82jJh' --authenticationDatabase admin

Добавляем пользователя для работы с приложением

use consulwar // вместо consulwar название основной БД вашего приложения db.createUser({     user: 'consulwar',      pwd: '37q4Re7m432dtDq',      roles: [{ // Права на чтение и запись в нашу БД.                // Включает ещё ряд прав, типа создание индексов и т.п.         role: "readWrite", db: "consulwar"      }, { // Права на чтение oplog'а, для быстрой работы приложения метеора         role: 'read', db: 'local'     }] });

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

Настройка реалтайм-бекапа

Реплицировать мы будем на внешний сервер (иначе в чём смысл бекпап? :-)).
На внешнем сервере должна быть установлена монга схожим образом.
Примерный конфиг:

mongod-backup.conf

processManagement:   fork: true   pidFilePath: "/data/db/mongod.pid"  storage:   dbPath: "/data/db"   journal:     enabled: true   indexBuildRetry: false # Отключаем построение индексов   wiredTiger:     engineConfig:       cacheSizeGB: 0 # Отключаем кеш  systemLog:   destination: "file"   path: "/var/log/mongodb/mongodb.log"   logAppend: true   quiet: false   verbosity: 0   logRotate: "reopen"   timeStampFormat: "iso8601-local"  net:   bindIp: 222.222.222.222 # Данный экземпляр должен быть доступен из-вне   port: 27000   http:     enabled: false # но не по http, само собой     JSONPEnabled: false     RESTInterfaceEnabled: false   ssl:     mode: disabled  security:   authorization: "enabled"   keyFile: "/data/mongod-keyfile" # mongod-keyfile берем с основного сервера   javascriptEnabled: false  replication:   oplogSizeMB: 0   replSetName: "consulwar"   enableMajorityReadConcern: false  operationProfiling:   mode: "off" # нам не нужно профилирование на бекапе

В фаерволе сервера-бекапа разрешаем коннект на 27000 порт ТОЛЬКО с IP сервера-приложения/бд.
Тоже самое, на сервере приложения/БД в bindIp указываем смотреть ещё и во внешний интерфейс (ip внешний сервера), и в iptables разрешаем доступ на 27000-27002 порты ТОЛЬКО с ip севера-бекапа.

При инициализации/реинициализации реплики добавляем

{     _id: 4,     host: '222.222.222.222:27000', // собственно интерейс, на который смотрит бекап     arbiterOnly: false,     buildIndexes: false, // не строим индексы вообще на бекапе      hidden: true, // скрытый! Используется ТОЛЬКО для хранения информации     priority: 0, // Не участвует в выборах     slaveDelay: 0, // Задержка бекапа нам не нужна,                     // но может использоваться если нужно пару бекапов в реалтайме "час назад"     votes: 0 // Не участвует в голосовании }

Готово! Теперь данные будут литься в реалтайме ещё и во внешний бекап, что очень круто.
В случае полного краха приложения мы можем инициализировать реплику точно так же, и она восстановится из бекапа.
Поверьте, это намного быстрее чем mongodump/mongorestore (по личным прикидкам в 25-100 раз).

Nodejs, npm, app user, meteor build

Устанавливаем ноду, ставим модуль n, ставим им версию ноды 4.8.1 (последняя, официально поддерживаемая метеором версия).
Устанавливаем pm2, т.к. именно им будем запускать процессы.

sudo apt-get install nodejs sudo apt-get install npm sudo npm install -g n sudo n 4.8.1 sudo npm install pm2@latest -g

Добавляем пользователя, из-под которого будет всё запускаться и который будет отвечать за деплой

sudo adduser consulwar

Заходим за данного пользователя

su consulwar mkdir app mkdir app/current

На локальной машине заходим в директорию с нашим meteor проектом.
Создаем папку для билдов, собираем проект в эту папку.

mkdir ../build meteor build ../build/ --architecture os.linux.x86_64

Полученный архив загружаем на наш сервер, например, по sftp. Заходим под нашим пользователем для приложения.
Загружаем в папку ~/app.
Заходим по ssh за нашего пользователя (consulwar у меня).

cd app mkdir 20170429 # создаем папку по сегодняшней дате tar -xvzf consulwar-master.tar.gz -C 20170429 ln -s 20170429/bundle ~/app/current # Создаем симлинк, что бы быстро переключаться (cd current/programs/server && npm install) vi pm2.config.js # создаем конфиг для нашего pm2

pm2.config.js

var settings = { ... }; // Объект заменяем объектом из settings.json вашего приложения  var instances = 10; // Сколько экземпляров запускаем? Советую не более N-1                     // Где N — количество ядер  var apps = [];  for (var i = 0; i < instances; i++) {   apps.push({     "script": "/home/consulwar/app/current/bundle/main.js", // укажите корректный путь     "exec_mode": "fork", // т.к. рулить будем через Nginx, создаем форками     "name": "consulwar", // имя приложения в списке процессов     "env": {       "ROOT_URL": "http://consulwar.ru/", // Адрес приложения       "HTTP_FORWARDED_COUNT": 1, // Указываем количество прокси перед приложением                                  // Что бы корректно разрулить IP пользователя в приложении       "PORT": 3000 + i, // Порты начинают с 3000 (3000, 3001, 3002...)       "MONGO_URL": "mongodb://consulwar:37q4Re7m432dtDq@localhost:27000,localhost:27001,localhost:27002/consulwar?replicaSet=consulwar&readPreference=primary&authSource=consulwar",       "MONGO_OPLOG_URL": "mongodb://consulwar:37q4Re7m432dtDq@localhost:27000,clocalhost:27001,localhost:27002/local?replicaSet=consulwar&authSource=consulwar",       "METEOR_SETTINGS": settings     }   }); }  module.exports = {   apps : apps }

И запускаем

pm2 startup pm2.js # Выведет команду, которую надо выполнить для автозапуска после перезагрузки ... # Выполняем команду pm2 start pm2.js pm2 status # Валидируем, что всё запустилось. В случае ошибок можем посмотреть pm2 logs

Готово, приложение развернуто и уже должно быть доступно по ip сервера/адресу с указанием порта, например http://consulwar.ru:3000

Nginx балансировка

sudo apt-get install software-properties-common sudo add-apt-repository ppa:nginx/stable sudo apt-get install nginx sudo vi /etc/nginx/nginx.conf

nginx.conf

user www-data; # из-под кого запускаем nginx worker_processes  6; # Указываем количество воркеров worker_rlimit_nofile 65535;  error_log  /var/log/nginx/error.log warn; pid        /var/run/nginx.pid;  events {     worker_connections  4000; # Кол-во подключений на воркера                               # В нашем случае мы можем обработать 6 * 4000 = 24 000 запросов                                # в момент времени }  http {     map $http_upgrade $connection_upgrade { # Для корретной установки сокет-подключения         default upgrade;         ''      close;     }      include       /etc/nginx/mime.types;     default_type  application/octet-stream;      log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '                       '$status $body_bytes_sent "$http_referer" '                       '"$http_user_agent" "$http_x_forwarded_for"';      access_log  /var/log/nginx/access.log  main;      server_tokens off;      sendfile on; # Для отправки статики     tcp_nopush on;     tcp_nodelay on;     keepalive_timeout 65;      gzip on; # Включаем gzip     gzip_comp_level 6;     gzip_vary on;     gzip_proxied any;     gzip_buffers 16 8k;     gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;     gzip_static on; # Разрешаем отдачу файлов с .gz на конце. Например, main.js.gz будет отдаваться при запросе main.js     gzip_http_version 1.1;     gzip_disable "MSIE [1-6]\.(?!.*SV1)"      proxy_connect_timeout      60;     proxy_read_timeout         620;     proxy_send_timeout         320;     proxy_set_header        X-Real-IP       $remote_addr;     proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;      upstream backends {         #ip_hash; # указываем если нам надо что бы пользователь всегда подключался к одному и тому же экземпляру приложения         least_conn; # Я выбрал что бы подключение отдавалось наименее нагруженному процессу          # Прописываем каждый из интерфейсов         # Я запускал их 10, значит тут 10 записей         server 127.0.0.1:3000 weight=5 max_fails=3 fail_timeout=60;          server 127.0.0.1:3001 weight=5 max_fails=3 fail_timeout=60;         server 127.0.0.1:3002 weight=5 max_fails=3 fail_timeout=60;         server 127.0.0.1:3003 weight=5 max_fails=3 fail_timeout=60;         server 127.0.0.1:3004 weight=5 max_fails=3 fail_timeout=60;         server 127.0.0.1:3005 weight=5 max_fails=3 fail_timeout=60;         server 127.0.0.1:3006 weight=5 max_fails=3 fail_timeout=60;         server 127.0.0.1:3007 weight=5 max_fails=3 fail_timeout=60;         server 127.0.0.1:3008 weight=5 max_fails=3 fail_timeout=60;         server 127.0.0.1:3009 weight=5 max_fails=3 fail_timeout=60;          # Интерфейс, который будет отрабатывать в случае недоступности приложения         server 127.0.0.1:3100 backup;     }      # Указываем пути до ssl сертификатов. Мы их создадим чуть позже     ssl_certificate /etc/letsencrypt/live/consulwar.ru/fullchain.pem;     ssl_certificate_key /etc/letsencrypt/live/consulwar.ru/privkey.pem;      ssl_dhparam /etc/ssl/certs/dhparam.pem;      ssl_stapling on;      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;     ssl_prefer_server_ciphers on;     ssl_ciphers         'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:!RC4:!aNULL:!eNULL:!MD5:!EXPORT:!EXP:!LOW:!SEED:!CAMELLIA:!IDEA:!PSK:!SRP:!SSLv:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';      server {         server_name consulwar.ru;         # указываем слушать 80 и 443 порты         listen 80;         listen 443 ssl http2;          # любой запрос переадресовываем на одно из наших приложений          location / {             proxy_pass http://backends;              proxy_set_header Upgrade $http_upgrade;             proxy_set_header Connection $connection_upgrade;             proxy_set_header X-Forwarded-For $remote_addr;         }          # Статику раздаем с помошью nginx         location ~* \.(jpg|jpeg|gif|ico|png)$ {             root /home/consulwar/app/current/programs/web.browser/app;         }          # Основной css и js файл лежит отдельно, добавляем правило дополнительное         location ~* "^/[a-z0-9]{40}\.(css|js)$" {             root /home/consulwar/app/current/programs/web.browser;         }          location ~ "^/packages" {             root /home/consulwar/app/current/programs/web.browser;         }          # В случае если у вас никаких систем мониторинга не стоит,          # можно убрать следующую конструкцию.         location /nginx_status {             stub_status on;             access_log off;             allow 127.0.0.1;             deny all;         }          # Для получения SSL сертификата         location ~ "^/.well-known" {             root /home/consulwar/app/current/programs/web.browser/app/.well-known;         }     }      include /etc/nginx/conf.d/*.conf;     client_max_body_size 128m; }

Перезапускаем nginx

sudo service nginx restart

Получаем SSL от Let’s Enctypt.
Само собой, домен уже должен быть привязан к этому IP адресу.

sudo apt-get install letsencrypt sudo letsencrypt certonly -a webroot --webroot-path=/home/consulwar/app/current/programs/web.browser/app -d consulwar.ru sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 # Генерируем дополнительный сертификат безопасности

Вжух! SSL Работает

iptables

sudo vi /etc/network/if-up.d/00-iptables

00-iptables

#!/bin/sh iptables-restore < /etc/firewall.conf ip6tables-restore < /etc/firewall6.conf

sudo chmod +x /etc/network/if-up.d/00-iptables apt-get install xtables-addons-dkms sudo vi /etc/firewall.conf

firewall.conf

*filter :INPUT ACCEPT [193038:64086301] :FORWARD DROP [0:0] :OUTPUT ACCEPT [194475:60580083] -A INPUT -i lo -j ACCEPT # Разрешаем локальное общение -A INPUT -m state --state RELATED,ESTABLISHED -p all -j ACCEPT # Разрешаем существующие подключения  # Разрешаем SSH -A INPUT -m state --state NEW -p tcp -m multiport --dport 355 -j ACCEPT  # Доступ к Nginx -A INPUT -m state --state NEW -p tcp -m multiport --dport 80,443 -j ACCEPT  # Ловушка для кривых подключений, будет тратить ресурсы атакующего, а не сервера -A INPUT -p tcp -m tcp -j TARPIT  # Дропаем всю фигню -A INPUT -p udp -j DROP   COMMIT

sudo vi /etc/firewall6.conf # оставляем пустым или заполняем что вам надо sudo iptables-restore < /etc/firewall.conf

itables настроены, и лишние порты закрыты.

DONE!

Если понравится подход/формат — выложу настройку почтовой системы, мониторинга инфраструктуры, CI через Bamboo и ещё ряд используемых у нас вещей.

Вполне вероятно что что-то я упустил (но в целом прямо вот так должно работать) — спрашивайте, дополню.
Надеюсь, у кого-то это теперь займет меньше времени, чем у меня 🙂

PS: У нас открыта вакансия front-end разработчика.

ссылка на оригинал статьи https://habrahabr.ru/post/327624/

Шпаргалка по работе с Tmux (терминальный мультиплексор)

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

Tmux (терминальный мультиплексор) позволяет работать с несколькими сессиями в 1 окне.
Вместо нескольких окон терминала к серверу — вы можете использовать одно.
Позволяет подключаться/отключаться к текущему состоянию сессии. Запущенные программы и процессы продолжают работать. (Можно использовать вместо nohup, dtach)

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

1. Установка:

CentOS (нужен подключенный репо EPEL)
# yum install tmux

Fedora
# dnf install tmux

Ubuntu/Debian
# apt-get install tmux

2. Конфигурационные файлы (пользователя, системный):

~/.tmux.conf
/etc/tmux.conf

3. Работа с Tmux

Старт
# tmux //без параметров будет создана сессия 0
# tmux new -s session1 //новая сессия session1. Название отображается снизу-слева в квадратных скобках в статус строке. Далее идет перечисление окон. Текущее окно помечается звездочкой.

Префикс (с него начинаются команды)
<C-b> (CTRL + b)

Новое окно (нажать CTRL+b, затем нажать с)
<C-b c>

Список окон
<C-b w> // переключиться курсором вверх-вниз

Переключение
<C-b n> // следующее окно
<C-b p> // предыдущее окно
<C-b 0> // переключиться на номер окна

Окна можно делить на панели (Panes)
Как в тайловых (мозаичных) оконных менеджерах.

Деление окна горизонтально
<C-b %>
либо команда
# tmux split-window -h

Деление окна вертикально
<C-b ">
либо команда
# tmux split-window -v

Переход между панелей
<C-b стрелки курсора>

Изменение размеров панелей
<C-b c-стрелки>

Закрытие окон
<C-b x> // нужно подтвердить y
либо
# exit

Отключение от сессии
<C-b d>
либо
# tmux detach

Список сессий
# tmux ls

Подключиться к работающей сессии
# tmux attach //подключение к сессии, либо к единственной, либо последней созданной
# tmux attach -t session1 // подключение к сессии session1

Выбрать сессию
<C-b s>

Завершение сессии
# tmux kill-session -t session1

Завершить все сессии
# tmux kill-server

Список поддерживаемых комманд
# tmux list-commands

Дополнительная информация
# man tmux

Официальный сайт
tmux.github.io

Другой известный мультиплексор Screen
ru.wikipedia.org/wiki/GNU_Screen

Буду рад любым дополнениям и замечаниям.
ссылка на оригинал статьи https://habrahabr.ru/post/327630/

«Ростелеком» стал причиной крупного сбоя в работе известных финансовых сервисов

Госкорпорация «Ростелеком» в течение нескольких дней вызывала проблемы в работе нескольких известных финансовых сервисов и организаций, включая Visa, MasterCard, Альфа-банк, HSBC. Причина сбоя пока что неясна, а сам он заключается в том, что «Ростелеком» перенаправлял трафик ряда сервисов и сайтов в свою внутреннюю сеть. Поэтому сами сервисы могли быть недоступными не только для абонентов «Ростелекома», но и других компаний, пишет «Коммерсант».

Первым тревогу забил сервис BGPmon, который отслеживает информацию о маршрутах трафика по всему мира. Специалисты компании сообщают, что «Ростелеком» вольно или невольно совершил «BGP-перехват». Другими словами, госорганизация проанонсировала по сети Интернет некорректные данные о маршрутизации до различных ресурсов. Компания Qrator Labs, по словам ее главы Александра Лямина, зафиксировала пять таких сбоев в течение нескольких дней. Первый сбой случился 18 апреля, его продолжительность составила около минуты. Затем повторный сбой случился днем 25 апреля, после чего подержался несколько часов, а потом еще несколько таких сбоев, которые проходили несколько раз за ночь 26-27 апреля.

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

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

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


Источник: РБК

Скорее всего, «Ростелеком» пропустил различные маршруты трафика через один узел за определенное время. Специалисты по кибербезопасности утверждают, что случившееся могло стать результатом учений: «Поскольку „Ростелеком“ сам или через дочерние компании присутствует на территории всей страны, в один узел собирался трафик маршрутов со всей России. Это могло понадобиться, чтобы проверить, какой объем трафика может прокачать один узел в случае отключения, изоляции российского сегмента сети, как, например, в случае с Северной Кореей».

Кстати, ранее BGP-переход использовали некоторые провайдеры других стран для блокировки различных ресурсов. В качестве примера можно привести Pakistan Telecom, телекоммуникационную компанию из Ирана. Когда ее руководство решило заблокировать YouTube, трафик многих пользователей всемирной сети случайным образом был перенаправлен в Пакистан. Как результат — YouTube недоступен.

Что касается аномалий с «Ростелекомом», то за последние несколько дней Qrator.Radar зафиксировал с ним несколько событий такого типа:

  • 2017-04-18 23:02:00 — 2017-04-18 23:03:00
  • 2017-04-26 22:37:00 — 2017-04-26 22:50:00
  • 2017-04-27 01:06:00 — 2017-04-27 02:20:00
  • 2017-04-27 03:21:00 — 2017-04-27 04:26:00

Цифры, приведенные выше, показывают дату и время начала аномалии, и, соответственно, дату и время ее завершения. Это те MOAS, которые показал сервис BGPStream. Кроме них, был еще один, более значительный инцидент route leak на 933 пострадавших префикса.


Схема, визуализирующая изменения, вызванные «Ростелекомом».

«Я бы классифицировал этот случай, как довольно подозрительный. Обычно проблемы вроде этой более масштабны и носят случайных характер. В этом же случае идет речь о целенаправленном воздействии на финансовые организации… Выглядит странно, что кто-то ограничил трафик в своей сети лишь в отношении сетей финансовых организаций», — заявил глава компании Dyn Дуг Мэдори (Doug Madory).

Трафик, которым управляют подобным образом, можно расшифровать. В первую очередь, это касается данных, которые и не были зашифрованы. Но и зашифрованные данные можно раскодировать, если использовать атаки вроде Logjam и DROWN.

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

Список организаций

202.138.100.0/24 Reliance Communications Bangalore State of Karnātaka IN
145.226.109.0/24 Euro-Information-Europeenne de Traitement de l’Information SAS Paris Île-de-France FR
193.58.4.0/24 Fortis Bank N.V. Brussels Bruxelles-Capitale BE
217.75.242.0/24 Servicios de Hosting en Internet S.A. ES
194.153.135.0/24 Norvik Banka LV
93.190.87.0/24 Modrium Mdpay Oy NUF Øy Nord-Trøndelag Fylke NO
217.117.65.0/24 NET_217_117_65 UA
195.76.9.0/24 REDSYS SERVICIOS DE PROCESAMIENTO SLU
64.75.29.0/24 Arcot Systems, Inc. Sunnyvale CA US
206.99.153.0/24 Savvis Singapore SG
198.241.161.0/24 VISA INTERNATIONAL CO US
203.112.91.0/24 HSBC banking and financial services Hong Kong HK
196.38.228.0/24 Internet Solutions Johannesburg Gauteng ZA
216.136.151.0/24 Savvis Arlington VA US
198.161.246.0/24 EMC Corporation Southborough MA US
212.243.129.0/24 UBS Card Center AG Glattbrugg Kanton Zürich CH
203.112.90.0/24 HSBC banking and financial services Hong Kong HK
216.150.144.0/24 Xand Corporation Farmingdale NY US
195.20.110.0/24 Bank Zachodni WBK S.A. Poznań Województwo Wielkopolskie PL
193.16.243.0/24 Servicios Para Medios De Pago S.A. ES
202.187.53.0/24 TIME DOTCOM BERHAD Shah Alam Selangor MY
160.92.181.0/24 Worldline France hosting FR
145.226.45.0/24 Euro-Information-Europeenne de Traitement de l’Information SAS Strasbourg Alsace FR
195.191.110.0/24 card complete Service Bank AG Vienna Wien AT
193.104.123.0/24 PROVUS SERVICE PROVIDER SA Bucharest București RO
69.58.181.0/24 Verisign, Inc. New York NY US
194.5.120.0/24 DOCAPOST BPO SAS FR
89.106.184.0/24 Worldline SA Frankfurt am Main Hessen DE
217.75.224.0/19 Servicios de Hosting en Internet S.A. Madrid Comunidad de Madrid ES
195.114.57.0/24 DNBNORD PLC LV
198.241.170.0/24 VISA INTERNATIONAL CO US
216.119.216.0/24 MasterCard Technologies LLC Wentzville MO US
193.203.231.0/24 SIA S.p.A. Milano Lombardia IT
65.205.249.0/24 Symantec Inc Mountain View CA US
194.126.145.0/24 Netcetera AG Zürich Kanton Zürich CH
65.205.248.0/24 Symantec Inc Mountain View CA US

Пока что «Ростелеком» не дал подробных комментариев о том, что произошло на самом деле.
ссылка на оригинал статьи https://geektimes.ru/post/288728/

Пьяные хакеры выложили 10 невышедших серий сериала и вымогают деньги у Netflix

Хакерская группа TheDarkOverlord Solutions нашла оригинальный способ заработать деньги и/или прославиться. Ребята выкрали с серверов одной из посторонних студий 5-й сезон сериала «Оранжевый — хит сезона» (“Orange Is The New Black”) — а теперь выкладывают их в открытый доступ. Чтобы киностудия Netflix не лишилась барышей, ей придётся заплатить хакерам откупные.

По графику 5-й сезон сериала должен стартовать с 9 июня 2017 года. Но есть вероятность, что некоторые зрители увидят его раньше, и даже при желании никому не смогут заплатить за просмотр.

«Оранжевый — хит сезона» — популярный комедийно-драматический сериал о жизни в женской тюрьме, основанный на реальных событиях. В 2014 году сериал был номинирован на премию «Эмми» в 12 категориях, в том числе и как «Лучший комедийный сериал», выиграв три награды. В 2015 году получил награду как «Лучший драматический сериал». В 2016 году он стал самым популярным (по количеству просмотров) оригинальным сериалом на Netflix — такое признание дорогого стоит, как в прямом, так и в переносном смыслах. Во многом благодаря этому сериалу Netflix рассчитывает добавить 3,2 млн платных подписчиков до июня 2017 года.

Группа TheDarkOverlord Solutions опубликовала заявление, в котором рассказывает историю взлома.

Хакеры говорят, что им удалось получить доступ к серверам некоей компании, где они нашли много интересного, в том числе 5-й сезон сериала «Оранжевый — хит сезона», а также несколько фильмов (или сериалов) других студий. Но хакеры сконцентрировались именно на Netflix.

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

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

«Теперь, поскольку мы наказываем по принципу виновности в связи с обвиняемым, другие компании из американской индустрии развлечений не должны удивляться, если они тоже однажды найдут в почтовом ящике многословное, снисходительное и матерное письмо, предлагающее руку дружбы и (вероятнее всего) требующее скромную сумму интернет-денег», — пишут хакеры. Они признают, что понятие «скромной суммы» весьма относительно. Но на самом деле любую сумму, которую они предложат, можно считать скромной: «Может мы злобные интернет-хулиганы, но не невменяемые создания».

29 апреля 2017 года 1-я серия 5-го сезона «Оранжевый — хит сезона» ушла в торренты, к огромной радости фанатов.

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

Сегодня же группа TheDarkOverlord Solutions в своём твиттере сообщила, что в их распоряжении есть также фильмы/сериалы производства ABC, FOX, IFC и National Geographic. “Мы больше не играем в игры», — заявили серьёзные ребята.

По информации TorrentFreak, источником утечки является компания Larson Studios, подрядчик многих голливудских киноостудий. Эта фирма занимается аудиообработкой, а именно — дублированием фильмов по технологии ADR (Automatic Dialog Replacement). Технология подразумевает отдельную запись диалогов в студии на хорошей аудиоаппаратуре. Затем этот звук накладывают на оригинальный материал, где качество звука всегда хуже. Судя по всему, хакеры взломали серверы именно этой компании и у неё требовали выкуп изначально. Не получив ответа, они нацелились на Netflix.

Компания Netflix признала факт утечки: «Мы осведомлены о ситуации. У подрядчика, который работает с несколькими крупными студиями, была скомпрометирована система безопасности. Правоохранительные органы уже занимаются делом».

Буквально несколько часов назад (примерно в 15:00 МСК) хакерская группа TheDarkOverlord Solutions опубликовала новое заявление. Они поздравляют студию Netflix с тем, что её сотрудники одними из первых скачали серию с торрентов (привер, IP-адрес 69.53.235.76). Значит, они получили сообщение, но при этом всё равно не ответили на предложение. Поэтому после длительных обсуждений в присутствии алкоголя хакеры решили выложить также серии 2-10 из 13 серий 5-го сезона: ссылка на торрент (11,46 ГиБ).

Наверное, в Netflix теперь кусают локти, почему же они не заплатили. Остался только один выход — срочно перенести премьеру сериала с 9 июня на 30 апреля.
ссылка на оригинал статьи https://geektimes.ru/post/288724/