Đây là những gì tôi đang làm với Red Hat Enterprise (RHEL).
RHEL có một iptables
dịch vụ tải các quy tắc từ /etc/sysconfig/iptables
và tôi đang làm việc với việc sửa đổi tệp đó và khởi động lại dịch vụ iptables. Nhiều người thích thả các đoạn vào thư mục iptables.d và xây dựng một quy tắc iptables (thông qua make hoặc đại loại như thế) từ đó. Tôi bao gồm các công cụ để xây dựng lại quy tắc mặc định, nhưng điều đó thường không bao giờ làm bất cứ điều gì. Nếu nhu cầu của bạn đơn giản, bạn có thể sao chép tệp iptables vào hệ thống.
Mặc dù điều này có vẻ xấu xí như thế nào, nhưng nó đã được thử nghiệm khá kỹ lưỡng trên RHEL4, RHEL5 và RHEL6.
Tôi đã có được điều này trước khi sự hỗ trợ của augeas là trong múa rối. Nếu tôi đã viết nó một lần nữa hôm nay tôi sẽ nhìn vào ống kính iptables trước khi dùng đến exec { "perl ...": }
.
Một số định nghĩa toàn cầu để chỉnh sửa các tập tin tại chỗ
# Ensure that the line "line" exists in "file":
# Usage:
# append_if_no_such_line { dummy_modules:
# file => "/etc/modules",
# line => dummy
# }
#
define append_if_no_such_line($file, $line, $refreshonly = 'false') {
exec { "/bin/echo '$line' >> '$file'":
unless => "/bin/grep -Fxqe '$line' '$file'",
refreshonly => $refreshonly,
}
}
# Ensure that the line "line" exists in "file":
# Usage:
# prepend_if_no_such_line { dummy_modules:
# file => "/etc/modules",
# line => dummy
# }
#
define prepend_if_no_such_line($file, $line, $refreshonly = 'false') {
$line_no_slashes = slash_escape($line)
exec { "/usr/bin/perl -p0i -e 's/^/$line_no_slashes\n/;' '$file'":
unless => "/bin/grep -Fxqe '$line' '$file'",
refreshonly => $refreshonly,
}
}
define insert_line_after_if_no_such_line($file, $line, $after) {
$line_no_slashes = slash_escape($line)
$after_no_slashes = slash_escape($after)
exec { "/usr/bin/perl -p0i -e 's/^($after_no_slashes)\$/\$1\n$line_no_slashes/m' '$file'":
onlyif => "/usr/bin/perl -ne 'BEGIN { \$ret = 0; } \$ret = 1 if /^$line_no_slashes/; END { exit \$ret; }' '$file'",
}
}
define insert_line_before_if_no_such_line($file, $line, $beforeline) {
$line_no_slashes = slash_escape($line)
$before_no_slashes = slash_escape($beforeline)
exec { "/usr/bin/perl -p0i -e 's/^($before_no_slashes)\$/$line_no_slashes\n\$1/m' '$file'":
onlyif => "/usr/bin/perl -ne 'BEGIN { \$ret = 0; } \$ret = 1 if /^$line_no_slashes/; END { exit \$ret; }' '$file'",
}
}
Lớp học iptables của tôi:
class iptables {
if $lsbmajdistrelease >= '6' {
$primarychain = 'INPUT'
} else {
$primarychain = 'RH-Firewall-1-INPUT'
}
package {
iptables:
ensure => installed # "latest" would be too much
}
service {
iptables:
enable => true, # default on
ensure => running, # start it up if it's stopped
hasstatus => true, # since there's no daemon
}
file {
"/etc/sysconfig/iptables":
ensure => present;
}
##
# Build up a config if it's missing components we expect; should
# automatically repair a config if it's broken for really simple reasons
##
# Very first thing: a comment at the top warning about our evil; add even if
# we're not touching anything else...
prepend_if_no_such_line {
"/etc/sysconfig/iptables comment":
file => "/etc/sysconfig/iptables",
line => "# This file partially managed by puppet; attempts to edit will result in magic reappearances"
}
# start
# *filter
insert_line_after_if_no_such_line {
"/etc/sysconfig/iptables *filter":
file => "/etc/sysconfig/iptables",
line => "\\*filter",
after => "#.*",
notify => Service[iptables],
}
# first default chain
# :INPUT ACCEPT [0:0]
insert_line_after_if_no_such_line {
"/etc/sysconfig/iptables:INPUT":
file => "/etc/sysconfig/iptables",
line => ":INPUT ACCEPT \\[0:0\\]",
after => "\\*filter",
notify => Service[iptables],
}
# second default chain
# :FORWARD ACCEPT [0:0]
insert_line_after_if_no_such_line {
"/etc/sysconfig/iptables:FORWARD":
file => "/etc/sysconfig/iptables",
line => ":FORWARD ACCEPT \\[0:0\\]",
after => ":INPUT ACCEPT \\[\\d+:\\d+\\]",
notify => Service[iptables],
}
# third default chain
# :OUTPUT ACCEPT [0:0]
insert_line_after_if_no_such_line {
"/etc/sysconfig/iptables:OUTPUT":
file => "/etc/sysconfig/iptables",
line => ":OUTPUT ACCEPT \\[0:0\\]",
after => ":FORWARD ACCEPT \\[\\d+:\\d+\\]",
notify => Service[iptables],
}
if $lsbmajdistrelease <= 5 {
# Finally, the RH special chain
# :RH-Firewall-1-INPUT - [0:0]
insert_line_after_if_no_such_line {
"/etc/sysconfig/iptables:RH-Firewall-1-INPUT":
file => "/etc/sysconfig/iptables",
line => ":RH-Firewall-1-INPUT - \\[0:0\\]",
after => ":OUTPUT ACCEPT \\[\\d+:\\d+\\]",
notify => Service[iptables],
}
# redirect INPUT to RH chain
# -A INPUT -j RH-Firewall-1-INPUT
insert_line_after_if_no_such_line {
"/etc/sysconfig/iptables:INPUT:RH-Firewall-1-INPUT":
file => "/etc/sysconfig/iptables",
line => "-A INPUT -j RH-Firewall-1-INPUT",
after => ":RH-Firewall-1-INPUT - \\[\\d+:\\d+\\]",
notify => Service[iptables],
}
# redirect FORWARD to RH chain
# -A FORWARD -j RH-Firewall-1-INPUT
insert_line_after_if_no_such_line {
"/etc/sysconfig/iptables:FORWARD:RH-Firewall-1-INPUT":
file => "/etc/sysconfig/iptables",
line => "-A FORWARD -j RH-Firewall-1-INPUT",
after => "-A INPUT -j RH-Firewall-1-INPUT",
notify => Service[iptables],
}
}
# Let anything on localhost work...
# -A $primarychain -i lo -j ACCEPT
insert_line_after_if_no_such_line {
"/etc/sysconfig/iptables:$primarychain lo":
file => "/etc/sysconfig/iptables",
line => "-A $primarychain -i lo -j ACCEPT",
after => "-A FORWARD -j $primarychain",
notify => Service[iptables],
}
# And let through all the ICMP stuff:
# -A $primarychain -p icmp --icmp-type any -j ACCEPT
if $lsbmajdistrelease >= '6' {
insert_line_after_if_no_such_line {
"/etc/sysconfig/iptables:$primarychain icmp":
file => "/etc/sysconfig/iptables",
line => "-A $primarychain -p icmp -j ACCEPT",
after => "-A $primarychain -i lo -j ACCEPT",
notify => Service[iptables],
}
} else {
insert_line_after_if_no_such_line {
"/etc/sysconfig/iptables:$primarychain icmp":
file => "/etc/sysconfig/iptables",
line => "-A $primarychain -p icmp --icmp-type any -j ACCEPT",
after => "-A $primarychain -i lo -j ACCEPT",
notify => Service[iptables],
}
}
# Finally, let anything that's part of an exisiting connection through:
# -A $primarychain -m state --state ESTABLISHED,RELATED -j ACCEPT
insert_line_after_if_no_such_line {
"/etc/sysconfig/iptables:ESTABLISHED":
file => "/etc/sysconfig/iptables",
line => "-A $primarychain -m state --state ESTABLISHED,RELATED -j ACCEPT",
after => "-A $primarychain -p icmp --icmp-type any -j ACCEPT",
notify => Service[iptables],
}
# Very last thing:
# COMMIT
append_if_no_such_line {
"/etc/sysconfig/iptables:COMMIT":
file => "/etc/sysconfig/iptables",
line => "COMMIT",
notify => Service[iptables],
}
# Next to last thing: reject!
# -A $primarychain -j REJECT --reject-with icmp-host-prohibited
insert_line_before_if_no_such_line {
"/etc/sysconfig/iptables:final reject":
file => "/etc/sysconfig/iptables",
line => "-A $primarychain -j REJECT --reject-with icmp-host-prohibited",
beforeline => "COMMIT",
notify => Service[iptables],
}
}
# example:
# iptable_rule { "iptable:ssh":
# rule => "-m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT"
# }
# change your mind about a rule, do this:
# iptable_rule { "iptable:ssh":
# rule => "-m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT",
# ensure => "absent",
# }
define iptable_rule($rule, $ensure = 'present') {
if $lsbmajdistrelease >= '6' {
$primarychain = 'INPUT'
} else {
$primarychain = 'RH-Firewall-1-INPUT'
}
$iptablesline = "-A $primarychain $rule"
case $ensure {
default: { err ( "unknown ensure value $ensure" ) }
present: {
insert_line_before_if_no_such_line {
"/etc/sysconfig/iptables:add $rule":
file => "/etc/sysconfig/iptables",
line => $iptablesline,
beforeline => "-A $primarychain -j REJECT --reject-with icmp-host-prohibited",
notify => Service[iptables],
}
}
absent: {
delete_lines {
"/etc/sysconfig/iptables:remove $rule":
file => "/etc/sysconfig/iptables",
pattern => $iptablesline,
notify => Service[iptables],
}
}
}
}
# Example:
# iptable_tcp_port { "iptable:ssh":
# port => "22",
# }
# Example:
# iptable_tcp_port { "iptable:oracle:130.157.5.0/24":
# port => "1521",
# source => "130.157.5.0/24",
# }
# (add ensure => "absent" to remove)
define iptable_tcp_port($port, $ensure = 'present', $source = 'ANY') {
case $source {
"ANY": {
iptable_rule {
"iptable_tcp_port:$port":
rule => "-m state --state NEW -m tcp -p tcp --dport $port -j ACCEPT",
ensure => $ensure,
}
}
default: {
iptable_rule {
"iptable_tcp_port:$port:$source":
rule => "-m state --state NEW -m tcp -p tcp --source $source --dport $port -j ACCEPT",
ensure => $ensure,
}
}
}
}
# Example:
# iptable_udp_port { "iptable:ntp":
# port => "123",
# }
# (again, ensure => "absent" if needed)
define iptable_udp_port($port, $ensure = 'present', $source = 'ANY') {
case $source {
"ANY": {
iptable_rule {
"iptable_udp_port:$port":
rule => "-p udp -m udp --dport $port -j ACCEPT",
ensure => $ensure,
}
}
default: {
iptable_rule {
"iptable_udp_port:$port":
rule => "-p udp -m udp --source $source --dport $port -j ACCEPT",
ensure => $ensure,
}
}
}
}
Một số ví dụ về việc sử dụng trong các lớp khác:
class ssh {
include iptables
iptable_tcp_port {
"iptables:ssh":
port => "22",
ensure => "present"
}
}
class ssh_restricted inherits ssh {
Iptable_tcp_port["iptables:ssh"]{ensure => "absent"}
iptable_tcp_port {
"ssh:RESTRICTED":
port => "22",
source => "X.Y.0.0/16",
ensure => "present";
}
}
class apache {
iptable_tcp_port {
"iptables:http":
require => Service["httpd"],
port => "80";
}
}
class apache::secure {
iptable_tcp_port {
"iptables:https":
require => Service["httpd"],
port => "443";
}
}
class snmp {
iptable_udp_port { "iptables:snmp": port => "161" }
}