Но это жутко опасная штука. Очень опасная.
Puppet
Но это жутко опасная штука. Очень опасная.
Точно так же, как и с DNS, существуют модули puppet, предназначенные для управления fierwall. Исходя из соображения, зачем использовать сторонние обёртки, когда iptables сам по себе крут и админ должен знать его на Ять, я не буду использовать эти модули.
Что будем делать:
На puppet сервере, создадим файл с конфигурацией firewall для машины с dns:
# cd /var/puppet/centos7-2.test.local/etc/
# mkdir sysconfig
# vim sysconfig/iptables
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state —state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state —state NEW -m tcp —dport 22 -j ACCEPT
-A INPUT -p udp -m state —state NEW -m udp —dport 53 -j ACCEPT
-A INPUT -p tcp -m state —state NEW -m tcp —dport 53 -j ACCEPT
COMMIT
В файле site.pp добавляем новый класс.
class minimal-iptables {
# Удаляем firewalld
package { ‘firewalld’:
ensure => absent,
before => Package[‘iptables-services‘]
}
# Перед удалением firewalld останавливаем соответствующий
# сервис и делаем ему disable.
service { ‘firewalld’:
name => «firewalld»,
enable => false,
ensure => stopped,
before => Package[‘firewalld’]
}
# Устанавливаем iptables-services
package { ‘iptables-services’ :
ensure => installed
}
service { ‘iptables’:
enable => true,
ensure => running,
require => Package[«iptables-services»]
}
# Определяем файл, в котором будем описывать
# правила firewall
file { ‘/etc/sysconfig/iptables’:
ensure => file,
mode => ‘0600’,
owner => ‘root’,
# Для каждой машины предполагается свой файл
source => «puppet:///configs/$fqdn/etc/sysconfig/iptables»,
require => Package[«iptables-services»]
}
# Описываем программу, которая будет выполняться
# на машине для поднятия правил fierwall
exec { ‘firewall’:
# «Подписываемся» на файл
subscribe => File[«/etc/sysconfig/iptables»],
# Устанавливаем правила фаервола из файла.
command => «/usr/bin/cat /etc/sysconfig/iptables | /usr/sbin/iptables-restore «,
# Говорим, что программа будет выполняться
# только если файл, на который мы подписаны,
# изменился.
refreshonly => true
}
}
Вносим изменения в node.
node ‘centos7-2.test.local’ {
include ‘baselinux’
include ‘minimal-iptables’
include ‘dns’
}
Проверяем файл манифеста.
# puppet parser validate /etc/puppet/manifests/site.pp
У данного способа есть недостаток — при исполнении скрипта будут рваться сессии. Это можно обойти, используя вместо файла /etc/sysconfig/iptables самописанный скрипт.
Я долго думал, использовать ли для управления DNS сервером скрипты из PuppetForge (https://forge.puppetlabs.com/)? Или держать на puppet сервере файлы конфигурации bind и рулить удаленным сервером изменяя эти файлы.
Победил второй путь. Я прекрасно умею управлять DNS сервером при помощи его конфигурационых файлов и файлов зон. Учить дополнительную обертку, написанную сторонними компаниями, на неизвестном мне ruby… Зачем так усложнять?
Поэтому, буду использовать конфигурационные файлы и тупо копировать их на машину с DNS сервером.
Создадим директорию /var/puppet.
# mkdir /var/puppet
В которой будут директории, содержащие конфигурационные файлы для отдельных машин.
# mkdir /var/puppet/centos7-2.test.local
# cd /var/puppet/centos7-2.test.local
# mkdir etc
# mkdir -p var/named/slaves
В новой директории etc разместим файл named.conf. Возьмем стандартный файл и внесем в него некоторые изменения. Не буду приводить тут весь файл, только измененные и добавленные строки.
listen-on port 53 { any; };
listen-on-v6 port 53 { none; };
allow-query { any; };
dnssec-enable no;
dnssec-validation no;
zone «test.local» IN {
type master;
file «test.local»;
allow-update { none; };
allow-query { any; };
allow-transfer { none; };
};
zone «200.168.192.in-addr.arpa» IN {
type master;
file «200.168.192»;
allow-update { none; };
allow-query { any; };
allow-transfer { none; };
};
В директории var/named создадим два файла описания зон
# cat var/named/test.local
$TTL 86400 ; 1 day
test.local. IN SOA post.test.local. artur.test.local. (
2015091701 ; serial
10800 ; refresh (3 hours)
3600 ; retry (1 hour)
604800 ; expire (1 week)
86400 ; minimum (1 day)
)
NS centos7-2.test.local.
MX 10 post.test.local.
TXT «v=spf1 mx -all»
SPF «v=spf1 mx -all»
artur-office A 192.168.200.1
post A 192.168.200.97
centos7-2 A 192.168.200.98
centos7-1 A 192.168.200.99
# cat var/named/200.168.192
$TTL 86400 ; 1 day
200.168.192.in-addr.arpa. IN SOA post.test.local. artur.test.local. (
2015091701 ; serial
10800 ; refresh (3 hours)
3600 ; retry (1 hour)
604800 ; expire (1 week)
86400 ; minimum (1 day)
)
NS centos7-2.test.local.
99 IN PTR centos7-1.test.local.
98 IN PTR centos7-2.test.local.
97 IN PTR post.test.local.
1 IN PTR artur-office.test.local.
Проверкой синтаксиса мы должны заниматься сами. Поэтому:
# named-checkconf etc/named.conf
# named-checkzone test.local var/named/test.local
zone test.local/IN: loaded serial 2015091701
OK
# named-checkzone 200.168.192.in-addr.arpa var/named/200.168.192
zone 200.168.192.in-addr.arpa/IN: loaded serial 2015091701
OK
Теперь необходимо что бы файловый сервер puppet узнал про нашу директорию с файлами.
# vim /etc/puppet/fileserver.conf
[configs]
path /var/puppet
allow *
Перезапустим сервер:
# systemctl restart puppetmaster
Внесем изменения в файл манифест site.pp. Сначала добавим новый класс.
class dns {
# для работы необходим пакет bind
package { ‘bind’:
ensure => installed
}
include ‘stdlib’
# Отключим ipv6 у bind.
# Для этого надо при запуске демона передать ему
# параметр -4. Добавим соответствующую строку в
# конфигурационный файл.
file_line { ‘named_no_ipv6’:
path => ‘/etc/sysconfig/named’,
line => ‘OPTIONS=»-4″‘
}
# Конфигурационный файл демона
file { «/etc/named.conf» :
ensure => file,
mode => ‘0640’,
# Путь к файлу на файловом сервере
# Я специально присвоил директории имя такое
# же как и имя машины.
# Теперь можно пользоваться переменной $fqdn
# И если у нас появится другой DNS сервер,
# то благодаря этой переменной
# мы спокойно разрулим кому какие конфиги
# отдавать.
source => «puppet:///configs/$fqdn/etc/named.conf»,
require => Package[«bind»],
# После изменения файла сделаем reload
# серверу bind
notify => Service[«named»]
}
file { «/var/named» :
path => «/var/named»,
mode => ‘0640’,
group => ‘named’,
source => «puppet:///configs/$fqdn/var/named»,
# Тут у нас передается содержимое директории
ensure => directory,
# Говорим, что бы передавались все файлы и
# поддиректории.
# Вместо remote можно использовать true.
# Тогда в целевой директории будут удаляться
# все файлы, которые отсутствуют в директории
# шаблоне.
# Поскольку делал по быстрому, пока оставлю
# так. Но в дальнейшем надо будет привести
# все в порядок.
recurse => remote,
sourceselect => all,
require => Package[«bind»],
notify => Service[«named»]
}
service { ‘named’:
enable => true,
ensure => running,
require => Package[«bind»]
}
}
Ну и изменим соответствующую ноду.
node ‘centos7-2.test.local’ {
include ‘baselinux’
include ‘dns’
}
Пока остановимся. Останется только разрулить правила фаервола.
Поэтому, для ntpdate.service можно оставить простейший файл /etc/ntp.conf следующего содержания:
server 0.centos.pool.ntp.org
server 1.centos.pool.ntp.org
server 2.centos.pool.ntp.org
server 3.centos.pool.ntp.org
Итого, нам надо удалить пакет ntp и добавить свой конфигурационный файл /etc/ntp.conf
Удалить пакет можно следующим образом:
package { ‘ntp’:
ensure => absent
}
Будет удален пакет, его конфигурационные файлы останутся на месте. Нам не надо удалять конфиги. Мы просто поменяем их содержимое.
Дальше надо будет добавить свой конфигурационный файл, убедившись, что пакет ntp не установлен, а ntpdate наоборот установлен.
Изменим класс ntpdate в файле манифеста следующим образом:
class ntpdate {
package { ‘ntpdate’:
ensure => installed
}
package { ‘ntp’:
ensure => absent,
# Пакет, если он есть, надо удалить до того как
# будет создан файл /etc/ntp.conf
before => File[‘/etc/ntp.conf’]
}
# Определяем конфигурационный файл
file { ‘/etc/ntp.conf’:
ensure => file,
owner => ‘root’,
group => ‘root’,
mode => ‘0644’,
# Для создания файла необходимо наличие
# установленного пакета ntpdate
require => Package[«ntpdate»],
# Содержимое файла указываем прямо тут
content => «server 0.centos.pool.ntp.org
server 1.centos.pool.ntp.org
server 2.centos.pool.ntp.org
server 3.centos.pool.ntp.org
«
}
service { ‘ntpdate’:
enable => true,
ensure => running,
require => Package[«ntpdate»],
}
}
Проверим конфиг на ошибки:
# puppet parser validate /etc/puppet/manifests/site.pp
В результате на клиенте:
Если в дальнейшем необходимо изменить конфигурационный файл, меняем его содержимое в файле манифеста.
Если конфигурационные файлы большие, включаем файловый сервер puppet или ftp сервер или … Размещаем конфиги там. Но об этом в другой раз.
Пока создал две виртуалки:
При установке клиента и сервера была сразу настроена сеть. DNS сервер пока не поднимался, поэтому в файле /etc/hosts на обеих машинах добавлены строки:
192.168.200.99 centos7-1.test.local centos7-1
192.168.200.98 centos7-2.test.local centos7-2
Маршрут по умолчанию на сервере, через хост машину. Маршрут по умолчанию на клиенте, через сервер.
Fierwall на сервере настроен. Удален fierwalld, настроен маскарадинг и доступ по ssh. На клиенте все по умолчанию.
При установке клиента выбрана минимальная конфигурация сервера.
Puppet будем конфигурить исходя из того, что у нас везде CentOS 7. Т.е. пока не будем заморачиваться с многоплатформенностью.
Установка puppet на сервер.
# rpm -ivh http://yum.puppetlabs.com/puppetlabs-release-el-7.noarch.rpm
# yum install puppet-server
Поскольку лениво руками возиться c сертификатами, включим автоматическое подписывание сертификатов. В реальной жизни так делать низзя.
# vim /etc/puppet/puppet.conf
[main]
…
autosign = true
Создадим манифест файл заглушку. По мере понимания системы, будем его расширять.
# vim /etc/puppet/manifests/site.pp
package {
‘mc’:
ensure => installed;
}
Собственно тут говориться, что надо поставить пакет mc, если его еще нет.
Запускаем сервер:
# systemctl start puppetmaster.service
# systemctl enable puppetmaster.service
# systemctl status puppetmaster
Проверяем наличие открытого порта 8140 в fierwall:
# iptables -L INPUT -n —line-numbers
Если порт не открыт, добавляем:
# iptables -I INPUT 5 -p tcp -m state —state NEW -m tcp —dport 8140 -j ACCEPT
# service iptables save
Установка puppet клиента на centos7-2.
# rpm -ivh http://yum.puppetlabs.com/puppetlabs-release-el-7.noarch.rpm
# yum install puppet
Указываем сервер, куда буем ходить:
# vim /etc/puppet/puppet.conf
[agent]
server=centos7-1.test.local
certname=centos7-2-cl.test.local
Подключаемся агентом, заодно генерируя и подписывая сертификаты:
# puppet agent —test
Если ошибок не показало, запускаем сервис:
# systemctl start puppet.service
# systemctl enable puppet.service
# systemctl status puppet
Кстати, пакет mc уже установился, программой можно пользоваться.
Переходим на сервер.
На всякий пожарный ставим средство для работы с конфигами. Чувствую, что оно нам пригодится.
# yum install augeas
Ставим библиотеку, необходимую для работы со строками.
# puppet module install puppetlabs-stdlib
Создадим манифест файл puppet, в котором опишем пакеты и параметры, которые будут использованы на всех серверах.
Мне понадобятся: ssh, ntp, mc, vim (мой любимый редактор), net-tools (ip ставиться по умолчанию, но я привык к стандартному ifconfig и route), traceroute, tzdata (с обязательным обновлением до последней версии, а вдруг, не дай бог, опять дадут порулить «Повелителю Времени»?).
Так же я люблю кастомную строку приглашения.
Итого файл будет выглядеть следующим образом:
# vim /etc/puppet/manifests/site.pp
class sshd {
# долен быть установлен пакет
package { ‘openssh-server’:
ensure => latest
}
# сервис должен быть запущен
service { ‘sshd’:
name => «sshd»,
enable => true,
ensure => running
}
}
# Сервер ntpd поднимать не будем, ограничимся ntpdate, благо в
# CentOS 7 проверку можно запускать как сервис.
# для ее работы потребуется конфигурационный файл /etc/ntpd.conf
# который находится в пакете ntp
class ntpdate {
# ставим пакет ntp. Ntpdate будет поставлен по зависимости.
package { ‘ntp’:
ensure => installed
}
# запускаем соотвествующий сервис.
service { ‘ntpdate’:
enable => true,
ensure => running
}
}
# создаем базовый класс, для всех машин
class baselinux {
package { ‘mc’: ensure => installed }
package { ‘vim-enhanced’: ensure => installed }
package { ‘net-tools’: ensure => installed }
package { ‘traceroute’: ensure => installed }
package { ‘tzdata’: ensure => latest }
include ‘sshd’
include ‘ntpdate’
# необходимо для работы file_line
include ‘stdlib’
# Добавляем переменную PS1 в конец /etc/bashrc, если ее в этом файле еще нет.
# Точнее говоря, PS1 там уже есть, мы контролируем наличие именно такой строки
# и если ее нет, то добавляем в конец файла.
file_line { ‘ps1_rule’:
path => ‘/etc/bashrc’,
# line пишем одной строкой
line => ‘PS1='[e[44;36m]t:[w][e[0;0m]n[e[0;31;04m]u[e[0;0m]@[e[0;32m]h[e[0;0m] $ »
}
}
# node по умолчанию, используется в том случае, если нет явного
# нода для конкретной машины.
node default {
include ‘baselinux’
}
# node для клиента.
node ‘centos7-2.test.local’ {
include ‘baselinux’
}
Node для клиента пока идентичен ноду по умолчанию. Но я буду его потихоньку добавлять.
Если лениво ждать пока на клиенте включатся наши изменения, на нем можно запустить:
# puppet agent —test
На клиенте будут установлены все необходимые пакеты и запустятся (если ещё не были запущены) указанные нами сервисы.
Пока как то так.