내 응용 프로그램을 처음부터 낮은 수준에서 실행할 수있는 경우 보안을 위해 샌드 박싱을 사용하는 이유는 무엇입니까?


14

C로 HTTP 서버 데몬을 작성하고 있습니다 (이유가 있음). 시스템 단위 파일로 관리합니다.

저는 1995 년 경에 20 년 전에 디자인 된 응용 프로그램을 다시 작성하고 있습니다. 그리고 그들이 사용하는 시스템은 chroot와 setuid 및 표준 절차입니다.

이전 작업에서 일반적인 정책은 프로세스를 루트로 실행하지 않는 것입니다. 사용자 / 그룹을 생성하고 거기서 실행합니다. 물론, 시스템은 일부를 루트로 실행했지만 루트가 아닌 모든 비즈니스 로직 처리를 달성 할 수있었습니다.

이제 HTTP 데몬의 경우 응용 프로그램 내부에서 chroot하지 않으면 루트없이 실행할 수 있습니다. 응용 프로그램이 루트로 실행되지 않는 것이 더 안전하지 않습니까?

처음부터 mydaemon 사용자로 실행하는 것이 더 안전하지 않습니까? 루트로 시작하는 대신 chrooting, myuimon-user로 setuid?


3
포트 80 또는 443을 사용하려면 루트로 실행해야합니다. 그렇지 않으면 tomcat을 수행하고 다른 webapp / web-server 소프트웨어가 더 높은 포트 (예 : 8080, 9090 등)를 수행 한 후 다음 중 하나를 사용하십시오. apache / nginx를 사용하여 웹 서버 소프트웨어에 대한 연결을 프록시하거나 시스템의 방화벽을 사용하여 포트 80에서 웹 서버로 트래픽을 NAT / 전달합니다. 포트 80 또는 443이 필요하지 않거나 연결을 프록시 또는 전달할 수있는 경우, 그런 다음 chroot 또는 다른 방법으로 루트로 실행할 필요가 없습니다.
SnakeDoc

3
Linux의 @SnakeDoc은 더 이상 사실이 아닙니다. 감사합니다 capabilities(7).
0xC0000022L

@SnakeDoc 당신이 사용할 수있는 authbind 뿐만 아니라
압둘 Ahad

답변:


27

다른 사람들이 당신의 요점을 놓친 것 같습니다. 왜냐하면 변경 된 뿌리를 사용하는 이유, 물론 당신이 이미 이미 알고있는 것, 또는 당신이 aæides에서 달리는 것에 대해 명확하게 알고있을 때, 당신은 dæmons에 제한을두기 위해 할 수있는 다른 것이 아닙니다. 권한이없는 사용자 계정; 그러나 왜 응용 프로그램 내 에서이 작업을 수행해야합니까 ? 실제로 그 이유에 대한 예가 상당히 있습니다.

httpdDaniel J. Bernstein의 공개 파일 패키지에있는 dæmon 프로그램 의 디자인을 고려하십시오 . 가장 먼저하는 일은 루트를 명령 인수와 함께 사용하도록 지시 된 루트 디렉토리로 변경 한 다음 두 환경 변수에 전달 된 권한이없는 사용자 ID 및 그룹 ID에 대한 권한을 삭제하는 것입니다.

Dæmon 관리 도구 세트에는 루트 디렉토리 변경 및 권한이없는 사용자 및 그룹 ID 로의 드롭과 같은 전용 도구가 있습니다. Gerrit Pape의 runit은 chpst. 내 nosh 툴셋에는 chroot및이 setuidgid-fromenv있습니다. Laurent Bercot의 s6에는 s6-chroot및이 s6-setuidgid있습니다. 웨인 마샬의 Perp는 runtoolrunuid. 기타 등등. 실제로, 그들은 모두 setuidgid선행사로서 M. 번스타인의 데몬 툴 툴셋을 가지고 있습니다.

httpd그러한 전용 툴 에서 기능을 추출하여 사용할 수 있다고 생각할 것입니다 . 그런 다음 구상 할 때 서버 프로그램의 어떤 부분도 수퍼 유저 권한으로 실행 되지 않습니다 .

문제는 직접적인 결과로서 변경된 루트를 설정하기 위해 훨씬 더 많은 작업을 수행해야하며, 이는 새로운 문제를 노출 시킨다는 것입니다.

