ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Linux] 계정 비밀번호 정책 및 설정 feat.정보보안기사
    Linux 2025. 6. 3. 23:35
    728x90
    반응형

    해킹 공격에서 비밀번호 탈취는 핵심적인 목표로 공격 대상이 되는 계정은 크게 일반 사용자, 시스템 운영에 필요한 특수 사용자 그리고 시스템의 모든 권한을 가진 루트(Root) 사용자로 나눌 수 있습니다.

    이 중 특히 특수 사용자나 루트 사용자의 비밀번호 탈취 사건은 시스템 전체의 보안을 무너뜨리고 대규모 정보 유출이나 서비스 마비와 같은 심각한 문제를 야기하며 뉴스 속보로 다뤄지곤 합니다.

     

    이처럼 치명적인 피해를 막기 위해 리눅스 시스템에서는 강력한 비밀번호 정책과 철저한 관리가 필수적입니다.

    이번 글에서는 리눅스 시스템의 사용자 계정 정보와 비밀번호 보안의 핵심이 되는 /etc/passwd/etc/shadow 파일을 깊이 있게 분석하고 이를 통해 비밀번호 정책을 어떻게 설정하고 관리하는지 알아보겠습니다.

    1. /etc/passwd 이해

    Linux 서버에 등록되어 있는 계정 정보가 담겨 있습니다.

    권한을 확인해보면 root 계정은 읽기 및 쓰기가 가능하고 root 그룹은 읽기만 가능하고 그외 계정도 읽기만 가능합니다.

    $ ls -al /etc/passwd
    
    -rw-r--r-- 1 root root 1416 Apr  7  2024 /etc/passwd

    해당 파일의 계정 정보는 아래와 같이 나열되며 보는 방법은 아래와 같습니다.

    • [계정명]:[비밀번호]:[계정ID - UID]:[그룹ID - GID]:[코멘트 - 사용자 정보]:[홈 디렉토리]:[로그인 쉘]
    $ cat /etc/passwd
    
    root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    sys:x:3:3:sys:/dev:/usr/sbin/nologin
    sync:x:4:65534:sync:/bin:/bin/sync
    games:x:5:60:games:/usr/games:/usr/sbin/nologin
    man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
    lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
    mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
    news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
    uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
    proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
    www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
    backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
    list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
    irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
    gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
    nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
    systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
    systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
    messagebus:x:102:105::/nonexistent:/usr/sbin/nologin
    systemd-timesync:x:103:106:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
    syslog:x:104:111::/home/syslog:/usr/sbin/nologin
    _apt:x:105:65534::/nonexistent:/usr/sbin/nologin
    uuidd:x:106:112::/run/uuidd:/usr/sbin/nologin
    tcpdump:x:107:113::/nonexistent:/usr/sbin/nologin
    jangto:x:1000:1000:,,,:/home/jangto:/bin/bash

    계정 ID 및 그룹ID : UID 및 GID 보는 방법

    • 0 : root 사용자, root 그룹
    • 1 ~ 99 : 시스템 사용자 (서비스용, 로그인 불가), 시스템 그룹 (OS 내부에서 사용하는 그룹)
    • 100 ~ 999 : 시스템 / 서비스용 사용자, 시스템 / 서비스용 그룹 (데몬, 시스템 서비에 할당)
    • 1000 이상 : 일반 사용자, 일반 사용자 그룹 (사용자 생성시 자동 생성되는 기본 그룹)

    해당 정보는 민감한 정보일까요?

    해당 파일에는 직접적으로 민감한 정보는 포함되어 있지 않습니다.

    이유는 해당 파일에는 비밀번호가 "x"로 대체되며 실제 비밀번호는 /etc/shadow 파일에 hash 형태로 저장되어 있습니다.

    2. /etc/shadow 이해

    해당 파일은 계정의 실제 비밀번호가 hash 형태로 저장되어 있습니다.

    권한을 확인해보면 root 계정은 읽기 및 쓰기가 가능하고 root 그룹은 읽기만 가능하고 그외 계정은 접근이 불가능합니다.

    • 실제 환경에서 해당 파일의 root 권한도 400으로 읽기만 열어서 혹시 모를 휴먼 에러를 방지합니다.
    $ ls -al /etc/shadow
    
    -rw-r----- 1 root shadow 827 Apr  7  2024 /etc/shadow

    해당 파일의 계정 정보는 아래와 같이 나열되며 보는 방법은 아래와 같습니다.

    • [계정명]: [Hash 비밀번호] :[마지막 비밀번호 변경일]:[최소변경일수]:[최대변경일수]:[경고일 수]: [최대비활성화일수]:[계정만료일자]
    $ cat /etc/shadow
    
    root:*:19683:0:99999:7:::
    daemon:*:19683:0:99999:7:::
    bin:*:19683:0:99999:7:::
    sys:*:19683:0:99999:7:::
    sync:*:19683:0:99999:7:::
    games:*:19683:0:99999:7:::
    man:*:19683:0:99999:7:::
    lp:*:19683:0:99999:7:::
    mail:*:19683:0:99999:7:::
    news:*:19683:0:99999:7:::
    uucp:*:19683:0:99999:7:::
    proxy:*:19683:0:99999:7:::
    www-data:*:19683:0:99999:7:::
    backup:*:19683:0:99999:7:::
    list:*:19683:0:99999:7:::
    irc:*:19683:0:99999:7:::
    gnats:*:19683:0:99999:7:::
    nobody:*:19683:0:99999:7:::
    systemd-network:*:19683:0:99999:7:::
    systemd-resolve:*:19683:0:99999:7:::
    messagebus:*:19683:0:99999:7:::
    systemd-timesync:*:19683:0:99999:7:::
    syslog:*:19683:0:99999:7:::
    _apt:*:19683:0:99999:7:::
    uuidd:*:19683:0:99999:7:::
    tcpdump:*:19683:0:99999:7:::
    jangto:$y$j9T$WEWfG2MdFRqUCeUrv2K87/$klDGfSwkHAbl3Q1aiqBfmn4MYWF2x4A:19819:0:99999:7:::

    Hash 비밀번호 보는법

    Hash 비밀번호는 기본적으로 $암호화 방법, $Salt, $3암호화된 비밀번호로 이루어져 있습니다.

    • * : 비밀번호로 로그인이 불가능 하지만 별도의 인증 방식으로 로그인 가능
    • Null : 비밀번호 미설정 (아무나 로그인 가능)
    • !! : 어떤 방식으로도 로그인 불가

    1. 암호화 방법

    $5 미만의 값으로 암호화 되어있는 경우 보안에 매우 취약합니다.

    2. Salt

    Salt는 비밀번호는 생성 및 수정할때 OS에서 랜덤하게 생성하게 되며 Hash 알고리즘으로 암호화할때 평문을 바로 Hash화 하는게 아니라 Salt 같은 양념을 쳐서 평문과 대응하는 Hash 결과값을 사용하는 공격을 피할 수 있습니다.

    마지막 비밀번호 변경일

    해당 숫자는 1970년 1월 1일부터 경과 한 일수를 의미합니다.

    최소 변경 일수

    • 0 : 즉시 변경 가능
    • 숫자 : N일이 지나야 변경 가능

    최대 변경 일수

    해당 일이 지났음에도 비밀번호를 변경하지 않은 경우 로그인 자체가 거부되거나 비밀번호 변경을 요구 받습니다.

    기업에서는 기본적으로 90 ~ 100일로 지정하는 경우가 많습니다.

    • 0 : 즉시 변경 요구
    • 99999 : 변경 필요 없음 (사실상 무기한) - 기본값
    • 1 ~ N : 마지막 변경일로 부터 해당 일이 지나면 변경 요구

    경고일 수

    최대 변경 일수를 기준으로 지정된 일(기본값 7) 전에 알림을 줘서 변경을 유도 합니다.

    최대 비활성화 일수

    최대 변경 일수가 지났음에도 불구하고 비밀번호를 변경하지 않았으며 최대 비활성화 일수가 지나게 되면 계정 로그인이 거부됩니다.

    계정 만료일자

    해당 일자로 도래하면 해당 계정은 사용 불가가 됩니다.

    이때 일자는 1970년 1월 1일부터 경과된 일을 작성하면 되고 해당 칸이 비어있다면 해당 계정의 만료일자는 없는것으로 간주합니다. 


    3. 다양한 설정 진행

    위에서 알아본 다양한 정보들을 설정하는 방법과 의미를 알아보겠습니다.

    해당 설정들은 OS 환경마다 상이하기 때문에 정보보안기사에서 사용하는 RHEL7과 사용중인 Ubuntu에 두가지 경우에 대해 알아보겠습니다.

    비밀번호 복잡도 설정

    비밀번호 복잡도 설정은 말 그대로 비밀번호를 생성할때 지켜야하는 것들을 설정하는 것입니다.

    • retry = N : N번까지 패스워드 재입력 가능
    • minlen = N : 최소 N자리 이상 필요
    • lcredit= -N : 소문자 최소 N개 이상 필요
    • ucredit= -N : 대문자 최소 N개 이상 필요
    • dcredit= -N : 숫자 최소 N개 이상 필요
    • ocredit= -N : 특수문자 최소 N개 이상 필요
    • difok = N : 비밀번호 변경 시 이전 비밀번호보다 N개 이상 차이 필요
    • enforce_for_root
      • root 계정에도 비밀번호 복잡성 정책을 적용할지 여부이며 없다면 적용하지 않게 됩니다.

    RHEL7 환경

    비밀번호 재시도 횟수는 3번이고 최소 8자리 이상이여야 하며 소문자 1개 이상, 대문자 1개이상, 숫자 1개 이상, 특수문자 1개 이상이여야 합니다.

    또한 비밀번호 변경 시 이전 비밀번호보다 8개의 글자가 달라야합니다.

    vi /etc/security/pwquality.conf
    
    password requisite pam_cracklib.so try_first_pass retry=3 minlen=8 lcredit=-1 ucredit=-1 dcredit=-1 ocredit=-1 difok=8

    Ubuntu 환경

    ubuntu 환경이라면 우선 apt install libpam-pwquality를 통해 패키지를 다운로드 받은 후 설정해줘야합니다.

    설정 내용은 RHEL7 환경과 동일하게 진행하지만 여기서는 root 계정에서 유저를 추가하더라도 비밀번호 복잡성 설정을 적용할 수 있도록 하겠습니다.

    vi /etc/pam.d/common-password
    
    ...
    
    password        requisite                       pam_pwquality.so retry=3 minlen=8 lcredit=-1 ucredit=-1 dcredit=-1 ocredit=-1 enforce_for_root
    password        [success=1 default=ignore]      pam_unix.so obscure use_authtok try_first_pass yescrypt
    
    ...

    배운 내용 TEST

    꼭 위 설정을 한 후 아래와 같이 테스트 해보는게 좋습니다.

    -- root 계정에서 유저 추가
    $ adduser usera
    
    Adding user `usera' ...
    Adding new group `usera' (1004) ...
    Adding new user `usera' (1003) with group `usera' ...
    Creating home directory `/home/usera' ...
    Copying files from `/etc/skel' ...
    New password: [asdf]
    BAD PASSWORD: The password contains less than 1 digits
    New password: [asdf1]
    BAD PASSWORD: The password contains less than 1 uppercase letters
    New password: [asdf1A]
    BAD PASSWORD: The password contains less than 1 non-alphanumeric characters
    passwd: Have exhausted maximum number of retries for service
    passwd: password unchanged
    Try again? [y/N] y
    New password: [asdf1A!]
    BAD PASSWORD: The password is shorter than 8 characters
    New password: [asdf1A!2]
    Retype new password: [asdf1A!2]
    passwd: password updated successfully
    Changing the user information for userc
    Enter the new value, or press ENTER for the default
            Full Name []:   [enter]
            Room Number []: [enter]
            Work Phone []:  [enter]
            Home Phone []:  [enter]
            Other []:       [enter]
    Is the information correct? [Y/n] y
    
    $ id usera
    
    uid=1003(usera) gid=1004(usera) groups=1004(usera)

    추가로 이번에 tester라는 group을 만들고 userb 계정을 만들때 group을 지정해서 만들어보겠습니다.

    그리고 usera의 그룹을 tester로 변경하겠습니다.

    $ getent group tester -- tester 라는 group이 있는지 확인
    
    $ usermod -g tester usrea -- usera 유저의 그룹을 tester로 변경
    
    $ adduser --ingroup tester userb -- userb 유저를 만드는데 tester라는 그룹으로 만든다.

    비밀번호 사용 기간 설정

    해당 설정은 비밀번호의 사용 가능 기간, 변경 가능 기간, 변경 알림을 설정할 수 있습니다.

    이 설정의 경우 RHEL7과 Ubuntu 환경 모두 동일한 곳에서 설정합니다.

    • PASS_MAX_DAYS N : 최대 N일간 비밀번호 사용 가능
      • 99999의 의미는 무제한 
    • PASS_MIN_DAYS N : 최소 1일 경과 후 비밀번호 변경 가능
      • 0의 의미는 바로 변경 가능
    • PASS_WARN_AGE N : PASS_MAX_DAYS 만료 N일이 남은 시점부터 비밀번호 변경 알림
    $ vi /etc/login.defs
    
    ...
    
    PASS_MAX_DAYS 100
    PASS_MIN_DAYS 1 
    PASS_WARN_AGE 7
    
    ...

    배운 내용 TEST

    위와 같이 login.defs 파일을 저런식으로 설정한후 우선 아까 만든 계정을 사용해서 테스트를 해봤는데 비밀번호 변경이 성공한 것을 알 수 있습니다.

    $ su - usera -- 아까 위에서 만든 usera 계정으로 변경
    
    $ passwd -- 비밀번호 변경
    
    Changing password for newuser.
    
    Current password: [asdf1A!2]
    
    New password: [newpwd1AA!@#]
    
    Retype new password: [newpwd1AA!@#]
    
    passwd: password updated successfully

    분명 1일 이후 변경이 가능하고 설정했는데 왜 이런건지 계정 설정을 확인해보겠습니다.

    분명 PASS_MIN_DAYS를 1로 설정했는데 지금 계정의 설정을 확인해보니 0으로 되어 있는것을 확인할 수 있습니다. 

    $ chage -l usera
    
    Last password change                                    : Jun 03, 2025
    Password expires                                        : never
    Password inactive                                       : never
    Account expires                                         : never
    Minimum number of days between password change          : 0
    Maximum number of days between password change          : 99999
    Number of days of warning before password expires       : 7

    이 사실로 알게된 것은 login.defs 설정을 변경하더라도 기존 유저에게는 적용되지 않는다는 사실입니다.

    그러기 때문에 만약 비밀번호 사용기간 설정을 변경하게 되면 모든 유저를 각각 설정해줘야 합니다.

    • 하지만 설정 후 생성 된 유저들은 자동으로 login.defs 설정이 적용됩니다.
    -- 해당 설정은 root 계정만 가능합니다.
    $ chage -m 1 usera
    
    -- usera 계정으로 변경 후
    $ chage -l usera
    
    Last password change                                    : Jun 03, 2025
    Password expires                                        : never
    Password inactive                                       : never
    Account expires                                         : never
    Minimum number of days between password change          : 1
    Maximum number of days between password change          : 99999
    Number of days of warning before password expires       : 7

    chage 명령어의 기본적인 옵션에 대해 알아 보겠습니다.

    • -m : PASS_MIN_DAYS
    • -M : PASS_MAX_DAYS
    • -W : PASS_WARN_AGE
    • -l : 현재 설정 상태를 확인

    이제 다시 usera 유저의 비밀번호를 변경해보겠습니다.

    -- usera 계정으로 접속 후
    $ passwd
    Changing password for newuser.
    Current password: [newpwd1AA!@#]
    You must wait longer to change your password. -- 이렇게 기다리라는 경고와 함께 변경이 되지 않습니다.
    passwd: Authentication token manipulation error
    passwd: password unchanged

    최대 사용 가능 날짜와 알림도 테스트 하고 싶지만 지금 당장 확인이 어려워서 패쓰하겠습니다.

    비밀번호 임계값 (잠금) 설정 

    해당 설정은 계정 잠금과 관련된 설정으로 각 OS 환경에 따라 설정 방식이 다르기 때문에 각각 알아보겠습니다.

    • deny = N : N회 입력 실패 시 계정 잠금
    • unlock_time = N : 계정이 잠긴 이후 N초 경과 후 잠김 해제
    • no_magic_root : root는 계정 잠금 설정 제외
    • reset : 로그인 성공 시 실패 횟수 초기화

    RHEL7 환경

    아래 설정은 5회 실패 시 계정이 잠기고, 계정이 잠기는 경우 120초 이후 풀리고 로그인 성공 시 실패 횟수 초기화합니다.

    하지만 root는 해당 설정을 따르지 않습니다.

    vi /etc/pam.d/system-auth
    
    auth required /lib/security/pam_tally.so deny=5 unlock_time=120 no_magic_root reset
    728x90
    반응형
Designed by Tistory.