我正在开发一个运行CIS合规性命令的InSpec控件。 在研究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
感谢您的帮助@Matt
我已经阅读了你的答案并发现它真的很有用,除了最后一段代码:
egrep "^d[r|w|x]{3}------\s*.\s*mysql\s*mysql\s*\d*.*mysql"
平均
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
答案 0 :(得分:1)
您可以使用以下方法提取SQL请求的输出:
command('mysql -u <user> -p -e "show variables where variable_name = \'datadir\'"').stdout.split(' ')
mysql -u <user> -p -e
部分是从Linux命令执行SQL查询所必需的。如果您使用的是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
的stdout而不是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
我知道这里有很多功能可以实现您正在寻找的功能以及许多修复和改进,因此请务必仔细检查代码和解释,以了解我在此处所做的一切。