-Поиск по дневнику

Поиск сообщений в rss_rss_hh_new

 -Подписка по e-mail

 

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 17.03.2011
Записей:
Комментариев:
Написано: 51

Habrahabr/New








Добавить любой RSS - источник (включая журнал LiveJournal) в свою ленту друзей вы можете на странице синдикации.

Исходная информация - http://habrahabr.ru/rss/new/.
Данный дневник сформирован из открытого RSS-источника по адресу http://feeds.feedburner.com/xtmb/hh-new-full, и дополняется в соответствии с дополнением данного источника. Он может не соответствовать содержимому оригинальной страницы. Трансляция создана автоматически по запросу читателей этой RSS ленты.
По всем вопросам о работе данного сервиса обращаться со страницы контактной информации.

[Обновить трансляцию]

Когда размер имеет значение: создаем приложение-линейку с помощью ARKit

Среда, 13 Сентября 2017 г. 14:01 + в цитатник
EverydayTools сегодня в 14:01 Разработка

Когда размер имеет значение: создаем приложение-линейку с помощью ARKit

  • Tutorial


Вот и прошел день долгожданного официального релиза iOS 11, а значит откладывать знакомство с ARKit – SDK производства Apple для создания приложений с дополненной реальностью — больше никак нельзя. О сути инструмента наслышаны многие: с помощью ARKit можно накладывать созданную виртуальную реальность на реальный мир вокруг нас. iPhone или iPad при этом выступают в роли смотрового окна, через которое мы можем наблюдать за происходящим и что-то в нем менять. В Интернете уже представлено немало различных демо-приложений – с их помощью можно расставлять мебель, парковать автомобиль на стоянке, рисовать в окружающем пространстве, создавать двери в другие миры и многое другое. Словом, круг возможностей широкий, нужно только разобраться с технической реализацией.

ARKit поддерживают девайсы исключительно с iOS 11 и процессором A9 или A10. Соотвественно, для написания и запуска приложения нам потребуется, во-первых, Xcode 9, во-вторых, девайс с одним из указанных процессоров и установленной последней версией iOS. Стартовый проект можно скачать отсюда.

ARKit использует данные с камеры и других датчиков девайса, чтобы распознавать ключевые точки и горизонтальные поверхности в окружающем пространстве в режиме реального времени. В скобках отметим, что процесс довольно ресурсозатратный – девайс будет нагреваться. Для начала добавим в метод viewDidLoad() строчку:
 
    
 sceneView.debugOptions = ARSCNDebugOptions.showFeaturePoints

     
Это позволит нам видеть ключевые точки, которые находит ARKit. Теперь можно запустить приложение, и через некоторое время перед нами предстанет следующая картина:
 
  /

Стоит отметить, что девайс необходимо немного перемещать в пространстве – в процессе движения в систему будет поступать больше меняющейся информации, чем в неподвижном состоянии. Обилие данных помогает ARKit определять ключевые точки, и в итоге их получается больше.
 
Для того чтобы «прощупать» возможности ARKit мы возьмем в качестве примера простое приложение-линейку и проследим весь процесс его создания. Сначала нам необходимо реализовать отрисовку линии между двумя точками, затем рассчитать ее длину, настроить вывод результата на экран – и наша примитивная линейка будет готова. Добавим переменные, которые нам понадобятся для отрисовки линии в пространстве:
    
private var points: (start: SCNVector3?, end: SCNVector3?)
private var line = SCNNode()
private var isDrawing = false 
private var canPlacePoint = false 

     
Кортеж points будет содержать в себе точки начала и конца линии. line – это SCNNode, объект, который добавляется в сцену SceneKit, isDrawing – переменная показывающая, закончили мы выбор точек или нет. Переменная сanPlacePoint говорит сама за себя: она показывает, можно ли расположить точку в фокусе. В нашем случае фокусом будет являться центр экрана.
 
Для того, чтобы определить, можем ли мы поместить точку в фокус, нужно использовать метод hitTest объекта ARSCNVeiw. Этот метод на основе данных ARKit определяет все распознанные объекты и поверхности, пересекающие луч, направленный от камеры, и возвращает в порядке удаления от девайса полученные данные о пересечении.
 
Использовать его мы будем в ARSCNViewDelegate, в методе
      
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) 

 
чтобы получать данные в режиме реального времени. В итоге у нас получится как-то так:
 
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
    DispatchQueue.main.async {
	self.measure()
    }
}
    
private func measure() {
    let hitResults = sceneView.hitTest(view.center, types: [.featurePoint])
    if let hit = hitResults.first {
        canPlacePoint = true
        focus.image = UIImage(named: "focus")
    } else {
        canPlacePoint = false
        focus.image = UIImage(named: "focus_off")
    }
}
     

Данный код проверяет наличие результатов hitTest в режиме реального времени, а дальше уже, в зависимости от них, выставляет значение canPlacePoint и изображение нашего фокуса (зеленое или красное). Также в методе hitTest есть список опций, задающий, какие объекты учитывать в реализации – в нашем случае это ключевые точки. При желании можно добавить горизонтальные поверхности.
 
Тап по экрану будет обозначать начальную либо конечную точку. Непосредственно в функции реализации тапа по экрану мы будем менять переменную isDrawing и обнулять значения начала и конца всякий раз, когда начинаем новую линию:
 
@objc private func tapped() {
    if canPlacePoint {
        isDrawing = !isDrawing
        if isDrawing {
                points.start = nil
                points.end = nil
        }
    }
}

Вернемся к функции делегата updateAtTime. Имея результат hitTest, мы получаем координаты точки и затем, в зависимости от значения переменных, ставим начальную или конечную точку линии:
     
if isDrawing {
   let hitTransform = SCNMatrix4(hit.worldTransform)
   let hitPoint = SCNVector3Make(hitTransform.m41, hitTransform.m42, hitTransform.m43)
                
   if points.start == nil {
       points.start = hitPoint
   } else {
       points.end = hitPoint
   }
}

Теперь у нас есть координаты начала и конца линии – осталось ее начертить. Для этого добавим функцию, которая будет возвращать геометрию линии (по ней SceneKit поймет, как и где рисовать SCNNode):
 
func lineFrom(vector vector1: SCNVector3, toVector vector2: SCNVector3) -> SCNGeometry {
    let indices: [Int32] = [0, 1]
        
    let source = SCNGeometrySource(vertices: [vector1, vector2])
    let element = SCNGeometryElement(indices: indices, primitiveType: .line)
        
    return SCNGeometry(sources: [source], elements: [element])  
}

 
И, наконец, добавим код, который будет отрисовывать нашу линию в пространстве:
 
if points.start == nil {
    points.start = hitPoint
} else {
    points.end = hitPoint
    line.geometry = lineFrom(vector: points.start!, toVector: points.end!)
    if line.parent == nil {
        line.geometry?.firstMaterial?.diffuse.contents = UIColor.white
        line.geometry?.firstMaterial?.isDoubleSided = true
        sceneView.scene.rootNode.addChildNode(line)
    }
}

Теперь, запустив приложение, мы можем провести линию между двумя точками: первый тап отмечает начало и начинает отрисовывать линию к точке в фокусе, второй тап прекращает режим отрисовки и фиксириует линию. Остается только рассчитать ее длину и вывести полученное значение на экран.
 

 
func distance(from startPoint: SCNVector3, to endPoint: SCNVector3) -> Float {
    let vector = SCNVector3Make(startPoint.x - endPoint.x, startPoint.y - endPoint.y, startPoint.z - endPoint.z)
    let distance = sqrtf(vector.x * vector.x + vector.y * vector.y + vector.z * vector.z)
    return distance
}

Эта функция вычисляет расстояние между двумя точками в пространстве. Дело за малым: добавить текстовое поле и выводить результат в него. В SceneKit 0.01 равняется одному сантиметру. В итоге получаем следущее:
 
 

Длина нарисованной линии, по мнению приложения, составляет 9 см, что довольно хорошо соотносится с показаниями реальной линейки. Но, на самом деле, точность не слишком высокая. Максимальная точность получается в тех случаях, когда объекты располагаются на небольшом от камеры расстоянии и измерение производится из положения девайса перпендикулярно поверхности (то есть нужно двигать телефон параллельно поверхности, а не поворачивать его). Измерение на горизонтальных поверхностях будут более точным. Также, если наводить камеру на далекие объекты, hitTest может возвращать невалидные результаты – расстояние до найденных объектов определяется неверно. Хотя здесь нужно оговориться, что все это тестировалось на iPhone 7, у которого нет двойной камеры. Да и если посмотреть на демо различных линеек в интернете, по большей части можно заметить те же самые ограничения и неточности в измерениях.
 
Вот что получилось в результате.
 
Если подытожить: ARKit – отличное SDK для создания игр и развлекательных приложений, с ним можно придумать много интересного. Существенная заслуга Apple в том, что они пустили дополненную реальность в массы: девайсов, поддерживающих ARKit, довольно много и теперь уже не нужно приобретать специальные шлемы и прочие аксессуары. К тому же, ARKit поддерживает работу как и с нативными SpriteKit SceneKit и Metal, так и с Unity и Unreal Engine, что упрощает разработку.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/337808/


Метки:  

[Из песочницы] Программирование с использованием PCAP

Среда, 13 Сентября 2017 г. 13:59 + в цитатник
Lupus_Anay сегодня в 13:59 Разработка

Программирование с использованием PCAP

Данный текст является переводом статьи Тима Карстенса Programming with pcap 2002 года. В русскоязычном интернете не так много информации по PCAP. Перевод сделан в первую очередь для людей, которым интересна тема захвата трафика, но при этом они плохо владеют английским языком. Под катом, собственно, сам перевод.


Вступление


Давайте начнем с того, что определим, для кого написана эта статья. Очевидно, что некоторое базовое знание C необходимо (если, конечно, вы не хотите просто понять теорию), для понимания кода приведенного в статье, но вам не нужно быть ниндзя программирования: в тех моментах, которые могут быть понятны только более опытными программистам я постараюсь подробно объяснить все концепции. Так же, пониманию может помочь некоторое базовое знание работы сетей, учитывая что PCAP — это библиотека для реализации сниффинга (Прим. переводчика: Сниффинг — процесс захвата сетевого трафика, своего, или чужого). Все представленные здесь примеры кода были протестированы на FreeBSD 4.3 с ядром по умолчанию.


Начало работы: Общая форма приложения PCAP


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


  1. Начнем с определения идентификатора интерфейса, трафик с которого мы хотим получить. В Linux это может быть что нибудь вроде eth0, в BSD это может быть xl1, и тому подобное. Мы можем либо указать этот идентификатор в строке, либо попросить PCAP предоставить его нам.
  2. Далее необходимо инициализировать PCAP. На данном этапе нам нужно передать PCAP имя устройства, с которым мы будем работать. При необходимости мы можем захватить трафик с нескольких устройств. Для их различия мы будем использовать дескрипторы сеансов. Так же, как и во время работы с файлами, нам нужно назвать наш сеанс захвата трафика, что бы мы могли отличить его от других подобных сеансов.
  3. В случае, если мы хотим получить какой то определенный трафик (например, только TCP/IP пакеты, или пакеты только с порта 23 и так далее) мы должны создать набор правил, "скомпилировать" их, и применить их к конкретному сеансу. Это трехфазный, тесно связанный процесс. Набор правил изначально находится в строке, а после компилируется в понятный PCAP формат. Компиляция производится вызовом функции внутри нашей программы, она не связана с использованием какого либо внешнего приложения. Далее мы говорим PCAP применить этот фильтр к необходимой нам сессии.
  4. Наконец, мы говорим PCAP начать захват трафика. В случае использования pcap_loop, PCAP будет работать до тех пор, пока не получит столько пакетов, сколько мы ему указали. Каждый раз, когда он получает новый пакет, он вызывает определенную нами функцию. Эта функция может делать все что мы хотим. Она может прочитать пакет, и передать информацию пользователю, она может сохранить его в файл, или вовсе не делать ничего.
  5. После того, как мы закончим работу по захвату, сессию можно закрыть.
    На самом деле это очень простой процесс. Всего пять шагов, один из которых не обязательный (шаг 3). Давайте рассмотрим каждый шаг, и их реализации.

Определение устройства


Это ужасно просто. Есть два способа определить устройство, которое мы хотим прослушивать.


Первый — просто позволить пользователю сказать программе имя того устройства с которого он хочет захватывать трафик. Рассмотрим этот код:


#include 
#include 

int main(int argc, char *argv[])
{
    char *dev = argv[1];
    printf("Device: %s\n", dev);
    return(0);
}

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


Второй способ также очень прост. Давайте взглянем на программу:


#include 
#include 

int main(int argc, char *argv[])
{
    char *dev, errbuf[PCAP_ERRBUF_SIZE];

    dev = pcap_lookupdev(errbuf);
    if (dev == NULL) 
    {
        fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
        return(2);
    }
    printf("Device: %s\n", dev);
    return(0);
}

В этом случае, PCAP просто установит имя устройства самостоятельно. "Но подожди, Тим", вы скажете. "Что делать со строкой errbuf?". Большинство PCAP команд позволяют нам передать им строку в качестве одного из аргументов. С какой целью? В том случае, если выполнение команды не удастся, PCAP запишет описание ошибки в переданную строку. В этом случае, если выполнение pcap_lookupdev() провалится, сообщение об ошибке будет помещено в errbuf. Круто, не правда ли? Вот так вот и устанавливается имя устройства для захвата трафика.


Настройка устройства для сниффинга


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


pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)

Первый аргумент — это имя устройства которое мы определили в предыдущем разделе. snaplen это целое число, которое определяет максимальное число байтов, которое может захватить PCAP. promisc, когда установлен в true, устанавливает устройство в неразборчивый режим (так или иначе, даже если он установлен в false, в определенных случаях интерфейс может находится в неразборчивом режиме). to_ms это время чтения в миллисекундах (значение 0 означает отсутствие таймаута; по крайней мере на некоторых платформах, это означает что вы можете дождаться появления достаточного количества пакетов для прекращения сниффинга до того, как закончите анализ этих пакетов. Поэтому вы должны использовать ненулевое время). Наконец, ebuf это строка в которой мы можем хранить сообщения об ошибках (так же, как мы делали до этого с errbuf). Функция возвращает дескриптор сеанса.


Для демонстрации, рассмотрим этот фрагмент кода:


#include 
...
pcap_t *handle;

handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
if (handle == NULL) 
{
    fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
    return(2);
}

Этот код открывает устройство помещенное в переменную dev, говорит читать столько байтов, сколько указано в BUFSIZ (константа, которая определена в pcap.h). Мы говорим переключить устройство в неразборчивый режим, что бы захватывать трафик до момента возникновения какой либо ошибки, и в случает ошибки, поместить ее описание в строку errbuf; и после, в случае ошибки, используем эту строку что бы вывести сообщение о том, что пошло не так.


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


Не все устройства предоставляют одни и те же заголовки канального уровня в прочитанных вами пакетах. Ethernet устройства, и некоторые не-Ethernet устройства, могут предоставить Ethernet заголовки, но другие типы устройств, например такие как замыкающие устройства в BSD и OS X, PPP-интерфейсы, и Wi-Fi-интерфейсы в режиме мониторинга — нет.


Вам нужно определить тип заголовков канального уровня, которые предоставляет устройство, и использовать для анализа содержимого пакетов. pcap_datalink() возвращает тип заголовков канального уровня. (Cм. список значений заголовков канального уровня. Возвращаемые значения — значения DHT_ в этом списке)


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


if (pcap_datalink(handle) != DLT_EN10MB) 
{
    fprintf(stderr, "Device %s doesn't provide Ethernet headers -not  supported\n", dev);
    return(2);
}

который сработает если устройство не поддерживает Ethernet — заголовки. Это может сработать для кода приведенного ниже, который использует заголовки Ethernet.


Фильтрация трафика


Часто мы заинтересованы в захвате только определенного типа трафика. Для примера — бывает такое, что единственное что мы хотим — это захватить трафик с порта 23(telnet) для поиска паролей. Или возможно мы хотим перехватить файл который был отправлен через порт 21(FTP). Может быть мы хотим захватить только DNS трафик (порт 53 UDP). Однако, бывают редкие случаи, когда мы просто хотим слепо захватывать весь интернет трафик. Давайте рассмотрим функции pcap_compile() и pcap_setfilter().


Процесс очень простой. После того, как мы вызвали pcap_open_live() и имеем работающую сессию сниффинга, мы можем применить наш фильтр. Вы спросите, почему просто не использовать обычные if/else if выражения? Две причины: первая — фильтр PCAP эффективнее, потому что он фильтрует непосредственно через BPF; соответственно нам нужно куда меньшее количество ресурсов, ведь драйвер BPF делает это напрямую. Вторая — это то, что фильтры PCAP просто проще.


Перед тем, как применить фильтр, мы должны скомпилировать его. Условие фильтра содержится в обычной строке (или массиве char). Синтаксис достаточно хорошо документирован на главной странице tcpdump.org; Я оставлю это вам на самостоятельное рассмотрение. Однако, мы будем использовать простые тестовые выражения, и, возможно, вы достаточно догадливы что бы самостоятельно вывести правила синтаксиса этих условий из приведенных примеров.


Что бы скомпилировать фильтр мы вызываем функцию pcap_compile(). Прототип определяет эту функцию как:


int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask)

Первый аргумент — это наш дескриптор сессии (pcap_t* handle в нашем предыдущем примере). Следующий — это указатель на место, где мы будем хранить скомпилированную версию фильтра. Далее идет само выражение, в обычном строковом формате. После идет целое число, которое определяет, нужно ли оптимизировать выражения фильтра, или нет (0 — нет, 1 — да). Наконец, мы должны определить сетевую маску той сети, к которой мы применяем фильтр. Функция возвращает -1 при ошибке; все остальные значения означают успех.


После компиляции фильтра, время применить его. Вызовем pcap_setfilter(). Следуя нашему формату объяснения PCAP, мы должны рассмотреть прототип этой функции:


int pcap_setfilter(pcap_t *p, struct bpf_program *fp)

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


Возможно этот пример поможет вам понять лучше:


Пример задания, компиляции и применения PCAP фильтра
#include 
...
pcap_t *handle;  /* Дескриптор сесси */
char dev[] = "rl0";  /* Устройство для сниффинга */
char errbuf[PCAP_ERRBUF_SIZE]; /* Строка для хранения ошибок */
struct bpf_program fp;  /* Скомпилированный фильтр */
char filter_exp[] = "port 23"; /* Выражение фильтра */
bpf_u_int32 mask;  /* Сетевая маска устройства */
bpf_u_int32 net;  /* IP устройства */

if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
    fprintf(stderr, "Can't get netmask for device %s\n", dev);
    net = 0;
    mask = 0;
}

handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
if (handle == NULL) {
    fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
    return(2);
}

if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
    fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
    return(2);
}

if (pcap_setfilter(handle, &fp) == -1) {
    fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
    return(2);
}

Эта программа настроена на сниффинг трафика который проходит через порт 23, в неразборчивом режиме, на устройстве rl0.


Мы можете заметить, что предыдущий пример содержит функцию, о которой мы еще не говорили. pcap_lookupnet() — это функция которая, получая имя устройства возвращает IPv4 сетевой номер и соответствующую сетевую маску (сетевой номер — это адрес IPv4 ANDed с сетевой маской, поэтому он содержит только сетевую часть адреса). Это существенно, потому что нам нужно знать сетевую маску для применения фильтра.


По моему опыту, этот фильтр не работает в некоторых ОС. В моей тестовой среде я обнаружил, что OpenBSD 2.9 c ядром по умолчанию поддерживает этот тип фильтра, но FreeBSD 4.3 с ядром по умолчанию — нет. Ваш опыт может отличаться.


Реальный сниффинг


На текущем этапе мы узнали как определить устройство, приготовить его для захвата трафика, и применить фильтры. Теперь время захватить несколько пакетов. Есть два основных способа захватывать пакеты. Мы можем просто захватить один пакет, или мы можем войти в цикл, который выполняется пока не будет захвачено n пакетов. Мы начнем с того, что покажем, как можно захватить один пакет, и после рассмотрим методы использования циклов. Взглянем на прототип pcap_next():


u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)

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


Это демонстрация использования pcap_next() для захвата пакетов:


Захват одного пакета
#include 
#include 

int main(int argc, char *argv[])
{
    pcap_t *handle;   /* Дескриптор сессии */
    char *dev;   /* Устройсто для сниффинга */
    char errbuf[PCAP_ERRBUF_SIZE]; /* Строка для хранения ошибки */
    struct bpf_program fp;  /* Скомпилированный фильтр */
    char filter_exp[] = "port 23"; /* Выражение фильтра */
    bpf_u_int32 mask;  /* Сетевая маска */
    bpf_u_int32 net;  /* IP */
    struct pcap_pkthdr header; /* Заголовок который нам дает PCAP */
    const u_char *packet;  /* Пакет */

    /* Определение устройства */
    dev = pcap_lookupdev(errbuf);
    if (dev == NULL) 
    {
        fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
        return(2);
    }

    /* Определение свойств устройства */
    if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) 
    {
        fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev,   errbuf);
        net = 0;
        mask = 0;
    }

    /* Создание сессии в неразборчивом режиме */
    handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
    if (handle == NULL) 
    {
        fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
        return(2);
    }

 /* Компиляция и применения фильтра */
    if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) 
    {
        fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
        return(2);
    }

    if (pcap_setfilter(handle, &fp) == -1) 
    {
        fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
        return(2);
    }

    /* Захват пакета */
    packet = pcap_next(handle, &header);
    /* Вывод его длины */
    printf("Jacked a packet with length of [%d]\n", header.len);
    /* Закрытие сессии */
    pcap_close(handle);
    return(0);
}

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


Второй способ захвата трафика — использование pcap_loop() или pcap_dispatch() (который в свою очередь сам использует pcap_loop()). Что бы понять использование этих двух функций, нам нужно понять идею функции обратного вызова.


Функция обратного вызова (callback function) не является чем то новым, это обычная вещь в большом количестве API. Концепция, которая стоит за функцией обратного вызова очень проста. Предположим, что у есть программа которая ждет события определенного рода. Просто для примера, предположим что программа ждет нажатие клавиши. Каждый раз, когда пользователь нажимает клавишу, моя программа вызовет функцию, что бы обработать это нажатие клавиши. Это и есть функция обратного вызова. Эти функции используются в PCAP, но вместо вызова их в момент нажатия клавиши, они вызываются тогда, когда PCAP захватывает пакет. Использовать функции обратного вызова можно только в pcap_loop() и pcap_dispatch() которые очень похожи в этом плане. Каждая из них вызывает функцию обратного вызова каждый раз, когда попадется пакет который проходит сквозь фильтр (если конечно фильтр есть. Если нет, то все пакеты, которые были захвачены вызовут функцию обратного вызова).


Прототип pcap_loop() приведен ниже:


int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)

