Puppet – dodajemy moduły firewall i httpd (część 2)

Puppet – konfiguracjaDziś rozwiniemy nieco naszą konfigurację i dodamy dwa nowe moduły: httpd oraz firewall. Pierwszy z nich zainstaluje w razie potrzeby pakiet httpd, stworzy podstawowe pliki, takie jak domyślny vhost oraz index.html. Drugi moduł firewall zainstaluje pakiet iptables, przekopiuje domyślną konfigurację oraz uruchomi go na maszynie puppet-slave01.

Dla przypomnienia nasze środowisko składa się z dwóch maszyn wirtualnych, jedna z nich pełni rolę puppet master’a druga to klient (zobacz wpis: Puppet – instalacja i konfiguracja część 1):

Nazwa hosta (fqdn) Adres IP Rola
puppet-master.local.net 192.168.34.20 Serwer
puppet-slave01.local.net 192.168.34.21 Klient

Puppet – konfiguracja modułu firewall

W /etc/puppet/modules dodajemy katalog firewall, a w nim tworzymy następującą strukturę:

[root@puppet-master firewall]# tree
.
├── files
│   └── iptables-centos
└── manifests
    └── init.pp

Plik init.pp już znamy, nowością tutaj jest katalog files. W nim zapisaliśmy podstawową konfigurację iptables. Są to tak naprawdę domyślne ustawienia firewall’a w systemie CentOS, dodaliśmy tylko jedną regułę, w której otwieramy port 80:

[root@puppet-master firewall]# cat files/iptables-centos
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

W pliku init.pp wyróżnić możemy 3 główne warunki:

  • upewnij się, że pakiet iptables jest zainstalowany
  • upewnij się, że usługa iptables działa
  • stwórz plik /etc/sysconfig/iptables na podstawie iptables-centos oraz nadaj mu odpowiednie uprawnienia

Zobaczmy jak to wygląda:

class firewall {
        package { iptables:
                ensure => present,
        }
        service { "iptables":
                ensure => running,
                enable => true,
                require => Package["iptables"],
        }

        file { "/etc/sysconfig/iptables":
                ensure => present,
                owner => root,
                group => root,
                mode => 600,
                source => "puppet://$puppetmaster/modules/firewall/iptables-centos",
                require => Package["iptables"],
                notify => Service["iptables"],
        }
}

Warto wspomnieć tutaj o opcji require => Package[„iptables”] w sekcji service i file. Zanim puppet wprowadzi niezbędne zmiany upewni się, że pakiet iptables jest zainstalowany w systemie. Druga istotna opcja to notify => Service[„iptables”]. Po każdej zmianie w iptables-centos (np. dodanie nowych reguł), puppet agent automatycznie przeładuje (zrestartuje) proces iptables.
Dodajemy moduł firewall do pliku nodes.pp po czym przetestujemy wszystko na puppet-slave01:

[root@puppet-master manifests]# cat /etc/puppet/manifests/nodes.pp
node default {
}

node 'puppet-slave01.local.net' {
        include firewall
        include motd
}

Zatrzymamy proces iptables oraz usuniemy jego konfigurację:

[root@puppet-slave01 ~]# /etc/init.d/iptables stop
[root@puppet-slave01 ~]# rm /etc/sysconfig/iptables -f

 

[root@puppet-slave01 ~]# puppet agent --test
Info: Applying configuration version '1414407669'
Notice: /Stage[main]/Firewall/File[/etc/sysconfig/iptables]/ensure: defined content as '{md5}ab92cd505bc1005480fc7b62cd3e5996'
Info: /Stage[main]/Firewall/File[/etc/sysconfig/iptables]: Scheduling refresh of Service[iptables]
Notice: /Stage[main]/Firewall/Service[iptables]/ensure: ensure changed 'stopped' to 'running'
Info: /Stage[main]/Firewall/Service[iptables]: Unscheduling refresh on Service[iptables]

Puppet od razu wprowadził niezbędne zmiany:

[root@puppet-slave01 ~]# ls -l /etc/sysconfig/iptables
-rw------- 1 root root 542 27. Okt 12:00 /etc/sysconfig/iptables
[root@puppet-slave01 ~]# iptables -L INPUT -nv
[root@puppet-slave01 ~]# iptables -L INPUT -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:22
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:80
REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited

Przetestujmy też z ciekawości opcję notify. Dodamy nową regułę, która zezwoli na połączenia na porcie 443:

[root@puppet-master files]# cat iptables-centos
...
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
...

Test:

[root@puppet-slave01 ~]# puppet agent --test
...
Info: Applying configuration version '1414407669'
Notice: /Stage[main]/Firewall/File[/etc/sysconfig/iptables]/content:
--- /etc/sysconfig/iptables     2014-10-27 12:00:46.280543614 +0100
+++ /tmp/puppet-file20141027-25603-eolzn1-0     2014-10-27 12:04:21.811543376 +0100
@@ -9,6 +9,7 @@
 -A INPUT -i lo -j ACCEPT
 -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
 -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
+-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
 -A INPUT -j REJECT --reject-with icmp-host-prohibited
 -A FORWARD -j REJECT --reject-with icmp-host-prohibited
 COMMIT

