계정에 2개의 비밀번호를 할당하고 싶습니다. 내가 알고 싶은 것은 1) 이것이 가능합니까? 2) 이것이 보안에 어떤 영향을 미치나요?
내가 이것을 하고 싶었던 이유는 현재 일부 로컬 테스트로 바쁘고 이것이 특정 상황에서 유용할 것이라고 생각했기 때문입니다. 약간의 조사 끝에 다음과 같은 도구를 발견했습니다.폴리아크릴아미드, 설치/구성 작동 방식에 대한 정보를 찾는 데 어려움을 겪고 있습니다.
저는 우분투 12.04를 실행하고 있습니다.
답변1
예, 비록 매우 드문 일이지만 확실히 가능합니다.
직접 구현하려고 시도하는 것보다 /etc/password
/etc/shadow
기본 기반 인증 방법은 이러한 구성을 제공하지 않으므로 이미 사용자에 대해 여러 암호를 지원하는 백엔드에 인증을 위임하는 것이 더 간단한 접근 방식입니다.
잘 알려진 것은LDAPuserPassword
다중값을 갖는 속성RFC4519:
'userPassword' 속성에 여러 값이 필요한 예는 사용자가 자동화 시스템에서 생성된 매달 다른 비밀번호를 사용해야 하는 환경에서일 수 있습니다. 전환 기간의 마지막 날과 첫 번째 날과 같은 전환 기간 동안 시스템에서 두 개의 연속 기간 동안 두 개의 비밀번호가 유효하도록 허용해야 할 수도 있습니다.
이 RFC에도 불구하고 이 설정을 실제로 적용하려면 대부분의 디렉토리 서버 구현에서 비밀번호 정책 구성을 변경해야 할 수도 있습니다.
Linux 측에서는 이를 금지하는 것이 없습니다(여기서는 계정 이름이 지정되고 속성 값 으로 testuser
지정됨 ).pass1
pass2
userPassword
$ uname -a
Linux lx-vb 3.8.0-19-generic #29-Ubuntu SMP Wed Apr 17 18:16:28 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
$ grep VERSION /etc/os-release
VERSION="13.04, Raring Ringtail"
$ grep "^passwd" /etc/nsswitch.conf
passwd: files ldap
$ ldapsearch -LLL -h localhost -p 1389 -D "cn=directory manager" -w xxxxxxxx "uid=testuser" userPassword
dn: uid=testuser,ou=People,dc=example,dc=com
userPassword:: e1NTSEF9b2JWYXFDcjhNQmNJVXZXVHMzbE40SFlReStldC9XNFZ0NU4yRmc9PQ==
userPassword:: e1NTSEF9eDlnRGZ5b0NhKzNROTIzOTFha1NiR2VTMFJabjNKSWYyNkN3cUE9PQ==
$ grep testuser /etc/passwd
$ getent passwd testuser
testuser:*:12345:12345:ldap test user:/home/testuser:/bin/sh
$ sshpass -p pass1 ssh testuser@localhost id
uid=12345(testuser) gid=12345 groups=12345
$ sshpass -p pass2 ssh testuser@localhost id
uid=12345(testuser) gid=12345 groups=12345
$ sshpass -p pass3 ssh testuser@localhost id
Permission denied, please try again.
이러한 구성의 몇 가지 기술 및 보안 관련 영향은 다음과 같습니다.
- 사용자 계정은 분명히 더 취약하지만, 여기서 정말로 중요한 것은 비밀번호의 수보다는 비밀번호의 품질과 보호입니다.
- 대부분의 유틸리티는 사용자가 하나의 비밀번호만 가지고 있다고 가정하므로 사용자가 비밀번호 중 하나를 개별적으로 업데이트하는 것을 허용하지 않습니다. 비밀번호 변경으로 인해 사용자가 비밀번호 속성을 갖게 될 수 있습니다.
- 여러 사람이 각자의 비밀번호를 사용하여 동일한 계정을 공유할 수 있도록 하는 것이 목표인 경우, 사용된 비밀번호를 기반으로 실제로 로그인한 사람을 식별할 수 있는 메커니즘이 없습니다.
답변2
방금 파일에 사용자에 대한 2개의 항목을 만들려고 시도했지만 /etc/shadow
성공하지 못했습니다. 첫 번째 항목은 사용된 비밀번호 항목입니다.
예
테스트 사용자를 만들었습니다.
$ useradd -d /home/newuser newuser
비밀번호를 "super123"으로 설정합니다:
$ passwd newuser
/etc/shadow
파일을 수동으로 편집 하고 두 번째 항목을 만듭니다.
newuser:$6$....password #1...:15963:0:99999:7:::
newuser:$6$....password #2...:15963:0:99999:7:::
그런 다음 2개의 비밀번호를 사용하여 계정에 로그인해 보세요.
su - newuser
첫 번째 항목 /etc/shadow
은 get이 사용하는 항목이며, 두 번째 위치의 항목은 다음과 같이 뒤집으면 작동하지 않습니다.
newuser:$6$....password #2...:15963:0:99999:7:::
newuser:$6$....password #1...:15963:0:99999:7:::
그러면 두 번째 비밀번호는 유효하지만 첫 번째 비밀번호는 유효하지 않습니다.
sudo 사용
이 방법은 내가 오직 사용하는 완전한 해킹이며 sudo
, sudo
이것이 존재하는 이유 중 일부입니다.
이 항목을 sudoers 파일( /etc/sudoers
)에 추가하면 사용자 joe가 다음을 수행할 수 있습니다.
joe ALL=(yourusername) ALL
답변3
이렇게 할 수 있다면 하지 말아야 할 것 같습니다.
PAM 구성은 다소 복잡하며 인증 메커니즘에 대한 당연한 사실이 있습니다. 올바른 구성 세트는 유한하고 안전하지 않은 구성 세트는 무한합니다. 이는 자신이 무엇을 하고 있는지 정확히 알지 못한 채 상황을 바꾸려고 하면 일을 망칠 것이라는 점을 거의 확실하게 해줍니다.
보안과 "특정 상황에서의 편의성" 중 하나를 선택해야 한다면 전자를 선택하세요.
답변4
하나의 계정에 여러 개의 서로 다른(하드코딩된) 비밀번호를 허용하는 작은 PAM 모듈을 작성할 수 있습니다.
다음은 그러한 모듈에 대한 예제 소스 코드입니다:
// Compile with:
// gcc -fPIC -shared -o pam_multipass.so pam_multipass.c -lpam -lssl -lcrypto
// Install into /lib/security/ (or other location, depending on your distribution):
// sudo install --mode=0755 --owner=root --group=root pam_multipass.so /lib/security/pam_multipass.so
#define _GNU_SOURCE
#include <stdio.h>
#include <security/pam_modules.h>
#include <security/pam_ext.h>
#include <string.h>
#include <openssl/sha.h>
#define USERNAME "username"
#define PASSWORD_HASH_1 "xxxxxxxx"
#define PASSWORD_HASH_2 "xxxxxxxx"
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) {
const char *username;
char *password;
unsigned char result[SHA256_DIGEST_LENGTH];
char hexstring[65];
// Get the username
pam_get_user(pamh, &username, NULL);
if (strcmp(username, USERNAME) != 0) {
return PAM_IGNORE; // Not the user we're interested in
}
// Prompt for password
if (pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, &password, "%s", "Password: ") != PAM_SUCCESS) {
fprintf(stderr, "pam_multipass pam_prompt failed\n");
return PAM_IGNORE;
}
if (pam_set_item(pamh, PAM_AUTHTOK, password) != PAM_SUCCESS) {
fprintf(stderr, "pam_multipass failed to set PAM_AUTHTOK\n");
}
SHA256((unsigned char *) password, strlen(password), result);
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
sprintf(hexstring + (i * 2), "%02x", result[i]);
}
// Compare with expected hash
if (
strcmp(hexstring, PASSWORD_HASH_1) == 0
|| strcmp(hexstring, PASSWORD_HASH_2) == 0
) {
return PAM_SUCCESS;
} else {
return PAM_IGNORE; // Allow other modules to authenticate
}
}
PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) { return PAM_IGNORE; }
PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) { return PAM_IGNORE; }
PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { return PAM_IGNORE; }
PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { return PAM_IGNORE; }
PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) { return PAM_IGNORE; }
PAM 구성에 모듈을 추가해야 하는데 이는 까다로울 수 있습니다. 저는 Arch Linux 배포판을 예로 들고 필요에 따라 다른 배포판에 적용합니다.
# in /etc/pam.d/system-auth
auth required pam_faillock.so preauth
auth [success=3 default=ignore] pam_multipass.so # <--- our module
auth [success=2 default=ignore] pam_unix.so try_first_pass nullok
-auth [success=1 default=ignore] pam_systemd_home.so
auth [default=die] pam_faillock.so authfail
auth optional pam_permit.so
auth required pam_env.so
auth required pam_faillock.so authsucc
그러나 어쨌든 각별히 주의하십시오. 수행 중인 모든 작업을 완전히 이해하지 못한다면 이와 같은 작업을 수행하지 마십시오(예: success=3
PAM 구성에 지시문이 왜 있는 걸까요?).