Первый аргумент — дескриптор сессии. Дальше идет целое число, которое сообщает pcap_loop() количество пакетов, которые нужно захватить (отрицательное значение говорит о том, что цикл должен выполняться до возникновения ошибки). Третий аргумент — имя функции обратного вызова (только идентификатор, без параметров). Последний аргумент полезен в некоторых приложениях, но в большинстве случаев он просто устанавливается NULL. Предположим, что у нас есть аргументы, которые мы хотим передать функции обратного вызова, в дополнение к тем, которые передает ей pcap_loop(). Последний аргумент как раз то место, где мы это сделаем. Очевидно, вы должны привести их к u_char * типу, что бы убедится что вы получите верные результаты. Как мы увидим позже, PCAP использует некоторые интересные способы передачи информации в виде u_char *. После того, как мы покажем пример того, как PCAP делает это, будет очевидно как сделать это и в этом моменте. Если нет — обратитесь к справочному тексту по С, так как объяснения указателей находятся за рамками темы этого документа. pcap_dispatch() почти идентична в использовании. Единственное различие между pcap_dispatch() и pcap_loop() это то, что pcap_dispatch() будет обрабатывать только первую серию пакетов полученных из системы, тогда как pcap_loop() будет продолжать обработку пакетов или партий пакетов до тех пор пока счетчик не закончится. Для более глубокого обсуждения различий, смотрите официальную документацию PCAP.


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


void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);

Давайте разберем его более детально. Первое — функция должна иметь void тип. Это логично, потому что pcap_loop() в любом случае не знал бы, что делать с возвращаемым значением. Первый аргумент соответствует последнему аргументу pcap_loop(). Независимо от того, какое значение передается последним аргументом pcap_loop(), оно передается первому аргументу нашей функции обратного вызова. Второй аргумент — это PCAP заголовок, который содержит информацию о том, когда пакет был захвачен, насколько он большой, и так далее. Структура pcap_pkthdr определена в файле pcap.h как:


struct pcap_pkthdr {
    struct timeval ts; /* Время захвата */
    bpf_u_int32 caplen; /* Длина заголовка */
    bpf_u_int32 len; /* Длина пакета */
};

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


Но как можно использовать эту переменную (названную packet) в прототипе? Пакет содержит много атрибутов, так что, как можно предположить, это не строка, а набор структур (для примера, пакет TCP/IP содержит в себе Ethernet заголовок, IP заголовок, TCP заголовок, и наконец, данные). Этот u_char указатель указывает на сериализованную версию этих структур. Что бы начать использовать какую нибудь из них необходимо произвести некоторые интересные преобразования типов.


Первое, мы должны определить сами структуры, прежде чем мы сможем привести данные к ним. Следующая структура используется мной для чтения TCP/IP пакета из Ethernet.


Объявления структур Ethernet, IP, TCP
/* Ethernet адреса состоят из 6 байт */
#define ETHER_ADDR_LEN 6

 /* Заголовок Ethernet */
 struct sniff_ethernet {
    u_char ether_dhost[ETHER_ADDR_LEN]; /* Адрес назначения */
    u_char ether_shost[ETHER_ADDR_LEN]; /* Адрес источника */
    u_short ether_type; /* IP? ARP? RARP? и т.д. */
 };

 /* IP header */
 struct sniff_ip {
    u_char ip_vhl;  /* версия << 4 | длина заголовка >> 2 */
    u_char ip_tos;  /* тип службы */
    u_short ip_len;  /* общая длина */
    u_short ip_id;  /* идентефикатор */
    u_short ip_off;  /* поле фрагмента смещения */
    #define IP_RF 0x8000  /* reserved флаг фрагмента */
    #define IP_DF 0x4000  /* dont флаг фрагмента */
    #define IP_MF 0x2000  /* more флаг фрагмента */
    #define IP_OFFMASK 0x1fff /* маска для битов фрагмента */
    u_char ip_ttl;  /* время жизни */
    u_char ip_p;  /* протокол */
    u_short ip_sum;  /* контрольная сумма */
    struct in_addr ip_src,ip_dst; /* адрес источника и адрес назначения */
 };
 #define IP_HL(ip)  (((ip)->ip_vhl) & 0x0f)
 #define IP_V(ip)  (((ip)->ip_vhl) >> 4)

 /* TCP header */
 typedef u_int tcp_seq;

 struct sniff_tcp {
    u_short th_sport; /* порт источника */
    u_short th_dport; /* порт назначения */
    tcp_seq th_seq;  /* номер последовательности */
    tcp_seq th_ack;  /* номер подтверждения */
    u_char th_offx2; /* смещение данных, rsvd */
    #define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
    u_char th_flags;
    #define TH_FIN 0x01
    #define TH_SYN 0x02
    #define TH_RST 0x04
    #define TH_PUSH 0x08
    #define TH_ACK 0x10
    #define TH_URG 0x20
    #define TH_ECE 0x40
    #define TH_CWR 0x80
    #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
    u_short th_win;  /* окно */
    u_short th_sum;  /* контрольная сумма */
    u_short th_urp;  /* экстренный указатель */
};

Так как в итоге это все относится к PCAP и нашему загадочному u_char указателю? Эти структуры определяют заголовки, которые предшествуют данным пакета. И как мы в итоге можем разбить пакет? Приготовьтесь увидеть одно из самых практичных использований указателей (для всех новичков в С которые думают что указатели бесполезны говорю: это не так).


Опять же, мы будем предполагать, что мы имеем дело с TCP/IP пакетом Ethernet. Этот же метод применяется к любому пакету. Единственное различие — это тип структуры, которые вы фактически используете. Итак, давайте начнем с определения переменных и определения времени компиляции. Нам нужно будет деконструировать данные пакета.


/* Заголовки Ethernet всегда состоят из 14 байтов */
#define SIZE_ETHERNET 14

const struct sniff_ethernet *ethernet; /* Заголовок Ethernet */
const struct sniff_ip *ip; /* Заголовок IP */
const struct sniff_tcp *tcp; /* Заголовок TCP */
const char *payload; /* Данные пакета */

u_int size_ip;
u_int size_tcp;

И теперь мы делаем наше магическое преобразование типов:


ethernet = (struct sniff_ethernet*)(packet);
ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
size_ip = IP_HL(ip)*4;
if (size_ip < 20) {
    printf("   * Invalid IP header length: %u bytes\n", size_ip);
    return;
}
tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);
size_tcp = TH_OFF(tcp)*4;
if (size_tcp < 20) {
    printf("   * Invalid TCP header length: %u bytes\n", size_tcp);
    return;
}
payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + size_tcp);

Как это работает? Рассмотрим структуру пакета в памяти. u_char указатель — просто переменная содержащая адрес в памяти.


Ради простоты, давайте скажем, что адрес на который указывает этот указатель это Х. Тогда, если наши структуры просто находятся в линии, то первая из них — sniff_ethernet, будет расположена в памяти по адресу Х, так же мы можем легко найти адрес структуры после нее. Этот адрес — это Х плюс длина Ethernet заголовка, которая равна 14, или SIZE_ETHERNET.


Аналогично, если у нас есть адрес этого заголовка, то адрес структуры после него — это сам адрес плюс длина этого заголовка. Заголовок IP, в отличие от заголовка Ethernet, не имеет фиксированной длины. Его длина указывается как количество 4-байтовых слов по полю заголовка IP. Поскольку это количество 4-байтных слов, оно должно быть умножено на 4, что бы указать размер в байтах. Минимальная длина этого заголовка составляет 20 байтов.


TCP заголовок так же имеет вариативную длину, эта длина указывается как число 4-байтных слов, в поле "смещения данных" заголовка TCP, и его минимальная длина так же равна 20 байтам.


Итак, давайте сделаем диаграмму:


VARIABLE LOCATION(in bytes)
sniff_ethernet X
sniff_ip X + SIZE_ETHERNET
sniff_tcp X + SIZE_ETHERNET + {IP header length}
payload X + SIZE_ETHERNET + {IP header length} + {TCP header length}

sniff_ethernet структура, находясь в первой линии, просто находится по адресу Х. sniff_ip, которая следует прямо за sniff_ethernet, это адрес Х плюс такое количество байтов, которое занимает структура sniff_ethernet (14 байтов или SIZE_ETHERNET). sniff_tcp находится прямо после двух предыдущих структур, так что его локация это — X плюс размер Ethernet, и IP заголовок. (14 байтов, и 4 раза длина заголовка IP). Наконец, данные (для которых не существует определенной структуры) расположены после них всех.


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


Завершение


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


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

This document is Copyright 2002 Tim Carstens. All rights reserved. Redistribution and use, with or without modification, are permitted provided that the following conditions are met:
Redistribution must retain the above copyright notice and this list of conditions.
The name of Tim Carstens may not be used to endorse or promote products derived from this document without specific prior written permission.
/ Insert 'wh00t' for the BSD license here /
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/337840/


Метки:  

Создание и нормализация словарей. Выбираем лучшее, убираем лишнее

Среда, 13 Сентября 2017 г. 13:37 + в цитатник
antgorka сегодня в 13:37 Разработка

