[RH7] Konfiguracja i edycja reguł lokalnego firewalla - firewalld i firewall-cmd [PT.1 - zones & services]

Red Hat 7.x / CentOS 7.x
Wersja 7 systemu spod znaku czerwonego kapelusza w nowy sposób spogląda na obsługę komunikacji sieciowej naszego systemu. Usługą odpowiedzialną za ten kawałek został firewalld.
Moje pierwsze wrażenia? Konfiguracja i definiowanie reguł jest chyba bardziej czytelne, z pewnością bardziej intuicyjne, choć od osoby przyzwyczajonej do iptables wymaga poświęcenia kilku chwil na zaznajomienie się z nowym sposobem operowania w środowisku.

firewalld operuje na zdefiniowanych strefach sieciowych (zonach), które są rodzajem kontenerów reguł sieciowych. Strefa taka określa zasady jakie będą stosowane dla np. interfejsu sieciowego sklasyfikowanego w takiej strefie. Reguły aplikacji korzystających z sieci oparto na innych pseudo kontenerach - serwisach - które w formie plików xml definiują porty, czy też zakresy portów jakie mają pozostać otwarte na naszym serwerze. Ale po kolei...

Obsługa wszystkiego co związane jest z firewalld odbywa się przez jedno z dwóch narzędzi - w trybie graficznym może to być firewall-config, w trybie tekstowym będzie to firewall-cmd. W drugim przypadku, zwyczajowo wszystko mamy ładnie opisane w manualu oraz w helpie dla komendy - przy czym, jak zaobserwowałem, w helpie jest kilka przełączników, których w manualu nie ma...

Wspomniałem o zonach, i od nich wypada rozpocząć szerszy opis przygody z firewalld. Zony, to predefiniowane zestawy reguł, które są stosowane w naszym systemie bez konieczności definiowania czegokolwiek. (możemy zdefiniować własną zonę z naszym zestawem reguł, ale to chyba zabawa dla admina, który cokolwiek już o firewalld wie, więc pominę temat, przynajmniej na razie).
Predefiniowane zony możemy podejrzeć sobie wydając polecenie:

[root@server ~]# firewall-cmd --get-zones
block dmz drop external home internal public trusted work

Poszczególne zony traktują naszą sieć mniej więcej tak:

- block - wypuszczamy wszystkie pakiety, a wpuszczamy jedynie te, które są odpowiedzią na nasze zapytanie
- dmz - jak wskazuje nazwa - wpuszczamy tylko wybrane połączenie w sieci wewnętrznej - domyślnie ssh
- drop - identycznie jak block, z tym, że połączenia są faktycznie dropowane i nie wysyłamy na nie odpowiedzi o zablokowaniu połączenia
- external - nie ufamy nikomu na zewnątrz, więc wpuszczamy tylko zdefiniowany ruch (domyślnie jedynie ssh)
- home - raczej ufamy innym komputerom, więc domyślnie wpuszczamy ssh, sambę, mdns, ipp-client i dhcpv6
- internal - w zasadzie tak samo jak home - sieć wewnątrzna
- public - nie ufamy nikomu... no chyba, że przez ssh albo dhcpv6
- trusted - ufamy wszystkim i wpuszczamy wszystko - taki domyślny ACCEPT na początku tablicy iptables
- work - w zasadzie wierzymy w dobre zamiary innych userów sieci, ale na wszelki wypadek wpuszczamy tylko ssh, ipp i dhcpv6

To tak z grubsza - moim zdaniem za dużo tych definicji, ale jak to mówią od przybytku głowa nie boli, a może są jakieś głąbsze różnice, do których póki co nie dotarłem.
W tym miejscu wspomnę o pierwszej ścieżce systemowej, która jest przydatna w pracy z firewalld, a mianowicie /usr/lib/firewalld. W podkatalogu zones znajdują się pliki xml zawierające definicję i krótki opis każdej ze stref.
W pierwszej kolejności zweryfikujmy, czy nasz deamon działa:

[root@server ~]# firewall-cmd --state
running

Działa. Więc zajmijmy się konfiguracją.

Działania z zonami

Domyślnie nasze interfejsy przypisane są do strefy public - rezultat jest mniej więcej taki sam, jak w przypadku domyślnej konfiguracji iptables w wersjach wcześniejszych systemu.
Przypisanie to możemy sprawdzić poprzez:

