데몬(daemon) 프로세스란 무엇인가?

오늘. 누군가가 “데몬(daemon) 프로세스”가 도대체 뭔가요?”라는 질문 던진 것을 인터넷의 한 게시판에서 봤다.

많은 개발자나 엔지니어들이 IT 바닥에서  일을 하면서도 쉽게 접하기 어려운 분야가 바로 서버의 운영체제다. 서버 운영체제는 일부 서버 엔지니어나 시스템 소프트웨어 엔지니어들의 전유물처럼 되어 있다. 그렇다보니 운영체제를 직접 다룰 일이 없는 개발자나 학생들은 운영체제에 대한 개념이 부족한게 사실이다. 사실 데몬 프로세스가 뭔지 몰라도 일하는데 전혀 지장이 없다.

데몬(daemon) 프로세스란?

구글에서 daemon process 를 검색하면 첫 번째로 뜨는 컨텐츠는 인디아나 주립대학교의 날리지베이스에 정의된 daemon in Unix 라는 정의다.

그렇다. 데몬(daemon) 이란 서비스의 요청에 대해 응답하기 위해 오랫동안 실행중인 백그라운드(background) 프로세스다. 유닉스(리눅스 포함) 운영체제에서 이름이 “d”로 끝나는 프로세스들이 대표적인데 inetd, httpd, nfsd, sshd, named와 lpd 등이 있다.

여기서 핵심은 “백그라운드(background) 프로세스”라는 것이다. 백그라운드란 무엇인가를 이해하면 데몬 프로세스가 무엇인지 쉽게 이해할 수 있다.

백그라운드(background) 프로세스란?

사실 실제 화면을 보지 않고 백그라운드 프로세스를 이해하는 것은 매우 어렵다. 이는 눈을 가린채 코끼리 다리를 만지게 하면서 코끼리의 생김새를 이해하라는 것과 같다.

백그라운드 프로세스가 있다면 그 반대의 개념인 포그라운드(Foreground) 프로세스가 있다는 것도 유추가능하다. 이 두 프로세스의 차이를 이해하면 데몬 프로세스가 무엇인지 아주 쉽게 이해할 수 있다.

포그라운드 프로세스는 사용자와의 대화창구인 표준입출력장치 즉 터미널과 키보드(tty 혹은 pts로 표현되는)을 통해 대화한다. 하지만 백그라운드 프로세스는 적어도 입력장치에 대해 터미널과의 관계를 끊은 모든 프로세스를 의미한다. 즉 사용자에게 무언가를 키보드를 통해 전달받지 않고 스스로 동작하는 프로세스가 바로 백그라운드 프로세스이다.

예를 들어 유닉스(리눅스) 운영체제가 설치되어 있는 서버에 전원을 넣고 웹서버인 아파치 서버를 설치했다고 치고 아파치 웹서버를 실행하는 시나리오를 기반으로 설명하도록 하겠다.

처음으로 아파치 서버를 구동하기 위해서는 아파치가 설치된 서버에 로그인을 해야한다. 이때는 서버에 ssh 혹은 telnet으로 접속해야 한다. 그것도 아니라면 서버 앞으로 가 물리적 콘솔에 로그인해야 한다.

개인이 사용하는 Windows PC에서 SSH 접속을 한다고 가정하자. 이런 화면이 보일 것이다.

서버에 SSH 접속하는 화면이다.

여기서 부터 프로세스에 대한 개념을 잡아야 한다.

ssh 192.168.100.100 까지는 PC의 Windows에서 실행된 cmd의 화면이다. 윈도의 cmd는 유닉스(리눅스)와는 다르지만 화면에 C:\>와 같이 표현되는 프롬프트를 표시하고 키보드로 입력을 받는다. 즉 키보드 입력과 화면 출력을 통해 사용자와 대화한다. 따라서 cmd는 포그라운드 프로세스다.

그리고 다음 라인의 taeho@192.168.100.100 ‘s password : 은 앞 라인에서 cmd가 사용자가 입력한 ssh 명령을 해석해 PC에 있는 ssh 명령을 실행하고 아규먼트로 전달받은 192.168.100.100 IP로 ssh 접속을 시도하여 서버에서 실행중인 ssh 데몬과 세션을 맺은 다음 ssh 데몬이 사용자에게 보여주기를 원하는 내용을 ssh 명령이 전달받아 화면에 출력한 내용이다.

