Można to zrobić, łącząc ze sobą moduły PAM. Ale zanim przejdę do jakichkolwiek szczegółów:
Niepoprawne skonfigurowanie PAM może i BĘDZIE uniemożliwić zalogowanie się do systemu
Na szczęście zawsze możesz uruchomić komputer w trybie pojedynczego użytkownika i rozwiązać problem, ale ostrzegaj, że PAM nie jest czymś, z czym chcesz zadzierać bardziej niż to konieczne.
Zresztą Ideą jest to, że możliwe jest wykorzystanie układania modułów PAM, aby upewnić się, że pam-google-authenticator, pam_unix(ta sprawdza hasło) i moduł certyfikat mają odnieść sukces, aby umożliwić dostęp. Domyślnie PAM jest skonfigurowany tak, aby umożliwić uwierzytelnienie dowolnego modułu uwierzytelnienia, pomijając pozostałe.
W /etc/pam.d/common-auth zobaczysz u góry linię, która wygląda podobnie do poniższej:
auth [success=2 default=ignore] pam_unix.so nullok_secure try_first_pass
Mówi to PAM, że powinno się pam_unix.sopowieść, pominie kolejne dwie reguły (które są zwykle kolejnym modułem uwierzytelniającym pam_deny.so) i przejdzie do modułów opcjonalnych. Jeśli jednak moduł ulegnie awarii, zostanie zignorowany, a kontrola przejdzie do następnego modułu w łańcuchu. Trwa to w dół każdego modułu uwierzytelniania, dopóki kontrola nie przejdzie do opcjonalnego bloku lub PAM nie trafi do pam_deny.so i nie powiedzie się.
Można to wykorzystać, aby to zagwarantować pam-google-authenticator, pam_unix.soa moduł PAM certyfikatu musi odnieść sukces, aby umożliwić ci dostęp. Nie znam nazwy modułu uwierzytelniającego Google ani modułu certyfikatu, którego używasz, ale powinieneś być w stanie znaleźć je w pliku common-auth. Umieszczając coś takiego na górze:
auth requisite pam_unix.so nullok_secure
auth requisite pam_google_authenticator.so
auth requisite pam_certificate_auth.so
auth [success=<n>] pam_permit.so
Zastąpienie <n>liczbą modułów między modułem pam_permit.so tutaj a następnym pam_permit.somodułem - innymi słowy, powinno to być ustawione na najwyższy kod autoryzacji [sukces = n domyślnie = ignoruj] + 1. Ta składnia jest nieco funky , ale zasadniczo pomija moduły uwierzytelniające po pomyślnym wykonaniu powyższych modułów.
Oczywiście możesz zastanawiać się, jak ograniczyć to trzyetapowe uwierzytelnianie tylko do konta użytkownika. Można to zrobić za pomocą pam_succeed_if.somodułu i należy go wstawić powyżej trzystopniowego bloku uwierzytelniania opisanego powyżej:
auth [success=ignore default=4] pam_succeed_if.so user = <username>
Gdzie <username>zastępuje twoja nazwa użytkownika. Ten wiersz mówi po prostu, że pam_succeed_if.so sukces (czyli twoja nazwa użytkownika pasuje do nazwy użytkownika w tym wierszu), a następnie PAM powinien przejść do następnych modułów, które są trzystopniowymi modułami uwierzytelniania. W przeciwnym razie PAM powinien przeskoczyć do prawdziwych modułów, które są oddalone o 4 moduły od tego.
Aby dopasować wiele elementów, na przykład członkostwo w grupie wraz z określoną nazwą użytkownika, należy użyć wielu wierszy, na przykład:
auth [success=1 default=ignore] pam_succeed_if.so user = <username>
auth [success=ignore default=4] pam_succeed_if.so user ingroup <group>
Zanim to zrobię, utworzę kopię zapasową pliku common-auth, a także zapoznam się z trybem pojedynczego użytkownika i sposobem przywracania starego pliku w nagłych przypadkach. Ta konfiguracja nie została przeze mnie przetestowana, ale powinna działać.
Aby przetestować to za pierwszym razem, zdobądź jedną lub dwie powłoki roota i zostaw je w spokoju. Działają one jako awaryjne na wypadek, gdyby coś poszło nie tak, ponieważ można łatwo zastąpić autouzupełnianie kopią zapasową. Następnie wprowadź te zmiany. Następnie spróbuj suzalogować się na swoje konto użytkownika - musisz przejść trzyetapowy proces uwierzytelnienia.
Pełna dokumentacja pam_succeed_if.somodułu znajduje się na stronie http://linux.die.net/man/8/pam_succeed_if