[root@server ~]# firewall-cmd --get-active-zones
public
  interfaces: enp0s3

Polecenie pokazuje nam wszystkie aktywne w systemie strefy, oraz przypisane do nich interfejsy.

Wszystkie interfejsy naszej maszyny są dodawane do strefy domyślnej, której definicję sprawdzimy następująco:

[root@server ~]# firewall-cmd --get-default-zone
public

Na dowód takiego zachowania, dodałem w swojej maszynie dwa kolejne interfejsy sieciowe, a efektem jest:

[root@server ~]# firewall-cmd --get-active-zones
public
  interfaces: enp0s3 enp0s8 enp0s9

Strefę domyślną możemy zmienić w bardzo prosty sposób:

[root@server ~]# firewall-cmd --set-default-zone=dmz
success
[root@server ~]# firewall-cmd --get-default-zone
dmz

Każdy z naszych interfejsów możemy przypisać do innej strefy, i definiować dla niego specyficzne reguły, które nie będą działały dla interfejsu w innej strefie.
Przypisanie takie realizujemy poprzez usunięcie go z obecnej strefy i przypisanie do nowej:

[root@server ~]# firewall-cmd --zone=public --remove-interface=enp0s8
success
[root@server ~]# firewall-cmd --zone=dmz --add-interface=enp0s8
success
[root@server ~]# firewall-cmd --get-active-zones
dmz
  interfaces: enp0s8
public
  interfaces: enp0s3

Nie udało mi się jednak w ten sposób uzyskać permanentnego przypisania interfejsów do różnych zone, a restart serwera przywraca wszystko do strefy domyślnej.... może to taki "feature" [firewall-cmd v.0.3.9].
Sam Red Hat podaje jednak alternatywną - działającą - metodę stałego przypisania do zony. W pliku konfiguracyjnym interfejsu /etc/sysconfig/network-scripts/ifcfg-enp0s* należy umieścić parametr ZONE= wraz z nazwą zony.

Serwisy

Domyślne ustawienia stref rzadko kiedy będą zadowalające dla administratora, ze względu na ograniczoną ilość usług, które są sieciowo "przepuszczane". Kolejnym poziomem abstrakcji wprowadzonym przez firewalld, a ułatwiającym korzystanie z niego są serwisy.
Serwis jest definicją portu oraz protokołu sieciowego, który ma zostać przepuszczony przez firewall np. na potrzeby aplikacji. Jest to bardzo ciekawe, i przydatne podejście. Tym bardziej, że definiowanie własnych serwisów jest banalnie proste. Ale po kolei.

Weryfikacja w jaki sposób obsługujemy ruch sieciowy sprowadza się do wylistowania zawartości wszystkich aktywnych zon. Biorąc pod uwagę problem z permanentnym skonfigurowaniem kilku na raz, aktywną pozostaje tylko domyślna, dlatego wystarczy polecenie:

[root@server ~]# firewall-cmd --list-all
dmz (default, active)
  interfaces: enp0s3
  sources:
  services: ssh
  ports:
  masquerade: no
  forward-ports:
  icmp-blocks:
  rich rules:

Jeśli aktywnych byłoby kilka - do powyższej komendy należy dodać przełącznik --zone=nazwa_zone
Jak wynika z powyższego, w zonie dmz mamy skonfigurowany serwis ssh, co oznacza, że ruch na porcie 22 jest otwarty.  Szybka weryfikacja, i faktycznie serwer odpowiada po ssh.

Dodawanie serwisów w danej zonie odbywa się poprzez polecenie:

[root@server ~]# firewall-cmd --zone=dmz --add-service=ftp
success

Analogicznie sytuacja wygląda z usuwaniem serwisu z zony:

[root@server ~]# firewall-cmd --zone=dmz --remove-service=ssh
success

Po tych dwóch operacjach nasze reguły sieciowe przedstawiać się będą następująco:

[root@server ~]# firewall-cmd --list-all
dmz (default, active)
  interfaces: enp0s3
  sources:
  services: ftp
  ports:
  masquerade: no
  forward-ports:
  icmp-blocks:
  rich rules:

I kolejna szybka weryfikacja.... nie zalogujemy się już po ssh (nie sprawdzam portu 21, ponieważ nie mam na tej maszynie ftp-a).