즉 ssh 명령도 화면에 sshd로 부터 전달받은 내용을 표시하고 키보드를 통해 사용자가 입력한 비밀번호를 서버의 sshd에 전달하므로 포그라운드 프로세스다.

그리고 비밀번호를 입력한 뒤 화면에는 $로 표현되는 리눅스의 쉘이 표시되었다. 여기서부터 유닉스(리눅스) 운영체제에 대한 이해가 필요하다.

sshd가 $ 를 보여주고 사용자가 명령을 입력하기를 기다리므로 sshd가 포그라운드 프로세스가 아니냐고 반문할 수 있다. 결론은 sshd는 포그라운드 프로세스가 아니다.

왜냐하면 sshd의 역할은 비밀번호를 입력받아 비밀번호가 맞는지를 확인하고 passwd 파일에서 해당 계정에게 할당된 bash 를 실행시키고 뒤로 물러나 있기 때문이다. 즉 화면에 표시된 $ 는 sshd가 보여준 것이 아니라 sshd가 실행시킨 bash가 보여주는 것이기 때문이다. 즉 sshd는 사용자에게 키보드로 부터 직접 입력을 받지 않으며 직접 무언가를 지시할 수 없다.

이 단계에서 프로세스의 관계를 살펴보면…

먼저 ps -ef 로 프로세스 목록을 보면 위 화면과 같다. 여기서 중요한 것은 PID와 PPID 항목이다.

맨 위에 보면 root 계정에서 실행된 sshd -D 프로세스가 보인다. (PID 6884) 그리고 아래쪽에 보면 PPID가 6884 인 sshd(PID 8111)이 보이고 바로 아래에 그 sshd(PID 8111)을 PPID로 하는 bash(8112)가 보인다.

이 관계는 root에서 실행된 sshd(6884)가  taeho에서 실행되는 sshd(8111)을 실행(또는 fork)하고  그 sshd(8111)가 bash(8112)를 실행했음을 알 수 있다. 그리고 마지막으로 실행된 bash가 앞 cmd 화면에서 보이는 $ 프롬프트를 표시해준 것이다.

즉 sshd 프로세스는 사용자와 직접 대화하지 않는 백그라운드 프로세스임을 알 수 있다. 그리고 마지막에 실행된 bash는 사용자와 대화하기 위해 $ 프롬프트를 보여주고 키보드로부터 입력을 기다리고 있으므로 포그라운드(foreground) 프로세스이다.

그렇다면 데몬(daemon) 프로세스란 ?

지금까지는 포그라운드 프로세스와 백그라운드 프로세스에 대해 설명했다. 그렇다면 데몬프로세스란 무엇일까?

결론부터 이야기하자면 데몬 프로세스란 백그라운드 프로세스 중에서 부모프로세스(PPID)가 1 혹은 다른 데몬프로세스인 프로세스를 말한다.

여기서 또 하나의 궁금증이 생긴다. 그렇다면 데몬 프로세스도 백그라운드 프로세스 중 하나인데 일반적인 백그라운드 프로세스와 부모프로세스가 1이거나 다른 데몬프로세스인 백그라운드 프로세스와 무엇이 다른가 하는 것이다.

그 차이는 바로 프로세스를 실행한 bash가 종료되었을 때 bash를 통해 실행한 다른 백그라운드 프로세스가 함께 종료되는가 아닌가이다.

역시 화면을 보자.

이 화면은 포그라운드 프로세스의 대명사인 vi 라는 문서편집기를 강제로 백그라운드로 실행시킨 화면이다. 명령어를 실행할 때 맨 뒤에 & (앰퍼샌드) 기로를 붙이면 해당 명령어는 백그라운드로 실행된다. 즉 표준입력인 pts와 tty가 vi 프로세스와 끊겨 vi를 통해 편집이 불가능해진다.

어쨌든 vi는 화면에서 사라지고 백그라운드에 실행중이다. 이 것은 다른 ssh 접속 후 ps 명령을 통해 확인할 수 있다.

ps 명령으로 해당 프로세스를 찾아보면 bash(8290)을 부모프로세스로 갖는 vi(8314)가 실행중임을 알 수 있다. 하지만 실제 작업은 할 수 없으며 q! 와 같은 명령을 입력해 vi를 종료할 수도 없다.

