로그인 및 su 내부 구조

로그인 및 su 내부 구조

Linux에서 사용자 권한이 어떻게 작동하는지 알고 싶습니다. 커널이 init부팅되고 루트로 시작됩니다. 그렇죠? 그런 다음 Init는 시작 스크립트를 실행하고 다시 루트로 실행됩니다 getty( agetty). login나는 Agetty가 단지 사용자 이름을 읽고 실행되며 여전히 루트로 실행되고 있다고 생각합니다. 아직 흥미로운 내용은 없습니다. 하지만 무슨 소용이 있어?로그인하다? "로그인을 시도했습니다"보다 더 나은 것을 찾을 수 없습니다. 로그인이 일치하는 비밀번호를 찾았다고 가정하고(그리고 일반 사용자로 로그인을 시도하는 경우) 사용자 ID는 어떻게 변경됩니까? 시스템 호출이 있어야 할 것 같은데 찾을 수 없습니다. (아마 제가 눈이 먼 걸까요?)


또한, su" susetuid" 비트가 설정되어 있으므로 실행할 때 항상 루트로 실행됩니다. 하지만 일반 사용자로 로그인하라고 하면 다시 사용자 ID를 변경해야 합니다. 사용자를 변경해야 할 때 동일한 "마법"이 발생한다는 것을 올바르게 이해하고 있습니까 su? login그렇다면 왜 두 가지 다른 프로그램이 있습니까? 로그인을 실행할 때 다른 유형의 심각한 비즈니스가 발생합니까?

답변1

로그인 프로그램의 기능은 여러 부분으로 나누어져 있습니다. 로그인 프로그램은 로그인을 시도하는 사용자와 다르게 상호 작용합니다. 여기 몇 가지 예가 있어요.

  • login: 텍스트 터미널의 입력을 읽습니다.
  • su: 로그인한 사용자가 호출하여 명령줄 인수에서 대부분의 데이터와 터미널에서 인증 데이터(비밀번호)를 가져옵니다.
  • gksu: 와 비슷 su하지만 X에서 인증 데이터를 읽습니다.
  • rlogind: TCP 연결을 통해 입력 받기로그인규약
  • sshd: TCP 연결을 통해 입력 받기SSH규약
  • X 디스플레이 관리자(xdm, gdm, kdm, ...): 유사 login하지만 X 디스플레이의 입력을 읽습니다.

이러한 프로그램은 비슷한 방식으로 작동합니다.

  1. 첫 번째 부분은확인하다: 프로그램은 사용자로부터 일부 입력을 읽고 사용자에게 로그인 권한이 있는지 확인합니다. 전통적인 접근 방식은 사용자 이름과 비밀번호를 읽고 해당 사용자가 시스템의 사용자 데이터베이스에 언급되어 있는지, 사용자의 비밀번호가 올바른지 확인하는 것입니다. 사용자가 입력한 내용은 데이터베이스의 내용입니다. 하지만 다른 가능성도 많습니다(일회용 비밀번호, 생체 인증, 권한 전송 등).

  2. 사용자에게 어떤 계정으로 로그인할 수 있는 권한이 있는지 확인되면 로그인 절차를 통해 이 세션 동안 사용자가 속한 그룹과 같은 사용자 권한을 설정합니다.

  3. 로그인 프로세스에서는 계정 제한 사항도 확인할 수 있습니다. 예를 들어 로그인 시간이나 최대 로그인 사용자 수를 적용하거나 특정 사용자에 대한 특정 연결을 거부할 수 있습니다.

  4. 마지막으로 로그인 프로그램은 사용자 세션을 설정합니다. 몇 가지 하위 단계가 있습니다:

    1. 사용자, 그룹, 제한 등 권한 부여에서 결정된 대로 프로세스 권한을 설정합니다.여기에서 이 하위 단계의 간단한 예를 볼 수 있습니다.(사용자와 그룹만 처리합니다). 기본 아이디어는 로그인 프로그램이 이 시점에서 여전히 루트로 실행 중이므로 최대 권한을 갖는다는 것입니다. 먼저 루트 사용자를 제외한 모든 권한을 제거하고 마지막으로 setuid가장 중요한 권한 제거를 호출합니다.
    2. 사용자의 홈 디렉토리가 마운트되고 "메일이 있습니다" 메시지가 표시될 수 있습니다.
    3. 사용자로서 프로그램, 일반적으로 사용자의 쉘을 호출합니다( login및 명령이 지정되지 su않은 sshd경우 X 디스플레이 관리자는 X 세션 관리자 또는 창 관리자를 호출합니다).

현재 대부분의 unice는PAM(플러그형 인증 모듈)로그인 서비스를 관리하는 통합된 방법을 제공합니다. PAM은 그 기능을 다음과 같이 나눕니다.4개 부품: "auth"에는 인증(위 1) 및 승인(위 2)이 포함됩니다. 위의 3 및 4와 같은 "계정"과 "비밀번호"는 로그인에는 사용되지 않지만 인증 토큰 업데이트에는 사용됩니다(예: 비밀번호) ).

답변2

찾고 있는 시스템 호출은 setuid및 같은 것으로 불립니다. seteuid하지만 실제로는 변경하려는 사용자 ID의 변형에 따라 전체 헴 시리즈가 있습니다.

setgid프로세스가 실행되는 그룹을 변경하는 것과 같은 일부 병렬 호출도 있습니다 .

답변3

login필요한 경우 루트 권한이 포기됩니다. 처음에 루트 권한만 필요한 많은 프로그램은 루트로 시작하여 필요한 작업을 수행한 다음 일반 사용자 계정으로 드롭다운하므로 누군가가 루트에 액세스하기 위해 바이너리의 버그를 사용하는 것에 대해 걱정할 필요가 없습니다. 껍데기. login당연히 특권은 더 오래 유지되지만 원칙은 동일합니다.

실제로 루트 권한을 포기하는 것은 매우 간단합니다. 사용자 ID와 그룹 ID를 각각 변경하는 POSIX 정의 setuid()및 함수(루트로 시작하는 경우 true이고 유효함). 이 두 그룹을 호출하고 추가 그룹을 설정하세요. ( 이는 기본 그룹 ID를 설정하는 데만 사용됩니다.)setgid()logininitgroups()setgid

물론 실제로 프로세스 UID/GID 변경을 처리하는 것은 커널입니다.Linux 커널 시스템 호출 구현을 찾는 방법은 무엇입니까?내 커널 소스 코드에는 시스템 호출에 대한 많은 설명이 나와 있습니다.

#define __NR_setgid 144
__SYSCALL(__NR_setgid, sys_setgid)
#define __NR_setuid 146
__SYSCALL(__NR_setuid, sys_setuid)

따라서 144와 146은 내 컴퓨터에 있는 이러한 기능의 시스템 호출 번호입니다.


su소스 코드가 무엇인지 확인 하지는 않았지만 exec()동일한 방법을 사용하여 셸을 실행하기 전에 루트 권한을 제거하는 것으로 의심됩니다.

관련 정보