Как сделать программу, которая может открыть MySQL - PullRequest
0 голосов
/ 03 мая 2018

Я разрабатываю элемент управления InSpec, который выполняет команды соответствия CIS. Работая над MySQL, я застрял здесь:

Выполните следующую инструкцию SQL, чтобы определить значение datadir:

show variables where variable_name = 'datadir';

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

ls -l <THE OUTPUT OF THE PREVIOUS COMMAND>/.. | egrep "^d[r|w|x]{3}------\s*.\s*mysql\s*mysql\s*\d*.*mysql"

Проблема в том, что первая команда - это запрос SQL, а вторая - терминальная команда.

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

control "mysql1" do
    impact 1.0
    title "Use dedicated Least Privileged Account for MySQL Daemon/Service"
    desc "May reduce the impact of a MySQL-born vulnerability"
    describe command ('ps -ef |e grep "^mysql.*$"') do
    its('stdout') { should match ''}
    end
end

Спасибо за помощь @ Мэтт

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

egrep "^d[r|w|x]{3}------\s*.\s*mysql\s*mysql\s*\d*.*mysql"

1020 * означает *

it { expect(subject).to_not be_owned_by 'mysql' }
it { expect(subject).to_not be_grouped_into 'mysql' }
it { expect(subject).to_not be_executable_by 'mysql' }

Плюс я попробовал все блоки, которые вы написали ранее, и ни один из них не работал .. И да, я использую Linux 16.04

1 Ответ

0 голосов
/ 03 мая 2018

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

command('mysql -u <user> -p -e "show variables where variable_name = \'datadir\'"').stdout.split(' ')

Часть mysql -u <user> -p -e необходима для выполнения SQL-запроса из команды Linux. Если вы используете Window, вам, вероятно, придется использовать sqlcmd. Это позволяет успешно выполнять запрос SQL с помощью метода command.

Причина, по которой метод command работает здесь, заключается в том, что это пользовательский тип RSpec (неявно, следовательно, также конструктор класса в том смысле, что у Ruby есть конструкторы), который будет выполняться локально или удаленно в тестируемой системе. Метод .stdout является членом класса для захвата стандартного вывода команды. .split обеспечит сохранение выходных переменных в массиве с пробелами.

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

# store array of variables
variables = command('mysql -u <user> -p -e "show variables where variable_name = \'datadir\'"').stdout.split(' ')
# use array in command
variables.each do |variable|
  describe command("ls -l #{variable}/.. | egrep \"^d[r|w|x]{3}------\s*.\s*mysql\s*mysql\s*\d*.*mysql\"") do
    its('stdout') { should match ''}
  end
end

Выше мы перебираем массив переменных, захваченных в запросе SQL, и тестируем его в тесте describe command() RSpec. Лучший способ выполнить этот тест - проверить стандартный вывод command в сопоставителе, а не egrep. Делаем это и убираем метод match:

# store array of variables
variables = command('mysql -u <user> -p -e "show variables where variable_name = \'datadir\'"').stdout.split(' ')
# use array in command
variables.each do |variable|
  describe command("ls -l #{variable}/..") do
    its('stdout') { should_not match(/^d[r|w|x]{3}------\s*.\s*mysql\s*mysql\s*\d*.*mysql/)}
  end
end

Обновление до устаревших средств сравнения RSpec и исправление вызова метода stdout в виде строки вместо символа, к которому мы пришли:

# store array of variables
variables = command('mysql -u <user> -p -e "show variables where variable_name = \'datadir\'"').stdout.split(' ')
# use array in command
variables.each do |variable|
  describe command("ls -l #{variable}/..") do
    its(:stdout) { is_expected.to_not match(/^d[r|w|x]{3}------\s*.\s*mysql\s*mysql\s*\d*.*mysql/)}
  end
end

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

# store array of variables
variables = command('mysql -u <user> -p -e "show variables where variable_name = \'datadir\'"').stdout.split(' ')
# use array in file type
variables.each do |variable|
  describe file("#{variable}/..") do
    # check permissions
    it { expect(subject).to_not be_owned_by 'mysql' }
    it { expect(subject).to_not be_grouped_into 'mysql' }
    it { expect(subject).to_not be_executable_by 'mysql' }
  end
end

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

...