Wczoraj, podczas rutynowej aktualizacji serwerów trafiłem na problem – skrypt odpowiadający za aktualizację serwera pocztowego MailCow (konkretnie MailCow: dockerized) zatrzymywał się na etapie weryfikacji, czy działa połączenie z internetem. Oczywiście serwer takie połączenie miał, bo nie tylko działały prawidłowo na nim usługi, ale i ja łączyłem się z nim zdalnie, za pomocą SSH. Z racji tego, że zależało mi na aktualizacji, postanowiłem poszukać przyczyny…

MailCow: Checking internet connection… failed

Z MailCow (MailCow: dockerized) lubię korzystać, bo dzięki swojej konstrukcji jest to oprogramowanie łatwe w codziennym zarządzaniu, a zarazem nie muszę (przynajmniej zazwyczaj) przejmować się poszczególnymi elementami wchodzącymi skład serwera pocztowego. A nawet jeśli któraś usługa się wysypie, to można ją relatywnie łatwo przywrócić, bez potrzeby ponownej konfiguracji całego serwera (poszczególne usługi działają w kontenerach Dockera).

Jednym z elementów jest skrypt, który automatyzuje proces aktualizacji. Wystarczy skorzystać z polecenia:

cd /opt/mailcow-dockerized/
sudo /opt/mailcow-dockerized/update.sh

Dziś jednak skrypt, zamiast dokonać aktualizacji, wyświetlał mi komunikat o braku połączenia z internetem:

Checking internet connection… failed

Było to o tyle dziwne, że nie dość, że – jak już pisałem – usługi były dostępne, ja się łączyłem z serwerem zdalnie, to jeszcze chwilę wcześniej sam skrypt się zaktualizował przez internet.

Szybka analiza skryptu doprowadziła mnie do funkcji, która przed właściwą aktualizacją sprawdza, czy jest dostęp do internetu:

echo -en "Checking internet connection... "
timeout 3 ping -c 1 9.9.9.9 > /dev/null # Linijka 266
if [[ $? != 0 ]]; then
  echo -e "\e[31mfailed\e[0m"
  exit 1
else
  echo -e "\e[32mOK\e[0m"
fifi

Jak widać (linijka 266 aktualnej wersji skryptu) odbywa się poprzez sprawdzenie dostępności (polecenie PING) adresu 9.9.9.9, czyli serwera DNS Quad9. Powinno działać, ale nie na tym konkretnym serwerze:

patryk@vps:~$ ping 9.9.9.9 -c 2
PING 9.9.9.9 (9.9.9.9) 56(84) bytes of data.

--- 9.9.9.9 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1009ms

Z kilkoma innymi adresami nie było problemu (adres ten działa z innych serwerów, więc możliwe, że… ;-)), więc postanowiłem podmienić ten adres IP na coś innego, np. serwer DNS od Cloudflare:

echo -en "Checking internet connection... "
timeout 3 ping -c 1 1.1.1.1 > /dev/null # Linijka 266
if [[ $? != 0 ]]; then
  echo -e "\e[31mfailed\e[0m"
  exit 1 # Linijka 269
else
  echo -e "\e[32mOK\e[0m"
fifi

W tym momencie wszystko ruszyło, przynajmniej jeśli chodzi o test dostępu do internetu (alternatywnie można zakomentować linijkę 269, odpowiedzialną za przerwanie pracy skryptu). Zmiany trzeba było wdrożyć jeszcze w mechanizmie sprawdzającym, czy dostępna jest inna (domyślnie nowa) wersja skryptu:

echo -e "\e[32mChecking for newer update script...\e[0m"
SHA1_1=$(sha1sum update.sh)
git fetch origin #${BRANCH}
git checkout origin/${BRANCH} update.sh
SHA1_2=$(sha1sum update.sh)
if [[ ${SHA1_1} != ${SHA1_2} ]]; then
  echo "update.sh changed, please run this script again, exiting."
  chmod +x update.sh
  exit 0 # Linijka 282
fi

W tym przypadku zakomentowałem linijkę 282 odpowiedzialną za przerwanie pracy skryptu w przypadku, gdy wersja na serwerze jest inna od wersji w źródłach na GitHubie (można pójść szerzej i zakomentować cały moduł odpowiedzialny za pobieranie nowej wersji).

Po tej operacji aktualizacja przebiegła bezproblemowo. Choć oczywiście mam świadomość, że jest to rozwiązanie tymczasowe. Z pozytywnych rzeczy mogę też od razu napisać, że (potencjalna) blokada zniknęła (lub została zdjęta) i skrypt aktualizacji działa w oryginalnej wersji. Tak więc artykuł zostaje ku pamięci… :-)

(!) Zgłoś błąd na stronie | Lub postaw nam kawę :-)
LUTy dla D-Cinelike (DJI Mini 3 Pro, DJI Avata, OSMO Pocket) od MiniFly
Wdrożenie Omnibusa w sklepie na WooCommerce
Jak (legalnie) latać dronem w Kategorii Otwartej
Patryk