1장. 소개

 

A wise man attacks the city of the mighty and pulls down the stronghold in which they trust.

 Proverbs 21:22 (NIV)

이 책은 리눅스와 유닉스 시스템에서 보안적인 프로그램을 작성하기 위한 일련의 설계 및 구현 지침들을 기술한다. 이 책의 목적을 위해 보안적인 (secure) 프로그램을 보안 경계에 존재하여 프로그램과 동일한 권한을 갖지 않는 출처로부터 입력을 받아들이는 프로그램으로 정의할 수 있는데 이들로는 원격 뷰어로 사용되는 애플리케이션 프로그램, CGI 스크립트를 포함한 웹 애플리케이션, 네트워크 서버와 setuid/setgid 프로그램들이 있다. 이 책에서 논의되는 원리들중 다수가 적용됨에도 불구하고 운영 체제의 커널 자체를 수정하는 것을 다루지는 않는다. 이 지침들은 저자가 추가한 의견과 함께 보안적인 프로그램들을 만드는 방법에 대한 다양한 출처들로부터 배운 교훈들을 조사함으로써 개발되었으며 일련의 더욱 커다란 원리들로 재구성되었다. 이 책은 C, C++, 자바, 펄, PHP, 파이썬, TCL 과 Ada95 를 포함한 많은 언어들에 대한 구체적인 안내를 포함한다.

이 책은 보증 조치, 소프트웨어 엔지니어링 프로세스와 품질 보증 방법을 다루지는 않는데 이는 중요하지만 다른 곳에 광범위하게 논의되어 있기 때문이다. 그러한 조치들로는 검사, 자세한 검토 (peer review), 설정 관리와 학문적인 (formal) 방법들이 있는데 보안 문제에 대한 일련의 발전하고 있는 보증 조치들을 명확하게 분간하는 문서들로는 Common Criteria [CC 1999] 와 System Security Engineering Capability Maturity Model [SSE-CMM 1999] 들이 있다. 일련의 더욱 일반적인 소프트웨어 엔지니어링 방법 또는 프로세스들은 Software Engineering Institute's Capability Maturity Model for Software (SE-CMM) [Paulk 1993a, 1993b] 과 ISO 12207 [ISO 12207] 과 같은 문서들내에 정의되어 있다. 품질 시스템에 대한 일반적인 국제적 표준은 ISO 9000 과 ISO 9001 [ISO 9000, 9001] 내에 정의되어 있다.

이 책은 주어진 환경에서 시스템 또는 네트워크를 보안적으로 설정하는 방법을 논의하지는 않는다. 이것이 주어진 프로그램을 보안적으로 사용하기 위해서는 분명히 필요하지만 매우 많은 다른 문서들이 보안적인 설정을 논의하고 있다. 유닉스 계열 시스템을 보안적으로 설정하는 방법에 대한 우수한 일반 책으로는 Garfinkel [1996] 이 있으며 유닉스 계열 시스템을 안전하게 하기 위한 다른 책으로는 Anonymous [1998] 가 있다. 또한 http://www.unixtools.com/security.html 와 같은 웹 사이트에서 유닉스 계열 시스템 설정에 관한 정보를 찾을 수 있다. 리눅스 시스템의 보안적 설정에 대한 정보는 Fenzi [1996], Seifried [1999], Wreski [1998], Swan [2001] 과 Anonymous [1999] 를 포함한 광범위한 문서들에서 얻을 수 있다. Geodsoft [2001] 은 OpenBSD 를 강화하는 방법을 기술하고 있는데 많은 제안들은 모든 유닉스 계열 시스템에 대해 유용하다. 리눅스 시스템 (결국 다른 유닉스 계열 시스템) 의 경우 리눅스 운영체제를 강화 또는 단련시키려고 하는 Bastille 강화 시스템의 검토를 원할 수도 있는데 이에 관해서는 http://www.bastille-linux.org 에서 더욱 많은 것을 배울 수 있다. 이는 GPL (General Public License) 라이센스로 무료로 얻을 수 있다. 윈도우 2000 의 경우는 Cox [2000] 을 살펴볼 수 있다.

