我正在尝试使用傀儡大师 3.1.1管理各种服务器上的 iptables。我的本地 puppet 代理是 2.7.19,服务器操作系统是CentOS 5.4。
/etc/puppet/modules/mycompany/manifests/config/iptables.pp
class base::iptables (
{
{
$identity_environment = $::identity_environment
}
if ($identity_environment == "production")
{
$start_iptables = "true"
$run_iptables = "running"
}
elsif ($identity_environment == "development")
{
$start_iptables = "false"
$run_iptables = "stopped"
}
if ($run_iptables != "stopped")
{
file { "/etc/sysconfig/iptables":
ensure => file,
owner => root,
group => root,
mode => 644,
source => "puppet://path_to_my_conf",
require => File["/etc/resolv.conf"],
}
service { "iptables":
subscribe => File["/etc/sysconfig/iptables"],
enable => "$start_iptables",
ensure => "$run_iptables",
status => "[[ `iptables -L -n | egrep -v '(Chain|target)' | grep '^[A-Za-z]' | wc -l` != 0 ]]",
}
}
else
{
service { "iptables":
enable =>"$start_iptables",
ensure =>"$run_iptables",
}
}
}
当我在开发服务器上运行 puppet 时:
puppet agent --verbose --no-daemonize --onetime --debug | grep iptable
发生以下情况:
调试:Puppet::Type::Service::ProviderRedhat:正在执行“/sbin/chkconfig iptables”调试:Serviceiptables:正在执行“/sbin/service iptables stop”调试:Puppet::Type::Service::ProviderRedhat:正在执行“/sbin/chkconfig iptables”通知:/Stage[main]/Base::Iptables/Service[iptables]/ensure:确保将“运行”更改为“已停止”调试:/Stage[main]/Base::Iptables/Service[iptables]:容器 Class[Base::Iptables] 将传播我的刷新事件调试:Serviceip6tables:正在执行“/sbin/service ip6tables status”调试:Puppet::Type::Service::ProviderRedhat:正在执行“/sbin/chkconfig ip6tables”调试:Class[Base::Iptables]:容器Stage[main] 将传播我的刷新事件
手动检查service iptables status
表明服务确实正在运行,Puppet 是否会停止该服务,然后由于“刷新”而以某种方式启动它?
我试图修改我的清单根据这个类似的问题但无济于事,
service { "iptables":
ensure => "stopped",
hasstatus => "true",
status => "true"
}
结果是相同的——puppet 检查,然后停止 iptables,但服务又重新打开。
我不知道这是否相关记录了此竞争条件错误在较新的 Puppet 版本中已经修复了这个问题,但我没有选择更新或实施适当的方法,例如puppetlab 的防火墙模块此时。
更新 [20140724]
在收到一些很好的反馈后,我从 /etc/init.d/iptables 脚本进行了一些调试/记录。后来发现,当 puppet 运行时,没有发出启动服务的调用,但是即使 puppet 停止了 iptables,操作系统仍报告 iptables 正在运行。
我倾向于查看 iptables 模块本身。果然,如果我删除 iptables 模块,然后再次运行 puppet,该模块就会重新加载。
更新 [20140729]
下面列出了我的解决方案作为答案。我将提出一个新问题,以继续用此方法排除 CentOS 6 故障。
答案1
我想把这个留在这里作为我问题的答案,因为它对我有用。如果您运行的是 CentOS 5.4,这将有效并确保从内核中卸载 iptables 模块。我将提出一个新问题,具体涉及我继续使用 CentOS 6 和 puppet 的工作。
exec { "chkconfig_iptables":
onlyif => "/sbin/chkconfig --level 3 iptables",
command => "/sbin/chkconfig --level 3 iptables off",
before => exec["kill_iptables"]
}
exec { "kill_iptables":
onlyif => "/sbin/lsmod | grep ip_tables",
command => "/sbin/service iptables stop;/sbin/modprobe -f -r ip_tables"
}