Dziś 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 podstawieiptables-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:
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.
0 Komentarze.