Bernstein 이있는 상태에서 루트 디렉토리 트리에 httpd있는 유일한 파일과 디렉토리는 세계에 공개 될 것입니다. 나무 에는 전혀 아무것도 없습니다 . 또한, 대한 이유가 없다 어떤 실행 프로그램 이미지 파일이 그 나무에 존재하는.

그러나 체인 로딩 프로그램 (또는 systemd)로 루트 디렉토리 변경을 이동에 갑자기 프로그램 이미지 파일 httpd, 어떤 공유 라이브러리 그것은 그 부하 및 특수 파일 /etc, /run/dev프로그램 로더 또는 C 라이브러리 액세스 런타임 것을 프로그램을 초기화하는 동안 (당신이 truss/ straceC 또는 C ++ 프로그램 이라면 상당히 놀랄 수도 있습니다 ), 변경된 루트에 있어야합니다. 그렇지 않으면 httpd연결할 수 없으며로드 / 실행되지 않습니다.

이 서버는 HTTP (S) 컨텐츠 서버입니다. 변경된 루트에서 (세계가 읽을 수있는) 파일을 제공 할 수 있습니다. 여기에는 공유 라이브러리, 프로그램 로더 및 운영 체제에 대한 다양한 로더 / CRTL 구성 파일 사본이 포함됩니다. 그리고 일부 (우연한) 컨텐츠 서버가 쓰기 작업에 액세스 할 수있는 경우 손상된 서버가 httpd자체적으로 또는 시스템의 프로그램 로더에 대한 프로그램 이미지에 대한 쓰기 액세스 권한을 얻을 수 있습니다 . (지금의 두 개의 평행 한 세트가 기억 /usr, /lib, /etc, /run, 및 /dev디렉토리 보안을 유지하기를.)

httpd루트를 변경하고 권한 자체를 삭제 하는 경우는 없습니다.

따라서 감사하기 쉽고 httpd프로그램 시작시 바로 실행되는 수퍼 유저 권한으로 실행되는 소량의 권한있는 코드를 거래했습니다 . 변경된 루트 내에서 파일 및 디렉토리의 공격 영역이 크게 확장되었습니다.

이것이 서비스 프로그램 외부에서 모든 것을 수행하는 것만 큼 간단하지 않은 이유입니다.

그럼에도 불구하고 이것은 httpd그 자체의 최소한의 기능 입니다. 예를 들면 처음에 그 환경 변수에 넣어 사용자 ID 및 그룹 ID에 대한 운영 체제의 계정 데이터베이스의 모습으로 일을 수행하는 코드의 모든 입니다 받는 외부 httpd와 같은 간단한 독립 감사 명령에 프로그램 envuidgid. (이 코드의 어느 것도 관련 TCP 포트 (들) 또는 연결을 허용하는 방법에 듣지을 포함, 그래서 물론 그것은 UCSPI 도구입니다 같은 명령의 도메인 인 그 tcpserver, tcp-socket-listen, tcp-socket-accept, s6-tcpserver4-socketbinder, s6-tcpserver4d, 등.)

추가 자료


+1, 유죄 판결. 제목과 마지막 단락이 모호한 것을 발견했으며 옳다면 요점을 놓쳤습니다. 이 답변은 매우 실용적인 해석을 제공합니다. 개인적으로 나는 이와 같은 chroot 환경을 구축하는 것이 대부분의 사람들이 피하고 싶어하는 추가 노력이라는 것을 분명히 지적합니다. 그러나 여기 2 개의 보안 포인트는 이미 잘 만들어졌습니다.
sourcejedi

기억해야 할 또 다른 점은 서버가 네트워크 트래픽을 처리하기 전에 권한을 삭제하면 권한있는 코드가 원격 익스플로잇에 노출되지 않는다는 것입니다.
kasperd

5

귀하의 질문에 대한 많은 세부 사항이 avahi-daemon최근에 살펴본 것과 동일하게 적용될 수 있다고 생각합니다 . (나는 다른 세부 사항을 놓쳤을 수도 있습니다). chroot에서 avahi-daemon을 실행하면 avahi-daemon이 손상된 경우 많은 이점이 있습니다. 여기에는 다음이 포함됩니다.

  1. 사용자 홈 디렉토리를 읽고 개인 정보를 유출 할 수 없습니다.
  2. / tmp에 쓰면 다른 프로그램의 버그를 악용 할 수 없습니다. 그러한 버그에는 적어도 하나의 전체 범주가 있습니다. 예 : https://www.google.co.uk/search?q=tmp+race+security+bug
  3. chroot 외부에있는 유닉스 소켓 파일을 열 수 없으며, 다른 데몬이 메시지를 듣고 읽습니다.