Listę wszystkich predefiniowanych serwisów znajdziemy w formie plików xml w katalogu /usr/lib/firewalld/services, a konfigurację możemy sprawdzić poprzez podejrzenie ich zawartości. Nazwa pliku jest tożsama z nazwą serwisu.
P.S. Jeśli nie potrzebujemy oglądać całej konfiguracji zony, możemy również podejrzeć skonfigurowane serwisy korzystając z przełącznika --list-services, choć nie daje to pełnego obrazu konfiguracji (ale o tym w następnej części).

W tym miejscu należy wspomnieć o jednej, bardzo ważnej właściwości. Ten sposób konfigurowania serwisów nie jest permanentny, i nie przetrwa restartu maszyny.
Do rozwiązania tego problemu możemy użyć dwóch metod:
- używając przełącznika --permanent podczas dodawania lub kasowania serwisu, który każdą wprowadzoną z nim regułę zapisze na stałe w konfiguracji, lub
- zapisując konfigurację zawartą w pamięci, poprzez użycie polecenia firewall-cmd --runtime-to-permanent po wprowadzeniu wszystkich interesujących nas reguł.

Używanie opcji --permanent implikuje z kolei konieczność przeładowania reguł firewalld, ponieważ wprowadzana tak reguła jest zapisywana w konfiguracji, ale nie ładowana do działająego już serwisu. Po dodaniu reguł permanentnych będziemy musieli użyć polecenia firewall-cmd --reload. Używanie jednej z kombinacji jest dowolne, zależnie od preferencji admina.

Tworzenie własnych definicji serwisów


Przydatność serwisów możemy zauważyć, m.in. w przypadku konieczności zdefiniowania własnych reguł aplikacji, która instalowana jest na wielu serwerach (np. aplikacja monitorująca, serwer aplikacyjny itp.). Aplikacje takie niejednokrotnie wymagają otwarcia kilku portów, i na wszystkich maszynach konfiguracja ta jest identyczna, dlatego wygodnie będzie stworzyć własny plik definicji, i dodawać nasz serwis do stref na poszczególnych maszynach. Operacja polegać będzie na skopiowaniu jednego z instniejących plików definicji do katalogu /etc/firewalld/services/ (w nim są przetrzymywane wszystkie definicje serwisów tworzone przez użytkownika), nazwaniu go zgodnie z nazwą serwisu i jego edycji - całość jest bardzo intuicyjna, więc ten temat zakończę na przykładzie, bez zbędnych komentarzy...
Scenariusz przykładu obejmuje: Skonfigurujemy przykładowy plik reguł dla serwera jboss, którego aplikacje nasłuchują na portach (TCP) 80, 8080, 443, 8180, multicast klastra działa na porcie (UDP) 45688, a klaster komunikuje się po porcie (TCP) 7800.

[root@server ~]# cp /usr/lib/firewalld/services/http.xml /etc/firewalld/services/jboss.xml
[root@server ~]# vi /etc/firewalld/services/jboss.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>WWW (HTTP)</short>
  <description>HTTP is the protocol used to serve Web pages. If you plan to make your Web server publicly available, enable this option. This option is not required for viewing pages locally or developing Web pages.</description>
  <port protocol="tcp" port="80"/>
</service>

Zawartość zmieniamy na założoną konfigurację:

<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>Jboss</short>
  <description>Moja definicja Jboss-a</description>
  <port protocol="tcp" port="80"/>
  <port protocol="tcp" port="8080"/>
  <port protocol="tcp" port="443"/>
  <port protocol="tcp" port="8180"/>
  <port protocol="udp" port="45688"/>
  <port protocol="tcp" port="7800"/>
</service>

Pozostaje nam jeszcze załadować serwis do strefy, i gotowe:

[root@server ~]# firewall-cmd --permanent --add-service=jboss
success
[root@server ~]# firewall-cmd --reload
success
[root@server ~]# firewall-cmd --list-all
dmz (default, active)
  interfaces: enp0s3
  sources:
  services: jboss ssh
  ports:
  masquerade: no
  forward-ports:
  icmp-blocks:
  rich rules:

W następnej części zajmiemy się konfiguracją portów, masqueradingu i definicjami direct, bardziej zbliżonymi w swej formie do reguł iptables.

Konfiguracja i edycja reguł lokalnego firewalla [PT.2 - port rules, masquerading, direct rules, lockdown]

Brak komentarzy:

Prześlij komentarz