데일 하그 룬드가 등장했습니다. 그래서 나는 똑같은 말을하지만 다른 구체적인 방법과 예를 들겠습니다. ☺
유닉스와 리눅스 세계에서해야 할 올바른 일은 :
- 수퍼 유저로서 실행되고 청취 소켓을 바인딩하는 작고 간단하며 쉽게 감사 할 수있는 프로그램이 있어야합니다.
- 첫 번째 프로그램에 의해 생성 된 권한을 삭제하는 또 다른 작고 간단하며 쉽게 감사 할 수있는 프로그램을 갖추어야합니다.
- 별도의 세 번째 프로그램 에서 서비스의 핵심을 수퍼 유저가 아닌 계정으로 실행하고 두 번째 프로그램에 의해로드 된 체인을 사용하여 소켓에 대한 열린 파일 설명자를 간단히 상속해야합니다.
높은 위험이 어디에 있는지 잘못 알고 있습니다. 높은 위험은 네트워크 에서 읽고 소켓을 열고 포트에 바인딩 한 다음 호출하는 간단한 동작으로 읽지 않은 내용을 처리하는 것 listen()
입니다. 위험이 높은 실제 통신을 수행하는 서비스의 일부입니다. bind()
, 및 listen()
, 심지어는 어느 정도까지 개방 된 부분은 accepts()
위험이 높지 않으며 수퍼 유저의 요구에 따라 실행될 수 있습니다. accept()
네트워크를 통해 신뢰할 수없는 낯선 사람이 제어하는 데이터를 사용하지 않습니다 (소스 IP 주소 제외 ).
이를 수행하는 방법에는 여러 가지가 있습니다.
inetd
데일 해글 런드 (Dale Hagglund)가 말했듯이, 오래된 "네트워크 슈퍼 서버" inetd
가이를 수행합니다. 서비스 프로세스가 실행되는 계정은의 열 중 하나입니다 inetd.conf
. 청취 부분과 삭제 권한 부분을 작고 쉽게 감사 할 수있는 두 개의 개별 프로그램으로 분리하지는 않지만 주 서비스 코드를 별도의 프로그램으로 분리 exec()
합니다 (서비스 프로세스에서 열린 파일 디스크립터로 생성됨) 소켓.
하나의 프로그램 만 감사하면되기 때문에 감사의 어려움은 그리 큰 문제가되지 않습니다. inetd
주요 문제는 너무 많은 감사가 아니라 최신 도구와 비교할 때 간단한 세분화 된 런타임 서비스 제어를 제공하지 않는 것입니다.
UCSPI-TCP 및 데몬 툴
Daniel J. Bernstein의 UCSPI-TCP 및 daemontools 패키지는이를 함께 수행하도록 설계되었습니다. 대안으로 Bruce Guenter의 대체로 동일한 daemontools-encore 도구 세트를 사용할 수 있습니다 .
소켓 파일 디스크립터를 열고 특권 로컬 포트에 바인드하는 프로그램 tcpserver
은 UCSPI-TCP의 것입니다. 와를 모두 수행 listen()
합니다 accept()
.
tcpserver
그런 다음 루트 권한 자체를 삭제하는 서비스 프로그램을 생성합니다 (서비스중인 프로토콜이 수퍼 유저로 시작한 다음 FTP 또는 SSH 데몬의 경우와 같이 "로그온"하기 때문에) setuidgid
. 자체적으로 포함 된 작고 쉽게 감사 할 수있는 프로그램으로, 권한을 떨어 뜨린 다음 서비스 프로그램에로드를 적절하게 연결합니다 (이와 같이 어떤 부분도 수퍼 유저 권한으로 실행되지 않습니다 qmail-smtpd
).
따라서 서비스 run
스크립트는 다음과 같습니다 (이것은 null IDENT 서비스를 제공 하기 위해 더미 ID 를 위한 것임 ).
#!/bin/sh -e
exec 2>&1
exec \
tcpserver 0 113 \
setuidgid nobody \
dummyidentd.pl
으악
내 nosh 패키지 는이 작업을 수행하도록 설계되었습니다. setuidgid
다른 것과 마찬가지로 작은 유틸리티가 있습니다. 하나 개 약간의 차이는 그것이로 사용할 수 있다는 것입니다 systemd
전통 그래서 스타일 "LISTEN_FDS"서비스뿐만 아니라와 UCSPI - TCP 서비스 tcpserver
프로그램은 두 개의 별도의 프로그램으로 대체됩니다 : tcp-socket-listen
와 tcp-socket-accept
.
다시 한 번, 다목적 유틸리티가 생성되고 체인이로드됩니다. 디자인의 흥미로운 점 중 하나는 listen()
심지어 그 이후에도 슈퍼 유저 권한을 떨어 뜨릴 수 있다는 것 accept()
입니다. 그에 대한 run
스크립트는 다음과 같습니다 qmail-smtpd
.
#!/bin/nosh
fdmove -c 2 1
clearenv --keep-path --keep-locale
envdir env/
softlimit -m 70000000
tcp-socket-listen --combine4and6 --backlog 2 ::0 smtp
setuidgid qmaild
sh -c 'exec \
tcp-socket-accept -v -l "${LOCAL:-0}" -c "${MAXSMTPD:-1}" \
ucspi-socket-rules-check \
qmail-smtpd \
'
수퍼 유저의 후원으로 실행 프로그램은 작은 서비스에 얽매이지 체인 로딩 도구 fdmove
, clearenv
, envdir
, softlimit
, tcp-socket-listen
,와 setuidgid
. 점으로 sh
시작, 소켓은 개방과 결합하지 smtp
포트, 프로세스는 더 이상 수퍼 유저 권한을가집니다.
s6, s6-networking 및 execline
Laurent Bercot의 s6 및 s6 네트워킹 패키지는이 작업을 함께 수행하도록 설계되었습니다. 명령은 daemontools
UCSPI-TCP 의 명령과 구조적으로 매우 유사합니다 .
run
스크립트는 s6-tcpserver
for tcpserver
및 s6-setuidgid
for를 대체하는 것을 제외하고는 거의 동일 합니다 setuidgid
. 그러나 M. Bercot의 execline 툴셋을 동시에 사용하도록 선택할 수도 있습니다 .
다음은 Wayne Marshall의 원본 에서 약간 수정 된 execline, s6, s6-networking 및 publicfile 의 FTP 서버 프로그램을 사용 하는 FTP 서비스의 예입니다 .
#!/command/execlineb -PW
multisubstitute {
define CONLIMIT 41
define FTP_ARCHIVE "/var/public/ftp"
}
fdmove -c 2 1
s6-envuidgid pubftp
s6-softlimit -o25 -d250000
s6-tcpserver -vDRH -l0 -b50 -c ${CONLIMIT} -B '220 Features: a p .' 0 21
ftpd ${FTP_ARCHIVE}
ipsvd
Gerrit Pape의 ipsvd 는 ucspi-tcp 및 s6-networking과 동일한 라인을 따라 실행되는 또 다른 툴셋입니다. 도구는 현재 chpst
와 tcpsvd
동일하지만 동일한 작업을 수행하며 신뢰할 수없는 클라이언트가 네트워크를 통해 전송 한 내용을 읽고 처리하고 작성하는 고위험 코드는 여전히 별도의 프로그램에 있습니다.
여기 M. 파페의 예를 실행하는 fnord
A의 run
스크립트 :
#!/bin/sh
exec 2>&1
cd /public/10.0.5.4
exec \
chpst -m300000 -Uwwwuser \
tcpsvd -v 10.0.5.4 443 sslio -v -unobody -//etc/fnord/jail -C./cert.pem \
fnord
systemd
systemd
일부 리눅스 배포판에서 찾을 수있는 새로운 서비스 감독 및 초기화 시스템은 일을하기위한 것입니다 inetd
할 수 있습니다 . 그러나 작은 자체 포함 된 프로그램 제품군을 사용하지 않습니다. systemd
불행히도 전체 감사 를해야합니다.
로 systemd
하나의 소켓 정의 구성 파일을 생성 systemd
수신 대기하고 서비스를 systemd
시작합니다. 서비스 "단위"파일에는 실행중인 사용자를 포함하여 서비스 프로세스를 크게 제어 할 수있는 설정이 있습니다.
해당 사용자가 수퍼 유저가 아닌 사용자로 설정 systemd
되면 소켓을 열고 포트에 바인딩 한 다음 프로세스 # 1에서 수퍼 유저로 호출하고 listen()
(필요한 경우 accept()
) 작업을 수행합니다. 스폰은 수퍼 유저 권한없이 실행됩니다.