포인트 3은 dbus 또는 이와 유사한 것을 사용 하지 않을 때 특히 좋을 수 있습니다 ... avahi-daemon은 dbus를 사용한다고 생각하므로 chroot 내부에서도 시스템 dbus에 액세스 할 수 있습니다. 시스템 dbus에서 메시지를 보낼 수있는 기능이 필요하지 않은 경우 해당 기능을 거부하면 매우 유용한 보안 기능이 될 수 있습니다.

시스템 단위 파일로 관리

avahi-daemon을 다시 쓰면 보안을 위해 systemd에 의존하고 예를 들어 사용할 수 있습니다 ProtectHome. chroot에서 보장하지 않는 추가 보호와 함께 이러한 보호를 추가 계층으로 추가하기 위해 avahi-daemon으로 변경을 제안했습니다. 여기에서 제안한 전체 옵션 목록을 볼 수 있습니다.

https://github.com/lathiat/avahi/pull/181/commits/67a7b10049c58d6afeebdc64ffd2023c5a93d49a

avahi-daemon이 chroot 자체를 사용 하지 않은 경우 사용할 수있는 더 많은 제한이있는 것처럼 보입니다 . 일부는 커밋 메시지에 언급되어 있습니다. 이것이 얼마나 적용되는지 잘 모르겠습니다.

내가 사용한 보호 기능은 데몬이 유닉스 소켓 파일을 여는 것을 제한하지 않았습니다 (위의 3 지점).

또 다른 방법은 SELinux를 사용하는 것입니다. 그러나 응용 프로그램을 Linux 하위 집합의 하위 집합에 연결하는 것이 좋습니다. SELinux를 긍정적으로 생각한 이유는 SELinux가 프로세스가 dbus에 대한 액세스를 세밀하게 제한하기 때문입니다. 예를 들어, systemd메시지를 :-)에 보낼 수 있어야하는 버스 이름 목록에 없을 것이라고 생각할 수 있습니다.

"시스템화 된 샌드 박스를 사용하는 것이 chroot / setuid / umask / ...보다 더 안전한지 궁금합니다."

요약 : 왜 둘 다? 위의 비트를 해독합시다 :-).

포인트 3에 대해 생각하면 chroot를 사용하면 더 많은 감금이 제공됩니다. ProtectHome =과 그 친구들도 chroot만큼 제한적이지 않습니다. (예를 들어, /run유닉스 소켓 파일을 넣는 경향이 있는 명명 된 systemd 옵션 blacklists는 없습니다 ).

chroot는 파일 시스템 액세스를 제한하는 것이 매우 강력 할 수 있지만 Linux의 모든 파일이 파일 인 것은 아닙니다 :-). 파일이 아닌 다른 것을 제한 할 수있는 시스템 옵션이 있습니다. 프로그램이 손상된 경우 유용합니다. 사용 가능한 커널 기능을 줄여 취약점을 악용하려고 시도 할 수 있습니다. 예를 들어 avahi-daemon에는 블루투스 소켓이 필요하지 않으며 웹 서버도 필요하지 않은 것 같습니다. :-). 따라서 AF_BLUETOOTH 주소 패밀리에 대한 액세스 권한을 부여하지 마십시오. RestrictAddressFamilies=옵션을 사용하여 AF_INET, AF_INET6 및 아마도 AF_UNIX를 화이트리스트에 추가하십시오.

사용하는 각 옵션에 대한 문서를 읽으십시오. 일부 옵션은 다른 옵션과 함께 사용하면 더욱 효과적이며 일부는 모든 CPU 아키텍처에서 사용할 수 없습니다. (CPU가 좋지 않기 때문이 아니라 해당 CPU의 Linux 포트가 잘 설계되지 않았기 때문입니다.)

