WebHosting lab w oparciu o Proxmox

Z biegiem postępu prac poniższy wpis będzie aktualizowany.
Lab w oparciu o pomysł, który opisałem we wpisie: Pomysły projektów dla Młodszego Administratora Linux (Junior Linux System Administrator)


Na niewykorzystywanej jednostce centralnej zainstalowałem Proxmox’a (który zresztą tu był poprzednio, ale chciałem czystą instalację). Aby zarządzanie serwerem było dostępne z dowolnego miejsca podpiąłem go pod jFroga. Dlaczego nie CloudFlare albo inne tego typu rozwiązania? Między innymi ze względów bezpieczeństwa – serwer dostępny jest jedynie po ustanowieniu tunelu przez froga. Tutaj też małe wtrącenie, jFrog w pakiecie podstawowym obsługuje 3 urządzenia. Warto było zajrzeć do powiadomień, aby dowiedzieć się, że brak zainstalowanego przed chwilą serwera nie oznacza błędu podczas instalacji/konfiguracji, ale po prostu limit urządzeń na koncie 😀
Dodatkowo w BIOSie ustawiłem opcję, aby PC sam się włączał po powrocie zasilania (kończę pracę i wyłączam, później przycisk na zasilaczu wędruje na 0, następnie wystarczy jedynie przełączyć zasilacz na 1 i sam się uruchamia – spróbujcie komuś przetłumaczyć jak się odpala PC na krótko 😀 Obecnie nie ma przedniego panelu w obudowie, więc są podłączone gołe kable, które po zwarciu załączają).

Roboczy schemat laba v1:

Po skonfigurowaniu powyższego przyszedł czas na utworzenie VM. Plan był prosty: przygotować Debian i RockyLinux jako szablony. No i problem – KernelPanic podczas próby uruchomienia RockyLinux. Po diagnostyce okazało się, że problemem jest CPU. Konieczne było zainstalowanie Rockiego w wersji 8.
Do tej pory na VirtualBoxie używam Ubuntu, no bo przygotowywałem dla techników, został, niech już będzie. Tutaj w rozpędzie też otworzyłem stronę Ubuntu Server, ale zapaliła się lampka w głowie 😀 Szybki ruch myszką w kierunku wyszukiwarki -> „debian download” 😀

Co zawiera szablon? Zaktualizowany na dzień dzisiejszy system + utworzone odpowiednie konta + odpowiednio skonfigurowane SSH + zainstalowany ZSH (którego jestem fanem 😉 )

Gdy szablony były gotowe utworzyłem VM z pfSensem, który będzie pełnił rolę bramy domyślnej dla całej podsieci labowej. Dodatkowo utworzyłem nową sieć Linux Bridge (192.168.100.0/24), która będzie wewnętrzną, do której będą wpięte wszystkie wirtualki i interfejs LAN pfSensa. Konfiguracja peefa ograniczyła się do przypisania statycznych adresów IP na interfejsach 🙂

Projekt rozpocząłem od instalacji serwerów bazodanowych. Dlaczego akurat od nich? Chciałem przećwiczyć replikację, którą miałem z tyłu głowy. Wiedziałem, że istnieje, ale nie labowałem jeszcze jej do tej pory. Klonowanie obu templatek (Rocky jako master, Debian jako slave). Instalacja mariadb, a następnie mysql_secure_installation. Gdy miałem już działające serwery przystąpiłem do konfiguracji replikacji. Wykorzystałem do tego dokumentację na mariadb.com.
Swoją drogą coraz bardziej zaczynam przekonywać się do manuali dostawcy / producenta w miejsce przypadkowych tutoriali znalezionych w necie. Tak, tak, wiem. Ale na początku przygody z administracją dużo lepiej czyta się proste tutoriale, a nie skomplikowane, techniczne dokumentacje. Niech pierwszy rzuci kamieniem ten, który zamiast klepnąć problem w Goole czyta manuale 😀.
Dodatkowo konieczne było odblokowanie portu na firewallu w przypadku Rockiego. Po konfiguracji całości szybki test na masterze: utworzenie bazy, utworzenie użytkownika, nadanie uprawnień użytkownikowi do nowej bazy. Sprawdzenie na slave – jest, czyli działa. Sprzątanie (bo po co mi jakieś dane testowe, bezpieczeństwo przede wszystkim ;)) w odwrotnej kolejności – drop user i database na slave. Zgadza się – czyściutko 😀