Info: Computing checksum on file /etc/sysconfig/iptables
Info: /Stage[main]/Firewall/File[/etc/sysconfig/iptables]: Filebucketed /etc/sysconfig/iptables to puppet with sum ab92cd505bc1005480fc7b62cd3e5996
Notice: /Stage[main]/Firewall/File[/etc/sysconfig/iptables]/content: content changed '{md5}ab92cd505bc1005480fc7b62cd3e5996' to '{md5}8aadda5bfc7398bbc0912b2e6130e1b0'
Info: /Stage[main]/Firewall/File[/etc/sysconfig/iptables]: Scheduling refresh of Service[iptables]
Notice: /Stage[main]/Firewall/Service[iptables]: Triggered 'refresh' from 1 events

Zawartość pliku się zmieniła, sprawdźmy czy reguła jest też w użyciu:

[root@puppet-slave01 ~]# iptables -L -n | grep -E "80|443"
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:80
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:443

Świetnie, zarówno port 80 jak i nowo dodany 443 są otwarte. Nasz firewall działa jak należy, możemy przejść do konfiguracji Apache.

Puppet – konfiguracja modułu httpd

Zaczynamy jak poprzednio od utworzenia katalogu httpd wraz z poniższą strukturą:

[root@puppet-master httpd]# tree
.
├── manifests
│   └── init.pp
└── templates
    ├── default-vhost.erb
    └── index.html.erb

Tutaj skorzystamy z dwóch template’ów, w jednym wygenerujemy konfigurację dla domyślnego vhost’a, w drugim prosty plik index.html.

[root@puppet-master httpd]# cat templates/default-vhost.erb
<VirtualHost *:80>
        ServerAdmin     admin@local.net
        DocumentRoot    /var/www/html/
        ServerName      <%= fqdn %>
        ErrorLog        /var/log/httpd/<%= fqdn %>.error_log
</VirtualHost>
[root@puppet-master httpd]# cat templates/index.html.erb
<html>
        <body>
                Default index.html site from <%= fqdn %>
        </body>
</html>

Korzystamy tu z parametru/faktu (fact) fqdn, który dla naszego klienta ma wartość puppet-slave01.local.net. Oznacza to, że po wpisaniu w przeglądarce podanego adresu zobaczymy prostą stronę www z nazwą hosta na którym uruchomiony jest apache. W pliku init.pp definiujemy klasę httpd wraz z niezbędnymi opcjami:

[root@puppet-master manifests]# cat init.pp
class httpd {
        package { httpd:
                ensure => present,
        }
        service { "httpd":
                ensure => running,
                enable => true,
                require => Package["httpd"],
        }

        file { "/etc/httpd/conf.d/00-default-vhost.conf":
                ensure => present,
                owner => root,
                group => root,
                mode => 444,
                content => template("httpd/default-vhost.erb"),
                require => Package["httpd"],
                notify => Service["httpd"],
        }
        file { "/var/www/html/index.html":
                ensure => present,
                owner => apache,
                group => apache,
                mode => 444,
                content => template("httpd/index.html.erb"),
                require => Package["httpd"],
        }
}

Chcemy aby puppet zainstalował pakiet httpd, upewnił się że proces działa w systemie oraz utworzył dwa pliki (dla vhost’a oraz index.html). Ponownie skorzystaliśmy z opcji notify, przez co po edycji pliku default-vhost.erb, puppet agent automatycznie przeładuje proces httpd. Ostatnia zmiana to dodanie naszego nowego modułu do puppet-slave01:

[root@puppet-master manifests]# cat nodes.pp
node default {
}

node 'puppet-slave01.local.net' {
        include firewall
        include httpd
        include motd
}

Logujemy się teraz na na drugą maszynę i sprawdzamy czy wszystko działa:

[root@puppet-slave01 ~]# puppet agent --test
Notice: /Stage[main]/Httpd/Package[httpd]/ensure: created
Notice: /Stage[main]/Httpd/File[/var/www/html/index.html]/ensure: created
Notice: /Stage[main]/Httpd/File[/etc/httpd/conf.d/00-default-vhost.conf]/ensure: created
Info: /Stage[main]/Httpd/File[/etc/httpd/conf.d/00-default-vhost.conf]: Scheduling refresh of Service[httpd]
Notice: /Stage[main]/Httpd/Service[httpd]/ensure: ensure changed 'stopped' to 'running'
Info: /Stage[main]/Httpd/Service[httpd]: Unscheduling refresh on Service[httpd]
[root@puppet-slave01 ~]# rpm -qa | grep httpd
httpd-tools-2.2.15-31.el6.centos.x86_64
httpd-2.2.15-31.el6.centos.x86_64
[root@puppet-slave01 ~]# /etc/init.d/httpd status
httpd (pid  32288) is running...

Apache’a działa, na koniec możemy dla pewności sprawdzić połączenie w przeglądarce:

puppet - konfiguracja modułu httpd

Jak widzimy puppet to narzędzie o szerokich możliwościach, szczególnie przydatne jeżeli musimy zarządzać wieloma serwerami, a zależy nam żeby nasze środowisko było spójne. Powyższa konfiguracja pokazuje prosty sposób jak skonfigurować serwer www. Można ją oczywiście łatwo rozwinąć o dodatkowe pakiety, pliki (takie jak php lub baza danych), usługi, etc. Tutaj nasuwa nam się pytanie: co jeśli korzystamy z różnych systemów operacyjnych? W różnych dystrybucjach pakiety mogą mieć (lub mają) różne nazwy (np. httpd i apache2), pliki konfiguracyjne znajdują się w różnych miejscach, etc. Dla puppet’a to żaden problem. A jak sobie z tym poradzić, opiszemy na łamach naszego bloga już w następnej części.

Zostaw komentarz


Podpowiedź - możesz użyć tych HTML tagów i atrybutów:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Obraz CAPTCHY

*