(여기에는 일반적인 원칙이 있습니다. 거부하려는 것이 아니라 허용하려는 항목의 목록을 작성할 수 있으면 더 안전합니다. chroot를 정의하는 것처럼 액세스 할 수있는 파일 목록이 제공되므로 더욱 강력합니다. 차단하고 싶다고 말하는 것보다 /home).

원칙적으로 setuid () 전에 동일한 제한을 모두 적용 할 수 있습니다. 그것은 모두 systemd에서 복사 할 수있는 코드 일뿐입니다. 그러나 시스템 단위 옵션은 작성하기가 훨씬 쉬워야하며 표준 형식이기 때문에 읽고 검토하기가 쉬워야합니다.

따라서 man systemd.exec대상 플랫폼 의 샌드 박싱 섹션을 읽는 것이 좋습니다 . 그러나 가장 안전한 디자인을 원한다면 프로그램에서 시도 chroot하고 root권한 을 포기하는 것을 두려워하지 않을 입니다. 여기에 절충점이 있습니다. 를 사용하면 chroot전체 디자인에 약간의 제약이 따릅니다. chroot를 사용하는 디자인을 이미 가지고 있고 필요한 작업을 수행하는 것 같습니다.


특히 시스템 제안에 +1합니다.
mattdm

스택 오버 플로우가 여러 답변을 허용하면 ur도 받아 들일 것입니다. chroot / setuid / umask /보다 안전한 시스템 샌드 박스를 사용한다면 궁금합니다.
mur

@mur 다행이 :). 그것은 내 대답에 대한 매우 자연스러운 반응입니다. 그래서 다시 업데이트하여 귀하의 질문에 대답합니다.
sourcejedi 2016 년

1

systemd에 의존 할 수 있다면, 샌드 박싱을 systemd 상태로 두는 것이 실제로 더 안전하고 간단합니다! (물론, 응용 프로그램은 systemd에 의해 샌드 박스로 시작되었는지 여부를 감지 할 수 있으며 여전히 루트 인 경우 샌드 박스 자체입니다.) 설명하는 서비스와 동등한 것은 다음과 같습니다.

[Service]
ExecStart=/usr/local/bin/mydaemon
User=mydaemon-user
RootDirectory=...

그러나 우리는 거기서 멈출 필요가 없습니다. systemd는 또한 당신을 위해 다른 많은 샌드 박싱을 할 수 있습니다 – 여기 몇 가지 예가 있습니다 :

[Service]
# allocate separate /tmp and /var/tmp for the service
PrivateTmp=yes
# mount / (except for some subdirectories) read-only
ProtectSystem=strict
# empty /home, /root
ProtectHome=yes
# disable setuid and other privilege escalation mechanisms
NoNewPrivileges=yes
# separate network namespace with only loopback device
PrivateNetwork=yes
# only unix domain sockets (no inet, inet6, netlink, …)
RestrictAddressFamilies=AF_UNIX

man 5 systemd.exec더 많은 지시문과 자세한 설명을 참조하십시오 . 데몬을 소켓 활성화 가능 ( man 5 systemd.socket)으로 설정하면 네트워크 관련 옵션을 사용할 수도 있습니다. 서비스의 외부 세계로의 유일한 링크는 systemd에서 수신 한 네트워크 소켓이며 다른 어떤 것에도 연결할 수 없습니다. 일부 포트에서만 수신하고 다른 서버에 연결할 필요가없는 간단한 서버 인 경우 유용 할 수 있습니다. ( RootDirectory필자의 의견으로 는 파일 시스템 관련 옵션도 쓸모 없게 만들 수 있으므로 더 이상 필요한 모든 바이너리 및 라이브러리가 포함 된 새 루트 디렉토리를 설정하지 않아도됩니다.)

최신 시스템 버전 (v232 이후)도 지원합니다 DynamicUser=yes. 여기서 systemd는 서비스 런타임에 대해서만 서비스 사용자를 자동으로 할당합니다. 이 방법은 해당 서비스에 대한 영구적 인 사용자를 등록해야하고, 그 이외의 파일 시스템 위치에 기록하지 않는 긴 서비스 등으로 잘 작동하지 않는 StateDirectory, LogsDirectory그리고 CacheDirectory(당신은 또한 유닛 파일에 선언 할 수있는 - man 5 systemd.exec동적 시스템에 올바르게 할당하도록주의하면서 관리 할 시스템을 다시 참조하십시오 ).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.