Następnym krokiem była instalacja serwera NFS. Akurat jego przerabialiśmy na studiach, w związku z tym z grubsza ogarniam ten temat. Do VM dodałem dwa dyski, które spiąłem RAID’em 1 (mirroring). Zależy mi na bezpieczeństwie danych, dlatego akurat taki wybór. Po podmontowaniu go do systemu, udostępniłem mountpoint dla trzech hostów: serwer FTP oraz dwa nginxy.
Gdy wszystko było skonfigurowane utworzyłem VM z przeznaczeniem na serwer FTP. Podmontowałem jedynie utworzony udział, w celu przetestowania NFSa. Wszystko działa, więc ten serwer na chwile zostaje „zawieszony”.

Następnym etapem będą serwery NGINX. Akurat jak je ugryźć sprawia mi najwięcej „problemów”. W przypadku serwerów bazodanowych stwierdziłem, że master podpinam pod WWW, slave jest jako zapasowy. Mógłbym dodać jakieś proxy, ale bez różnicy czy padnie proxy czy padnie master – efekt taki sam, a tylko 1 punkt, który może położyć całe DB. Może ugram tym samym trochę na wydajności 🙂 Wracając do nginx, chciałbym aby oba były bliźniacze, tj. serwowały takie same strony (WordPressy). Kwestia DB załatwiona, pliki w sumie też na jednym serwerze NFS. Awaryjność załatwi HAProxy. Zastanawiałem się, aby postawić je na Dockerze, ale na razie chcę spróbować na pełnych systemach. W związku z tym przystępuje do testów: instaluje na obu nginx, montuje udziały do domyślnych DocumentRoot’ow na serwerach przez nfs. Na Debianie ruszyło od strzała, na Rockim był pewien problem – błąd 403. SELinux się aktywował 😉 Następnie przepiąłem Rockiego również na katalog /var/www/html, gdyż będzie jeden plik z vhostami serwowany na oba serwery.

Na pfSense dodałem przekierowania portów umożliwiając dostęp do serwerów przez SSH z zewnątrz. Celem był dostęp z sieci domowej do wszystkich serwerów wewnątrz sieci Proxmoxowej. Porty dodawałem wg schematu 2000+adres_IP_serwera -> 22.

Gdy powyższe miałem gotowe przystąpiłem do instalacji PHP-FPM na WEB serwerach. Wykorzystałem wersję 7.4 oraz 8.1. Na Debianie udało się od strzała. Na Rockim pojawiło się trochę schodów, ale po dodaniu remi-php-repo udało się zainstalować (za drugim podejściem). Pierwsze zakończyło się przywróceniem snapshota, w drugim trzeba było się trochę pobawić konfiguracją obu php-fpm, aby lokalizacje socketów były takie same na obu systemach (co w domyślnej konfiguracji jest rozbieżne) + zmiana właściciela tych socketów na nginx. Finalnie wyrzeźbiłem jeszcze skrypt bashowy, który tworzy odpowiedni katalog, restartuje usługi fpm (aby utworzyły sockety w tym katalogu) oraz zmienia właściciela socketów. Z jego wykorzystaniem utworzyłem usługę, która startuje wraz ze startem systemu.

Dodatkowo utworzyłem dwa pliki konfiguracyjne dla wirtualnych hostów na udziale vhost na serwerze NFS i podmontowałem go odpowiednio do katalogu conf.d (Rocki) oraz sites-enabled (Debian).

Ten udział został udostępniony w trybie RO, ponieważ serwer nie musi nic zapisywać w tych plikach konfiguracyjnych. Wykorzystałem domeny:
– wojst.pl.lcl (php7.4)
– druga.strona.com (php8.1)

Na pierwszej będzie odtworzona moja strona firmowa wojst.pl z ostatniej kopii zapasowej, druga natomiast będzie zawierała testowego WordPressa. Na udziale WWW utworzyłem dwa podkatalogi dla poszczególnych stron i wrzuciłem do nich index.html wyświetlający domenę – posłużył do przetestowania czy na obu serwerach działają oba vhosty.