Создание и нормализация словарей. Выбираем лучшее, убираем лишнее



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

    Инструменты


    crunch

    Пожалуй, один из самых известных инструментов для быстрого создания словарей. Он по умолчанию входит в популярный дистрибутив для проведения пентеста Kali Linux.

    Инструмент работает в нескольких режимах:

    Создание словаря, состоящего из перечисленных символов, например чисел

    crunch 4 5 1234567890 -o all_numbers_from_4_to_5.txt



    Создается словарь длиной от четырех до пяти цифр.

    Создание словаря по шаблону

    crunch 10 10 qwe RTY 123 \#\@ -t P^@@,ord%% -o Password_template.txt
    



    Сперва указывается длина пароля — 10 символов. Затем перечисляются наборы символов: буквы в нижнем регистре, буквы в верхнем регистре, цифры и спецсимволы. Ключ -t задает шаблон, где

    • ^ — спецсимволы
    • @ — буквы в нижнем регистре
    • , — буквы в верхнем регистре
    • % — цифры

    И третий режим работы crunch — перестановки.

    crunch 1 1 -p Alex Company Position



    Словарь состоит из всех возможных комбинаций слов Alex, Company и Position.

    Подробнее изучить инструмент можно через стандартные man страницы, они достаточно подробные.

    maskprocessor

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

    Вы можете задать до четырех собственных наборов символов и использовать готовые наборы

    ?l = abcdefghijklmnopqrstuvwxyz
    ?u = ABCDEFGHIJKLMNOPQRSTUVWXYZ
    ?d = 0123456789
    ?s =  !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
    ?a = ?l?u?d?s
    ?b = 0x00 - 0xff

    Пример использования

    mp64.bin -1 Pp -2 \@\#\$ ?1assw?2r?d



    Или можно задать набор из цифр, но добавить к нему еще несколько спецсимволов так

    mp64.bin -1 Qq -2 ?d\@\#\$ ?1werty_12?2

    Получаем такой результат



    John the Ripper

    Популярный брутфорсер John the Ripper (JTR) тоже позволяет генерировать словари на основе правил. Делается это при помощи ключа --rules, а сами правила описываются в файле john.conf

    Вот так выглядит стандартное правило, используемое для взлома NTLM хэша

    [List.Rules:NT]
    :
    -c T0Q
    -c T1QT[z0]
    -c T2QT[z0]T[z1]
    -c T3QT[z0]T[z1]T[z2]
    -c T4QT[z0]T[z1]T[z2]T[z3]
    -c T5QT[z0]T[z1]T[z2]T[z3]T[z4]
    -c T6QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]
    -c T7QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]
    -c T8QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]
    -c T9QT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]
    -c TAQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]
    -c TBQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]T[zA]
    -c TCQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]T[zA]T[zB]
    -c TDQT[z0]T[z1]T[z2]T[z3]T[z4]T[z5]T[z6]T[z7]T[z8]T[z9]T[zA]T[zB]T[zC]

    В первой строчке сказано, что нужно изменить регистр символа на нулевой позиции (T0), символ Q позволяет не допустить дубликатов в результирующем словаре. Во второй строке символ на первой позиции меняет свой регистр, затем скобки задают препроцессор, чтобы были сгенерированы пароли и с измененным нулевым символом и так далее.

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

    john -w:QWERTY123.dict --stdout --rules:NT
    



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

    hashcat-tools

    Еще одним полезным инструментом является набор утилит от популярного брутфорсера hashcat.

    Скачать их можно с официального сайта.

    Рассмотрим некоторые их них. Описания всех утилит на английском языке можно найти тут.

    combinanor.bin — позволяет генерировать словарь из слов, входящих в два других словаря.



    combinanor3.bin делает то же самое, но на вход принимает три файла, вместо двух.

    combipow.bin — создает все возможные комбинации из слов, перечисленных в файле (похоже на ключ -p в crunch)



    cutb.bin — обрезает слова в словаре до указанной длины. Можно указывать смещение (offset)



    expander.bin — получает на ввод слова, разбирает их на символы, комбинирует и отправляет в STDOUT



    permute.bin — создает словарь, который используется hashcat при атаке типа Permutation attack. Перед использованием словарь нужно пропустить через утилиту prepare.

    gate.bin — разбивает словарь на несколько частей для параллельной обработки несколькими ядрами или несколькими машинами. В примере ниже мы разбиваем стандартный словарь JTR на две части. В первую часть попадают слова под номером 0, 2, 4, 6,…. Во вторую 1, 3, 5, 7,…



    len.bin — оставляет в словаре только слова определенной длины от min до max



    mli2.bin — объединяет два словаря.

    req-include.bin — крайне полезный инструмент, который убирает из словаря все, что не подходит под заданные правила. Например, вы знаете, что по парольной политике в пароле обязательно присутствует буква в верхнем регистре, цифра и спецсимвол.



    Число выбрано исходя из таблицы



    Если таким образом нормализовать известный словарь rockyou, то можно сократить его размер в 270 раз! и не тратить ресурсы на заведомо ложные комбинации.



    req-exclude.bin делает то же самое, что req-include, но с точностью до наоборот.

    rli.bin — эта утилита удаляет значения из первого словаря, если они встречаются во втором. Полезно использовать, если вы создаете один словарь из нескольких.

    Когда под рукой нет утилит



    Может оказаться так, что воспользоваться набором hashcat-utils или crunch нет возможности, а нужно срочно создать словарь или нормализовать его. Некоторые алгоритмы довольно сложны в реализации, но базовые операции можно выполнить просто в командной строке.

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

    echo 0{1..9}0{1..9}19{60..99} | tr ' ' '\n' >> dates
    



    Если нужно разбить словарь на части для параллельной обработки, можно воспользоваться командой split

    split -d -l 1000 password.lst splitted_



    Быстро объединить два словаря можно так

    cat dict1 dict2 > combined_dict



    Чтобы сделать заглавной первую или последнюю буквы в каждом слове, нужно выполнить, соответственно, команды

    sed 's/^./\u&/' dict_file
    sed 's/.$/\u&/' dict_file

    Для перевода регистра в нижний нужно заметить «u» на «l»

    Дописать что-то в начало каждого слова из словаря можно так

    sed 's/^./word/' dict_file

    А так можно дописать слово в конец

    sed 's/.$/word/' dict_file
    

    Следующей командой можно добавить в начало число от 0 до 99 к каждому слову в словаре

    for i in $(cat dict_file) ; do seq -f %02.0f$i 0 99 ; done > numbers_dict_file
    

    Можно очистить словарь от значений, в которых не присутствует хотя бы 2 числа так

    nawk 'gsub("[0-9]","&",$0)==2' password.lst

    Получаем



    Это лишь некоторые примеры. Можно писать более сложные обработки на Python и других скриптовых языках. Но всегда нужно помнить, что создание качественного словаря и его нормализация под целевой протокол — важный этап при проведении тестирования на проникновение.
    Original source: habrahabr.ru (comments, light).

    https://habrahabr.ru/post/337718/


    Метки:  

    Отчет по пентесту: краткое руководство и шаблон

    Среда, 13 Сентября 2017 г. 13:18 + в цитатник
    alexdorofeeff сегодня в 13:18 Разработка

    Отчет по пентесту: краткое руководство и шаблон

    • Tutorial

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




    Читатели


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


    • Кто будет читать отчет?
    • Что читатели ждут от данного документа?

    В случае отчета по тестированию защищенности в качестве читателей выступают:


    • Генеральный директор;
    • Руководитель департамента информационной безопасности;
    • Руководитель департамента информационных технологий.

    Генеральный директор оплачивает наши услуги по тестированию защищенности и ожидает увидеть в отчете основные результаты: можно ли проникнуть в сеть его компании и какую информацию можно таким образом получить.


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


    • Какие уязвимости и в каких системах были обнаружены?
    • Сможет ли потенциальный злоумышленник их использовать?
    • К какой информации возможен доступ?
    • Какие инструменты взлома использовались?
    • Что необходимо делать для закрытия уязвимостей?

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


    Писатели


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


    Специалистам по тестированию защищенности в отчете необходимо продемонстрировать что:


    • работы были выполнены в полном объеме в соответствии с договоренностями с заказчиком;
    • свидетельства проведенного тестирования защищенности достаточны для подтверждения сделанных заключений.

    Теперь мы можем разработать соответствующую структуру отчета.


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


    Структура отчета по тестированию защищенности


    Разберем ключевые элементы отчета по тестированию защищенности.


    Раздел «Резюме для руководства»
    Раздел на одну, максимум, две страницы в котором пишем, что и зачем мы делали, описываем основные результаты и выводы, приводим ключевые рекомендации. Технические термины стараемся не использовать, так как читатели – высшее руководство, которое не всегда обладает хорошими познаниями в области ИТ/ИБ.


    Раздел «Границы проекта»


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


    Раздел «Наш подход»


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


    Полезным будет и сопоставление этапов тестирования защищенности с выявленными уязвимостями.


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


    Описание выявленных уязвимостей


    Основной объем отчета о тестировании защищенности составят описания обнаруженных уязвимостей. Для аудиторских отчетов, а отчет о тестировании защищенности без сомнения относится к данной категории, классической является следующая структура представления информации: наблюдение(finding) – риск – рекомендация.


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


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


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


    Вместо заключения


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


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


    Полезные ссылки


    1. Шаблон отчета по тестированию защищенности от учебного центра «Эшелон»
    2. Коллекция отчетов по тестированию на проникновение: https://github.com/juliocesarfort/public-pentesting-reports
    Original source: habrahabr.ru (comments, light).

    https://habrahabr.ru/post/337824/


    Метки:  

    Миграция схемы данных без головной боли: идемпотентность и конвергентность для DDL-скриптов

    Среда, 13 Сентября 2017 г. 13:15 + в цитатник
    IvanPonomarev сегодня в 13:15 Разработка

    Миграция схемы данных без головной боли: идемпотентность и конвергентность для DDL-скриптов

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

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

      image


      Я думаю, на разных этапах своей карьеры в IT мы все сталкивались с тем, как это бывает тяжело: контролировать структуру рабочей базы данных и выполнять её обновления по мере разворачивания новых версий софта. Баги, возвращающиеся после того, как их вроде уже исправили, ошибки «поле отсутствует в таблице», жалобы «я исправил хранимку, а вы затёрли!» — знакомо ли вам это всё?

      Острота этой проблемы особенно ясна по контрасту с тем, насколько кардинально решена задача контроля версий исходного кода: системы типа Git или Subversion позволяют вам держать под контролем совместную работу многих разработчиков, не терять ни одного изменения, «записывать все ходы» и собирать результаты труда команды воедино. Но эта благостная картина заканчивается там, где заканчивается область применимости систем контроля версий. Если мы говорим о структуре схемы данных, то до сих пор применение систем контроля версий для их разработки — весьма ограничено.

      Так легко и соблазнительно бывает внести изменения структуры прямо на базе! Если такие изменения оказываются не задокументированы, то в будущем наступает необходимость развивать систему и приближается катастрофа. Но и осознав необходимость документировать каждый шаг по изменению структуры БД, мы приходим к тому, что делать это — очень неудобно, а язык DDL определения схемы данных нам в этом никак не помогает. Например, добавление поля в таблицу требует команды ALTER TABLE ADD. Выполнить это выражение имеет смысл ровно один раз и ровно тот самый момент, когда в таблице поле ещё отсутствует, а необходимость в нём – уже есть. Выполнение этого скрипта в другие моменты приведёт либо к ошибке выполнения самого скрипта, либо, что хуже, к неправильному состоянию структуры базы данных.

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

      Подход №1: накопление change-скриптов


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

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

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

      Во-первых, change-скрипты накапливаются. Достаточно долго идущий проект тянет за собой большой «хвост» из этих скриптов, большинство из которых утрачивают свою актуальность, т. к. содержат в себе изменения, выполненные очень давно. Сохранение всего «хвоста» бывает бессмысленно, т. к. изменение в одном месте лога может отменять результат изменения в другом месте: допустим, в ходе развития системы мы попробовали какой-то вариант и отказались от него, но два изменения уже навсегда остаются change-log-е. Глядя на разросшийся лог, становится невозможно понять наше текущее представление о структуре базы. А если мы хотим воспроизвести структуру базы данных «с нуля» на, допустим, совершенно новом проекте, нам придётся в процессе выполнения скрипта повторять весь её путь эволюционного развития!

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

      Допустим, у вас есть код, описывающий класс в вашем любимом языке программирования, и вам в процессе улучшения системы понадобилось один метод в класс добавить, а другой – удалить. Что вы делаете? Берёте и меняете исходный код класса, а затем коммитите его на систему контроля версий, не так ли? Не вынуждены же вы создавать change set с командами вида:

      alter class drop method foo;
      alter class add method bar(…) {

      }


      Почему мы должны это делать для структуры схемы данных?

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

      Подход №2: идемпотентный DDL-скрипт


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

      Как автоматизировать установку нужного софта на сервер и обеспечить обновление конфигураций? Мы можем написать shell-скрипт, который, будучи выполнен на пустой виртуальной машине, всё на ней установит и сконфигурирует. Это аналог скрипта создания структуры БД (CREATE TABLE…-скрипта), но его проблема в том, что он может быть выполнен только один раз и только на пустой машине. Если машина уже развёрнута и работает, а по новой спецификации для работы системы нам нужна, например, другая версия Java, как тут постуить — дописывать change скрипт, сносящий старую версию и устанавливающий новую версию Java? Ну а если нам нужно будет воспроизвести конфигурацию на пустой машине — нам что же, проходить через все шаги, которые мы прошли исторически?

      Главный, ключевой вопрос, который при этом возникает: можно ли править инфраструктуру/схему данных так же легко, как мы правим исходный код – прямым изменением её описания и записи в контроль версий?

      Ответом на эти вопросы для задачи конфигурирования серверов явилось появление принципа Infastructure as Code (IaC) и целого класса систем, известных как configuration management-системы: Ansible, Chef, Puppet и т. д. В основе всех систем этого вида стоят два главных принципа: идемпотентность (idempotence) и конвергентность (сходимость, convergence). Оба этих термина позаимствованы из математики. Если отбросить ненужный формализм, применительно к нашей проблематике термины эти обозначают следующее:

      1. Идемпотентный и конвергентный скрипт описывает не действия, которые надо произвести над объектом, а состояние, в которое нужно привести объект.
      2. Идемпотентность означает, что если такой скрипт выполнен успешно и объект уже находится в нужном состоянии, то повторное выполнение скрипта ничего не изменит и ни к чему не приведёт. Например, если мы говорим о скрипте configuration management системы, декларирующем установку необходимых пакетов, то, если эти пакеты уже установлены, при повторном запуске скрипт просто не выполнит никаких операций.
      3. Конвергентность означает, что если скрипт не был выполнен или завершился неуспешно, при его повторном выполнении система будет стремиться к желаемому состоянию. Например, если установка одного из пакетов завершилась с ошибкой, т. к. в момент скачивания пакета пропала сеть, то повторный запуск скрипта приведёт к тому, что пропущенный пакет доустановится (а те, что установились в прошлый раз, останутся на своём месте).


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

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

      CONVERGE TABLE OrderHeader(
      id VARCHAR(30) NOT NULL,
      date DATETIME DEFAULT GETDATE(),
      customer_id VARCHAR(30),
      customer_name VARCHAR(100),
      CONSTRAINT Pk_OrderHeader PRIMARY KEY (id)
      );


      Ключевое слово CONVERGE должно интерпретироваться как «приведи таблицу к желаемой структуре». То есть: если таблицы нет — создай, если таблица есть, посмотри, какие в ней поля, с какими типами, какие индексы, какие внешние ключи, какие default-значения и т. п. и не надо ли что-то изменить в этой таблице, чтобы привести её к нужному виду.

      Если бы базы данных могли поддерживать такое ключевое слово, т. е. если бы была возможность писать для баз данных идемпотентные и конвергентные DDL-скрипты — необходимости в написании этой статьи не возникло бы. Все мы просто держали бы в системе контроля версий “CONVERGE TABLE”-скрипты, описывающие желаемую на текущий момент схему данных, и работали бы с ними точно так же, как работаем с исходным кодом: нужно новое поле в таблице — добавили, нужен другой состав полей в индексе — отредактировали. (Я слышу ваш вопрос: а как же быть с миграцией данных — но терпение, я к этому перейду уже скоро.)

      К сожалению, в мире реляционных БД движения к поддержке настоящей идемпотентности DDL пока этого не происходит. Всё, что до сих пор было сделано в базах данных по направлению к идемпотентности DDL-кода – это поддержка конструкции CREATE IF NOT EXISTS, но это, скажем прямо – довольно слабая попытка. Скрипт CREATE TABLE IF NOT EXISTS, конечно, внешне поведёт себя как идемпотентный (не выдаст ошибку, если таблица уже создана), но не как конвергентный (не будет модифицировать структуру уже созданной таблицы).

      Приходится уповать на внешние инструменты. Идемпотентный и конвергентный DDL доступен, например, в системе Celesta. Чтобы для разработчиков и для инструментов разработки (например, визуального редактора ER-диаграмм) выглядеть как обычный DDL-скрипт, в Celesta применяется ключевое слово CREATE, хотя в Celesta оно обладает смыслом именно гипотетического CONVERGE. При каждом старте, Celesta сравнивает актуальную структуру базы данных, к которой она присоединена, с желаемой структурой, описанной в виде DDL-скрипта CelestaSQL, и при необходимости выполняет минимально необходимую серию CREATE/ALTER/DROP-команд. На сегодня поддерживаются четыре типа баз данных: PostgreSQL, Oracle, MS SQL Server и H2 (последняя, в основном, для нужд организации модульного тестирования).

      Идемпотентный скрипт, задающий структуру БД, нельзя просто взять и линейно выполнить. Как известно, одни объекты в базе данных зависят от других объектов — например, таблицы ссылаются друг на друга через внешние ключи, представления и индексы зависят от таблиц и т. д. Поэтому, прежде чем выполнять серию создания / перестроения объектов, их необходимо ранжировать в порядке зависимости друг от друга: говоря формально, выполнить топологическую сортировку графа зависимостей, и далее обрабатывать объекты, начиная с тех, от которых не зависит ничего. Часто бывает необходимо сбросить внешние ключи, чтобы затем восстановить их после модификации соединяемых ими таблиц. Эта задача решена в Celesta, и это позволяет без проблем выполнять апгрейд для абсолютного большинства случаев.

      Миграция данных


      Так как же быть с трансформацией данных, ведь простого ALTER не всегда достаточно? Что делать, если мы, допустим, захотим добавить в непустую таблицу NOT NULL-поле и не снабдим его DEFAULT-значением? Ведь если такое поле не заполнить предварительно данными, то база данных не даст выполнить ALTER TABLE ADD-скрипт. А если мы хотим добавить Foreign Key, но не все данные в таблице удовлетворяют ограничению? А если, допустим, логика приложения изменилась и требуется перенести данные из одного столбца в другой?

      Всё это вопросы совершенно корректные, но для начала заметим, что для большинства изменений, которые вы производите в базе данных в процессе развития вашего приложения, никакой миграции не требуется и простого ALTER-скрипта достаточно. Вам не надо мигрировать данные, если вы просто добавляете новую таблицу или новую колонку в таблицу (NULLABLE или с DEFAULT-значением). Вам не надо мигрировать данные, если вы добавляете или перестраиваете индекс. Не нужно ничего мигрировать, если изменяется запрос для view. Практика применения системы Celesta показывает, что подавляющее большинство производимых разработчиками изменений относится именно к такому типу.

      Если же миграция данных действительно необходима, то, да: придётся написать и выполнить одноразовый миграционный скрипт. Вот только сохранять этот скрипт «на века» не нужно и история с его отладкой и применением гораздо проще, чем в системах, построенных на change log.

      Рассмотрим случай добавления внешнего ключа на непустую таблицу, не все записи которой удовлетворяют такому ключу. В процессе обновления Celesta попробует создать такой ключ при помощи команды ALTER TABLE … ADD CONSTRAINT … FOREIGN KEY. Если ей это удаётся – отлично, если нет – система останавливается и Celesta сообщает, что апдейт такого-то объекта она выполнить полностью не сумела по такой-то причине, с таким-то сообщением БД.

      Для changelog-систем нет ничего хуже changeset-а, выполнившегося наполовину и зафиксированного в промежуточном состоянии: в такой ситуации система находится «посередине» между двумя ревизиями и ситуацию можно разрулить лишь вручную. Отсутствие поддержки откатываемых DDL-транзакций во многих базах вносит дополнительные трудности.

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

      Столкнувшись с ситуацией, когда апдейт не может быть выполнен автоматически (ситуация, повторюсь, довольно редкая), вы можете сделать одноразовый скрипт. Допустим, наполняющий таблицу-справочник нужными данными и тем самым создающий для Celesta условия автоматического выполнения апдейта. Этот скрипт можно отладить на свежей копии production-базы, затем выполнить на production базе, затем произвести Celesta-апдейт.

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

      Возможно, такой подход покажется кому-то менее надёжным, чем использование changelog-систем, которые заставляют вас думать о необходимых шагах по миграции данных при каждом изменении структуры и о встраивании таких шагов в changeset. Но если подумать, то становится понятно, что надёжность changelog-систем в этом плане – мнимая. Как известно, не бывает программ без потенциальных ошибок, это правило относится и к скриптам модификации данных. Тот факт, что на имеющемся у вас наборе данных скрипт модификации change set-а был отлажен и показал корректную работу, на самом деле не гарантирует со 100% уверенностью, что он выполнится без ошибок на любых данных. В случае с применением идемпотентного DDL мы по крайней мере не объявляем скрипт модификации данных не подлежащим изменению, защищённым контрольной суммой атрибутом ревизии. В случае, если ошибка всё же произойдёт, мы всегда можем повторять попытки апдейта до тех пор, пока не сведём систему к желаемой структуре. Ваши данные не будут потеряны, т. к. Celesta никогда автоматически не выполняет drop столбцов и таблиц, содержащих данные, оставляя эту операцию на выполнение вручную.

      * * *



      К сожалению, область применения CelestaSQL ограничена использованием его в паре с системой Celesta для создания кода бизнес-логики, поэтому именно для вашего проекта на сегодня, пожалуй, я бы порекомендовал Liquibase. Однако Celesta — проект открытый и одно из возможных направлений его развития – создание инструмента миграции структуры БД общего назначения.

      Хотя лично я бы предпочёл, чтобы разработчики БД когда-нибудь реализовали реальную поддержку идемпотентности и конвергентности DDL.
      Original source: habrahabr.ru (comments, light).

      https://habrahabr.ru/post/337816/


      Метки:  

      Настройка двухфакторной аутентификации в домене Astra Linux Directory

      Среда, 13 Сентября 2017 г. 12:37 + в цитатник
      shuralev сегодня в 12:37 Разработка

      Настройка двухфакторной аутентификации в домене Astra Linux Directory

        В этом посте мы решили рассказать о доменной аутентификации в Linux, с использованием смарт-карт и USB-токенов JaCarta PKI в качестве второго фактора аутентификации. Если о локальной аутентификации через PAM-модуль информации существует довольно много, то вопрос доменной инфраструктуры и аутентификация по Kerberos-билетам в Linux рассмотрен слабо, особенно на русском языке. В качестве операционной системы возьмем Astra Linux и на примере Astra Linux Directory (ALD) это и покажем.

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


        Немного вводных об Astra Linux Directory (ALD) и JaCarta PKI


        Домен Astra Linux Directory (ALD) предназначен для организации единого пространства пользователей (домена локальной вычислительной сети) в автоматизированных системах.

        ALD использует технологии LDAP, Kerberos5, Samba/CIFS и обеспечивает:

        • централизованное хранение и управление учетными записями пользователей и групп;
        • сквозную аутентификацию пользователей в домене с использованием протокола Kerberos5;
        • функционирование глобального хранилища домашних директорий, доступных по Samba/CIFS;
        • автоматическую настройку файлов конфигурации UNIX, LDAP, Kerberos, Samba, PAM;
        • поддержку соответствия БД LDAP и Kerberos;
        • создание резервных копий БД LDAP и Kerberos с возможностью восстановления;
        • интеграцию в домен входящих в дистрибутив СУБД, серверов электронной почты, Web-серверов, серверов печати и другие возможности.


        JaCarta PKI — это линейка PKI-токенов для строгой аутентификации пользователей в корпоративных системах, безопасного хранения ключевых контейнеров программных СКЗИ и цифровых сертификатов российского производителя – компании «Аладдин Р.Д.».



        В среде Astra Linux Directory (ALD) электронные ключи JaCarta PKI могут использоваться для двухфакторной аутентификации пользователя в домене ALD и отказа от паролей. Кроме того, с этими же электронными ключами можно выполнять различные сценарии внутри ОС, после аутентификации, такие, как: электронная подпись, хранение ключевых контейнеров, доступ к Web-ресурсам, проброс ключа в сессии MS Windows. Доступ к VDI сервисам, таким, как VmWare или Citrix.

        Процесс настройки


        Пример демо-зоны


        • Сервер — Astra Linux Smolensk SE 1.5 4.2.0-23-generic, x86_64, с установленными пакетами:
          • JaCarta IDProtect 6.37;
          • libccid;
          • pcscd;
          • libpcsclite1;
          • krb5-pkinit;
          • libengine-pkcs11-openssl;
          • opensc.

        • Клиент — Astra Linux Smolensk SE 1.5 4.2.0-23-generic, x86_64, с установленными пакетами:
          • JaCarta IDProtect 6.37;
          • libccid;
          • pcscd;
          • libpcsclite1;
          • krb5-pkinit.


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

        Установка драйверов на сервер и клиент


        Для обеспечения работы со смарт-картой JaCarta PKI на клиенте и сервере установите следующие пакеты: libccid, pcscd, libpcsclite1. После установки этих обязательных пакетов установите пакет драйверов IDProtectClient, который можно загрузить с официального сайта «Аладдин Р.Д.».

        Для обеспечения работы со смарт-картой подсистемы Kerberos добавочно к предустановленным пакетам ald/kerberos установите пакет krb5-pkinit на клиенте и сервере.

        Для обеспечения возможности выпуска ключей и сертификатов на JaCarta PKI на сервере также установите пакеты libengine-pkcs11-openssl и opensc.

        Установка и настройка центра сертификации на сервере


        В качестве центра сертификации (CA) будет использован OpenSSL.

        OpenSSL — криптографический пакет с открытым исходным кодом для работы с SSL/TLS. Позволяет создавать ключи RSA, DH, DSA и сертификаты X.509, подписывать их, формировать CSR и CRT.

        Все настройки в руководстве выполняются для тестового домена EXAMPLE.RU. Примем, что сервер и клиент принадлежат домену EXAMPLE.RU, имя сервера – kdc, а клиента – client. При настройке используйте имя вашего домена, сервера и клиента. Выполните следующие действия.

        1. Создайте каталог CA командой mkdir /etc/ssl/CA и перейдите в него. В этом каталоге будут размещаться сгенерированные ключи и сертификаты.

        2. Создайте ключ и сертификат CA:
          $ openssl genrsa -out cakey.pem 2048
          $ openssl req -key cakey.pem -new -x509 –days 365 -out cacert.pem
          В диалоге заполните необходимую информацию о вашем центре сертификации. В Common name указать EXAMPLE.RU.
        3. Создайте ключ и сертификат KDC:
          $ openssl genrsa -out kdckey.pem 2048
          $ openssl req -new -out kdc.req -key kdckey.pem
          В диалоге заполните необходимую информацию о вашем сервере. В Common name указать kdc.
        4. Установите переменные среды. Переменные среды устанавливаются в рамках сессии и не устанавливаются для других сессий и не сохраняются после закрытия сессии.
          export REALM=EXAMPLE.RU — Ваш домен
          export CLIENT=kdc — Вашего сервер

        5. Загрузите файл pkinit_extensions http://dms.aladdin-rd.ru/970c5538-afbf-4a26-a7ef-d76550cbc435

        Содержимое файла pkinit_extensions (его следует положить в тот каталог, откуда вы выполняете команды):
         [ kdc_cert ]
        basicConstraints=CA:FALSE
         
        # Here are some examples of the usage of nsCertType. If it is omitted
        keyUsage = nonRepudiation, digitalSignature, keyEncipherment, keyAgreement
         
        #Pkinit EKU
        extendedKeyUsage = 1.3.6.1.5.2.3.5
         
        subjectKeyIdentifier=hash
        authorityKeyIdentifier=keyid,issuer
         
        # Copy subject details
         
        issuerAltName=issuer:copy
         
        # Add id-pkinit-san (pkinit subjectAlternativeName)
        subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:kdc_princ_name
         
        [kdc_princ_name]
        realm = EXP:0, GeneralString:${ENV::REALM}
        principal_name = EXP:1, SEQUENCE:kdc_principal_seq
         
        [kdc_principal_seq]
        name_type = EXP:0, INTEGER:1
        name_string = EXP:1, SEQUENCE:kdc_principals
         
        [kdc_principals]
        princ1 = GeneralString:krbtgt
        princ2 = GeneralString:${ENV::REALM}
         
        [ client_cert ]
         
        # These extensions are added when 'ca' signs a request.
         
        basicConstraints=CA:FALSE
         
        keyUsage = digitalSignature, keyEncipherment, keyAgreement
         
        extendedKeyUsage =  1.3.6.1.5.2.3.4
        subjectKeyIdentifier=hash
        authorityKeyIdentifier=keyid,issuer
         
         
        subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:princ_name
         
         
        # Copy subject details
         
        issuerAltName=issuer:copy
         
        [princ_name]
        realm = EXP:0, GeneralString:${ENV::REALM}
        principal_name = EXP:1, SEQUENCE:principal_seq
         
        [principal_seq]
        name_type = EXP:0, INTEGER:1
        name_string = EXP:1, SEQUENCE:principals
         
        [principals]
        princ1 = GeneralString:${ENV::CLIENT} 


        1. Выпустите сертификат KDC:
          $ openssl x509 -req -in kdc.req -CAkey cakey.pem -CA cacert.pem -out kdc.pem -extfile pkinit_extensions -extensions kdc_cert –CAcreateserial –days 365

        2. Файлы kdc.pem, kdckey.pem, cacert.pem перенесите в /var/lib/krb5kdc/

        3. Создайте резервную копию файла /etc/krb5kdc/kdc.conf. Отредактируйте /etc/krb5kdc/kdc.conf, дополнив секцию [kdcdefaults] следующими записями:
          pkinit_identity = FILE:/var/lib/krb5kdc/kdc.pem,/var/lib/krb5kdc/kdckey.pem
          pkinit_anchors = FILE:/var/lib/krb5kdc/cacert.pem
          Первая запись задает ключи и сертификат сервера, а вторая указывает на корневой сертификат центра сертификации.

        4. Для принятия изменений выполните:
          /etc/init.d/krb5-admin-server restart
          /etc/init.d/krb5-kdc restart


        Подготовка смарт-карты. Выпуск ключей и сертификата пользователя


        Убедитесь в том, что установлены пакеты libengine-pkcs11-openssl и opensc. Подключите устройство, которое следует подготовить.

        Проинициализируйте устройство, установите PIN-код пользователя. Помните, что инициализация устройства удалит все данные на JaCarta PKI без возможности восстановления.

        Для инициализации необходимо воспользоваться утилитой pkcs11-tool.

        pkcs11-tool --slot 0 --init-token --so-pin 00000000 --label 'JaCarta PKI' --module /lib64/libASEP11.so,

        где:

        --slot 0 — указывает, в какой виртуальный слот подключено устройство. Как правило, это слот 0, но могут быть и другие значения – 1,2 и т.д.;

        --init-token – команда инициализации токена;

        --so-pin 00000000 – PIN-код администратора JaCarta PKI. По умолчанию имеет значение 00000000;

        --label 'JaCarta PKI' – метка устройства;

        --module /lib64/libASEP11.so — указывает путь до библиотеки libASEP11.so. Устанавливается в рамках пакета idprotectclient см. раздел «Установка драйверов на сервер и клиент».

        Для задания PIN-кода пользователя используйте команду:

        pkcs11-tool --slot 0 --init-pin --so-pin 00000000 --login --pin 11111111 --module /lib64/libASEP11.so,

        где:

        --slot 0 — указывает, в какой виртуальный слот подключено устройство. Как правило, это слот 0, но могут быть и другие значения – 1,2 и т.д.;

        --init-pin – команда установки PIN-кода пользователя;

        --so-pin 00000000 – PIN-код администратора JaCarta PKI. По умолчанию имеет значение 00000000;

        --login – команда логина;

        --pin 11111111 – задаваемый PIN-код пользователя;

        --module /lib64/libASEP11.so — указывает путь до библиотеки libASEP11.so. Устанавливается в рамках пакета idprotectclient см. раздел «Установка драйверов на сервер и клиент».

        Сгенерируйте ключи на устройстве, для этого введите следующую команду:

        pkcs11-tool --slot 0 --login --pin 11111111 --keypairgen --key-type rsa:2048 --id 42 --label “test1 key” --module /lib64/libASEP11.so,

        где:

        --slot 0 — указывает, в какой виртуальный слот подключено устройство. Как правило, это слот 0, но могут быть и другие значения – 1,2 и т.д.;

        --login --pin 11111111 — указывает, что следует произвести логин под пользователем с PIN-кодом «11111111». Если у Вашей карты другой PIN-код пользователя, укажите его;

        --keypairgen --key-type rsa:2048 — указывает, что должны быть сгенерированы ключи длиной 2048 бит;

        --id 42 — устанавливает атрибут CKA_ID ключа. CKA_ID может быть любым;

        Запомните это значение! Оно необходимо для дальнейших шагов подготовки устройства к работе.

        --label “test1 key” — устанавливает атрибут CKA_LABEL ключа. Атрибут может быть любым;

        --module /lib64/libASEP11.so — указывает путь до библиотеки libASEP11.so. Устанавливается в рамках пакета idprotectclient см. раздел «Установка драйверов на сервер и клиент».

        Сгенерируйте запрос на сертификат с помощью утилиты openssl. Для этого введите следующие команды:

        #openssl
        OpenSSL> engine dynamic -pre SO_PATH:/usr/lib/ssl/engines/engine_pkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/lib64/libASEP11.so
        OpenSSL> req -engine pkcs11 -new -key 0:42 -keyform engine -out client.req -subj "/C=RU/ST=Moscow/L=Moscow/O=Aladdin/OU=dev/CN=test1 (!Ваш_Пользователь!)/emailAddress=test1@mail.com"
        OpenSSL>quit. 


        Обратите внимание на -new -key 0:42, где 0 — номер виртуального слота с устройством, 42 — атрибут CKA_ID сгенерированных раннее ключей.

        Информацию, которую необходимо указать в запросе, следует задавать в поле "/C=RU/ST=Moscow/L=Moscow/O=Aladdin/OU=dev/CN=test1 (! Ваш_Пользователь!)/emailAddress=test1@mail.com".

        Необходимо установить переменные окружения

        $ export REALM=EXAMPLE.RU #Ваш домен
        $ export CLIENT=test1 #Ваш пользователь

        и выпустить сертификат на пользователя.

        $ openssl x509 -CAkey cakey.pem -CA cacert.pem -req -in client.req -extensions client_cert -extfile pkinit_extensions -out client.pem –days 365

        Далее перекодируйте полученный сертификат из PEM в DER.

        # openssl x509 -in client.pem -out client.cer -inform PEM -outform DER

        Запишите полученный сертификат на токен.

        pkcs11-tool --slot 0 --login --pin 11111111 --write-object client.cer --type 'cert' --label 'Certificate' --id 42 --module /lib/libASEP11.so,

        где:

        --slot 0 — указывает, в какой виртуальный слот подключено устройство. Как правило, это слот 0, но могут быть и другие значения – 1,2 и т.д.;

        --login --pin 11111111 — указывает, что следует произвести логин под пользователем с PIN-кодом «11111111». Если у Вашей карты другой PIN-код пользователя, укажите его;

        --write-object ./client.cer — указывает, что необходимо записать объект и путь до него;

        --type 'cert' — указывает, что тип записываемого объекта – сертификат;

        'cert' --label 'Certificate' — устанавливает атрибут CKA_LABEL сертификата. Атрибут может быть любым;

        --id 42 — устанавливает атрибут CKA_ID сертификата. Должен быть указан тот же CKA_ID, что и для ключей;

        --module /lib64/libASEP11.so — указывает путь до библиотеки libASEP11.so.

        Настройка клиента. Проверка работоспособности


        Создайте на клиенте каталог /etc/krb5/. Скопируйте в /etc/krb5/ сертификат CA (cacert.pem) c сервера.

        Настройте kerberos в /etc/krb5.conf. Секцию [libdefaults] дополните следующими строками.

         [libdefaults]
        default_realm = EXAMPLE.RU
        pkinit_anchors = FILE:/etc/krb5/cacert.pem
        # для аутентификации по токену
        pkinit_identities = PKCS11:/lib64/libASEP11.so

        Выполните проверку:

        kinit Когда появится строка запроса PIN-кода к карте, введите его.

        Для проверки того, что kerberos-тикет был успешно получен для пользователя, введите команду klist. Для удаления тикета — kdestroy.

        Для входа в домен по смарт-карте на экране входа в ОС вместо пароля введите PIN-код от смарт-карты.

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

        Original source: habrahabr.ru (comments, light).

        https://habrahabr.ru/post/337820/


        Найм тестировщиков — по обе стороны баррикад

        Среда, 13 Сентября 2017 г. 12:01 + в цитатник
        DarinaCharisma сегодня в 12:01 Управление

        Найм тестировщиков — по обе стороны баррикад

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


          Не будет нам обоим накладно


          В первую очередь — потому что, как и на всех остальных рынках, работодатели — особенно в текущей экономической ситуации — систематически завышают требования к кандидатам, понижая планку предлагаемых доходов, а кандидаты, наоборот, пытаются получить за свои услуги как можно больше. По результатам опросов тестировщиков за 2016 и 2017 гг., в которых приняло участие более 1,5 тыс. человек, можно видеть, что чаще всего тестировщик в Москве получает от 75 до 110 тыс. р. в месяц. Имеет место определенная зависимость от опыта специалиста — если человеку с опытом работы менее одного года едва ли стоит надеяться на зарплату выше 75 тыс. р., то тестировщики, отработавшие 1–3 года, получают до 110 тыс. р., тестировщики с 3–6-летним опытом — до 150 тыс. р., а зарплата тестировщиков с более чем 8-летним опытом в текущем году начинается от 160 и переваливает за отметку в 200 тыс. р.


          В Санкт-Петербурге более выражена динамика роста зарплат тестировщиков — если в 2016 г. большинство специалистов получало 50–75 тыс. р., то в 2017 г. — 90–110 тыс. р. Зависимость зарплаты от опыта работы аналогична московской, но потолок зарплаты у самых опытных тестировщиков крайне редко превышает 200 тыс. р.

          По России все выглядит несколько менее впечатляюще. Основная масса специалистов по тестированию программного обеспечения может рассчитывать на зарплаты от 25 до 55 тыс. р., тестировщики с опытом работы до 6 лет — до 75 тыс. р., с опытом работы до 8 лет — до 90 тыс. р., самые опытные — до 110 тыс. р. Хотелось бы сказать что-нибудь позитивное по результатам опроса о зарплатах удаленной работы, но данных слишком мало для составления репрезентативной выборки — можно ориентироваться разве что на самые «кучные» ответы, сосредоточенные в диапазоне от 45 до 75 тыс. р.



          К сожалению, у нас совсем мало данных о зарплатах тестировщиков-киевлян. По территории Украины данных несколько больше, и можно сделать вывод о том, что зарплаты основной массы украинских специалистов по тестированию лежат в пределах 0,3–1,3 тыс. долл., что комплементарно распределению зарплат по российским регионам. Зарплаты тестировщиков с опытом до 3 лет доходят до 1,5 тыс. долл., а тестировщики с опытом работы до 6 лет могут получать и 2,5–3 тыс. долл., как и их старшие товарищи. Подобная картина наблюдается и в Минске, а вот по Беларуси за пределами Минска данных слишком мало, чтобы вывести из них какие-либо закономерности. Правда, не исключено, что в этой картине не в полной мере отражены показатели украинских компаний, занимающихся аутсорсинговой разработкой для зарубежного рынка, но более точных данных у нас пока нет.



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

          Чего ты взыскался?


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

          Другая сторона этой проблемы заключается в том, что, увы, собеседование все чаще превращается в процесс отсева подходящих кандидатов. Коллеги-кадровики, вы понимаете, что ваш любимый вопрос о канализационных люках уже стал притчей во языцех? Легче найти кандидата, который не смотрел «Игру престолов», чем того, кто не знает про канализационные люки. Это касается и ответов на другие 20–30 ваших любимых вопросов «на логику, эрудицию и креативное мышление» — все они давно опубликованы в Интернете.

          Скажите, почему вы так уверены, что лучший кандидат — это тот, кто пришел в идеально отглаженном дорогом костюме, отвечает на вопросы с лицом игрока в покер, помнит тригонометрию и термодинамику, и успешно проходит стресс-интервью — или, хуже того, полиграф? Почему вы так настойчиво спрашиваете о причинах ухода с предыдущего места работы, о причинах выбора «именно нашей компании», о «ваших главных достоинствах и недостатках», о семейном положении и детях, о том, кем кандидаты видят себя через 5–10 лет и о том, какую пользу они могут принести компании? По всем этим вопросам уже сотни раз проехались психологи, журналисты и блогеры; во многом именно из-за подобных вопросов понятие «эйчар» стало нарицательным в плохом смысле слова, и вообще — это so last season.
          Кажется, самой черной ненавистью соискатели ненавидят пресловутое требование кадровиков, которое формулируется как «не более двух мест работы за последние пять лет». Вот что пишут реальные тестировщики с опытом работы более 8 лет — те самые, чьи московские зарплаты сейчас могут составлять более 200 тыс. р.:

          «Две «крайние» работы — не показатель. У меня они по девять месяцев».
          «Я знаю на каком предложении я сменю текущую работу. Но я и пять лет в одной команде работал. И предпочитаю работать долго, потому что интересные мне результаты делаются за 3–5 лет, а не за полгода».
          «В моем случае хотелось все поменять не по какой-то одной причине, а просто из-за психологической усталости от одного места».


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

          • Возраст: 22–25 лет.
          • Высшее образование: физико-математическое, экономическое, в области техники, энергетики или информатики.
          • Опыт в тестировании: 1–3 года.
          • Личные качества: проактивность, целеустремленность, самостоятельность и организованность (как только вы это проверите?)
          • Готовность к полному рабочему дню в офисе.

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

          А теперь разверните ваш перечень в список требуемых вами качеств и умений. Очень важно написать ваш список на том языке, на котором разговаривают, читают и думают потенциальные кандидаты, а не на корпоративном арго, к которому вы привыкли в компании. К сожалению, непонятно оформленные вакансии — одна из причин потери подходящих кандидатов. Чтобы вас правильно поняли, начните описание вакансии с того, чем занимается компания, чем занимается команда, расскажите, почему возникла вакансия. Очень коротко и внятно напишите, как устроен и как автоматизирован процесс тестирования в данный момент, сколько человек в команде, какое место среди них займет успешный кандидат, в чем будут заключаться его обязанности и какие требования предъявляются к его знаниям, умениям и опыту. Готова вакансия? Можно готовиться к интервью.

          Нужен мне работник...


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

          Общие вопросы


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

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

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

          Вопросы о знаниях и компетенциях


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

          Вопросы о развитии и мотивации


          Мотивационные вопросы — самое интересное. Судьба человека, которого вы примете в компанию, будет зависеть не от того, насколько хорошо он в данный момент знаком с Redmine, Trac или Jira, а от его способностей и потребности к обучению (здесь нужны вопросы о том, насколько быстро он может освоить ту или иную систему и какие у него планы на дальнейшее образование), от его карьерных ожиданий (стоит выяснить его взгляды на развитие сотрудников в организации, совмещение обязанностей, работу в команде и взаимоотношения с руководителями), от его умения справляться со стрессом, а главное — от того, что ему действительно нравится делать, что способствует его самореализации, чего он очень хотел бы, но боялся попробовать раньше. Поможет ли его развитию существующая у вас система «выращивания кадров»? А может быть, результаты собеседований помогут вам скорректировать эту систему?

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

          Идет, сам не зная куда


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

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

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

          А канализационные люки делают круглыми для того, чтобы они не проваливались. Запомните это — и не провалитесь.
          Original source: habrahabr.ru (comments, light).

          https://habrahabr.ru/post/337818/


          Метки:  

          Новая уязвимость веб-сервера Apache Struts позволяет удаленно исполнять код

          Среда, 13 Сентября 2017 г. 11:48 + в цитатник
          ptsecurity сегодня в 11:48 Разработка

          Новая уязвимость веб-сервера Apache Struts позволяет удаленно исполнять код



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

            Apache Software Foundation присвоила уязвимости средний уровень опасности, однако Cisco сообщила в своем бюллетене безопасности, что ошибке подвержено множество ее продуктов.

            В чем проблема


            Уязвимость содержится в функциональности Freemarker пакета Apache Struts 2. Freemarker Template Language — это популярный язык шаблонов, который применяется в Apache Struts и многих проектах на основе Java. С его помощью разработчики могут «биндить» значения параметров, передаваемых серверу пользовательским приложением, с внутренними декларированными переменными приложения.

            Некорректная работа механизма позволяет атакующим отправлять серверу выражения Object Graph Navigation Language (OGNL), обработка которых может привести к выполнению на нем произвольного кода.

            На данный момент точно подтвержден факт наличия уязвимости в нескольких продуктах Cisco:

            • Cisco Digital Media Manager — патч для него не будет выпущен, поскольку поддержка продукта официально прекращена 19 августа 2016 года;
            • Cisco Hosted Collaboration Solution for Contact Center;
            • Cisco Unified Contact Center Enterprise;
            • Cisco Unified Intelligent Contact Management Enterprise.

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

            Не только Cisco: взлом Equifax


            Помимо уязвимости CVE-2017-12611 (S2-053), в Apache Struts ранее уже было найдено еще несколько аналогичных ошибок безопасности, среди которых CVE-2017-9805 (S2-052), CVE-2017-9791 (S2-048) и CVE-2017-5638 (S2-045). СМИ сообщали о том, что громкая утечка данных клиентов одного из американских кредитных бюро Equifax была следствием именно уязвимости в Apache Struts.

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

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



            XSS на сайте Equifax, изображение: ZDNet

            По следам истории со взломом Equifax команда разработчиков Apache Struts выпустила заявление, в котором рекомендовала всем пользователям своего веб-сервера не надеяться на отсутствие уязвимостей в нем, а использовать для обеспечения безопасности инфраструктуры специализированные средства. Один из инструментов, позволяющих предотвращать атаки с применением подобных уязвимостей, — это WAF (мы разрабатываем свой межсетевой экран уровня приложений PT Application Firewall).

            Как защититься


            Несмотря на то, что уязвимости CVE-2017-12611 подвержен ряд продуктов Cisco, ее последствия не будут масштабными, поскольку для эксплуатации необходима специфическая конфигурация атакуемого приложения. Если же разработчики не используют конструкции языка шаблонов Freemarker или применяют только сущности read-only для инициализации атрибутов, то эксплуатировать ошибку не удастся.

            Кроме того, эксперты Positive Technologies рекомендуют разработчикам приложений установить Apache Struts версий 2.5.12 или 2.3.34, которые содержат более жестко настроенную конфигурацию Freemarker. Это также поможет снизить риски успешной атаки.
            Original source: habrahabr.ru (comments, light).

            https://habrahabr.ru/post/337760/


            Метки:  

            [Перевод] «Инновации вокруг»: почему описания на сайтах компаний такие непонятные, и чем это плохо

            Среда, 13 Сентября 2017 г. 11:45 + в цитатник

            Метки:  

            Файловый сервер SAMBA на базе Linux CentOS 7

            Среда, 13 Сентября 2017 г. 11:41 + в цитатник
            dklm сегодня в 11:41 Администрирование

            Файловый сервер SAMBA на базе Linux CentOS 7

            • Tutorial


            Привет Хабр!
            После активности шифровальщика Petya 27.07.2017, я отключил SMB1 он же CIFS, и получил производственное оборудование и сетевые МФУ которые не умеют работать на «новых» версиях SMB протокола.

            Как тогда получать данные с «старых» устройств? Как показала практика, отдельная «машина» с Windows не выход, во время атаки кроме доменных «машин» пострадали также не включенные в домен, по этому, а также по лицензионным соображениям я решил использовать Linux.

            Под катом находится пошаговая инструкция по установке и настройке файлового сервера SAMBA на базе CentOS 7:
            — Анонимный доступ
            — Аутентификация и авторизация
            — Интеграция с Active Directory

            Установка CentOS 7


            Сервера работают под управлением VMware ESXi, и по этому я установил CentOS 7 1611 на VM, выделив 1 CPU, 1GB RAM и 3GB HDD.

            LVM я не использую, SWAP раздел не создаю, на загрузочный раздел выделяю 500MB, а все остальное отдаю под корень файловой системы. В качестве файловой системы использую ext4.


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

            Если вы новичок в линукс, делайте копии оригинальных файлов с конфигами, используйте команду cp.
            cp /etc/somefile.conf /etc/somefile.conf.bak


            Получение ip адреса по DHCP


            Если по какой-то причине в сети нету DHCP сервера, вам стоит его поднять. Работать с большим количеством VM без DHCP не удобно.

            Для принудительного обновления или получения ip адреса выполните команду
            dhclient

            Показать ip адрес
            ifconfig


            YUM


            CentOS 7 использует пакетный менеджер YUM. Шпаргалка по yum находится тут.

            Если выход в интернет организован через прокси сервер, добавьте адрес прокси в файл конфигурации /etc/yum.conf, используйте редактор vi или следующую команду
            echo proxy=http://your.proxy:8888 >> /etc/yum.conf

            В случае использования логина и пароля для доступа к прокси серверу, добавьте следующие параметры:
            proxy_username=yum-user
            proxy_password=qwerty


            Установка на VM агентов для взаимодействия с хост сервером


            Для VMware ESXi необходимо установить open-vm-tools
            yum install open-vm-tools

            Для Hyper-V, hyperv-daemons
            yum install hyperv-daemons


            Установка обновлений


            Очень важно установить все доступные обновления
            yum update


            Midnight Commander


            Редактировать файлы без нормального редактора очень не удобно, и я предлагаю использовать mc и mcedit
            yum install mc


            Настройка сети


            Для настройки статического ip адреса и имени хоста можно использовать утилиту nmtui



            В командной строке список сетевых адаптеров можно получить командой
            nmcli device status

            Статический ip и gateway задается следующей командой, где «ens192» это имя сетевого адаптера
            nmcli connection modify “ens192” ipv4.addresses “192.168.1.100/24 192.168.1.1”


            Настройка FQDN


            Пусть полное имя хоста будет ls01.fqdn.com, выполняем команду
            hostnamectl set-hostname ls01.fqdn.com

            Перезагружаем службу имен
            systemctl restart systemd-hostnamed

            Проверить результат можно следующими командами
            hostnamectl status
            hostname
            hostname -s
            hostname -f


            ipv6


            Если протокол ipv6 не используется, логично его отключить, для этого нужно добавить два параметра в файл /etc/sysctl.conf, выполните следующие команды или используйте редактор mcedit
            echo net.ipv6.conf.all.disable_ipv6 = 1 >>  /etc/sysctl.conf
            echo net.ipv6.conf.default.disable_ipv6 = 1 >>  /etc/sysctl.conf


            Перезагрузите службу сети
            service network restart


            SELINUX


            На данном этапе службу SELINUX необходимо отключить, проверить статус службы SELINUX можно командой
            sestatus

            Измените значение SELINUX в файле /etc/selinux/config на SELINUX=disabled затем перезагрузите сервер.
            reboot

            Вернусь к SELINUX в конце статьи

            SAMBA


            Установка
            yum install samba

            Добавление службы в автоматический запуск
            chkconfig smb on

            Запуск службы и проверка состояния
            service smb start
            smbstatus


            firewallD


            По умолчанию CentOS 7 использует брандмауэр firewallD, состояние службы можно узнать командой
            firewall-cmd --state

            Для получения списка правил и сервисов используйте
            firewall-cmd --list-all
            firewall-cmd --list-services



            Обратите внимание на список сервисов, если вы отключили протокол ipv6, логично также поступить и с dhcpv6-client
            firewall-cmd –permanent –remove-service=dhcpv6-client

            Создаем правило для SAMBA и перезагружаем
            firewall-cmd --permanent --add-service=samba
            firewall-cmd --reload


            Общий ресурс с анонимным доступом


            Создаем папку для ресурса /samba/guest
            mkdir /samba
            mkdir /samba/guest

            Меняем владельца и назначаем права
            chown nobody:nobody /samba/guest
            chmod 777 /samba/guest

            Редактируем файл конфигурации SAMBA /etc/samba/smb.conf
            mcedit  /etc/samba/smb.conf

            Меняем содержание оригинального файла на следующее
            [global]
            workgroup = WORKGROUP
            security = user
            map to guest = bad user
            min protocol = NT1

            [guest]
            path = /samba/guest
            guest ok = Yes
            writable = Yes

            На всякий случай я указал минимальную версию протокола SMB=NT1. Если вы укажите SMB2 или SMB3, клиенты с Windows XP и ниже не смогут получить доступ к ресурсам.

            Проверка параметров и перезагрузка службы
            testparm
            service smb restart


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

            Бантики


            По умолчанию лог файлы находятся в папке /var/log/samba. При необходимости получить подробные логи, в раздел [global] необходимо добавить параметр log level = 2 или 3. По умолчанию используется значение 1, значение 0 отключает ведение логов.
            [global]
            log level = 2


            Как вы можете знаете, предоставление доступа к файлам это только часть функционала SAMBA. Если на сервере будут только файловые ресурсы, службу печати логично отключить. В разделе [global] добавьте следующие параметры
            [global]
            load printers = no
            show add printer wizard = no
            printcap name = /dev/null
            disable spoolss = yes

            Конфигурация SAMBA находиться в каталоге /etc/samba, а логи в каталоге /var/log/samba
            Мне удобней все инструменты держать по рукой, по этому я монтирую необходимые мне каталоги в /samba

            Создаем каталоги, в которые будет все монтироваться
            mkdir /samba/smbconf
            mkdir /samba/smblogs

            Редактируем конфиг файл /etc/fstab, я предполагаю что вы знаете за что отвечает fstab.
            mcedit /etc/fstab

            Добавляем следующие строки
            /etc/samba /samba/smbconf none bind 0 0
            /var/log/samba /samba/smblogs none bind 0 0

            Монтируем без перезагрузки
            mount -a


            Подключение диска


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

            Для получения списка устройств можно использовать команду lsblk
            lsblk

            Создание таблицы разделов на диске /dev/sdb
            parted /dev/sdb mklabel msdos
            или
            parted /dev/sdb mklabel gpt


            Подробную информация про gpt можно прочитать тут

            Создание раздела на весь диск sdb, в лучших традициях жанра я решил сделать отступ 1MiB в начале диска.
            parted /dev/sdb mkpart primary ext4 1MiB 100%

            Создаем файловую систему ext4
            mkfs.ext4 /dev/sdb1

            Редактируем fstab
            mcedit /etc/fstab

            Добавляем еще одну строку
            /dev/sdb1 /samba/guest ext4 defaults 0 0

            Монтирование
            mount –a

            Проверяем результат
            df -h

            Назначение прав
            chmod 777 /samba/guest


            Подключение образа диска


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

            Создаем каталог для хранения образов
            mkdir /samba/smbimg	

            Создаем файл образа размером 100 мб
            dd if=/dev/zero of=/samba/smbimg/100M.img bs=100 count=1M

            Про команду dd много интересного можно прочитать тут

            В варианте с образом я решил не создавать таблицу разделов, просто создаем файловую систему ext4.
            mkfs.ext4 /samba/smbimg/100M.img

            Редактируем fstab
            mcedit /etc/fstab

            Конфиг для монтирования образа
            /samba/smbimg/100M.img /samba/guest ext4 defaults 0 0

            Монтирование
            mount -a

            Проверяем результат
            df -h

            Назначение прав
            chmod 777 /samba/guest


            Подключение RAM диска


            Для временных ресурсов где не нужен большой объем, как мне кажется RAM диск это наилучший вариант, очень быстро и просто настраивается, а скорость работы поражает воображение.

            Редактируем fstab
            mcedit /etc/fstab

            Конфиг для RAM диска
            none /samba/guest tmpfs defaults,size=100M 0 0

            Монтирование
            mount -a

            Проверяем результат
            df -h


            Удаление старых файлов


            В случае «файлопомойки» ресурсы нужно как-то освобождать, для этого можно использовать планировщик задач crontab

            Просмотр заданий
            crontab –l

            Редактирование заданий
            crontab –e	

            Пример конфига:
            SHELL=/bin/bash
            PATH=/sbin:/bin:/usr/sbin:/usr/bin
            MAILTO=“”
            HOME=/

            #удалять файлы и каталоги каждый час
            * 0-23 * * * rm –R /samba/guest/*

            #Удалить только файлы старше 1 дня, запуск команды каждые 10 минут
            0-59/10 * * * * find /samba/guest/* -type f -mtime +1 -exec rm –f {} \;

            #удалить файлы старше 50 минут, запуск команды каждые 10 минут
            0-59/10 * * * * find /samba/guest/* -type f -mmin +50 -exec rm -f {} \;

            Выход из vi
            
            :wq

            Логи службы crontab находятся в файле /var/log/cron

            Ограничение доступа к SAMBA по ip адресам


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

            Пример:
            [global]
            hosts allow = 192.168.1.100, 192.168.1.101
            hosts deny = ALL

            [guest]
            hosts allow = 192.168.0.0/255.255.0.0
            hosts deny = 10. except 10.1.1.1


            Аутентификация и авторизация пользователей


            Ограничение доступа по ip адресам не всегда удобно или возможно, тогда можно использовать логины и пароли.

            Сначала необходимо создать локального пользователя в системе
            adduser user1

            Если пользователь будет работать только с SAMBA ресурсами, задавать ему пароль для системы нет необходимости. Пароль для системы и для SAMBA хранятся в разных файлах и могут отличаться.

            Затем необходимо добавить системного пользователя в пользователи самбы и задать ему пароль
            smbpasswd -a user1

            По умолчанию для хранения паролей используется файл формата tdb, которые расположен в каталоге /var/lib/samba/private/

            Изменить каталог расположения файла можно глобальным параметром passdb backend
            [global]
            passdb backend=tdbsam:/etc/samba/smbpassdb.tdb

            tdb файлы были созданы для замены «устаревших» текстовых, если вы хотите использовать текстовые файлы, для этого используйте параметр passdb backend=smbpasswd в разделе global
            passdb backend=smbpasswd:/etc/samba/smbpasswd

            Затем укажите списки пользователей и групп для доступа к ресурсам
            [guest]
            path = /samba/guest
            writable = no
            read list = user1, @group2
            write list = user2, user3


            Интеграция с Active Directory


            Также есть возможность получать информацию о пользователей из LDAP, но мне этот вариант не интересен и я сразу перехожу к AD. Подробная инструкция от Microsoft находится тут.

            Для AD очень важна синхронизация времени, по этому стоит начать с этого.

            Установка соответствующей службы
            yum install ntp

            Добавляем в конфиг файл /etc/ntp.conf сервера выполняющих роль домен контроллеров
            mcedit /etc/ntp.conf

            Пример:
            server 192.168.1.10
            server 192.168.1.20
            server someserver.contoso.com

            Добавляем службу ntp в автоматический запуск
            chkconfig ntpd on

            Запускаем службу
            service ntpd start

            Проверяем синхронизацию времени
            ntpq –p


            winbind


            Для получения информации о пользователях из AD необходимо установить пакет samba-winbind
            yum install samba-winbind

            Добавляем службу в автоматический запуск
            chkconfig winbind on

            Запускаем службу
            service winbind start


            Добавление хоста в AD


            Напомню что в начале даной инструкции задали имя хоста ls01.fqdn.com. Будем считать что полное имя домена fqdn.com, а короткое пусть будет fqdn_com

            Для внесения всех необходимых параметров в конфигурационные файлы можно воспользоваться утилитой authconfig-tui, установите флажок Use Winbind, затем перейдите на следующее окно



            Выберите модель безопасности ADS и укажите имена вашего домена. В поле домен контролер укажите “*”, это необходимо для автоматического поиска доступного домен контроллера. Затем нажмите ОК и закройте утилиту.



            Для добавления хоста в AD используйте команду net ads join –U %username%, пользователь должен обладать правами на создание учетной записи ПК в домене
            net ads join –U youruser



            Если машина не добавляется в домен, добавьте FQDN имя хоста в файл /etc/hosts.
            Я несколько раз все проверял, и в файл hosts я вносил изменения когда на этапе настройки сети задавал не полное имя хоста.

            Для того чтобы вывести хост из домена используйте команду net ads leave –U %username%

            Что делает утилита authconfig-tui?


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

            /etc/krb5.conf
            [libdefaults]
            Default_realm = FQDN.COM

            [realms]
            FQDN.COM = {
            kdc = *
            }


            /etc/nsswitch.conf
            passwd: files sss winbind
            shadow: files sss winbind
            group: files sss winbind


            /etc/samba/smb.conf
            [global]
            workgroup = FQDN_COM
            password server = *
            realm = FQDN.COM
            security = ads
            idmap config *: range = 16777216-33554431
            template shell = /sbin/nologin
            kerberos method = secrets only
            winbind use default domain = false
            winbind pffline logon = false

            Вы могли заметить что данная утилита вносит заметно меньше параметров чем написано в инструкции от Microsoft или других инструкциях, но если так работать – то почему бы и нет?

            Из инструкции Microsoft я добавляю следующие параметры в конфиг
            [global]
            domain master = no
            local master = no
            preferred master = no
            os level = 0
            domain logons = no


            Настройка прав доступа на ресурс
            В качестве примера и для наглядности рекомендую настроить ресурсы с разными правами на одну папку
            [domain users read only]
            path = /samba/guest
            read list = "@fqdn_com\domain users"
            force create mode = 777
            directory mask = 777

            [domain users writable]
            path = /samba/guest
            read list = "@fqdn_com\domain users"
            write list = "@fqdn_com\domain users"
            force create mode = 777
            directory mask = 777


            Перезапускаем службу samba
            service smb restart

            Проверяем
            smbstatus

            На скриншоте видно пользователя домена который находится в одной из общих папок


            THE END

            Список полезных ссылок:

            Боремся с вирусами и инфраструктурой, или отключение SMB v1
            Критическая уязвимость SambaCry: как защититься
            How to Fix SambaCry Vulnerability (CVE-2017-7494) in Linux Systems

            Yum, шпаргалка
            Команда dd и все, что с ней связано

            Using Samba, 2nd Edition
            Включение Samba-сервера на базе Ubuntu в домен AD
            Setting Up Samba and Configure FirewallD and SELinux to Allow File Sharing on Linux/Windows Clients

            SELinux — описание и особенности работы с системой. Часть 1
            SELinux — описание и особенности работы с системой. Часть 2

            P.S.
            Вернемся к SELINUX, чтобы SAMBA сервер мог предоставить доступ к любым каталогам необходимо выполнить следующие команды
            setsebool -P samba_export_all_ro=1
            setsebool -P samba_export_all_rw=1


            К сожалению я так и не смог настроить работу winbind при включенном SELINUX, если подскажете как, я буду благодарен.
            Original source: habrahabr.ru (comments, light).

            https://habrahabr.ru/post/337556/


            Метки:  

            Компания Oracle передаст проект Java EE в руки сообщества Eclipse Foundation

            Среда, 13 Сентября 2017 г. 11:30 + в цитатник
            Crandel сегодня в 11:30 Разработка

            Компания Oracle передаст проект Java EE в руки сообщества Eclipse Foundation

              image
              Недавно мы объявили, что Oracle начинает изучать возможность перевода технологий Java EE в OpenSource, чтобы сделать процесс разработки этих стандартов более гибким и открытым. С середины августа у нас было много дискуссий с другими поставщиками, членами сообщества и фондами OpenSource, чтобы продвинуть процесс вперед. Вот обновленная информация о достигнутом прогрессе.


              Во-первых, мы обратились к IBM и Red Hat, другим крупнейшим вкладчикам платформы Java EE, чтобы запросить поддержку этого нового направления. Oracle, IBM и Red Hat сотрудничают на постоянной основе, чтобы усовершенствовать подход, который мы можем коллективно поддерживать. Мы достигли хорошего прогресса на этом фронте и ожидаем продолжения совместной работы, чтобы сделать этот переход успешным для всех сторон. Спасибо, IBM и Red Hat!


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


              Озвучены намерения перелицензировать принадлежащие Oracle технологии Java EE и наработки, связанные с проектом GlassFish, включая эталонные реализации, наборы для оценки совместимости (TCK) и всю документацию. Независимый проект планируется распространять под новым брендом, т.е. вместо Java EE будет выбрано другое имя, но пакеты javax и определённые в спецификации компоненты сохранят свои прежние названия. Дополнительно будет продемонстрирована возможность сборки совместимых сторонних реализаций Java EE на основе предоставленных исходных текстов, соответствующих требованиям Java EE 8 TCK.


              В-третьих, мы встретились с несколькими фондами для обсуждения нашего предложения. Мы ценим время, которое они вложили в нас, и отзывы и предложения, которые они предложили. После тщательного анализа мы выбрали Eclipse Foundation для передачи всех имущественных прав. Eclipse Foundation имеет большой опыт и участие в Java EE и связанных с ним технологиях. Это поможет нам быстро перейти на Java EE, создать благоприятные для сообщества процессы для развития платформы и использовать дополнительные проекты, такие как MicroProfile. Мы с нетерпением ждем этого сотрудничества.


              Обратите внимание, что в дополнение ко всему вышесказанному, Oracle продолжит поддерживать существующие лицензии Java EE, включая лицензии, перемещающиеся в Java EE 8. Oracle также намерена продолжать поддерживать существующие версии WebLogic Server и поддерживать Java EE 8 в будущих версиях WebLogic Server. Мы считаем, что этот план позволит нам продолжать поддерживать существующие стандарты Java EE, обеспечивая тем самым эволюцию в более открытой среде. Нам предстоит еще большая работа, но мы уверены, что мы на верном пути. Мы надеемся получить дополнительные обновления в ближайшее время!
              Источник

              Original source: habrahabr.ru (comments, light).

              https://habrahabr.ru/post/337812/


              Метки:  

              Подборка: 10 полезных инструментов для интернет- маркетолога

              Среда, 13 Сентября 2017 г. 11:16 + в цитатник
              Marger1 сегодня в 11:16 Маркетинг

              Подборка: 10 полезных инструментов для интернет- маркетолога



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

                DashaMail




                Cервис для создания и отправки рассылок позволяет составлять красивые письма с помощью шаблонов в онлайн-редакторе и доставлять их с учетом местного времени подписчиков. Инструмент дает аналитику по открытиям, кликам, возвратам, отпискам и географии, его можно интегрировать с Google.Analytics и Яндекс.Метрикой.

                DashaMail подходит для тех компаний, которые только начали заниматься email-маркетингом и пока не собрали своей базы – сервис позволяет набрать подписчиков с помощью специальных форм.

                Главред




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

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

                Орфограммка




                Сервис для проверки грамотности текста. Помогает вычислить орфографические и пунктуационные ошибки, а также улучшить стилистику. Например, предлагает синонимы и эпитеты к словам.

                Similar Web




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

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

                Notify




                Сервис отслеживает упоминания бренда, конкурентов, событий и тем в Twitter, Facebook, Instagram, Youtube, Google+, Medium, блогах, новостях и на форумах. Удобен для того, чтобы оперативно находить и отрабатывать негатив, отвечать на вопросы в соцсетях и т.д. Можно настроить сервис так, чтобы уведомления приходили в Slack.

                Canva




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

                Amplifr




                Сервис для отложенного постинга и аналитики в соцсетях. Интерфейсом и удобством использования похож на хорошо известный Buffer, но в отличие от последнего позволяет работать с российскими соцсетями – ВКонтакте и Одноклассниками, а также Instagram и Telegram. Сервис определяет лучшее время для публикации постов, показывает аналитику по каждому из них и формирует удобный понятный отчет.

                K50




                Инструмент призван увеличить эффективность контекстной рекламы в рамках заданных KPI. Интегрируется с «Яндекс.Директом», «Яндекс.Метрикой», Google Analytics, Google AdWords, Competera, CRM и коллтрекинговыми сервисами. Сервис собирает статистику из этих источников и формирует отчет с данными о транзакциях, расходах, доходах и прочих важных показателях. Также анализирует онлайн и офлайн-заявки, помогает оптимизировать рекламный бюджет и прогнозируюет конверсии.

                Google Consumer Survey




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

                Сервис добавляет вопросы в баннеры, показывает их людям, готовым отвечать онлайн. Взамен они получают доступ к качественному контенту или кредиту Google Play, а маркетологи – достоверные результаты по низкой цене. При этом аудиторию можно сегментировать, выбирать, кому показывать баннеры, и получать репрезентативную выборку всего за 48 часов.

                User Testing




                Подходит для тех, кто запускает новый сайт или приложение или улучшает старый. Позволяет провести юзабилити-тестирование сервиса без лаборатории. Вы можете давать задание пользователям, а они будут его выполнять (система в это время записывает действия) и комментировать процесс.
                Original source: habrahabr.ru (comments, light).

                https://habrahabr.ru/post/337806/


                «Восточный» — наш космодром

                Среда, 13 Сентября 2017 г. 11:00 + в цитатник
                virtser сегодня в 11:00 Управление

                «Восточный» — наш космодром

                  В 2012 году на месте космодрома «Восточный» в Амурской области была только тайга. Построить здесь за три с половиной года самый современный космодром в мире, пусть пока только первую его очередь, — колоссальная работа. Нашей компании «ИНСИСТЕМС» посчастливилось участвовать в этом проекте. Объект оказался очень непростым, начиная с того, что он очень большой, и заканчивая сложными климатическими условиями, удаленностью, отсутствием какой бы то ни было инфраструктуры. Проект потребовал от нас много сил, энергии и нестандартных подходов.

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




                  О «Восточном»



                  Космодром «Восточный» расположен в Амурской области, в восьми тысячах километров от Москвы. Это первый гражданский космодром России.

                  Его площадь составляет 1035 кв. км (что сравнимо с Москвой в пределах МКАД), площадь под строительство — 96,6 кв. км. На космодроме более 450 сооружений. Протяженность автомобильных и железных дорог космодрома — более 200 км. В строительстве объекта принимало участие более 400 подрядных организаций.



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

                  О космосе
                  Космическая отрасль – одна из самых молодых. Первый искусственный спутник Земли был запущен 4 октября 1957 года. Первый полет человека состоялся 12 апреля 1961 года. Впервые человек вышел в открытый космос 18 марта 1965 года, высадился на Луну – 21 июля 1969 года. Первый беспилотный полет на Марс состоялся 20 июля 1976 года, а первый полет за пределы солнечной системы – летом 2012 года.

                  На сегодняшний день в мире 22 действующих космодрома:
                  США — 6
                  Китай — 4
                  Россия — 3
                  Франция — 2
                  Япония — 2
                  Южная Корея — 1
                  КНДР — 1
                  Израиль — 1
                  Индия — 1
                  Бразилия — 1
                  1 мобильный стартовый комплекс «Морской старт» (Россия)


                  Данные за 1957-2014 гг.

                  Космодром изнутри — это:

                  • Стартовый комплекс
                  • Командный пункт
                  • Технические комплексы
                  • Заправочные станции
                  • Центр эксплуатации районов падения
                  • Метрологический комплекс
                  • Метеорологический комплекс
                  • Комплекс изготовления и хранения топлива
                  • Вспомогательные служебные объекты


                  Космодром Байконур (Казахстан)

                  Самый эксплуатируемый космодром
                  Площадь — 6717 кв. км
                  9 стартовых площадок, 15 технических комплексов, 6 заправочно-нейтрализационных станций
                  Ракета-носители: Протон, Зенит, Союз, Циклон, Рокот, Днепр
                  В аренде у Казахстана до 2050 года
                  Единственный на сегодня космодром в России, с которого осуществляются пилотируемые запуски.

                  Космодром Плесецк (Архангельская область)

                  Самый северный космодром в мире
                  Площадь — 1762 кв. км
                  8 стартовых площадок, 4 технических комплекса, 2 заправочно-нейтрализационных станции
                  Ракета-носители: Рокот, Циклон, Космос-3М, Р-7, Ангара
                  С 1994 года — первый государственный испытательный космодром Министерства обороны РФ.


                  Начало



                  23 января 2014 года состоялась наша первая командировка на «Восточный».


                  Вот так выглядел монтажно-испытательный комплекс, когда мы туда попали в первый раз. Это был просто бетонный каркас


                  А это место нашего будущего городка — русское поле

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


                  Склад блоков

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


                  Трансбордерная галерея



                  Вот это здание — заправочно-нейтрализационная станция (ЗНС), она примыкает к монтажно-испытательному корпусу космических аппаратов (МИК КА). Внутри МИК КА космические аппараты собираются, проходят различные испытания и тесты, и уже полностью готовые к запуску, отправляются в ЗНС на заправку. Далее уже заправленный космический аппарат перемещается в монтажно-испытательный корпус ракет-носителей (МИК РН). Топливо, используемое в двигателях космических аппаратов, является токсичным. Поэтому вопросам безопасности здесь уделено особое внимание: предусмотрены автоматические системы газового анализа и сигнализации, аварийной вентиляции, предусмотрены тамбур-шлюзы и большое количество организационных мер безопасности.


                  Заправочно-нейтрализационная станция

                  Вот это монтажно-испытательный корпус ракет-носителей.



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

                  К лету 2014 года из окна вертолета стартовый комплекс выглядел так.



                  Наша зона ответственности


                  Задача «ИНСИСТЕМС» и хабаровской компании «ЛАНИТ-ПАРТНЕР», с которой мы вместе работали на проекте, была оснастить инженерными системами несколько объектов технического комплекса космодрома: монтажно-испытательный комплекс ракет-носителей (МИК РН), энергоблок, холодильный центр и заправочно-нейтрализационную станцию.

                  В нашей зоне ответственности были:

                  • механические системы (вентиляция, кондиционирование, холодоснабжение, отопление, индивидуальные тепловые пункты (ИТП), водоснабжение, водоотведение, канализация),
                  • системы электропитания и электроснабжения (трансформаторные подстанции 10/0,4 кВт, ДГУ, ИБП, распределительные сети 0,4 кВт),
                  • противопожарные системы (пожарная сигнализация, оповещение, пожаротушение, дымоудаление, контроль загазованности),
                  • сервисные системы и системы связи (СКС, ЛВС, СТС, часофикация, командная связь),
                  • автоматизация и диспетчеризация инженерных систем.


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

                  Управление бытом


                  Амурская область – дотационный регион. В 2016 году занял 67-е место в рейтинге российских регионов по качеству жизни.

                  Ближайший к космодрому населенный пункт в 25 км — это Углегорск. Называть его городом пока рано. Живет в этом поселке 5,5 тысяч человек. Райцентры тоже довольно немноголюдны и далеко расположены: Свободный (55 тысяч человек) — 80 км, Шимановск (19 тысяч человек) — 83 км, Белогорск (67 тысяч человек) — 120 км.

                  До столицы Амурского края города Благовещенск нужно проехать 230 км. Здесь живет 224 тысячи человек (для сравнения: население района Выхино в Москве — 226 тысяч).


                  В наш первый приезд мы разместились в Углегорске. Это типовой военный городок, закрытая территория, ...

                  … вход по пропускам


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

                  Летом поселок тоже неповторим

                  Градообразующим объектом Углегорска до 2007 года был космодром Свободный. Поэтому тема космоса здесь повсюду


                  От Углегорска до космодрома всего 25 километров, но дорога занимала около часа на машине (мы передвигались в зависимости от ситуации или на пикапе Mitsubishi, или микроавтобусе Toyota Hiace, или на грузовичке KIA Bongo). Ехать приходилось по грунтовой дороге, разбитой большегрузными самосвалами, которые здесь курсировали постоянно. На фото еще не самый плохой вариант. Когда проложили асфальт, доехать можно было за 20 минут

                  А это земля, которую генподрядчик выделил нам под строительство нашего городка

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

                  Во-первых, на территории 2 га мы построили бытовой городок с общежитием на 350 человек и полноценной столовой. Здесь же располагались офисные помещения, теплый склад, гараж.


                  Общежитие у нас было, скажем так, на три звезды


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


                  Даже сделали волейбольную площадку и тренажерный зал

                  Управление ресурсами



                  Мы зашли на объект как две независимые компании «ИНСИСТЕМС» и «ЛАНИТ-ПАРТНЕР», каждая со своим уставом. Опыта работы на похожих по размерам проектах не было почти ни у кого. Местных квалифицированных кадров практически нет. Вообще «местные» — понятие условное: все равно все работают по вахтовому методу.

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

                  За два года работы на проекте сотрудниками «ИНСИСТЕМС» было совершено 586 командировок. Мы пролетели на самолетах более 6,5 млн км (это как 162 раза вокруг экватора или как 17 раз от Земли до Луны).


                  Празднуем День строителя, 2015 год

                  Управление коммуникациями


                  Основные действующие лица проекта находились в трех часовых поясах: Амурская область (Мск+6), Хабаровский край (Мск+7), Москва. В 7 утра по местному времени работы начинались и в 8 вечера по Москве заканчивались. Когда Дальний Восток уходил спать, Москва продолжала трудиться. Но тем не менее, был налажен полноценный информационный обмен. (Кстати, за время проекта нами было направлено 2546 официальных писем.)

                  Почти сразу было принято важное правило — все решения принимаются на объекте.

                  А с этой машиной у нас связаны особые воспоминания.


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

                  Была суббота. (К слову, считается, что на объекте нет выходных. Если в документе указано до 25-го числа каждого месяца, значит, точно до 25-го все должно быть сделано и подписано, даже если этот день выпадает на субботу или воскресенье.) Мы собрали подписи всех, кроме главного человека, на подписи которого ставится синяя печать. А этот человек сидит в Благовещенске (за 230 км!), уехал на выходные.

                  Со всеми договорились по телефону, сели в машину. За руль садится руководитель нашего краснодарского филиала — мастер спорта по раллийным гонкам — и ставит рекорд на участке «космодром — Благовещенск» по времени. Гнал он в районе 200 километров в час. Подписал акт, а потом вернулся (!) и успел поставить сверху подпись и печать. Мы смогли все закрыть именно первым кварталом 2016 года. Все в последние часы было сделано.



                  Управление содержанием


                  Серьезным испытанием для нас стал обвал рубля. Сметы на поставку оборудования из-за рубежа были составлены по курсу 45 рублей за евро. Дополнительных бюджетных средств на строительство не предусматривалось. В итоге совместно с проектным институтом мы заменили часть импортного оборудования отечественным. Часть систем перепроектировали. Холодильный центр мощностью 8,75 МВт сконструировали самостоятельно. Это позволило сократить стоимость на 28%, а срок изготовления — в 2 раза. Подробнее о холодильном центре я расскажу ниже.

                  Управление сроками


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

                  Управление поставками


                  Для обеспечения работ мы доставили в Амурскую область более 160 сорокафутовых контейнеров с грузами и материалами. Только у нашей компании было свыше 450 поставщиков со всего мира – от Испании до Вьетнама. Нами были использованы все виды транспорта: воздушный, железнодорожный, морской, автомобильный.



                  Что нами сделано


                  Просто некоторые цифры
                  Трубы — 131,6 км
                  Воздуховоды — 28,4 км
                  Лоток — 29,6 км
                  Кабель — 1444 км
                  Шинопроводы — 3,8 км
                  Вентустановки — 443 шт
                  Фанкойлы — 223 шт
                  Прецизионные кондиционеры — 28 шт
                  Чиллеры — 16 шт
                  Чиллеры — 14,4 МВт
                  Тепловые завесы — 84 шт
                  Радиаторы отопления — 1028 шт
                  Трансформаторы — 26,1 МВт
                  Силовые шкафы и шкафы автоматики — 689 шт
                  Светильники — 8600 шт

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

                  Холодильный центр


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

                  Зимой в Амурской области температура достигает -40°С, а летом — +38°С. Гигантский холодильный центр обеспечивает поддержание нужных климатических параметров в залах сборки монтажно-испытательных комплексов ракет-носителей (МИК РН) и космических аппаратов (МИК КА). Производительность холодильного центра космодрома составляет 8,75 МВт. Это сопоставимо с системой охлаждения шести ледовых дворцов или комплекса офисных зданий площадью около 150 тыс. кв. м.

                  Нами было разработано и предложено решение о замене проектного холодильного центра производства Smardt-OPK Chillers AG (Германия) на аналогичный производства SME-ИНСИСТЕМС. В состав холодильного центра входят компрессоры. Их еще пока в России не производят вообще. Да и в мире их производством занимается небольшое количество заводов. Наша задача состояла в том, чтобы спроектировать конструктивные решения, которые позволили бы произвести максимум подготовительных монтажных работ в заводских условиях, чтобы упростить и ускорить монтаж на объекте, и мы ее решили.

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



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



                  Модуль готовится к транспортировке

                  Все критичные элементы систем холодильного центра имеют резерв (холодильные машины, сухие охладители жидкости, насосное оборудование, распределительные трассы). Расчетная температура эксплуатации — от -48°С до +32°С. Конструкция холодильного центра рассчитана на сейсмическую устойчивость 7 баллов.


                  Идет монтаж. 28 сухих градирин, внешних блоков кондиционеров занимают целое поле


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

                  Вентиляция зала сборки МИК РН



                  Общая площадь МИК РН — свыше 45 тыс. км. м. Монтаж воздуховодов под потолком на высоте 33 м (представьте десятиэтажный дом) вели бригады промышленных альпинистов.

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






                  Мы обеспечили помещению с два футбольных поля 9-й класс чистоты (такой же, как у предоперационных или в боксах микробиологических лабораторий). Для этого нужны целый комплекс мероприятий, строительные конструкции и инженерное обеспечение. В нашу зону ответственности входила система вентиляции. Это больше двух километров герметичных воздуховодов диаметром до 1600 мм, смонтированных в запотолочном пространстве, 24 установки общеобменной вентиляции со специальными секциями фильтров грубой и тонкой очистки.




                  Начало монтажа вентмашин

                  Суммарная производительность вентиляционных установок составляет 1,68 млн м3/час.







                  Аварийная вентиляция заправочно-нейтрализационной станции


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

                  Нами установлено 18 комплектов по три блока фильтров. Эти фильтры — уникальные изделия, которые производит единственный завод в России. Масса одного такого фильтра — 2400 кг, а изготовление занимает 9 месяцев.





                  Если хочется взглянуть на грандиозную инфраструктуру «Восточного» изнутри, то вы можете посмотреть фильм компании «ЛАНИТ-ПАРТНЕР» о системах, которые мы делали на объекте:




                  Фильм посвящен Дню космонавтики — 56-й годовщине первого полета человека в космос.

                  Космодромные уроки


                  Этот проект стал для "ИНСИСТЕМС" и "ЛАНИТ-ПАРТНЕР" вызовом. Но не с технической точки зрения, ведь инженерные системы — это абсолютно наша тема, а на космодроме мы не делали ничего такого, чего не делали раньше. Объект был сложен с управленческой точки зрения — по объемам, срокам, видам оборудования и т.д. Это как художника попросили бы: «Нарисуй то же самое, но только на поверхности размером 10 х10 метров».

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

                  Original source: habrahabr.ru (comments, light).

                  https://habrahabr.ru/post/337770/


                  Метки:  

                  Конференция VMworld 2017 Europe. День 0

                  Среда, 13 Сентября 2017 г. 10:46 + в цитатник
                  omnimod сегодня в 10:46 Администрирование

                  Конференция VMworld 2017 Europe. День 0



                    Привет, Хабр! Это первый из небольшого цикла постов, посвященных конференции VMworld 2017 Europe, которая прямо сегодня проходит в Барселоне.

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

                    Ежегодно VMware устраивает две большие конференции — VMworld US и VMworld Europe, предназначенные, соответственно, для заказчиков и партнеров из США и региона EMEA. В этом году организаторы решили перенести европейскую конференцию ближе к американской — с октября на 11—14 сентября, что логично, так как основные анонсы делаются на конференции в США. Как и в прошлые годы, местом проведения выбран конгресс-центр Fira Gran Via в Барселоне.



                    Прагматичные читатели спросят: «Сколько стоит сие мероприятие?» Отвечу так: удовольствие не из дешевых и сравнимо со стоимостью тура на какой-нибудь тропический курорт. Входной билет на конференцию обойдется в 1475€ без учета налогов (VAT). Перелет и проживание оплачиваются отдельно. Участие в партнерской конференции (день 0) потребует дополнительных взносов. Однако для тех, кто зарегистрировался заранее, организаторы скидывают 200€. Для членов сообщества VMUG Advantage, сертифицированных специалистов VCP, а также постоянных участников (Alumni) действуют скидки.

                    Что было на нулевом дне


                    Понедельник — день проведения партнерской конференции (Partner Exchange) и сессий, куда могут попасть только зарегистрированные партнеры компании. Остальные участники, приехавшие в этот день, должны пройти предварительную регистрацию, получить раздаточные материалы, потусоваться в зоне отдыха или выполнить лабораторные работы Hands-on labs.
                    Еще с воскресенья между аэропортом Барселоны и местом проведения конференции курсируют бесплатные автобусы. Чем мы и воспользовались.



                    В понедельник первые сессии начались уже в 8:30. В нулевой день их около 150. Все сессии записываются и спустя какое-то время становятся доступны на портале VMworld для просмотра участниками конференции. Наиболее значимые и популярные сессии VMware выкладывает в публичный доступ. Примеры: https://www.vmworld.com/en/us/video/top-sessions.html.



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



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



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





                    В нулевой день выставка не работает, но через окно можно видеть, как кипит работа:



                    Lounge-зона для расслабона:



                    Здесь можно скоротать время между мероприятиями, пообщаться с коллегами по цеху, сыграть в напольные шахматы, бильярд или шестиметровый настольный футбол (требуется 16 пар рук):



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



                    Вкратце суть выступления: компания поблагодарила своих партнеров за вклад в развитие совместного бизнеса (большая часть продаж продуктов VMware в мире и особенно в Европе делается через партнерские каналы). VMware поделилась успехами роста продаж vSAN и NSX и приоткрыла завесу тайны над планами развития облачного направления совместно с Amazon и другими сервис-провайдерами.

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



                    Зона Meet the Experts, где можно встретиться с ведущими мировыми экспертами в области виртуализации. Расписание выведено на экраны.



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



                    Хакатон


                    С 6 вечера до 00:00 часов прошел хакатон. В этом году девять команд состязались в создании приложений и модулей, облегчающих управление виртуальными или VDI-инфраструктурами, облаками, программными СХД. Участники сами выбирают, к какой команде присоединиться, на каком языке программирования писать (в таблице на регистрацию значились участники с навыками программирования на Perl, Python, Java, JavaScripts, PowerShell) и какой посильный вклад вносить в проект.

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

                    Лабораторные работы Hands-on labs


                    Те, кто работает с VMware, знают, что многие их решения возможно опробовать в онлайн-режиме на сайте Hands-on Labs. В дни проведения конференции VMware делает доступным множество новых лабораторных работ, к которым можно подключиться либо с рабочего места, оборудованного тонкими клиентами Dell Wyse, либо из зоны BYOD (Bring Your Own Device), воспользовавшись своим собственным устройством – ноутбуком или планшетом.

                    Помимо индивидуальных, доступны и групповые лабораторные работы под руководством тренера (Expert-Led Workshop), но на них требуется предварительная регистрация.
                    Если при выполнении лабораторной работы возникнут какие-либо проблемы, можно обратиться к проктору. Есть специалисты и из российского представительства VMware, поэтому вы всегда можете попросить помощи на родном языке.

                    Экзаменационный центр


                    В дни конференции на территории выставочного центра работает мобильный центр Pearson VUE, в котором любой желающий может попробовать сдать сертификационные экзамены VCP, VCAP или vSAN Specialist. На все экзамены действует 50% скидка. Правда стоит сказать, что дисконт этот считается от европейской цены (250$ за экзамен на статус VCP), но все равно получается дешевле, чем в Тестовом Центре в России (порядка 175$).

                    Для тех, кто не смог посетить конференцию, VMware предоставляет 25% скидку при регистрации онлайн на сайте VUE, достаточно всего лишь указать секретное слово: VMWBARC25. Скидка распространяется на все экзамены при регистрации до 14 сентября 2017 включительно, а забронированные таким образом экзамены должны быть сданы не позднее 14 ноября 2017. Если вы давно готовились, у вас появился дополнительный стимул.

                    На этом нулевой день подошел к концу. Продолжение в следующей части.

                    Андрей Коновалов, начальник отдела виртуализации компании «Инфосистемы Джет»
                    Original source: habrahabr.ru (comments, light).

                    https://habrahabr.ru/post/337786/


                    Метки:  

                    7 причин, почему СМБ не нужны программы лояльности в том виде, в каком они представлены на рынке

                    Среда, 13 Сентября 2017 г. 10:39 + в цитатник
                    TS_Consulting сегодня в 10:39 Управление

                    7 причин, почему СМБ не нужны программы лояльности в том виде, в каком они представлены на рынке



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



                      Пара слов о программах лояльности


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


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


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


                      • собирать и хранить данные о клиентах и покупках
                      • давать бонусы и скидки
                      • делать рассылки по смс и е-мейл
                      • строить отчеты

                      7 причин


                      Итак, сразу перейдем к нашим 7-м причинам, почему СМБ не нужны программы лояльности. На деле, запустив такую систему, СМБ получает примерно следующее:


                      1. Потратим деньги на саму систему, интеграцию, поддержку;
                      2. Потратим на сотрудников, которые будут заниматься программой лояльности;
                      3. Увеличим время обслуживания на кассе;
                      4. Потратим на эмиссию карт, либо разработку мобильного приложения;
                      5. На скидках и бонусах потеряем часть маржи;
                      6. Дадим кассирам дополнительные инструменты для собственного обогащения за счет собственника;
                      7. Хранение персональных данных и рассылки также принесут затраты, жалобы, а порой, и судебные иски.


                      Источник


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


                      А что же крупный бизнес?


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


                      На самом деле программа лояльности зарабатывает деньги, когда выполняются следующие три условия, и в крупных бизнесах они, как правило, действительно выполняются:


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

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



                      Источник


                      Благодаря аналитическому модулю программы лояльности, выявляем, что среди клиентов АЗС есть клиенты, которые во время заправки покупают кофе и вишневую слойку. Клиенты данного сегмента делают так не всегда, а в 40% случаях приезда на заправку. Но если они покупают вишневую слойку, то в 100% случаев к ней покупают кофе. Выделим этот сегмент и назовем его «любители вишневых слоек».


                      Запускаем акцию: в момент посещения заправки «любителю вишневых слоек» сообщается, что отныне он персонально будет получать скидку 20% на его любимый продукт и что мы будем счастливы, если он будет покупать свой любимый продукт еще чаще.


                      Ниже в таблице приведены результаты такой акции.


                      До запуска акции


                      После запуска акции


                      Кофе


                      Слойка


                      Кофе


                      Слойка


                      Себестоимость 1 шт.


                      20


                      40


                      20


                      40


                      Цена 1 шт.


                      80


                      60


                      80


                      48


                      Продано штук в день


                      20 000


                      20 000


                      40 000


                      40 000


                      Выручка итого по продукту


                      1600000


                      1200000


                      3200000


                      1920000


                      Себестоимость итого по продукту


                      400000


                      800000


                      800000


                      1600000


                      Маржа итого по продукту


                      1200000


                      400000


                      2400000


                      320000


                      Итого маржа


                      1600000


                      2720000



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


                      Для достижения максимального результата аналитику пришлось немного попотеть. Было проведено множество различных тестов. Сегмент клиентов был разделен на множество подсегментов. Одному подсегменту, например, направилось сообщение по СМС с одним текстом и скидкой 10%, другому – пуш-уведомление с немного измененным текстом и размером скидки и т.д.


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


                      На этом пока все. Если какие-то другие темы по лояльности и CRM интересны – пишите. Напишу отдельный материал, а пока у меня в планах рассказать Вам как программы лояльности могут заработать в сегменте среднего и малого бизнеса.


                      Буду рад ответить на Ваши вопросы по теме. Велком!

                      Original source: habrahabr.ru (comments, light).

                      https://habrahabr.ru/post/337748/


                      Расследование утечек информации из корпоративной базы данных перевозчика

                      Среда, 13 Сентября 2017 г. 10:27 + в цитатник
                      bogatrev сегодня в 10:27 Разработка

                      Расследование утечек информации из корпоративной базы данных перевозчика

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

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



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

                        С технической точки зрения информацию о своем грузе можно получить двумя путями.
                        Первый — на сайте перевозчика, второй, более сложный — подключив свою логистическую информационную систему (АСУ клиентов) непосредственно к базе перевозчика. Все запросы АСУ клиентов к базе данных (БД) перевозчика реализованы посредством набора Хранимых Процедур. Для управления доступом каждому клиенту выделяется его собственный аккаунт с набором необходимых ему полномочий и прав.



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

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

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

                        Ознакомившись со структурой базы, мы поняли, что информация о координатах того или иного транспортного средства может быть получена либо из таблицы базы, либо из представления (View). Мы выбрали один из грузовиков компании, который находился в рейсе, попросили администраторов базы данных диспетчерского центра включить трассировку обращений к таблице и представлениях, содержащих данные о координатах грузовика. В течение трех последующих часов мы сделали 10 запросов на мошенническом сайте и по каждому запросу получили GPS-координаты. Данные по каждому запросу к нам приходили с задержкой не более секунды. За эти три часа набралось около 70 мегабайт текстовых журналов. Анализировать их мы отправились в свой офис, где были подходящие инструменты, оставив в покое администраторов базы.

                        В ходе анализа мы поняли, что данные в ответ на наши запросы приходят в режиме онлайн, и версии об утечках из резервных копий, или об обработке запросов в ручном режиме были отметены. Мы надеялись, что в течение секунды после нашего запроса в трассировке появятся данные о внешнем клиенте, который «сливает» информацию. Результаты анализа были неутешительными — в трассировке, сделанной стандартными средствами СУБД, была информация по обращениям к таблице и представлениям, но отсутствовала информация о конкретных запросах к данным по нашему грузовику. Оказалось, что в секунду обращений к таблице и представлениям более двух сотен, и выделить среди них обращения, сделанные в ответ на наши запросы, не представляется возможным.

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

                        Хорошо, что такой инструмент нам удалось быстро найти и договориться о его временном использовании. Данное решение (InfoSphere Guardium) может анализировать запросы от хранимых процедур с помощью программного агента непосредственно на сервере БД. Проводя анализ запросов «на лету», система позволяет получить все необходимые нам данные. После ночных работ по установке и настройке, мы снова провели серию из 10 запросов данных по нашему грузовику на «левом» ресурсе. В этот раз, благодаря встроенным методам фильтрации нашей аналитической системы, мы получили список из 12 аккаунтов, к которым «улетали» данные по координатам нашего грузовика в течение секунды после каждого нашего запроса. За любым из таких аккаунтов стоит АСУ одного из клиентов перевозчика. Встала задача определить, какая конкретно АСУ клиента передает данные на сторону, для чего мы воспользовались методом установки индивидуальных «меток».

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

                        Теперь настал довольно деликатный момент — для дальнейшего расследования нужны были данные с АСУ клиента. Это означало, что клиент должен быть хотя бы частично посвящен в суть дела. Более того, если данные сливает администратор этой АСУ, он может успеть замести все следы. Необходимо было действовать очень осторожно. Обстоятельства сложились удачно, т.к. была достигнута договоренность о взаимодействии на уровне служб безопасности перевозчика и этого клиента — крупного логистического оператора. Служба безопасности клиента согласилась предоставить нам журналы сервера АСУ. Анализ журналов дал нам единственный аккаунт, получавший данные с метками. Аккаунт принадлежал одному из сотрудников логистической компании. Что было с ним дальше история умалчивает. Главное, что цель была достигнута — продажа украденных данных остановилась.
                        Original source: habrahabr.ru (comments, light).

                        https://habrahabr.ru/post/337804/


                        Двухфакторная авторизация для VPN-соединений

                        Среда, 13 Сентября 2017 г. 08:19 + в цитатник
                        PandaSecurityRus сегодня в 08:19 Администрирование

                        Двухфакторная авторизация для VPN-соединений



                          Чтобы еще больше повысить безопасность внешних соединений к внутренним ресурсам корпоративной сети, рекомендуется «усилить» VPN-соединения процедурой двухфакторной авторизации. Это можно легко сделать с помощью Panda GateDefender.

                          VPN позволяет двум раздельным локальным сетям напрямую безопасно подключаться друг к другу, используя потенциально небезопасные сети, такие как Интернет. Весь сетевой трафик в рамках VPN-соединения безопасно передается внутри зашифрованного туннеля, скрытого от любопытных глаз. Такая конфигурация называется Gateway-to-Gateway VPN (Gw2Gw VPN). Аналогичным образом и один-единственный удаленный компьютер, расположенный где-то в Интернете, может использовать VPN-туннель для подключения к требуемой локальной сети. В этом случае, удаленный компьютер, иногда называемый Road Warrior, выглядит так, словно он физически присутствует в этой локальной сети до тех пор, пока активен VPN-туннель.

                          Такие возможности VPN очень удобны: в эпоху BYOD и распределенных информационных систем безопасные VPN-соединения являются достаточно простым и эффективным решением, которое позволяет обеспечить безопасный доступ удаленных и мобильных сотрудников предприятия к внутренним корпоративным ИТ-ресурсам (внутренняя локальная сеть, БД, файловые серверы и пр.).

                          UTM-решение Panda GateDefender для защиты периметра корпоративной сети позволяет решать данный вопрос. Решение поддерживает создание VPN, основанного либо на протоколе IPsec, который поддерживается большинством операционных систем и сетевых устройств, либо на сервисе OpenVPN.

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

                          • настраивать сервер OpenVPN таким образом, чтобы клиенты могли подключаться к одной из локальных зон
                          • настраивать клиентскую часть схемы Gateway-to-Gateway между двумя или более решениями Panda GateDefender
                          • настраивать основанные на IPsec VPN-туннели и L2TP-соединения
                          • управлять пользователями VPN-соединений
                          • настраивать сертификаты, которые будут использоваться для VPN-соединений.

                          Сами по себе VPN-соединения достаточно безопасны, чтобы их можно было перехватить и расшифровать. Но что делать в том случае, если злоумышленник каким-либо способом (а их достаточно много…) узнал логин и пароль для VPN-соединения и/или даже получил удаленный (физический) доступ к компьютеру вашего мобильного или удаленного сотрудника, чтобы от его лица подключаться к корпоративной VPN-сети? Каким образом можно повысить уровень безопасности VPN-соединений?

                          Двухфакторная авторизация

                          В этом случае поможет двухфакторная авторизация (2FA) — это процесс безопасности, в рамках которого пользователи должны предоставлять дополнительный временный одноразовый пароль (TOTP) для более безопасной собственной идентификации. Этот дополнительный пароль генерируется токеном или устройством генерации кодов, или, в качестве альтернативного варианта, специальным приложением, установленным на смартфоне пользователя.

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

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

                          Для достижения совместимости между производителями, существует открытый стандарт, который может быть использован без необходимости в лицензировании стороннего ПО. Этот стандарт был опубликован в RFC 6238.

                          Установка токена на устройство пользователя

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



                          Чтобы генерировать TOTP-коды, пользователь должен в приложении настроить аккаунт. Существует два способа настройки аккаунта применительно к решению Panda GateDefender:

                          • Вручную создать аккаунт, копируя текстовый код одноразового пароля, сгенерированный в консоли управления Panda GateDefender
                          • Сфотографировать с помощью камеры смартфона QR-код, сгенерированный в консоли GateDefender.

                          Текстовый код и QR-код содержат всю информацию, необходимую для настройки аккаунта.
                          После того как аккаунт был настроен, приложение токена начнет генерировать одноразовые пароли каждые 30 секунд. Т.к. алгоритм генерации паролей основан на часах устройства, то Интернет-подключение не требуется. Однако не должно быть большой разницы между временем, настроенным в решении GateDefender и на устройстве пользователя. На рисунке ниже показаны интерфейсы некоторых приложений для смартфонов по генерации паролей.



                          Настройка двухфакторной авторизации в GateDefender


                          Выполните действия ниже для включения двухфакторной авторизации в решении GateDefender:

                          • Добавьте сервер авторизации одноразовых паролей.
                          • Определите новый мэппинг к данному серверу.

                          Добавление нового сервера авторизации одноразовых паролей

                          Перейдите в раздел VPN -> Авторизация -> Настройки и нажмите ссылку Добавить новый сервер авторизации.



                          У опции Тип выберите Одноразовый пароль. Затем выберите Local (local) в полях Провайдер информации о пользователе и Провайдер пароля. Укажите название нового сервера авторизации в поле Имя и нажмите кнопку Добавить.



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

                          Определение нового мэппинга к серверу авторизации

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



                          В новом окне нажмите иконку для добавления нового мэппинга к серверу авторизации. Новый сервер появится в правой панели. Чтобы удалить мэппинг, нажмите иконку . Чтобы добавить или удалить все мэппинги, нажмите ссылки Добавить все и Удалить все, соответственно.



                          Настройка сервиса 2FA на устройстве пользователя


                          Рисунок ниже показывает процедуру конфигурации:



                          • Создайте нового пользователя в GateDefender и сгенерируйте QR-код или ключ.
                          • Отправьте пользователю по почте QR-код или распечатайте его и передайте вручную. Если у пользователя нет камеры на смартфоне, то передайте ему текстовый код.
                          • Пользователь должен просканировать QR-код (ввести текстовый код) с помощью TOPT-совместимого приложения, установленного на своем смартфоне.
                          • Приложение сможет генерировать коды доступа.

                          Создание нового пользователя в GateDefender и генерация QR-кода или текстового кода

                          Перейдите в VPN-> Авторизация-> Пользователи и нажмите Добавить нового локального пользователя.



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



                          Чтобы скачать QR-код из консоли GateDefender, просто нажмите правой кнопкой мыши на нем и выберите в контекстном меню опцию Read QR code from image.



                          Отправка QR-кода (текстового кода) пользователю по почте или его печать и передача вручную

                          После того как Вы скачали QR-код (скопировали текстовый код), Вы можете отправить его пользователю по электронной почте или распечатать его и передать ему вручную.

                          Сканирование пользователем QR-кода (ввод текстового кода) с помощью TOPT-совместимого приложения, установленного на его смартфоне

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

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

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



                          Заключение


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

                          Более подробная информация о Panda GateDefender:

                          Описание продукта Panda GateDefender
                          Техническое описание
                          Спецификация и требования к серверам

                          Также Вы можете заказать бесплатную версию Panda GateDefender сроком на 1 месяц, отправив заявку на адрес sales@rus.pandasecurity.com.
                          Original source: habrahabr.ru (comments, light).

                          https://habrahabr.ru/post/337800/


                          Детский сад, штаны на лямках: откуда берутся программисты

                          Среда, 13 Сентября 2017 г. 07:36 + в цитатник
                          SmirkinDA сегодня в 07:36 Управление

                          Детский сад, штаны на лямках: откуда берутся программисты


                            Жил был мальчик. Стал программистом. Примерно так может начинаться и заканчиваться короткая биографическая справка о любом разработчике. При этом очевидно, что далеко не все в детстве и даже в юности планировали связать свою судьбу с высокими технологиями. Было любопытно покопаться в детских пеленках и узнать о детских мечтах айтишников из разных стран. Enjoy!
                            З.Ы. Пользуясь случаем поздравляем с Днем программиста всех сопричастных!

                            Марко Каласан


                            Челюсть моя ударилась о пол, когда узнал, что этот македонский парнишка в возрасте восьми лет стал самым молодым в мире сертифицированным системным администратором Microsoft, получив сертификат Microsoft Certified Professional. В возрасте девяти лет, он также успешно сдал экзамен на получение сертификата системного инженера Microsoft Certified Systems Engineer. Кстати, сейчас Марко уже 17 лет. К этому времени, он успел написать книгу по Windows 7 и продолжает кодить.



                            Марк Цукерберг


                            Вы знали, что основатель Facebook учился в Гарварде на факультете психологии? Марк Цукерберг родился в штате Нью-Йорк в семье стоматолога и психиатра. Помимо него у родителей еще трое дочерей. С ранних лет Марк проявлял интерес к программированию. В школе он отличился тем, что создал довольно популярную сетевую компьютерную стратегическую игру. Несмотря на то, что уже в юности мировые корпорации заметили талантливого программиста и предлагали ему работу, молодой человек выбрал факультет психологии Гарвардского университета. Будучи студентом Марк создал Facebook и по-началу забросил учебу. Но совсем недавно Цукерберг вернулся в Гарвард и получил диплом почетного доктора Гарвардского университета. Кстати, там он озвучил весьма воодушевляющую речь.



                            Линус Торвальдс


                            Кажется, что папа Linux в тихой Финляндии с детства хотел быть программистом. Учитывая, что к первому компьютеру парнишка прикоснулся в 12 лет. В 1981 году Лео, дед Линуса, математик, познакомил внука с ЭВМ Commodore VIC-20, используемой им для математических вычислений. Линус заинтересовался программированием и прочитал руководства к машине. Затем он начал читать компьютерные журналы и писать собственные программы, сначала на Бейсике, а затем на Ассемблере. Со школьных лет Линус получал стипендии за успехи по математике. Первой купленной им ЭВМ была Sinclair QL, тогда стоивший почти 2 000 долларов США.


                            Тест на внимательность. Найдете на школьной фотографии старину Линуса?


                            Сергей Брин


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



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



                            Отец рассказывал о Сергее, что тот рос обычным мальчиком, но всегда старался быть ближе к компьютеру. Начиналось всё с игр и старенького Commodore 64s, одного из первых персональных компьютеров. Это был подарок девятилетнему ребёнку на день рождения. Правда, бабушка была недовольна. Что вырастет из этого ребёнка, ворчала она, если он часами не отходит от компьютера. В самом начале 80-х, когда даже в США компьютеры оставались технической диковинкой, Брин освоил программирование и выбрал главную дорогу своей жизни. Его интересы сосредоточились на математике, применительно к новейшим компьютерным технологиям. По этой тропинке и пошло его саморазвитие.



                            В 1993 году Брин поступил в Стэнфордский университет штата Калифорния. Именно там он познакомился со своим нынешним другом и соратником Лари Пейджем. О рождении Google сложены легенды, так что на этой истории долго останавливаться особо не будем.

                            Павел Дуров


                            Вообще русский Цукерберг, если бы не создал Вконтакте, вполне мог бы быть лингвистом-переводчиком. Дуров учился в классе с углубленным изучением четырех иностранных языков. После окончания Академической гимназии с отличием он поступил на филологический факультет СПбГУ (специальность «Английская филология и перевод»). Кстати, университет Павел закончил с красным дипломом, который, по слухам, до сих пор не забрал из вуза.



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

                            Виталик Бутерин


                            Коломенскому парнишке Виталику Бутерину 23 года. Большую часть жизни крипто-гуру живет в Канаде, но связи с Родиной не потерял. О себе Виталик распространяется мало. Говорит лишь, что с детства увлекался математикой, программированием и компьютерными играми. Несколько лет Бутерин безвылазно играл в World of Warcraft. Не исключено, что не создай он Ethereum, вполне бы мог стать звездным киберспортсменом. Кстати, многие спрашивают, почему Виталия Дмитриевича до сих пор называют Виталиком, тот в ответ говорит, что так к нему обращаются с детства. Интересно, какое у него было прозвище в школе?



                            Николай Добровольский


                            Сооснователь и вице-президент Parallels до того, как успешно скрестил ужа и ежа запустил с командой единомышленников Windows на Mac, благополучно грыз гранит науки в лингвистической школе. Увлечений была масса, но уже в 10 лет пытливый ум и неутомимые стопы завели Николая в столичный Дом пионеров. Тамошний кружок программирования привил тягу к кодотворчеству. Через пару лет была первая победа во всесоюзном конкурсе программистов, затем премия им.Зворыкина и много чего еще. Далее состоялось знакомство со Стивом Джобсом и мировой триумф Parallels.



                            Жил, был, стал…


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

                            Дмитрий Гейнисман, Team Leader
                            — В детстве хотел быть Оптимусом Праймом. Работая сегодня с техподдержкой наших пользователей можно сказать, что частично мое желание исполнилось.



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



                            Илья Вербин, Sr Software Developer
                            — Посмотрите на фоточку, думаю сразу станет понятно, кем я хотел быть в детстве.



                            Руслан Садовников, Lead Software Developer
                            — Хотел быть DJ.



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



                            Илья Коломейцев, Software Developer
                            — Хотел стать музыкантом или DJ.



                            Дима Смиркин, пиарщик
                            — Я хотел быть брокером на бирже или сразу бандитом. У них были БМВ.



                            Делитесь в комментариях своими детскими мечтами и фотками. Интересно, кто кем хотел быть и что из этого получилось.
                            Original source: habrahabr.ru (comments, light).

                            https://habrahabr.ru/post/337674/


                            Чтоб root стоял и фичи были

                            Среда, 13 Сентября 2017 г. 00:01 + в цитатник
                            RegionSoft сегодня в 00:01 Разработка

                            Чтоб root стоял и фичи были

                              Сегодня 256-й день в году, а значит настал профессиональный праздник программистов, разработчиков, девелоперов, кодеров. В общем, всех тех, кто делает современную жизнь современной, технику умной, работу удобной — короче, улучшает этот мир. Мы долго думали, что же такое написать, но в итоге наткнулись на крутые свежие комиксы о жизни разработчиков и решили, что им будет и день, и место. Для тех, у кого, как и у нас «инглиш политех финишд», мы перевели смысл и немного адаптировали к российским реалиям. С праздником, друзья!

                              Картинка взята тут, подпись наша

                              Пара слов о том, как это было. Мы нашли комиксы прекрасных авторов в блоге разработчиков таймтрекеров Toggl и уже не могли остановиться их рассматривать. Написали в техподдержку на своём bad english, что мы небольшая компания-разработчик CRM-систем из России и хотим опубликовать это дело к дню программиста в своем блоге на Хабре. Нам ответили, что дают согласие и что english не такой уж и bad. На сей позитивной ноте мы и засели за перевод и адаптацию. Работать над этим постом было реально в кайф — есть, над чем погрустить и посмеяться.

                              Рабочее окружение программиста


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


                              Аналитики, SEO-шники и лидогенераторы. По-нашему, интернет-маркетологи. Чёрные маги интернета, прокачанные в тёмном искусстве генерации кликов (не путать с кликбейтом!), трафика и конверсий. Да-да, мы действительно нашли этот комикс по поисковому запросу.

                              Техподдержка. Фронтлайновые войска со стальными нервами. Саппортовые коммандос имеют странную способность говорить «Нет» так, что это не звучит как «Нет» (нам бы такое в процессе создания ТЗ и внесения в него 458-ой итерации правок!). Техподдержка, в основном, миролюбива (ибо вымотана?).

                              Финансовый директор (в российских реалиях — бухгалтерия). Хранитель казны и клада. Озабочен обслуживанием финансовых обязательств. Часто говорит «Нет», но в целом иногда позволяет какие-то расходы на глупые запросы, чтобы поддержать мир и иллюзию демократии в компании. В российских реалиях владеет мощным оружием массового поражения программистов и тыж-программистов (обычно по трудовой — системных администраторов) — учётной системой 1С.

                              SMM-щик. Хипстер по профессии или профессиональный хипстер — тут зависит от уровня достигнутого дзена. Предпочитает общаться с помощью GIF-ок. SMM-хипстеры — единственные, кто может навык ведения Твиттера или Фейсбука указывать как скилл в своём резюме.

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

                              Фронтенд-разработчики, они же «не тру инженеры» на жаргоне бэкендеров. Сильны в классическом роке или гангста рэпе (или обоих). Странность их хобби может сравниться только с надписями на их футболках.

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

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

                              Бэкенд-разработчики — негламурные технари. Осторожные покровители и бесшумные рыцари — они держат бизнес работающим и на вообще на плаву. Их можно заслуженно считать героями компании (правда, ни один из них в этом не нуждается).

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

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

                              Серверы. Только они одни работают в режиме 24/7. Быть бы, как сервер…

                              Семь кругов ада разработчиков


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


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

                              Второй круг — люди. И документация, документация эта вся тоже реально задолбала. Маркетинг и продажи и их вечное вот это: «Ты уже накодил половину своего сайта? Маловато для нас работаешь, я прав?» (amirite — сокращение от «am I right?»). На этом же круге обитают типа-технические HR-ы: «Привет, ты знаешь JavaScript? Ну потому что мы как раз в поисках программиста Java!»

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

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

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

                              Шестой круг — отрыв и отвлечение от работы. «Ты чем-то занят?» (Ну что вы, на работе, как можно!) «А ты можешь выгрузить мне кое-какие данные? Да неее, мне не к спеху, сегодня вечером устроит». На этом же кругу находится мифическая пропасть «Вчера» — такое место, где всё должно быть готово согласно сегодняшней информации.

                              Не верите, что мы от этого страдаем? Не верите?! Просто посмотрите вот этот старый и правдивый комикс.


                              И на последнем круге ломается источник внутреннего света и энергии — кофемашина :-)

                              Но мы все умеем работать. В команде. По-своему


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


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

                              Фронтэнд-разработчики красят лампу в жёлтый цвет и втирают бэкенду, что лампочка работает, но только в дневное время.

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

                              Маркетологи разрабатывают концепцию и договариваются, что темнота — это новый свет. А потом маркетолог даёт вам возможность почитать пост об этом в блоге, а сам идёт доигрывать в Candy Crush.

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

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

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

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



                              Перевод и адаптация — разработчик CRM-систем RegionSoft Developer Studio
                              Источник картинок — блог разработчика таймтрекеров Toggl.com
                              Источник КДПВ — комментарий пользователя портала фотографов Penta_Club

                              P.S.: если у вас есть более удачные идеи перевода фрагментов, пишите в комментариях — добавим.
                              Original source: habrahabr.ru (comments, light).

                              https://habrahabr.ru/post/337778/


                              Метки:  

                              [Из песочницы] Имплементация OpenId Connect в ASP.NET Core при помощи IdentityServer4 и oidc-client

                              Среда, 13 Сентября 2017 г. 00:00 + в цитатник
                              NickT сегодня в 00:00 Разработка

                              Имплементация OpenId Connect в ASP.NET Core при помощи IdentityServer4 и oidc-client


                              Недавно мне потребовалось разобраться, как делается аутентификация на OpenId Connect на ASP.NET Core. Начал с примеров, быстро стало понятно, что чтения спецификации не избежать, затем пришлось уже перейти к чтению исходников и статей разработчиков. В результате возникло желание собрать в одном месте всё, что необходимо для того, чтобы понять, как сделать рабочую реализацию OpenId Connect Implicit Flow на платформе ASP.NET Core, при этом понимая, что Вы делаете.


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


                              Немного об OpenId Connect


                              Если Вы понимаете OpenId Connect, можете начинать читать со следующей части.


                              OpenId Connect (не путать с OpenId) — протокол аутентификации, построенный на базе протокола авторизации OAuth2.0. Дело в том, что задачу OAuth2 входят вопросы только авторизации пользователей, но не их аутентификации. OpenID Connect также задаёт стандартный способ получения и представления профилей пользователей в качестве набора значений, называемых claims. OpenId Connect описывает UserInfo endpoint, который возвращает эти информацию. Также он позволяет клиентским приложениям получать информацию о пользователе в форме подписанного JSON Web Token (JWT), что позволяет слать меньше запросов на сервер.


                              Начать знакомство с протоколом имеет смысл с официального сайта, затем полезно почитать сайты коммерческих поставщиков облачных решений по аутентификации вроде Connect2id, Auth0 и Stormpath. Описание всех нужных терминов не привожу, во-первых это была бы стена текста, а во вторых всё необходимое есть по этим ссылкам.


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


                              Что мы хотим получить в итоге


                              Мы реализуем OpenId Connect Implicit Flow, который рекомендован для JavaScript-приложений, в браузере, в том числе для SPA. В процессе мы чуть глубже, чем это обычно делается в пошаговых руководствах, обсудим разные значимые настройки. Затем мы посмотрим, как работает наша реализация с точки зрения протокола OpenId Connect, а также изучим, как имплементация соотносится с протоколом.


                              Инструменты


                              • На стороне сервера воспользуемся IdentityServer4
                              • На стороне клиента будем использовать библиотеку oidc-client

                              Основные авторы обеих библиотек — Брок Аллен и Доминик Брайер.


                              Сценарии взаимодействия


                              У нас будет 3 проекта:


                              1. IdentityServer — наш сервер аутентификации OpenId Connect.
                              2. Api — наш тестовый веб-сервис.
                              3. Client — наше клиентское приложение на JavaScript, основано на коде JavaScriptClient.

                              Сценарий взаимодействия таков: клиентское приложение Client авторизуется при помощи сервера аутентификации IdentityServer и получает access_token (JWT), который затем использует в качестве Bearer-токена для вызова веб-сервиса на сервере Api.


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


                              1. Клиент готовит запрос на аутентификацию, содержащий нужные параметры запроса.
                              2. Клиент шлёт запрос на аутентификацию на сервер авторизации.
                              3. Сервер авторизации аутентифицирует конечного пользователя.
                              4. Сервер авторизации получает подтверждение от конечного пользователя.
                              5. Сервер авторизации посылает конечного пользователя обратно на клиент с id_token'ом и, если требуется, access_token'ом.
                              6. Клиент валидирует id_token и получает Subject Identifier конечного пользователя.

                              Implicit Flow


                              Имплементация


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


                              Запускать Api и IdentityServer в процессе выполнения этого упражнения рекомендую через dotnet runIdentityServer пишет массу полезной диагностической информации в процессе своей работы, данная информация сразу будет видна в консоли.


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


                              Давайте приступим к реализации. Для определённости будем предполагать, что Вы используете Visual Studio 2017 (15.3). Готовый код решения можно посмотреть здесь
                              Создайте пустой solution OpenIdConnectSample.


                              Большая часть кода основана на примерах из документации IdentityServer, однако код в данной статье дополнен тем, чего, на мой взгляд, не хватает в официальной документации, и аннотирован.


                              Рекомендую ознакомиться со всеми официальными примерами, мы же поглубже рассмотрим именно Implicit Flow.


                              1. IdentityServer


                              Создайте solution с пустым проектом, в качестве платформы выберите ASP.NET Core 1.1.


                              Установите такие NuGet-пакеты


                              Install-Package Microsoft.AspNetCore.Mvc -Version 1.1.3
                              Install-Package Microsoft.AspNetCore.StaticFiles -Version 1.1.2
                              Install-Package IdentityServer4 -Version 1.5.2

                              Версии пакеты здесь значимы, т.к. Install-Package по умолчанию устанавливает последние версии. Хотя авторы уже сделали порт IdentityServer на Asp.NET Core 2.0 в dev-ветке, на момент написания статьи, они ещё не портировали Quickstart UI. Различия в коде нашего примера для .NET Core 1.1 и 2.0 невелики.


                              Измените метод Main Program.cs так, чтобы он выглядел следующим образом


                              public static void Main(string[] args)
                              {
                                  Console.Title = "IdentityServer";
                              
                                  // https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?tabs=aspnetcore2x
                                  var host = new WebHostBuilder()
                                      .UseKestrel()
                                      // задаём порт, и адрес на котором Kestrel будет слушать
                                      .UseUrls("http://localhost:5000")
                                      // имеет значения для UI логина-логаута 
                                      .UseContentRoot(Directory.GetCurrentDirectory())
                                      .UseIISIntegration()
                                      .UseStartup()
                                      .Build();
                              
                                  host.Run();
                              }

                              Затем в Startup.cs


                              1. Добавьте пространства имён
                                using System.Security.Claims;
                                using IdentityServer4;
                                using IdentityServer4.Configuration;
                                using IdentityServer4.Models;
                                using IdentityServer4.Test;
                              2. Добавьте несколько вспомогательных методов, которые содержат настройки IdentityServer, обратите внимание на комментарии. Эти методы будут в дальнейшем вызваны в ConfigureServices. Рекомендую читать текст методов перед их добавлением в проект — с одной стороны это позволит сразу иметь целостную картину происходящего, с другой стороны лишнего там мало.

                              Настройки информации для клиентских приложений


                              public static IEnumerable GetIdentityResources()
                              {
                                  // определяет, какие scopes будут доступны IdentityServer
                                  return new List
                                  {
                                      // "sub" claim
                                      new IdentityResources.OpenId(),
                                      // стандартные claims в соответствии с profile scope
                                      // http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
                                      new IdentityResources.Profile(),
                                  };
                              }

                              Эти настройки добавляют поддержку claim sub, это минимальное требование для соответствия нашего токена OpenId Connect, а также claim scope profile, включающего описанные стандартом OpenId Connect поля профиля типа имени, пола, даты рождения и подобных.


                              Это аналогичные предыдущим настройки, но информация предназначается для API


                              public static IEnumerable GetApiResources()
                              {
                                  // claims этих scopes будут включены в access_token
                                  return new List
                                  {
                                      // определяем scope "api1" для IdentityServer
                                      new ApiResource("api1", "API 1", 
                                          // эти claims войдут в scope api1
                                          new[] {"name", "role" })
                                  };
                              }     

                              Сами клиентские приложения, нужно чтобы сервер знал о них


                              public static IEnumerable GetClients()
                              {
                                  return new List
                                  {
                                      new Client
                                      {
                                          // обязательный параметр, при помощи client_id сервер различает клиентские приложения 
                                          ClientId = "js",
                                          ClientName = "JavaScript Client",
                                          AllowedGrantTypes = GrantTypes.Implicit,
                                          AllowAccessTokensViaBrowser = true,
                                          // от этой настройки зависит размер токена, 
                                          // при false можно получить недостающую информацию через UserInfo endpoint
                                          AlwaysIncludeUserClaimsInIdToken = true,
                                          // белый список адресов на который клиентское приложение может попросить
                                          // перенаправить User Agent, важно для безопасности
                                          RedirectUris = {
                                              // адрес перенаправления после логина
                                              "http://localhost:5003/callback.html",
                                              // адрес перенаправления при автоматическом обновлении access_token через iframe
                                              "http://localhost:5003/callback-silent.html"
                                          },
                                          PostLogoutRedirectUris = { "http://localhost:5003/index.html" },
                                          // адрес клиентского приложения, просим сервер возвращать нужные CORS-заголовки
                                          AllowedCorsOrigins = { "http://localhost:5003" },
                                          // список scopes, разрешённых именно для данного клиентского приложения
                                          AllowedScopes =
                                          {
                                              IdentityServerConstants.StandardScopes.OpenId,
                                              IdentityServerConstants.StandardScopes.Profile,
                                              "api1"
                                          },
                              
                                          AccessTokenLifetime = 300, // секунд, это значение по умолчанию
                                          IdentityTokenLifetime = 3600, // секунд, это значение по умолчанию
                              
                                          // разрешено ли получение refresh-токенов через указание scope offline_access
                                          AllowOfflineAccess = false,
                                      }
                                  };
                              }

                              Тестовые пользователи, обратите внимание, что bob у нас админ


                              public static List GetUsers()
                              {
                                  return new List
                                  {
                                      new TestUser
                                      {
                                          SubjectId = "1",
                                          Username = "alice",
                                          Password = "password",
                              
                                          Claims = new List
                                          {
                                              new Claim("name", "Alice"),
                                              new Claim("website", "https://alice.com"),
                                              new Claim("role", "user"),
                                          }
                                      },
                                      new TestUser
                                      {
                                          SubjectId = "2",
                                          Username = "bob",
                                          Password = "password",
                              
                                          Claims = new List
                                          {
                                              new Claim("name", "Bob"),
                                              new Claim("website", "https://bob.com"),
                                              new Claim("role", "admin"),
                                          }
                                      }
                                  };
                              }

                              1. Измените метод ConfigureServices так

                              public void ConfigureServices(IServiceCollection services)
                              {
                                  services.AddMvc();
                              
                                  services.AddIdentityServer(options =>
                                  {
                                      // http://docs.identityserver.io/en/release/reference/options.html#refoptions
                                      options.Endpoints = new EndpointsOptions
                                      {
                                          // в Implicit Flow используется для получения токенов
                                          EnableAuthorizeEndpoint = true,
                                          // для получения статуса сессии
                                          EnableCheckSessionEndpoint = true,
                                          // для логаута по инициативе пользователя
                                          EnableEndSessionEndpoint = true,
                                          // для получения claims аутентифицированного пользователя 
                                          // http://openid.net/specs/openid-connect-core-1_0.html#UserInfo
                                          EnableUserInfoEndpoint = true,
                                          // используется OpenId Connect для получения метаданных
                                          EnableDiscoveryEndpoint = true,
                              
                                          // для получения информации о токенах, мы не используем
                                          EnableIntrospectionEndpoint = false,
                                          // нам не нужен т.к. в Implicit Flow access_token получают через authorization_endpoint
                                          EnableTokenEndpoint = false,
                                          // мы не используем refresh и reference tokens 
                                          // http://docs.identityserver.io/en/release/topics/reference_tokens.html
                                          EnableTokenRevocationEndpoint = false
                                      };
                              
                                      // IdentitySever использует cookie для хранения своей сессии
                                      options.Authentication = new IdentityServer4.Configuration.AuthenticationOptions
                                      {
                                          CookieLifetime = TimeSpan.FromDays(1)
                                      };
                              
                                  })
                                      // тестовый x509-сертификат, IdentityServer использует RS256 для подписи JWT
                                      .AddDeveloperSigningCredential()
                                      // что включать в id_token
                                      .AddInMemoryIdentityResources(GetIdentityResources())
                                      // что включать в access_token
                                      .AddInMemoryApiResources(GetApiResources())
                                      // настройки клиентских приложений
                                      .AddInMemoryClients(GetClients())
                                      // тестовые пользователи
                                      .AddTestUsers(GetUsers());
                              }

                              В этом методе мы указываем настройки IdentityServer, в частности сертификаты, используемые для подписывания токенов, настройки scope в смысле OpenId Connect и OAuth2.0, настройки приложений-клиентов, а также настройки пользователей.


                              Теперь чуть подробнее. AddIdentityServer регистрирует сервис IdentityServer в механизме разрешения зависимостей ASP.NET Core, это нужно сделать, чтобы была возможность добавить его как middleware в Configure.


                              • IdentityServer подписывает токены при помощи RSA SHA 256, поэтому требуется пара приватный-публичный ключ. AddDeveloperSigningCredential добавляет тестовые ключи для подписи JWT-токенов, а именно id_token, access_token в нашем случае. В продакшне нужно заменить эти ключи, сделать это можно, например сгенерировав самоподписной сертификат.
                              • AddInMemoryIdentityResources. Почитать о том, что понимается под ресурсами можно тут, а зачем они нужны — тут.

                              Метод Configure должен выглядеть так


                              
                              public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
                              {
                                  loggerFactory.AddConsole(LogLevel.Debug);
                                  app.UseDeveloperExceptionPage();
                              
                                  // подключаем middleware IdentityServer
                                  app.UseIdentityServer();
                              
                                  // эти 2 строчки нужны, чтобы нормально обрабатывались страницы логина
                                  app.UseStaticFiles();
                                  app.UseMvcWithDefaultRoute();
                              }
                              

                              Скачайте из официального репозитория Starter UI для IdentityServer, затем скопируйте файлы в папку проекта, так чтобы папки совпали по структуре, например wwwroot с wwwroot.


                              Проверьте, что проект компилируется.


                              2. Api


                              Данный проект — игрушечный сервер API с ограниченным доступом.


                              Добавьте в solution ещё один пустой проект Api, в качестве платформы выберите ASP.NET Core 1.1. Т.к. мы не собираемся создавать полноценное веб-приложение в данном проекте, а лишь легковесный веб-сервис, отдающий JSON, ограничимся лишь MvcCore middleware вместо полного Mvc.


                              Добавьте нужные пакеты, выполнив эти команды в Package Manager Console


                              Install-Package Microsoft.AspNetCore.Mvc.Core -Version 1.1.3
                              Install-Package Microsoft.AspNetCore.Mvc.Formatters.Json -Version 1.1.3
                              Install-Package Microsoft.AspNetCore.Cors -Version 1.1.2
                              Install-Package IdentityServer4.AccessTokenValidation -Version 1.2.1

                              Начнём с того, что добавим нужные настройки Kestrel в Program.cs


                              public static void Main(string[] args)
                              {
                                  Console.Title = "API";
                              
                                  var host = new WebHostBuilder()
                                      .UseKestrel()
                                      .UseUrls("http://localhost:5001")
                                      .UseContentRoot(Directory.GetCurrentDirectory())
                                      .UseIISIntegration()
                                      .UseStartup()
                                      .Build();
                              
                                  host.Run();
                              }

                              В Startup.cs потребуется несколько меньше изменений.
                              Для ConfigureServices


                              public void ConfigureServices(IServiceCollection services)
                              {
                                  services.AddCors(options=>
                                  {
                                      // задаём политику CORS, чтобы наше клиентское приложение могло отправить запрос на сервер API
                                      options.AddPolicy("default", policy =>
                                      {
                                          policy.WithOrigins("http://localhost:5003")
                                              .AllowAnyHeader()
                                              .AllowAnyMethod();
                                      });
                                  });
                              
                                  // облегчённая версия MVC Core без движка Razor, DataAnnotations и подобного, сопоставима с Asp.NET 4.5 WebApi
                                  services.AddMvcCore()
                                      // добавляем авторизацию, благодаря этому будут работать атрибуты Authorize
                                      .AddAuthorization(options =>
                                          // политики позволяют не работать с Roles magic strings, содержащими перечисления ролей через запятую
                                          options.AddPolicy("AdminsOnly", policyUser =>
                                          {
                                              policyUser.RequireClaim("role", "admin");
                                          })
                                      )
                                      // добавляется AddMVC, не добавляется AddMvcCore, мы же хотим получать результат в JSON 
                                      .AddJsonFormatters();
                              
                              }

                              А вот так должен выглядеть Configure


                              public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
                              {
                                  loggerFactory.AddConsole(LogLevel.Debug);
                              
                                  // добавляем middleware для CORS 
                                  app.UseCors("default");
                              
                                  // добавляем middleware для заполнения объекта пользователя из OpenId  Connect JWT-токенов
                                  app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
                                  {
                                      // наш IdentityServer
                                      Authority = "http://localhost:5000",
                                      // говорим, что нам не требуется HTTPS при общении с IdentityServer, должно быть true на продуктиве
                                      // https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.aspnetcore.builder.openidconnectoptions
                                      RequireHttpsMetadata = false,
                              
                                      // это значение будет сравниваться со значением поля aud внутри access_token JWT
                                      ApiName = "api1",
                              
                                      // можно так написать, если мы хотим разделить наш api на отдельные scopes и всё же сохранить валидацию scope
                                      // AllowedScopes = { "api1.read", "api1.write" }
                              
                                      // читать JWT-токен и добавлять claims оттуда в HttpContext.User даже если не используется атрибут Authorize со схемоЙ, соответствующей токену
                                      AutomaticAuthenticate = true,
                                      // назначаем этот middleware как используемый для формирования authentication challenge
                                      AutomaticChallenge = true,
                              
                                      // требуется для [Authorize], для IdentityServerAuthenticationOptions - значение по умолчанию
                                      RoleClaimType = "role", 
                                  });
                              
                                  app.UseMvc();
                              }

                              Осталось добавить наш контроллер, он возвращает текущие Claims пользователя, что удобно для того, чтобы понимать, как middleware аутентификации IdentityServer расшифровал access_token.
                              Добавьте в проект единственный контроллер IdentityController.
                              Cодержимое файла должно быть таким.


                              using System.Linq;
                              using Microsoft.AspNetCore.Mvc;
                              using Microsoft.AspNetCore.Authorization;
                              
                              namespace Api.Controllers
                              {
                              
                                  [Authorize]
                                  public class IdentityController : ControllerBase
                                  {
                                      [HttpGet]
                                      [Route("identity")]
                                      public IActionResult Get()
                                      {
                                          return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
                                      }
                              
                                      [HttpGet]
                                      [Route("superpowers")]
                                      [Authorize(Policy = "AdminsOnly")]
                                      public IActionResult Superpowers()
                                      {
                                          return new JsonResult("Superpowers!");
                                      }
                                  }
                              }

                              Убедитесь, что проект компилируется.


                              3. Client


                              Этот проект фактически не содержит значимой серверной части. Весь серверный код — это просто настройки веб-сервер Kestrel, с тем чтобы он отдавал статические файлы клиента.


                              Так же, как и прошлых 2 раза добавьте в решение пустой проект, назовите его Client.


                              Установите пакет для работы со статическими файлами.


                              Install-Package Microsoft.AspNetCore.StaticFiles -Version 1.1.2

                              Измените файл Program.cs


                              public static void Main(string[] args)
                              {
                                  var host = new WebHostBuilder()
                                      .UseKestrel()
                                      .UseUrls("http://localhost:5003")
                                      .UseContentRoot(Directory.GetCurrentDirectory())
                                      .UseIISIntegration()
                                      .UseStartup()
                                      .Build();
                              
                                  host.Run();
                              }

                              Класс Startup должен содержать такой код.


                              public void ConfigureServices(IServiceCollection services)
                              {
                              }
                              public void Configure(IApplicationBuilder app)
                              {
                                  app.UseDefaultFiles();
                                  app.UseStaticFiles();
                              }

                              Клиентский код на JavaScript, с другой стороны, и содержит всю логику аутентификации и вызовов Api.


                              Мы по одному добавим в папку wwwroot проекта следующие файлы.


                              • index.html — простой HTML-файл с кнопками различных действий и ссылкой на JavaScript-файл приложения app.js и oidc-client.js.
                              • oidc-client.js — клиентская библиотека, реализующая OpenId Connect
                              • app.js — настройки oidc-client и обработчики событий кнопок
                              • callback.html — страница, на которую сервер аутентификации перенаправляет клиентское приложение, передавая параметры, необходимые для завершения процедуры входа.
                              • callback-silent.html — страница, аналогичная callback.html, однако именно для случая, когда происходит "фоновый" повторный логин через iframe. Это нужно чтобы продлевать доступ пользователя к ресурсам без использования refresh_token.

                              index.html
                              Добавьте новый HTML-файл с таким названием в папку wwwroot проекта.


                              
                              
                              
                                  
                                  
                              
                              
                                  
                                  
                                  
                                  
                                  
                              
                                  
                              
                              
                                  
                                  
                              
                              

                              oidc-client.js
                              Скачайте этот файл отсюда (1.3.0) и добавьте в проект.


                              app.js
                              Добавьте новый JavaScript-файл с таким названием в папку wwwroot проекта.


                              Добавьте


                              /// 

                              в начале файла для поддержки IntelliSense.


                              Вставьте этот код к началу app.js


                              Oidc.Log.logger = console;
                              Oidc.Log.level = 4;

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


                              Теперь давайте по частям добавим остальной код в этот файл.


                              Эта часть кода самая длинная, и, пожалуй, самая интересная. Она содержит настройки библиотеки основного объекта UserManager библиотеки oidc-client, а также его создание. Рекомендую ознакомиться с самими настройками и комментариями к ним.


                              var config = {
                              
                                  authority: "http://localhost:5000", // Адрес нашего IdentityServer
                                  client_id: "js", // должен совпадать с указанным на IdentityServer
                                  // Адрес страницы, на которую будет перенаправлен браузер после прохождения пользователем аутентификации
                                  // и получения от пользователя подтверждений - в соответствии с требованиями OpenId Connect
                                  redirect_uri: "http://localhost:5003/callback.html",
                                  // Response Type определяет набор токенов, получаемых от Authorization Endpoint
                                  // Данное сочетание означает, что мы используем Implicit Flow
                                  // http://openid.net/specs/openid-connect-core-1_0.html#Authentication
                                  response_type: "id_token token",
                                  // Получить subject id пользователя, а также поля профиля в id_token, а также получить access_token для доступа к api1 (см. наcтройки IdentityServer)
                                  scope: "openid profile api1",
                                  // Страница, на которую нужно перенаправить пользователя в случае инициированного им логаута
                                  post_logout_redirect_uri: "http://localhost:5003/index.html",
                                  // следить за состоянием сессии на IdentityServer, по умолчанию true
                                  monitorSession: true,
                                  // интервал в миллисекундах, раз в который нужно проверять сессию пользователя, по умолчанию 2000
                                  checkSessionInterval: 30000,
                                  // отзывает access_token в соответствии со стандартом https://tools.ietf.org/html/rfc7009
                                  revokeAccessTokenOnSignout: true,
                                  // допустимая погрешность часов на клиенте и серверах, нужна для валидации токенов, по умолчанию 300
                                  // https://github.com/IdentityModel/oidc-client-js/blob/1.3.0/src/JoseUtil.js#L95
                                  clockSkew: 300,
                                  // делать ли запрос к UserInfo endpoint для того, чтоб добавить данные в профиль пользователя
                                  loadUserInfo: true,
                              };
                              var mgr = new Oidc.UserManager(config);

                              Давайте теперь добавим обработчики для кнопок и подписку на них.


                              function login() {
                                  // Инициировать логин
                                  mgr.signinRedirect();
                              }
                              
                              function displayUser() {
                                  mgr.getUser().then(function (user) {
                                      if (user) {
                                          log("User logged in", user.profile);
                                      }
                                      else {
                                          log("User not logged in");
                                      }
                                  });
                              }
                              
                              function api() {
                                  // возвращает все claims пользователя
                                  requestUrl(mgr, "http://localhost:5001/identity");
                              }
                              
                              function getSuperpowers() {
                                  // этот endpoint доступен только админам
                                  requestUrl(mgr, "http://localhost:5001/superpowers");
                              }
                              
                              function logout() {
                                  // Инициировать логаут
                                  mgr.signoutRedirect();
                              }
                              
                              document.getElementById("login").addEventListener("click", login, false);
                              document.getElementById("api").addEventListener("click", api, false);
                              document.getElementById("getSuperpowers").addEventListener("click", getSuperpowers, false);
                              document.getElementById("logout").addEventListener("click", logout, false);
                              document.getElementById("getUser").addEventListener("click", displayUser, false);
                              
                              // отобразить данные о пользователе после загрузки
                              displayUser();

                              Осталось добавить пару утилит


                              function requestUrl(mgr, url) {
                                  mgr.getUser().then(function (user) {
                                      var xhr = new XMLHttpRequest();
                                      xhr.open("GET", url);
                                      xhr.onload = function () {
                                          log(xhr.status, 200 == xhr.status ? JSON.parse(xhr.responseText) : "An error has occured.");
                                      }
                                      // добавляем заголовок Authorization с access_token в качестве Bearer - токена. 
                                      xhr.setRequestHeader("Authorization", "Bearer " + user.access_token);
                                      xhr.send();
                                  });
                              }
                              
                              function log() {
                                  document.getElementById('results').innerText = '';
                              
                                  Array.prototype.forEach.call(arguments, function (msg) {
                                      if (msg instanceof Error) {
                                          msg = "Error: " + msg.message;
                                      }
                                      else if (typeof msg !== 'string') {
                                          msg = JSON.stringify(msg, null, 2);
                                      }
                                      document.getElementById('results').innerHTML += msg + '\r\n';
                                  });
                              }

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


                              callback.html


                              
                              
                              
                                  
                                  
                              
                              
                                  
                                  
                              
                              

                              callback-silent.html


                              
                              
                              
                                  
                                  
                              
                              
                                  
                                  
                              
                              

                              Готово!


                              Как это работает


                              Запускать проекты рекомендую так: запускаете консоль, переходите в папку проекта, выполняете команду dotnet run. Это позволит видеть что IdentityServer и другие приложения логируют в консоль.


                              Запустите вначале IdentityServer и Api, а затем и Client.


                              Откройте страницу http://localhost:5003/index.html Client.
                              На этом этапе Вы можете захотеть очистить консоль при помощи clear().


                              Теперь давайте настроим консоль, чтобы на самом деле видеть всю интересную информацию.
                              Например, для Chrome 60 настройки консоли должны выглядеть так.



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


                              Обновите страницу при помощи CTRL+F5.


                              Happy path


                              Посмотрим, какие действия соответствуют первым двум шагам спецификации.
                              1. Клиент готовит запрос на аутентификацию, содержащий нужные параметры запроса.
                              2. Клиент шлёт запрос на аутентификацию на сервер авторизации.
                              Кликните на кнопку Login.


                              Взаимодействие с сервером авторизации начинается с GET-запроса на адрес
                              http://localhost:5000/.well-known/openid-configuration
                              Этим запросом oidc-client получает метаданные нашего провайдера OpenId Connect (рекомендую открыть этот адрес в другой вкладке), в том числе authorization_endpoint
                              http://localhost:5000/connect/authorize


                              Обратите внимание, что для хранения данных о пользователе используется WebStorage. oidc-client позволяет указать, какой именно объект будет использоваться, по умолчанию это sessionStorage.


                              В этот момент будет послан запрос на аутентификацию на authorization_endpoint с такими параметрами строки запроса


                              Имя Значение
                              client_id js
                              redirect_uri http://localhost:5003/callback.html
                              response_type id_token token
                              scope openid profile api1
                              state некоторое труднопредсказуемое значение
                              nonce некоторое труднопредсказуемое значение

                              Обратите внимание, что redirect_uri соответствует адресу, который мы указали для нашего клиента с client_id js в настройках IdentityServer.


                              Т.к. пользователь ещё не аутентифицирован, IdentityServer вышлет в качестве ответа редирект на форму логина.


                              Затем браузер перенаправлен на http://localhost:5000/account/login.


                              3. Сервер авторизации аутентифицирует конечного пользователя.
                              4. Сервер авторизации получает подтверждение от конечного пользователя.
                              5. Сервер авторизации посылает конечного пользователя обратно на клиент с id token'ом и, если требуется, access token'ом.


                              Вводим bob в качестве логина и password в качестве пароля, отправляем форму.
                              Нас вначале вновь перенаправляют на authorization_endpoint, а оттуда на страницу подтверждения в соответствии с OpenId Connect разрешения получения relying party (в данном случае нашим js-клиентом) доступа к различным scopes.


                              Со всем соглашаемся, отправляем форму. Аналогично форме аутентификации, в ответ на отправку формы нас перенаправляют на authorization_endpoint, данные на authorization_endpoint передаются при помощи cookie.


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


                              При использовании Implicit Flow параметры передаются после #. Это нужно для того, чтобы эти значения были доступны нашему приложению на JavaScript, но при этом не отправлялись на веб-сервер.


                              Имя Значение
                              id_token Токен с данными о пользователе для клиента
                              access_token Токен с нужными данными для доступа к API
                              token_type Тип access_token, в нашем случае Bearer
                              expires_in Время действия access_token
                              scope scopes на которые пользователь дал разрешение через пробел

                              6. Клиент валидирует id token и получает Subject Identifier конечного пользователя.


                              oidc-client проверяет вначале наличие сохранённого на клиенте state, затем сверяет nonce с полученным из id_token. Если всё сходится, происходит проверка самих токенов на валидность (например, проверяется подпись и наличие sub claim в id_token). На этом этапе происходит чтение чтение содержимого id_token о объект профиля пользователя библиотеки oidc-client на стороне клиента.


                              Если Вы захотите расшифровать id_token (проще всего его скопировать из вкладки Network инструментов разработчика), то увидите, что payload содержит что-то подобное


                              {
                                "nbf": 1505143180,
                                "exp": 1505146780,
                                "iss": "http://localhost:5000",
                                "aud": "js",
                                "nonce": "2bd3ed0b260e407e8edd0d03a32f150c",
                                "iat": 1505143180,
                                "at_hash": "UAeZEg7xr23ToH2R2aUGOA",
                                "sid": "053b5d83fd8d3ce3b13d3b175d5317f2",
                                "sub": "2",
                                "auth_time": 1505143180,
                                "idp": "local",
                                "name": "Bob",
                                "website": "https://bob.com",
                                "amr": [
                                  "pwd"
                                ]
                              }

                              at_hash, который затем используется для валидации в соответствии со стандартом.


                              Для access_token в нашем случае payload будет выглядеть, в том числе в соответствии с настройками, чуть иначе.


                              {
                                "nbf": 1505143180,
                                "exp": 1505143480,
                                "iss": "http://localhost:5000",
                                "aud": [
                                  "http://localhost:5000/resources",
                                  "api1"
                                ],
                                "client_id": "js",
                                "sub": "2",
                                "auth_time": 1505143180,
                                "idp": "local",
                                "name": "Bob",
                                "role": "admin",
                                "scope": [
                                  "openid",
                                  "profile",
                                  "api1"
                                ],
                                "amr": [
                                  "pwd"
                                ]
                              }

                              Если Вы не умеете для себя объяснять все их отличия, сейчас — прекрасный момент устранить этот пробел. Начать можно отсюда, или с повторного прочтения кода настроек IdentityServer.


                              В случае когда проверка завершается успехом, происходит чтение claims из id_token в объект профиля на стороне клиента.


                              Затем, но только если указана настройка loadUserInfo, происходит обращение к UserInfo Endpoint. При этом при обращении UserInfo Endpoint для получения claims профиля пользователя в заголовке Authorization в качестве Bearer-токена используется access_token, а полученные claims будут добавлены в JavaScript-объект профиля на стороне клиента.


                              loadUserInfo имеет смысл использовать если Вы хотите уменьшить размер access_token, если Вы хотите избежать дополнительного HTTP-запроса, может иметь смысл от этой опции отказаться.


                              Вызываем метод API


                              Нажмите кнопку "Call API".
                              Произойдёт ajax-запрос на адрес http://localhost:5001/identity.
                              А именно, вначале будет OPTIONS-запрос согласно требованиями CORS т.к. мы осуществляем запрос ресурса с другого домена и используем заголовки, не входящие в список "безопасных" (Authorization, например).


                              Затем будет отправлен, собственно, сам GET-запрос. Обратите внимание, что в заголовке запроса Authorization будет указано значение Bearer <значение access_token>.


                              IdentityServer middleware на стороне сервера проверит токен. Внутри кода IdentityServer middleware проверка токенов фактически осуществляется стандартным Asp.Net Core JwtBearerMiddleware.


                              Пользователь будет считаться авторизованным, поэтому сервер вернёт нам ответ с кодом 200.


                              Logout


                              Отправляется GET-запрос на end_session_endpoint


                              Имя Значение
                              id_token_hint Содержит значение id_token
                              post_logout_redirect_uri URI, на который клиент хочет, чтобы провайдер аутентификации

                              В ответ нас перенаправляют на страницу, содержащую данные о логауте для пользователя.


                              Проверяем работу ролей


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


                              Попробуйте зайти вначале под пользователем alice и нажать кнопку Get Superpowers!, затем зайдите под пользователем bob и проделайте то же самое.


                              Другие варианты развития событий


                              Пользователь жмёт do not allow


                              Нажмите Logout и залогиньтесь ещё раз, на этот раз используйте данные
                              Username: alice
                              Password: password


                              На странице подтверждения http://localhost:5000/consent нажмите No, Do Not Allow.


                              Вы попадёте на страницу завершения логина клиентского приложения http://localhost:5003/callback.html.
                              По причине того, что страница подтверждения пользователем передаёт фрагмент URL #error=access_denied, выполнение signinRedirectCallback пойдёт по другому пути, и промис в результате будет иметь статус rejected.


                              На странице callback.html будет для промиса выполнен catch-обработчик, он выведет текст ошибки в консоль.


                              Пользователь не даёт разрешения на профиль


                              Скопируйте закодированный id_token из одноимённого параметра URL ответа и убедитесь, что теперь в него не входят claims, которые входят в стандартный scope profile.


                              Claims, которые входят в стандартный scope profile можно посмотреть тут.


                              При этом вызвать API получится.


                              Пользователь на даёт разрешение на api1


                              В токене теперь нет claim api1


                              "scope": [
                                  "openid",
                                  "profile"
                              ],

                              При попытке вызвать Api нам теперь возвращают 401 (Unathorized).


                              access_token устаревает


                              Дождитесь устаревания access_token, нажмите кнопку Call API.


                              API будет вызван! Это вызвано тем, что IdentityServer использует middleware Asp.Net Core, который использует понятие ClockSkew. Это нужно для того, чтобы всё в целом работало в случае если часы на клиенте и разных серверах несколько неточны, например, не возникали ситуации вроде токена, который был выпущен на период целиком в будущем. Значение ClockSkew по умолчанию 5 минут.


                              Теперь подождите 5 минут и убедитесь, что вызов API теперь возвращает 401 (Unathorized).


                              Замечание В клиентском приложении может быть полезно явно обрабатывать ответы с кодом 401, например пытаться обновить access_token.


                              access_token обновляется


                              Давайте теперь добавим в app.js в объект config код, так чтобы получилось


                              var config = {
                                  // ...
                                  // если true, клиент попытается обновить access_token перед его истечением, по умолчанию false
                                  automaticSilentRenew: true,
                                  // эта страница используется для "фонового" обновления токена пользователя через iframe
                                  silent_redirect_uri: 'http://localhost:5003/callback-silent.html',
                                  // за столько секунд до истечения oidc-client постарается обновить access_token
                                  accessTokenExpiringNotificationTime: 60,
                                  // ...
                              } 

                              При помощи консоли браузера убедитесь что теперь происходит автоматическое обновление access_token. Нажмите кнопку Call API чтобы убедиться, что всё работает.


                              id_token устаревает


                              Если access_token предназначается для ресурса API и ресурс обязан проверить его валидность, в том числе не устарел ли токен, при обращении к нему, то id_token предназначен именно для самого клиентского приложения. Поэтому и проверка должна проводиться на клиенте js-клиенте. Хорошо описано тут.


                              Заключение


                              Если Вы следовали инструкциям, на данный момент Вы:


                              1. Своими руками сделали рабочую реализацию OpenId Connect Implicit Flow при помощи IdentityServer и oidc-client на платформе ASP.NET Core 1.1.
                              2. Ознакомились с различными параметрами, позволяющими настроить части имплементации для Ваших нужд.
                              3. И, главное, несколько подразобрались, как имплементация соотносится со стандартом, причём до того, как выучили стандарт наизусть.

                              Полезные ссылки


                              1. Хороший туториал.
                              2. Официальные примеры IdentityServer4
                              3. Официальные примеры oidc-client.
                              4. Тут можно почитать про политики авторизации в ASP.NET Core. Заодно стоит прочитать и это.
                              5. В этой статье описано как использовать атрибут Authorize со списками ролей совместно с IdentityServer.
                              6. Здесь описано почему в стандарте OpenId Connect 2 токена — id_token и access_token вместо одного.
                              7. В процессе подготовки этой статьи вышла эта статья по реализации OpenId Connect в ASP.NET Core.
                              Original source: habrahabr.ru (comments, light).

                              https://habrahabr.ru/post/337784/


                              Метки:  

                              Поиск сообщений в rss_rss_hh_new
                              Страницы: 1437 ... 1141 1140 [1139] 1138 1137 ..
                              .. 1 Календарь