One place for hosting & domains

      Использование

      Использование Cron для автоматизации задач в CentOS 8


      Предыдущая версия данного обучающего руководства была написана Шоном Льюисом.

      Введение

      Cron — это хронологический демон-планировщик задач, работающий в операционных системах типа Unix, включая дистрибутивы Linux. Cron запускается в фоновом режиме, а задачи, запланированные в cron и именуемые «задачи cron», выполняются автоматически, что делает cron полезным для автоматизации связанных с обслуживанием задач.

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

      Предварительные требования

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

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

      Установка cron

      Почти все дистрибутивы Linux имеют ту или иную форму cron, установленную по умолчанию. Но если вы используете компьютер на базе CentOS, на котором не установлен cron, вы можете установить его с помощью dnf.

      Перед установкой cron на компьютер с CentOS обновите локальный индекс пакетов компьютера:

      Затем выполните установку демона cron с помощью следующей команды:

      • sudo dnf install crontabs

      Эта команда будет запрашивать подтверждение установки пакета crontabs и его зависимостей. Подтвердите действие, нажав y, а затем ENTER.

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

      Чтобы запустить демон cron, воспользуйтесь следующей командой:

      • sudo systemctl start crond.service

      Чтобы настроить запуск cron при загрузке сервера, введите:

      • sudo systemctl enable crond.service

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

      Как работает Cron

      Задачи в cron записываются и управляются в специальном файле crontab. Каждый профиль пользователя в системе может иметь собственный файл crontab, где составляются расписания задач, который хранится в директории /var/spool/cron/.

      Чтобы запланировать задачу, вам нужно открыть ваш файл crontab для редактирования и добавления задачи, написанной в форме выражения cron. Синтаксис выражений cron можно разбить на два элемента: расписание и команда для запуска.

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

      ПолеДопустимые значения
      минута0–59
      час0–23
      День месяца1–31
      месяц1–12 или ЯНВ–ДЕК
      День недели0–6 или ПНД–ВСК

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

      minute hour day_of_month month day_of_week command_to_run
      

      Ниже представлен функциональный пример выражения cron. Это выражение запускает команду curl http://www.google.com каждый вторник в 17:30:

      30 17 * * 2 curl http://www.google.com
      

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

      • *: в выражениях cron звездочка () служит подстановочным символом, который представляет все значения. Таким образом, задача, запланированная в форме ` * * * * …`, будет запускаться каждую минуту, каждый час, каждый день каждого месяца.
      • ,: запятые разбивают значения расписания для получения списка. Если вы хотите запускать задачу в начале и середине каждого часа, а не выполнять две отдельные задачи (например, 0 * * * * ... и 30 * * * * ...), вы можете добиться той же функциональности с помощью одного выражения (0,30 * * * * ...).
      • -: дефис представляет диапазон значений в поле расписания. Вместо создания 30 отдельных запланированных задач для команды, которую вы хотите запускать первые 30 минут каждого часа (например, 0 * * * * ..., 1 * * * * ..., 2 * * * * ... и т. д.), вы можете просто запланировать его следующим образом: 0-29 * * * * ....
      • /: вы можете использовать косую черту со звездочкой для выражения значения шага. Например, вместо написания восьми отдельных задач cron для запуска команды каждые три часа (например, 0 0 * * * ..., 0 3 * * * ..., 0 6 * * * ... и т. д.), вы можете задать расписание для запуска следующим образом: 0 */3 * * * ....

      Примечание. Вы не можете выражать значения шага произвольно, допускается использование только целых чисел, которые равномерно делят диапазон, допустимый для данного поля. Например, в поле «часы» вы можете указать после косой черты только 1, 2, 3, 4, 6, 8 или 12.

      Ниже представлено несколько примеров использования компонента расписания cron:

      • * * * * * — запускать команду каждую минуту.
      • 12 * * * * — запускать команду 12 минут в начале каждого часа.
      • 0,15,30,45 * * * * — запускать команду каждые 15 минут.
      • */15 * * * * — запускать команду каждые 15 минут.
      • 0 4 * * * — запускать команду каждый день в 4:00.
      • 0 4 * * 2-4 — запускать команду каждый вторник, среду и четверг в 4:00.
      • 20,40 */8 * 7-12 * — запускать команду в 20-ю и 40-ю минуту каждого 8-го часа каждый день последних 6 месяцев года.

      Если вы найдете что-то из этого затруднительным или вам потребуется помощь при написании расписания для ваших собственных задач cron, Cronitor предоставляет удобный редактор выражений cron, который называется Crontab Guru и который вы можете использовать для проверки действительности ваших расписаний cron.

      Управление файлами crontab

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

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

      Вы можете изменить файл crontab с помощью следующей команды:

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

      Примечание. В новых серверах CentOS 8 команда crontab -e будет открывать файл crontab вашего пользователя в редакторе vi по умолчанию. vi — очень надежный и гибкий текстовый редактор, но он может показаться непонятным тем, кто не имеет опыта работы в этом редакторе.

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

      Для этого нужно установить nano с помощью dnf:

      Нажмите y, а затем ENTER, чтобы подтвердить, что вы хотите установить nano.

      Чтобы настроить nano в качестве визуального текстового редактора для вашего профиля пользователя, откройте файл .bash_profile для редактирования. Теперь, когда вы установили редактор, вы можете выполнить редактирование в nano:

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

      ~/.bash_profile

      . . .
      export VISUAL="nano"
      

      В результате для переменной среды VISUAL присваивается значение nano. VISUAL — это переменная среды Unix, которую многие программы — в том числе crontab — вызывают для редактирования файла. После добавления этой строки сохраните и закройте файл, нажав CTRL + X, Y, а затем ENTER.

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

      После входа в редактор вы можете ввести свое расписание для каждой задачи в новой строке. Либо пока вы можете сохранить и закрыть файл crontab. Если вы открыли файл crontab в vi, текстовом редакторе CentOS 8 по умолчанию, вы можете сделать это, нажав ESC, чтобы убедиться, что вы находитесь в режиме командной строки vi, а затем введите :x и нажмите ENTER.

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

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

      Вы можете стереть файл crontab с помощью следующей команды:

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

      Эта команда удаляет файл crontab пользователя немедленно. Однако вы можете включить флаг -i, чтобы добавить в команду подтверждение того, что вы действительно хотите удалить пользовательский файл crontab:

      Output

      crontab: really delete sammy's crontab?

      После получения запроса вы должны ввести y, чтобы удалить файл crontab, или n, чтобы отменить удаление.

      Управление выводом задачи cron

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

      Если у вас есть агент передачи почты, например, Sendmail, который установлен и настроен на сервере, вы можете отправить результат выполнения задачи cron на электронный адрес, связанный с вашим профилем пользователя Linux. Также вы можете вручную задать адрес электронной почты, указав параметр MAILTO вверху crontab.

      Например, вы можете добавить следующие строки в файл crontab. К ним относятся оператор MAILTO, за которым следует пример адреса электронной почты, директива SHELL, которая указывает оболочку для запуска (в данном примере bash), директива HOME, указывающая путь поиска бинарного файла cron, и единственная задача cron:

      . . .
      
      MAILTO="example@digitalocean.com"
      SHELL=/bin/bash
      HOME=/
      
      * * * * * echo ‘Run this command every minute’
      

      Эта конкретная задача будет возвращать «Run this command every minute», а этот вывод будет отправляться каждую минуту на адрес электронной почты, заданный директивой MAILTO.

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

      Чтобы добавить вывод запланированной команды в файл журнала, добавьте >> в конец команды, после чего укажите имя и расположение файла журнала, как показано здесь:

      * * * * * echo ‘Run this command every minute’ >> /directory/path/file.log
      

      Скажем, что мы хотим использовать cron для запуска скрипта, но скрипт при этом должен выполняться в фоновом режиме. Для этого вы можете перенаправить вывод скрипта в пустую директорию, например /dev/null, которая немедленно удаляет все данные, добавляемые в нее. Например, следующая команда cron выполняет скрипт PHP и запускает его в фоновом режиме:

      * * * * * /usr/bin/php /var/www/domain.com/backup.php > /dev/null 2>&1
      

      Эта задача cron также перенаправляет стандартную ошибку — представляемую как 2 — в стандартный вывод (>&1). Поскольку стандартный вывод уже перенаправляется в директорию /dev/null, это позволяет запускать скрипт без лишнего шума. Даже если в crontab содержится оператор MAILTO, вывод команды не будет отправляться на заданный адрес электронной почты.

      Ограничение доступа

      Вы можете управлять тем, каким пользователям разрешается использовать команду crontab, с помощью файлов cron.allow и cron.deny, которые хранятся в директории /etc/. Если файл cron.deny существует, любой пользователь, который будет указан в нем, не будет иметь возможность менять файл crontab. Если cron.allow существует, то только пользователи, указанные в нем, будут иметь возможность изменять файлы crontab. Если оба файла существуют, и пользователь указан в каждом файле, файл cron.allow будет иметь приоритет над cron.deny, и этот пользователь сможет изменять файл crontab.

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

      • sudo echo ALL >>/etc/cron.deny
      • sudo echo ishmael >>/etc/cron.allow

      Сначала мы закрываем доступ для всех пользователей, добавив ALL в файл cron.deny. Затем, добавив имя пользователя в файл cron.allow, мы предоставим пользователю ishmael доступ к выполнению задач cron.

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

      Однако, если cron.deny существует, и user добавлен в него, но не указан в файле cron.allow, вы получите следующую ошибку после запуска предыдущей команды:

      Output

      The user user cannot use this program (crontab)

      По умолчанию большинство демонов cron полагает, что все пользователи имеют доступ к cron, если только не существует cron.allow или cron.deny.

      Специальный синтаксис

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

      СокращениеКраткая запись для
      @hourly0 * * * *
      @daily0 0 * * *
      @weekly0 0 * * 0
      @monthly0 0 1 * *
      @yearly0 0 1 1 *

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

      Кроме того, краткая запись @reboot будет запускать любую команду, которая следует за ней при каждом запуске сервера:

      @reboot echo "System start up"
      

      Использование этих комбинаций при возможности поможет понимать расписание задач в вашем файле crontab.

      Заключение

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



      Source link

      Использование миграции и пополнения базы данных для настройки абстрактной базы данных в Laravel


      Миграции и пополнения — это мощные утилиты для базы данных, предоставляемые PHP-фреймворком Laravel, которые позволяют разработчикам быстро инициализировать, уничтожать и воссоздавать базу данных приложения. Эти утилиты помогают свести к минимуму проблемы несогласованности базы данных, которые могут возникать, когда несколько разработчиков работают над одним приложением: новым участникам нужно будет запустить всего несколько команд artisan для настройки базы данных при новой установке.

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

      Предварительные требования

      Для выполнения этого обучающего руководства вам потребуется следующее:

      Примечание. В этом обучающем руководстве мы будем использовать контейнеризованную среду разработки под управлением Docker Compose для запуска приложения, но вы можете использовать приложение на сервере LEMP. Чтобы воспользоваться этим вариантом, ознакомьтесь с нашим руководством по установке и настройке Laravel с LEMP в Ubuntu 18.04.

      Шаг 1 — Получение демонстрационного приложения

      Вначале мы получим демонстрационное приложение Laravel из репозитория GitHub. Нас интересует раздел tutorial-02, который содержит настройку Docker Compose для запуска приложения в контейнерах. В данном примере мы загрузим приложение в домашнюю папку, но вы можете использовать любую директорию по вашему выбору:

      • cd ~
      • curl -L https://github.com/do-community/travellist-laravel-demo/archive/tutorial-2.0.1.zip -o travellist.zip

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

      Затем выполните установку пакета unzip:

      Распакуйте содержимое приложения:

      Далее необходимо переименовать директорию на travellist-demo для удобства доступа:

      • mv travellist-laravel-demo-tutorial-2.0.1 travellist-demo

      На следующем шаге мы создадим файл конфигурации .env для настройки приложения.

      Шаг 2 — Настройка файла .env приложения

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

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

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

      Перейдите в директорию travellist-demo:

      Теперь мы создадим новый файл .env для настройки индивидуальных параметров конфигурации для создаваемой нами среды разработки. В комплектацию Laravel входит образец файла .env, который мы скопируем для создания собственного файла:

      Откройте этот файл с помощью nano или другого текстового редактора на ваш выбор:

      Теперь ваш файл .env выглядит следующим образом:

      .env

      APP_NAME=Travellist
      APP_ENV=dev
      APP_KEY=
      APP_DEBUG=true
      APP_URL=http://localhost:8000
      
      LOG_CHANNEL=stack
      
      DB_CONNECTION=mysql
      DB_HOST=db
      DB_PORT=3306
      DB_DATABASE=travellist
      DB_USERNAME=travellist_user
      DB_PASSWORD=password

      Текущий файл .env для демонстрационного приложения travellist содержит настройки для работы в контейнеризованной среде, которую мы создали с помощью Docker Compose в последней статье данной серии. Вам не обязательно вносить изменения в эти значения, но вы можете изменить значения DB_DATABASE, DB_USERNAME и DB_PASSWORD, если захотите, так как они автоматически подставляются из нашего файла docker-compose.yml для настройки базы данных разработки. Убедитесь, что переменная DB_HOST остается без изменений, поскольку она указывает имя нашей службы базы данных в среде Docker Compose.

      При внесении любых изменений в файл обязательно сохраните и закройте его, нажав CTRL + X, Y, а затем ENTER.

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

      Шаг 3 — Установка зависимостей приложения с помощью Composer

      Теперь мы воспользуемся Composer, инструментом для управления зависимостями PHP, чтобы установить зависимости приложения и обеспечить возможность выполнения команд artisan.

      Сформируйте вашу среду Docker Compose с помощью следующей команды. В результате будет создан образ travellist для службы app и добавлены дополнительные образы Docker, необходимые службам nginx и db, чтобы создать среду приложения:

      Output

      Creating network "travellist-demo_travellist" with driver "bridge" Building app Step 1/11 : FROM php:7.4-fpm ---> fa37bd6db22a Step 2/11 : ARG user ---> Running in 9259bb2ac034 … Creating travellist-app ... done Creating travellist-nginx ... done Creating travellist-db ... done

      Выполнение этой операции может занять несколько минут. После завершения процесса мы сможем запустить Composer для установки зависимостей приложения.

      Для выполнения composer и других команд в контейнере службы app мы будем использовать docker-compose exec. Команда exec позволяет нам выполнять любую команду по нашему выбору в контейнерах под управлением Docker Compose. Она имеет следующий синтаксис: docker-compose exec service_name command.

      Примечание. Если вы предпочитаете использовать сервер LEMP для запуска демонстрационного приложения, можно проигнорировать часть docker-compose exec app для команд, представленных в рамках этого руководства. Например, вместо запуска следующей команды, как она написана, вы можете использовать следующую команду:

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

      • docker-compose exec app composer install

      Output

      Loading composer repositories with package information Installing dependencies (including require-dev) from lock file Package operations: 85 installs, 0 updates, 0 removals - Installing doctrine/inflector (1.3.1): Downloading (100%) - Installing doctrine/lexer (1.2.0): Downloading (100%) - Installing dragonmantank/cron-expression (v2.3.0): Downloading (100%) …

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

      • docker-compose exec app php artisan db:wipe

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

      Output

      Dropped all tables successfully.

      Теперь, когда вы установили зависимости приложения с помощью Composer, вы можете использовать инструмент artisan для создания миграций и пополнений.

      Шаг 4 — Создание миграций базы данных

      Инструмент командной строки artisan, предоставляемый вместе с Laravel, содержит ряд вспомогательных команд, которые могут использоваться для управления приложением и загрузки новых классов. Чтобы сгенерировать новый класс миграции, мы можем использовать команду make:migration следующим образом:

      • docker-compose exec app php artisan make:migration create_places_table

      Laravel выводит операцию, которую необходимо выполнить (create), имя таблицы (places), а также то, будет ли эта миграция создавать новую таблицу или нет, на основе описательного имени, предоставленного команде make:migration.

      Вывод будет выглядеть следующим образом:

      Output

      Created Migration: 2020_02_03_143622_create_places_table

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

      Используйте предпочитаемый вами текстовый редактор для открытия сгенерированного файла миграции. Обязательно замените выделенное значение на имя вашего файла миграции:

      • nano database/migrations/2020_02_03_143622_create_places_table.php

      Сгенерированный файл миграции содержит класс CreatePlacesTable:

      database/migrations/2020_02_03_143622_create_places_table.php

      <?php
      
      use IlluminateDatabaseMigrationsMigration;
      use IlluminateDatabaseSchemaBlueprint;
      use IlluminateSupportFacadesSchema;
      
      class CreatePlacesTable extends Migration
      {
          /**
           * Run the migrations.
           *
           * @return void
           */
          public function up()
          {
              Schema::create('places', function (Blueprint $table) {
                  $table->bigIncrements('id');
                  $table->timestamps();
              });
          }
      
          /**
           * Reverse the migrations.
           *
           * @return void
           */
          public function down()
          {
              Schema::dropIfExists('places');
          }
      }
      
      

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

      Мы изменим метод up так, чтобы таблица places имела структуру, которую мы уже использовали в текущей версии приложения:

      • id: поле первичного ключа.
      • name: название места.
      • visited: было ли посещено это место или нет.

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

      Автоматически генерируемый код задает поле основного идентификатора id. Метод timestamps создает два поля datetime, которые автоматически обновляются классами соответствующей базы данных, когда данные помещаются в таблицу или обновляются. Помимо этого, нам потребуется добавить поля name и visited.

      Наше поле name будет иметь тип string, а для поля visited будет установлен тип boolean. Также мы зададим значение по умолчанию 0 для поля visited, так что если значение не будет передано, это будет означать, что место пока не посещено. Вот как в настоящий момент выглядит метод up:

      database/migrations/2020_02_03_143622_create_places_table.php

      …
          public function up()
          {
              Schema::create('places', function (Blueprint $table) {
                  $table->bigIncrements('id');
                  $table->string('name', 100);
                  $table->boolean('visited')->default(0);
                  $table->timestamps();
              });
          }
      …
      

      Примечание. Вы можете найти полный список доступных типов столбцов в документации Laravel.

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

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

      Шаг 5 — Создание пополнений для базы данных

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

      Теперь мы воспользуемся командой artisan, которая генерирует новый класс seeder для нашей таблицы places с названием PlacesTableSeeder:

      • docker-compose exec app php artisan make:seeder PlacesTableSeeder

      Команда будет создавать новый файл с именем PlacesTableSeeder.php внутри директории database/seeds. Откройте этот файл в текстовом редакторе по выбору:

      • nano database/seeds/PlacesTableSeeder.php

      Вот как выглядит автоматически сгенерированный файл PlacesTableSeeder.php:

      database/seeds/PlacesTableSeeder.php

      <?php
      
      use IlluminateDatabaseSeeder;
      
      class PlacesTableSeeder extends Seeder
      {
          /**
           * Run the database seeds.
           *
           * @return void
           */
          public function run()
          {
              //
          }
      }
      
      

      Наш новый класс seeder содержит пустой метод с именем run. Этот метод будет вызываться при выполнении команды db:seed Artisan.

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

      Конструктор запросов Laravel предоставляет гибкий интерфейс для операций с базами данных, например, для вставки, обновления и восстановления данных. Также он обеспечивает защиту от внедрения SQL-кода. Конструктор запросов определяется фасадом DB, статическим прокси для классов базы данных в контейнере службы.

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

      Мы назовем эту переменную $places:

      database/seeds/PlacesTableSeeder.php

      <?php
      
      use IlluminateDatabaseSeeder;
      
      class PlacesTableSeeder extends Seeder
      {
          static $places = [
              'Berlin',
              'Budapest',
              'Cincinnati',
              'Denver',
              'Helsinki',
              'Lisbon',
              'Moscow',
              'Nairobi',
              'Oslo',
              'Rio',
              'Tokyo'
          ];

      Далее нам потребуется включить оператор use сверху класса PlacesTableSeeder, чтобы проще ссылаться на фасад DB в коде:

      database/seeds/PlacesTableSeeder.php

      <?php
      
      use IlluminateDatabaseSeeder;
      use IlluminateSupportFacadesDB;
      
      class PlacesTableSeeder extends Seeder
      …
      

      Теперь мы можем пробежаться по значениям массива $places с помощью цикла foreach и добавить их в нашу таблицу places с помощью конструктора запросов:

      database/seeds/PlacesTableSeeder.php

      …
          public function run()
          {
              foreach (self::$places as $place) {
                  DB::table('places')->insert([
                      'name' => $place,
                      'visited' => rand(0,1) == 1
                  ]);
              }
          }
      
      

      Цикл foreach проходит по каждому значению статического массива $places. В каждой итерации мы используем фасад DB для добавления новой строки в таблице places. Мы сохраним в поле name название места, которое мы только что получили из массива $places, а для поля visited будет использоваться случайное значение 0 или 1.

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

      database/seeds/PlacesTableSeeder.php

      <?php
      
      use IlluminateDatabaseSeeder;
      use IlluminateSupportFacadesDB;
      
      class PlacesTableSeeder extends Seeder
      {
          static $places = [
              'Berlin',
              'Budapest',
              'Cincinnati',
              'Denver',
              'Helsinki',
              'Lisbon',
              'Moscow',
              'Nairobi',
              'Oslo',
              'Rio',
              'Tokyo'
          ];
      
          /**
           * Run the database seeds.
           *
           * @return void
           */
          public function run()
          {
              foreach (self::$places as $place) {
                  DB::table('places')->insert([
                      'name' => $place,
                      'visited' => rand(0,1) == 1
                  ]);
              }
          }
      }
      

      Сохраните и закройте файл после внесения всех изменений.

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

      Откройте файл database/seeds/DatabaseSeeder.php с помощью nano или вашего любимого редактора:

      • nano database/seeds/DatabaseSeeder.php

      Класс DatabaseSeeder выглядит стандартным образом: он наследуется от класса Seeder и имеет метод run. Мы обновим этот метод, чтобы включить PlacesTableSeeder.

      Обновите текущий метод run внутри вашего класса DatabaseSeeder, удалив закомментированную строку и заменив ее на следующий выделенный код:

      database/seeds/DatabaseSeeder.php

      …
          public function run()
          {
              $this->call(PlacesTableSeeder::class);
          }
      ...
      

      Так будет выглядеть класс DatabaseSeeder после обновления:

      database/seeds/DatabaseSeeder.php

      <?php
      
      use IlluminateDatabaseSeeder;
      
      class DatabaseSeeder extends Seeder
      {
          /**
           * Seed the application's database.
           *
           * @return void
           */
          public function run()
          {
              $this->call(PlacesTableSeeder::class);
          }
      }
      
      
      

      Сохраните и закройте файл после внесения изменений в его содержимое.

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

      Шаг 6 — Запуск миграции и наполнения базы данных

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

      Чтобы сгенерировать ключ шифрования, требуемый Laravel, вы можете использовать команду artisan key:generate:

      • docker-compose exec app php artisan key:generate

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

      http://server_host_or_ip:8000
      

      Страница будет выглядеть следующим образом:

      Ошибка MySQL

      Это означает, что приложение может подключаться к базе данных, но оно не может найти таблицу с именем places. Теперь мы создадим таблицу places, используя следующую команду migrate artisan:

      • docker-compose exec app php artisan migrate

      Вывод будет выглядеть следующим образом:

      Output

      Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table (0.06 seconds) Migrating: 2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_table (0.06 seconds) Migrating: 2019_08_19_000000_create_failed_jobs_table Migrated: 2019_08_19_000000_create_failed_jobs_table (0.03 seconds) Migrating: 2020_02_10_144134_create_places_table Migrated: 2020_02_10_144134_create_places_table (0.03 seconds)

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

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

      • docker-compose exec app php artisan db:seed

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

      Output

      Seeding: PlacesTableSeeder Seeded: PlacesTableSeeder (0.06 seconds) Database seeding completed successfully.

      Теперь перезагрузите страницу приложения в браузере. Вы увидите приблизительно следующую страницу:

      Демонстрационное приложение Laravel

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

      • docker-compose exec app php artisan db:wipe

      Output

      Dropped all tables successfully.

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

      • docker-compose exec app php artisan migrate --seed

      Output

      Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table (0.06 seconds) Migrating: 2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_table (0.07 seconds) Migrating: 2019_08_19_000000_create_failed_jobs_table Migrated: 2019_08_19_000000_create_failed_jobs_table (0.03 seconds) Migrating: 2020_02_10_144134_create_places_table Migrated: 2020_02_10_144134_create_places_table (0.03 seconds) Seeding: PlacesTableSeeder Seeded: PlacesTableSeeder (0.06 seconds) Database seeding completed successfully.

      Если вы захотите откатить изменения, запустите следующую команду:

      • docker-compose exec app php artisan migrate:rollback

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

      Output

      Rolling back: 2020_02_10_144134_create_places_table Rolled back: 2020_02_10_144134_create_places_table (0.02 seconds) Rolling back: 2019_08_19_000000_create_failed_jobs_table Rolled back: 2019_08_19_000000_create_failed_jobs_table (0.02 seconds) Rolling back: 2014_10_12_100000_create_password_resets_table Rolled back: 2014_10_12_100000_create_password_resets_table (0.02 seconds) Rolling back: 2014_10_12_000000_create_users_table Rolled back: 2014_10_12_000000_create_users_table (0.02 seconds)

      Команда отката изменений особенно полезна, когда вы вносите изменения в модели приложения, а команда db:wipe не может использоваться, например, если несколько систем используют одну базу данных.

      Заключение

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

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



      Source link

      Установка и использование Radamsa для фаззи-тестирования программ и сетевых служб в Ubuntu 18.04


      Автор выбрал Electronic Frontier Foundation Inc для получения пожертвований в рамках программы Write for DOnations.

      Введение

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

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

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

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

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

      Предварительные требования

      Для прохождения этого обучающего руководства вам потребуется следующее:

      • Один сервер Ubuntu 18.04, настроенный в соответствии с указаниями руководства Начальная настройка сервера Ubuntu 18.04, включая пользователя sudo без привилегий root и активный брандмауэр для блокирования ненужных портов.
      • Приложение командной строки или сетевое приложение, которое вы хотите протестировать, например Gzip, Tcpdump, Bind, Apache, jq или любое другое приложение по вашему выбору. Для целей этого обучающего руководства в качестве примера мы будем использовать jq.

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

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

      Шаг 1 — Установка Radamsa

      Прежде всего, мы загрузим и выполним компиляцию Radamsa для использования этого инструмента в нашей системе. Исходный код Radamsa доступен в официальном репозитории на GitLab.

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

      Затем мы установим пакеты gcc, git, make и wget, необходимые для компиляции исходного кода в исполняемый двоичный файл:

      • sudo apt install gcc git make wget

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

      Затем мы загрузим копию исходного кода Radamsa, клонировав ее из репозитория на GitLab:

      • git clone https://gitlab.com/akihe/radamsa.git

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

      Далее вы можете запустить процесс компиляции с помощью make:

      Теперь мы можем установить скомпилированный двоичный файл Radamsa в директорию $PATH:

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

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

      Output

      Radamsa 0.6

      Если появится сообщение об ошибке radamsa: command not found, необходимо проверить установку всех требуемых зависимостей и убедиться в отсутствии ошибок при компиляции.

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

      Шаг 2 — Подготовка примеров для фаззинга

      Мы установили Radamsa и теперь можем использовать его для рассмотрения нескольких примеров фаззинга.

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

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

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

      • echo "Hello, world!" | radamsa

      Вводимые данные будут изменены (фаззинг) и получится пример для тестирования:

      Output

      Hello,, world!

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

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

      Output

      Hello, '''''''wor'd!

      На этот раз мы вставили в строку несколько одинарных кавычек ('), в том числе один символ, заменивший l в слове world. Этот пример с большей вероятностью вызовет проблемы в приложении, поскольку одинарные и двойные кавычки часто используются как разделители элементов данных в списке.

      Повторим попытку еще один раз:

      Output

      Hello, $+$PATHu0000`xcalc`world!

      В данном случае Radamsa вставляет строку оболочки, которая поможет тестировать приложение на уязвимость к вставке команд.

      Мы использовали Radamsa для фаззинга вводимой строки и подготовили ряд примеров для тестирования. Далее мы используем Radamsa для фаззинга приложения командной строки.

      Шаг 3 — Фаззинг приложения командной строки

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

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

      Вы можете использовать любую другую программу подобного рода, если она также принимает структурированные или неструктурированные данные, выполняет с ними какие-то операции и выводит результат. В частности, данный пример также подойдет для Gzip, Grep, bc, tr и т. д.

      Если вы еще не установили jq, вы можете выполнить установку сейчас с помощью apt:

      Сейчас будет выполнена установка jq.

      Чтобы начать фаззинг, создайте образец файла JSON, который будете использовать в качестве исходного для Radamsa:

      Добавьте в файл следующие данные JSON:

      test.json

      {
        "test": "test",
        "array": [
          "item1: foo",
          "item2: bar"
        ]
      }
      

      Вы можете проверить этот файл с помощью jq, если хотите убедиться в правильности синтаксиса JSON:

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

      Далее мы проведем фаззинг тестового файла JSON в Radamsa и передадим его в jq. В результате jq прочитает измененный тестовый файл, а не первоначальные правильные данные JSON:

      Если Radamsa изменит данные JSON так, что синтаксис останется верным, jq выведет данные со всеми изменениями, которые были внесены Radamsa.

      Если Radamsa изменит формат данных JSON на неверный, программа jq выдаст сообщение об ошибке. Например:

      Output

      parse error: Expected separator between values at line 5, column 16

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

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

      Создайте файл с именем jq-fuzz.sh:

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

      Скопируйте скрипт в файл jq-fuzz.sh:

      jq-fuzz.sh

      #!/bin/bash
      while true; do
        radamsa test.json > input.txt
        jq . input.txt > /dev/null 2>&1
        if [ $? -gt 127 ]; then
          cp input.txt crash-`date +s%.%N`.txt
          echo "Crash found!"
        fi
      done
      

      Этот скрипт содержит оператор while, чтобы сделать его содержимое цикличным. При каждом цикле скрипта Radamsa генерирует тестовый пример на базе файла test.json и сохраняет его в файл input.txt.

      Тестовый пример input.txt пропускается через jq так, что все стандартные сообщения и сообщения об ошибках направляются в /dev/null для предотвращения переполнения экрана терминала.

      В заключение проверяется значение jq на выходе. Если значение на выходе превышает 127, это означает критическое завершение работы (сбой), и в этом случае входные данные сохраняются для последующего использования в файле с именем crash- и суффиксом текущей даты Unix с указанием секунд и наносекунд.

      Отметьте этот скрипт как исполняемый и запустите его для автоматического тестирования jq методом фаззинга:

      • chmod +x jq-fuzz.sh
      • ./jq-fuzz.sh

      Вы можете в любой момент нажать CTRL+C для остановки скрипта. Затем вы сможете проверить наличие сбоев, используя ls для вывода списка директории с созданными файлами регистрации сбоев.

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

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

      Шаг 4 — Фаззинг запросов сетевых служб

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

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

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

      Вначале нужно настроить веб-сервер для тестирования. Для этой цели можно использовать встроенный сервер разработки, входящий в состав пакета php-cli. Также для тестирования веб-сервера нам потребуется curl.

      Если у вас не установлены php-cli и/или curl, вы можете установить их с помощью apt:

      • sudo apt install php-cli curl

      Затем создайте директорию для хранения файлов веб-сервера и перейдите в нее:

      Далее создайте файл HTML с образцом текста:

      Добавьте в файл следующее:

      index.html

      <h1>Hello, world!</h1>
      

      Теперь вы можете запустить свой веб-сервер PHP. Вам потребуется возможность просматривать журнал веб-сервера во время использования другого сеанса терминала, и поэтому нужно открыть другой сеанс терминала и канал SSH для подключения к серверу:

      • cd ~/www
      • php -S localhost:8080

      Будет выведен текст следующего вида:

      Output

      PHP 7.2.24-0ubuntu0.18.04.1 Development Server started at Wed Jan 1 16:06:41 2020 Listening on http://localhost:8080 Document root is /home/user/www Press Ctrl-C to quit.

      Теперь вы можете вернуться к исходному сеансу терминала и проверить работу веб-сервера с помощью curl:

      В результате будет выведен образец файла index.html, который вы создали ранее:

      Output

      <h1>Hello, world!</h1>

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

      Мы настроили тестовый веб-сервер и теперь можем начать фаззинг с помощью Radamsa.

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

      Затем скопируйте в файл следующий образец запроса HTTP:

      http-request.txt

      GET / HTTP/1.1
      Host: localhost:8080
      User-Agent: test
      Accept: */*
      

      Теперь мы можем использовать Radamsa для отправки этого запроса HTTP на локальный веб-сервер. Для этого нужно использовать Radamsa в качестве клиента TCP, что можно сделать посредством указания IP-адреса и порта для подключения:

      • radamsa -o 127.0.0.1:8080 http-request.txt

      Примечание. Использование Radamsa в качестве клиента TCP может привести к передаче через сеть неправильно сформированных или вредоносных данных. Это может повлечь за собой неисправности, и поэтому вы должны использовать только сети, которые вам разрешено тестировать, а лучше всего использовать только адрес localhost (127.0.0.1).

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

      Журналы будут отображаться во втором окне терминала:

      Output

      [Wed Jan 1 16:26:49 2020] 127.0.0.1:49334 Invalid request (Unexpected EOF) [Wed Jan 1 16:28:04 2020] 127.0.0.1:49336 Invalid request (Malformed HTTP request) [Wed Jan 1 16:28:05 2020] 127.0.0.1:49338 Invalid request (Malformed HTTP request) [Wed Jan 1 16:28:07 2020] 127.0.0.1:49340 Invalid request (Unexpected EOF) [Wed Jan 1 16:28:08 2020] 127.0.0.1:49342 Invalid request (Malformed HTTP request)

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

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

      Шаг 5 — Фаззинг сетевых клиентских приложений

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

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

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

      Приложение whois используется для отправки запросов на серверы WHOIS и получения записей WHOIS в составе ответов. WHOIS работает через порт TCP 43 в формате простого текста, что делает его отличным вариантом для фаззинга сетевого клиента.

      Если у вас еще нет приложения whois, вы можете установить его с помощью apt:

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

      • whois example.com > whois.txt

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

      • radamsa -o :4343 whois.txt -n inf

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

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

      • whois -h localhost:4343 example.com

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

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

      На этом заключительном шаге мы использовали Radamsa для тестирования сетевого клиентского приложения методом фаззинга.

      Заключение

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

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

      Также вы можете рассмотреть и другие инструменты для фаззинга, например продвинутую программу фаззинга American Fuzzy Lop (AFL), предназначенную для тестирования двоичных приложений с очень высокой скоростью и точностью:



      Source link