Czas powrócić do serwera FTP. Zainstalowałem proftpd, wyłączyłem dostęp dla anonymous. Dodałem użytkowników lokalnych (jako homedir katalog z udziału podmontowanego z NFSa, shell false). Skonfigurowałem, aby serwer działał tylko jako SFTP. Zmodyfikowałem konfigurację, aby wpuszczała jedynie userów z grupy ftp_users (do której dodałem obu użytkowników). Pierwotnie pojawił się problem, ponieważ nie miałem modułów odpowiedzialnych za sftp. Jak się okazało zainstalowała się wersja proftpd-core, która ich nie posiada. Konieczne było zainstalowanie wersji basic tego pakietu.

Podczas uploadu plików okazało się, że pliki jako właściciela mają user:grupa z serwera FTP. Spowodowało to problemy na serwerach WWW (user i gid ustawione na 1002). Konieczna była rekonfiguracja serwera FTP, aby ustawiał właściciela jako nginx. Niestety SetOwner, UserOwner itp. nie chciało działać. Wykonywanie skryptu podczas uploadu też niekoniecznie, ponieważ DocumentRoot miałem ustawiony na ~. ChatGPT (po dłuższym czasie, bo też musiałem się z nim trochę pokopać „Przepraszam, wprowadziłem Cię w błąd„) podpowiedział, aby stworzyć skrypt Pythonowy, który nasłuchuje w danych katalogach i jak coś do niego wpadnie wówczas robi chowna. Odpaliłem ten skrypt jako usługę. Działa.

Proxmox na ten moment wygląda następująco:

Serwery bazodanowe chwilowo wyłączone, ponieważ jednak spróbuję wdrożyć ProxySQL.
Odpalone maszyny na ten moment są skończone (skonfigurowane). GUI-Access jest to Debian z zainstalowanym LXDE, który wykorzystuje do testów (poprawność działania vhostów nginx), wrzucenie plików na FTP przez filezille itd itp.

W kolejnym etapie przyszedł czas na ProxySQL. Na podstawie oficjalnej dokumentacji (i kilku tutoriali z YT) zainstalowałem go na VM pod kontrolą Debiana. Konfigurację rozszerzyłem o zmianę domyślnego hasła admina. Replikację MariaDB miałem już włączoną wcześniej. Serwer master jest w grupie „WRITE„, natomiast slave w grupie „READ„. Zapytania SELECT wędrują na serwer master, natomiast pozostałe na serwer slave.

Gdy to miałem gotowe przez FTP wrzuciłem pliki kopii zapasowej strony wojst.pl, a na serwerze master utworzyłem odpowiedniego użytkownika i z wykorzystaniem mysqldump zaimportowałem backup bazy danych. Zmodyfikowałem również plik wp-config.php podając jako serwer baz danych adres IP ProxySQLa. Pierwsza próba uzyskania dostępu do strony zakończona błędem:

Zainstalowałem php7.4-mysql (php74-php-mysqlnd) oraz php8.1-mysql (php81-php-mysqlnd) ona obu web serwerach. Po drobnych modyfikacjach plików konfiguracyjnych WP strona ruszyła 🙂

 

Do tego momentu musiałem przełączać wpisy w /etc/hosts jeżeli chodzi o adresy IP dla stron testowych. Przyszedł czas na wdrożenie HAProxy. Pierwotnie myślałem o jednej maszynie, jednak w trakcie czytania na ten temat rzuciła mi się w oczy opcja keepalived. Jest ona odpowiedzialna za przełączanie load balancerów. Eliminujemy tym samym jeden punkt błędu, tj. jeżeli padnie loadbalancer nie położy nam to całej infrastruktury.

Utworzyłem dwie maszyny, klasycznie jedna na Debianie druga na Rockim. Zainstalowałem HAProxy oraz Keepalived. No i? Nie działa… Czas na troubleshooting. Wyłączyłem keepa, zabawa z logami itd itp. Jak się okazało zrobiłem czeski błąd w konfiguracji HAProxy – wpisałem adresy IP maszyn z HA zamiast z nginxem. Po podmianie i uruchomieniu obu usług wszystko działa. Ładuje przemiennie strony z serwera nginx-1 i nginx-2.

Proxmox w tym momencie prezentuje się następująco:

W celu świadczenia usług na najwyższym poziomie stosujemy pliki cookies, które będą zamieszczane w Państwa urządzeniu (komputerze, laptopie, smartfonie). W każdym momencie mogą Państwo dokonać zmiany ustawień Państwa przeglądarki internetowej i wyłączyć opcję zapisu plików cookies. View more
Zaakceptuj