Klient vpn dostarczany z Cisco AnyConnect zachowuje się jak rozmowa: wypisuje pytanie, czeka na linię, a potem wypisuje następne. Podaj tę rozmowę z pliku lub potoku, a ta sama binarka działa bez nadzoru. Technika to jedno przekierowanie plus uporządkowana lista odpowiedzi, i to lista, a nie przekierowanie, decyduje, czy skrypt jest niezawodny.

W praktyce psują to dwie rzeczy. Kolejność pytań przesuwa się, gdy brama pyta o coś dodatkowego, a zapisane hasło zamienia jedną literówkę w zablokowanie konta. Traktuj sekwencję jak dane wersjonowane, które możesz porównać po każdej zmianie bramy. Zawodź głośno zamiast ponawiać, bo pętla jest dokładnie tym, jak źle wpisane hasło staje się zablokowanym kontem.

Jedna sekwencja, w kolejności, w jakiej pyta klient

Uruchom klienta raz interaktywnie i zapisz każde pytanie w kolejności pojawiania się. Ten zapis staje się plikiem odpowiedzi. Gdy przekierujesz plik do binarki, pierwsza linia musi być samą komendą połączenia, dlatego sekwencja zaczyna się nazwą hosta, a nie nazwą użytkownika.

connect vpn.example.com
0
<username>
<password>
y
exit

Samo 0 wybiera pierwszy profil połączenia, gdy brama oferuje listę; użyj indeksu, który wypisuje twoja brama. y akceptuje baner logowania, więc usuń tę linię, jeśli banera nie ma, i wstaw jedną tam, gdzie brama zadaje dodatkowe pytanie. Końcowe exit pozwala klientowi zakończyć się czysto, gdy ostatnia odpowiedź zostanie zużyta.

/opt/cisco/anyconnect/bin/vpn -s < anyconnect.txt

Tryb nieinteraktywny nie jest tu opcjonalny. Bez -s klient może przejąć terminal i ignorować przekierowane wejście; z nim odpowiedzi są czytane ze strumienia, a proces wraca. Tam, gdzie binarka wymaga podwyższonych uprawnień, opakuj wywołanie w sudo -n, żeby skrypt zawiódł od razu, zamiast blokować się na pytaniu o hasło.

Gdzie wycieka plik odpowiedzi

Plik zawierający hasło jest poświadczeniem, więc daj mu uprawnienia poświadczenia: tryb 600, właściciel to konto, które wykonuje zadanie, i nigdy wewnątrz katalogu współdzielonego lub synchronizowanego. Utwórz go z już zastosowanym trybem, zamiast poprawiać później, bo plik jest przez chwilę czytelny dla wszystkich między zapisem a chmod.

install -m 600 /dev/null ~/.config/anyconnect.txt
chmod 700 ~/.config

Druga połowa to argv. Hasło przekazane jako argument jest widoczne dla każdego lokalnego użytkownika, który listuje procesy, i trafia też do historii powłoki. Czytaj je z deskryptora pliku albo zmiennej środowiskowej, i ujmij ładunek w cudzysłów, żeby powłoka nie mogła nic w nim rozwinąć.

printf '%s\n' 'connect vpn.example.com' '0' "$VPN_USER" "$VPN_PASS" 'y' 'exit' \
  | sudo -n /opt/cisco/anyconnect/bin/vpn -s

Uważaj na cytowanie. W podwójnych cudzysłowach hasło zawierające ! może zostać rozwinięte przez interaktywną powłokę, zanim klient je zobaczy, a błąd przychodzi jako ogólny błąd event-not-found, który wygląda jak problem protokołu.

Udowodnij tunel, potem go zamknij

Stan połączony dowodzi tylko, że klient wierzy, iż ma sesję. Wybierz host, który odpowiada wyłącznie od wewnątrz sieci firmowej, i sprawdź go raz, zanim zrobisz cokolwiek innego. Błąd tam to usterka routingu lub polityki, a ponowne uruchomienie logowania tego nie zmieni.

/opt/cisco/anyconnect/bin/vpn state
curl -sS -o /dev/null -w '%{http_code}\n' --max-time 10 https://<internal-host>/
/opt/cisco/anyconnect/bin/vpn disconnect

Sprawdź wyjście stanu przed rozłączeniem i po nim. Klient pozostawiony z nieaktualną sesją może odrzucić kolejne połączenie, podczas gdy skrypt nadal raportuje sukces, a ten tryb awarii jest niewidoczny, jeśli patrzysz tylko na kody wyjścia. Porównaj oba odczyty, zamiast wierzyć drugiemu osobno. Aliasy w profilu powłoki wystarczą do codziennego użytku, ale wszystko zaplanowane zasługuje na ten sam przegląd poświadczeń i tożsamości co każde inne zadanie bez nadzoru.

Kiedy stała lista przestaje być bezpieczna

Plik odpowiedzi koduje dzisiejszą kolejność pytań. Zmieniony baner, wymuszona zmiana hasła albo wyzwanie drugiego składnika zamieniają go w pętlę, która może zablokować konto, dlatego skrypt musi wyjść przy pierwszej nieoczekiwanej odpowiedzi, zamiast się restartować.

Przechwyć to, co wypisał klient, zwróć niezerowy status i pozwól zdecydować wywołującemu. Tam, gdzie brama wymaga drugiego składnika, uczciwa odpowiedź brzmi, że logowanie bez nadzoru nie jest dostępne dla tego profilu, a nie że sekwencja potrzebuje jeszcze jednej linii.

Rotacja należy do tego samego przeglądu. Jeśli poświadczenie jest zapisywane, zdecyduj, kto może je czytać, kiedy się zmienia i co je usuwa, gdy host jest odtwarzany. Skrypt, który działa rok, bo nikt nie dotknął hasła, nie jest projektem, tylko wypadkiem czekającym na politykę rotacji.

Profile, które nie są AnyConnect

Dwa starsze style poświadczeń Cisco bywają mylone z tym. Profil vpnc pyta o IPSec ID, czyli właściwie nazwę grupy, potem o sekret grupy, potem o twoje własne poświadczenia, i wszystkie trzy pochodzą od tego, kto zarządza bramą. Stary Cisco IPsec to inny protokół niż AnyConnect, więc vpnc nie sięgnie usługi przeznaczonej tylko dla AnyConnect; openconnect --protocol=anyconnect jest otwartym klientem do tego zadania.

Plik .pcf opisuje profil starszego klienta. Host, nazwę grupy i hasło grupy z niego można wpisać ręcznie w kliencie mówiącym Cisco IPsec, choć plik nie jest uniwersalnym importem i każdy niestandardowy port lub tryb tunelowania zwykle znika przy przenoszeniu.

Zacznij od tego, co brama rzeczywiście oferuje, a potem wybierz klienta, który mówi tym protokołem. Kopiowanie profilu z innej strony to sposób, w jaki ludzie kończą na debugowaniu poświadczeń, które nigdy nie były problemem.

Powiązane artykuły