여기서 ssh 접속을 끊으면 고아가 되어버린 vi 는 어떻게 될까? 앞에서 설명했듯 비록 백그라운드로 실행중이지만 exit 명령을 통해 ssh 접속을 끊으면 bash(8290)과 bash(8290)을 ppid 로 갖는 8314는 자동으로 종료된다.

exit로 ssh 접속을 끊는다.

vim이 죽으라는 HUP 시그널을 받았음을 화면에 표시한다. 즉 vim의 부모프로세스인 bash가 스스로를 종료하면서 자식프로세스인 vim에게 “너도 죽어!!”라고 HUP 시그널을 보낸 것이다. 그리고 Connection이 종료되었음을 알린다.

그렇다면 실제로 vi 프로세스가 종료되었는지 ps 명령으로 확인해 본다.

원래 있던 자리에 taeho 계정으로 실행중이던 vi 프로세스가 없음을 알 수 있다. ssh에서 exit 명령으로 로그아웃 하자 taeho 계정으로 실행되던 sshd, bash, vi가 자동으로 종료된 것이다.

즉 이 sshd, bash, vi는 백그라운드 프로세스로 실행되었지만 데몬(daemon)이 된 것은 아니다. 데몬이 되기 위해서는 백그라운드 프로세스가 부모프로세스로 1 혹은 다른 데몬 프로세스를 가져야 한다.

대표적인 데몬 프로세스 (웹서버)

가장 대표적인 데몬 프로세스는 웹서버 데몬이다. 웹서버 데몬 프로세스는 서버에서 터미널을 통해 실행될 수 있지만 tty 또는 pts 등 터미널을 통해 사용자와 대화할 필요가 없기 때문에 백그라운드 프로세스로 생성하도록 만들어져 있다.

즉 프로그램의 소스 안에서 fork() 함수를 통해 자식을 생성하고 부모는 죽는다. 그리고 생성된 자식은 부모프로세스를 1 (init) 로 변경한 뒤 실제로 서비스를 수행할 자식(손자에 해당)프로세스를 여러개 fork() 한다. 그리고 그 자식(손자) 프로세스들은 계정을 setuid() 함수를 이용해 웹서버가 실행되도록 설정된 계정으로 바꾼다. (실제로는 과정이 조금 다를 수도 있음)

그 결과 다음과 같이 프로세스가 생성된다.

httpd(8064)는 PPID(부모프로세스ID)가 1 이다. 그리고 실행된 계정은 root 이다. 이는 웹서버를 root 계정에서 실행시키기 때문이다. 그 이유는 TCP 1024 포트 이하는 root 에서만 Binding이 가능하기 때문이다.

그리고 PPID를 8064로 갖는 httpd 프로세스가 5개가 있고 그 계정은 실행계정이 apache 임을 알 수 있다. root가 아니고 apache로 변경한 이유는 보안상의 이유다. PPID가 1 인 httpd는 실제로 웹브라우저의 요청을 처리하는 웹서버 데몬이 아니다. 사용자의 접속이 많아 웹서버 대몬이 더 이상 사용자의 접속 요청을 처리할 수 없을 때 자식을 포크(fork)해주는 역할만 수행한다. 실제로 웹브라우저의 요청을 처리하는 웹서버 데몬은 apache 계정이 실행계정으로 되어 있는 나머지 5개의 웹서버 데몬이다.

이는 만약 root 계정으로 실행중인 웹서버가 해킹을 당하는 상황을 가정하면 해커는 곧바로 서버의 관리자 권한인 root 권한을 획득하는 것이 된다. 이런 상황은 매우 치명적인 상황을 유발할 수 있기 때문에 실제 서비스를 수행하는 웹서버 데몬은 apache 계정으로 실행하도록 만들어져 있는 것이다.

이렇게 PPID가 1 인 httpd 프로세스와 PPID가 1인 프로세스를 PPID로 갖는 5개의 httpd 프로세스가 바로 데몬(daemon) 프로세스다.

이 데몬프로세스들은 로그인한 ssh 세션에서 exit로 로그아웃 하더라도 종료되지 않고 웹 서비스를 제공하게 된다.

#데몬프로세스 #daemon #fork #ppid #부모프로세스ID

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

Scroll to Top