컴퓨터를 설정하는 것은 바이러스에 어떻게 대처하는가, 어떤 종류의 조직상의 보안 정책이 필요한가, 사업의 연속성 계획 등을 포함하는 더욱 큰 영역인 보안 관리의 단지 일부분이다. 보안 관리를 위해 국제적 표준 및 길잡이 들이 있다. ISO 13335 는 보안 관리에 대한 길잡이 역할을 하는 다섯 부분으로 구성된 기술적 보고서이다 [ISO 13335]. 또한 ISO/IEC 17799:2000 은 실제 관례를 정의하고 있다 [ISO 17799]; 그 공표된 목적은 ``조직내에서 보안 발의, 구현 또는 유지하는 책임을 지는 사람들이 사용하도록 정보 보안 관리를 위한 권고를 주는 것이다" (대략적인 의미에서 이는 기술 문서는 아니다). ISO/IEC 17799:2000 이 매우 논의의 여지가 있음을 언급하는 것은 가치가 있다; 벨기에, 캐나다, 프랑스, 독일, 이탈리아, 일본과 미국은 이의 채택에 반대 투표를 했다. 이 논쟁에 대한 더욱 자세한 정보는 NIST 의 ISO/IEC 17799:2000 FAQ 를 보라. http://www.caspr.org 의 Commonly Accepted Security Practices & Recommendations (CASPR) 프로젝트는 정보 보안 지식에서 모든 사람이 사용할 수 있는 일련의 논문을 만들려고 하고 있다 (GNU FDL 라이센스하에서 함으로써 추후 파생 문서도 모든 사람이 계속 사용할 수 있을 것이다).

이 책은 독자가 일반적인 컴퓨터 보안 문제, 유닉스 계열 시스템의 일반적인 보안 모델, 네트워킹 (특히 TCP/IP 기반 네트워크) 과 C 프로그래밍 언어를 이해하고 있다고 가정하며 보안 목적의 리눅스와 유닉스 프로그래밍 모델에 대해 상당한 정보를 포함하고 있다. TCP/IP 기반 네트워크 및 프로토콜이 어떻게 작동하는지에 대한 더욱 자세한 (보안 프로토콜을 포함해) 정보가 필요하다면 [Murhammer 1998] 과 같은 TCP/IP 에 대한 일반적인 연구를 참고해라.

이 책은 리눅스 및 유닉스의 다양한 변형들을 포함한 모든 유닉스 계열 시스템들을 다루지만 특히 리눅스에 중점을 두어 명확하게 이에 대한 세부 사항들을 제공한다. 윈도우 CE 에 대해 명확하게 설명하는 약간의 자료들도 있지만 사실 이들중 많은 것들은 특정 운영 체제에 한정되어 있지 않다. 이 책에 포함되어 있지 않은 관련 정보를 알고 있다면 저자에게 알려주기 바란다.

이 책의 원본은 http://www.dwheeler.com/secure-programs 에서 찾을 수 있으며 http://www.linuxdoc.org 의 리눅스 문서화 프로젝트 (Linux Documentation Project, LDP) 의 한 부분으로 몇몇의 다른 사이트에서도 또한 미러링되고 있다. LDP 복사본 및/또는 각 배포 복사본을 포함한 이러한 복사본들이 원본보다 오래된 것일 수도 있음을 주목하기 바란다. 저자는 이 책에 대한 의견을 듣고 싶지만 반드시 여러분의 의견이 최신 버전에 대해 타당한지 검사한 후 의견을 보내주기 바란다.

이 책의 저작권은 1999-2001 David A. Wheeler 에 있으며 그 라이센스는 GNU Free Documentation License (GFDL) 이다; 더욱 자세한 정보는 부록 C부록 D 를 보라.

2장 은 유닉스, 리눅스 및 보안에 대한 배경을 논의하며 3장 은 프로세스, 파일시스템 객체 등의 보안 속성과 연산을 개괄적으로 설명하는데 일반적인 유닉스 및 리눅스 보안 모델을 기술한다. 다음 장에서는 이 책의 골자인 리눅스와 유닉스 시스템에서 애플리케이션을 개발하기 위한 일련의 설계 및 구현 지침들을 논의한다. 이 책은 11장에서 결론으로 매듭지으며 다음에 이 책에서 인용한 도서 목록과 부록이 나온다.

설계 및 구현 지침들은 저자가 믿기에 프로그래머의 관점에 중점을 둔 범주로 나누어진다. 그림 1-1 에 보이는 것과 같이 프로그램은 입력을 받고, 데이타를 처리하고, 다른 자원들을 호출하고 출력을 산출한다; 개념적으로 모든 보안 지침들은 이러한 범주들중 하나와 일치하는데 저자는 ``데이타 처리" 를 프로그램 내부 구조화하기와 접근 방법, 버퍼 오버플로우 피하기 (어떤 경우 입력 문제로 고려될 수 있다), 언어에 특정적인 정보와 특별 주제로 세분화하였다. 각 장들은 쉽게 따라갈 수 있도록 정리되었는데 따라서 지침들을 제공하는 각 장들은 모든 입력 유효화하기 (4장), 버퍼 오버플로우 피하기 (5장), 프로그램 내부 구조화하기 및 접근 방법 (6장), 주의깊게 다른 자원들 호출하기 (7장), 신중히 정보를 되돌려주기 (8장), 언어에 특정적인 정보 (9장) 그리고 난수 (random number) 를 얻는 방법과 같은 특별 주제에 대한 정보 (10장) 들을 논의한다.

그림 1-1. Abstract View of a Program

A program accepts inputs, processes data,
possibly calls out to other programs, and produces output.