PEP 466 – Python 2.7.x의 네트워크 보안 개선
- Author:
- Alyssa Coghlan <ncoghlan at gmail.com>
- Status:
- Final
- Type:
- Standards Track
- Created:
- 23-Mar-2014
- Python-Version:
- 2.7.9
- Post-History:
- 23-Mar-2014, 24-Mar-2014, 25-Mar-2014, 26-Mar-2014, 16-Apr-2014
- Resolution:
- Python-Dev message
Table of Contents
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
대부분의 CPython 트래커 이슈는 동작 오류 또는 제안된 개선 사항으로 분류됩니다. 동작 오류를 수정하는 대부분의 패치는 모든 활성 유지 관리 브랜치에 적용됩니다. 개선 패치는 다음 Python 버전이 되는 기본 브랜치로 제한됩니다.
이 주기는 Python의 일반적인 18~24개월 기능 릴리스 주기에서 상당히 잘 작동하며, 이는 여전히 Python 3 시리즈에 적용됩니다. 그러나 Python 2의 표준 라이브러리는 이제 네트워크 보안 프로토콜의 최신 수준에 비해 충분히 뒤처진 상태에 이르렀으므로, 가까운 시일 내에 Python 3으로 업그레이드하기 어려운 사용 사례에서 실제 문제를 일으키고 있습니다.
Python 2.7의 4년 이상에 걸친 유지 관리 주기 동안 발생한 추가적인 실무적 고려 사항을 반영하여, 이 PEP는 중요한 네트워크 보안 관련 기능 집합을 Python 3.4에서 향후 Python 2.7.x 유지 관리 릴리스로 백포트할 수 있도록 허용합니다.
이 PEP는 더 이상 활성 유지 관리되지 않는 보안 수정 전용 브랜치에 대한 핵심 개발 팀의 처리 방식을 변경하지는 않지만, does Python 표준 라이브러리에 장기 지원 기간을 제공하는 상업적 재배포 업체가 이러한 기능을 지원 대상 버전에 백포트하거나, 공용 인터넷에 직접 연결하는 역할에서 이전 버전을 사용하는 것에 대한 지원을 명시적으로 부인할 것을 권고합니다.
Python 2.7 유지 관리 릴리스의 새로운 보안 관련 기능
이 제안에 따라 다음 기능이 Python 3.4에서 향후 Python 2.7.x 유지 관리 릴리스로 백포트됩니다.
os모듈에서:os.urandom()에 대한 영속 파일 디스크립터입니다.
hmac모듈에서:- 일정 시간 비교 함수(
hmac.compare_digest())입니다.
- 일정 시간 비교 함수(
hashlib모듈에서:- 비밀번호 해싱 함수(
hashlib.pbkdf2_hmac())입니다. - 해시 알고리즘 사용 가능 여부에 대한 세부 정보(
hashlib.algorithms_guaranteed및hashlib.algorithms_available)입니다.
- 비밀번호 해싱 함수(
ssl모듈에서:- 이 모듈은 Python 3 대응 모듈과 거의 완전히 동기화되어 TLSv1.x 설정, SSLContext 조작, 서버 이름 표시, 플랫폼 인증서 저장소에 대한 액세스, 피어 호스트 이름 검증을 위한 표준 라이브러리 지원 등을 Python 2 시리즈에 제공합니다.
- 이 정책에 따라 백포트되지 않은 유일한
ssl모듈 기능은 OpenSSL의 난수 생성 기능에 대한 접근을 제공하는ssl.RAND_*함수입니다 - 대신os.urandom()을 사용하십시오.
유지 관리 정책의 일반적인 변경 사항으로, Python 2.7의 새로운 유지 관리 릴리스용 바이너리 설치 프로그램을 준비할 때 OpenSSL의 최신 기능 릴리스로 업그레이드하는 것도 허용됩니다.
이 PEP는 Python 2.7에 새로운 기능을 백포트하기 위한 일반적인 예외를 제안하지 않습니다. 백포트를 위해 제안되는 모든 새로운 기능은 여전히 독립적으로 정당화되어야 합니다. 특히 Python 패키지 색인에서 독립적으로 업데이트되는 백포트에 의존하는 것이 허용 가능한 해결책이 아닌 이유를 설명해야 합니다.
구현 상태
이 PEP는 원래 나열된 모든 기능을 Python 2.7.7 유지 관리 릴리스에 추가할 것을 제안했습니다. 그러나 PEP가 처음 작성된 시점과 승인된 시점 사이 및 Python 2.7.7rc1 릴리스까지의 기간이 제한적이었으므로, 이 접근 방식은 지나치게 야심 찬 것으로 판명되었습니다. 대신 승인된 각 기능 백포트의 진행 상황은 Python 2.7을 대상으로 하는 독립적인 개선 사항으로 추적되고 있습니다.
Python 2.7.7에 구현됨:
- Issue #21306:
hmac.compare_digest백포트 - Issue #21462: Python 2.7 Windows 설치 프로그램의 OpenSSL 업그레이드
Python 2.7.8에 구현됨:
- Issue #21304:
hashlib.pbkdf2를 백포트합니다
Python 2.7.9에 구현되었습니다(개발 중):
- Issue #21308: 지정된
ssl모듈 기능을 백포트합니다 - Issue #21307: 지정된 나머지
hashlib모듈 기능을 백포트합니다 - Issue #21305:
os.urandom공유 파일 디스크립터 변경 사항을 백포트합니다
하위 호환성 고려 사항
Python 3 계열에서와 마찬가지로, 백포트된 ssl.create_default_context() API에는 하위 호환성 예외가 부여되며, 이에 따라 유지 관리 릴리스에서 생성된 SSL 컨텍스트의 프로토콜, 옵션, 암호 및 기타 설정을 업데이트하여 더 높은 기본 보안 설정을 사용할 수 있습니다. 이를 통해 원래 기능 릴리스 시점이 아니라 유지 관리 릴리스 시점에 호환성과 보안의 균형을 적절하게 맞출 수 있습니다.
이 PEP는 유지 보수 릴리스에 대한 통상적인 하위 호환성 정책에 어떠한 추가 예외도 부여하지 않습니다. 대신 기능 기반 검사를 사용하도록 명시적으로 권장함으로써, 새 Python 2.7 유지 관리 릴리스로 업그레이드할 때 현재 작동하는 소프트웨어가 중단될 위험은 제한하면서 더욱 안전한 버전 간 호환 Python 소프트웨어를 쉽게 작성할 수 있도록 설계되었습니다.
이 제안이 Python 2.7 릴리스 계열에 새로운 기능을 백포트하도록 허용하는 모든 경우에, Python 버전을 명시적으로 검사하지 않고도 “기능 탐지”(예를 들어 모듈의 특정 속성을 검사함)로 작동하는 버전 간 호환 코드를 작성할 수 있습니다.
그런 다음 원하는 기능이 누락된 것으로 확인되면 적절한 경고와 대체 동작을 제공하는 것은 라이브러리 및 프레임워크 코드의 몫입니다. 특히 보안에 민감한 일부 소프트웨어는 원하는 보안 기능을 사용할 수 없을 경우 즉시 실패할 수도 있지만, 대부분의 소프트웨어는 대신 경고를 발생시키고 보안 구성이 약간 저하된 상태로 계속 작동해야 합니다.
백포트된 API를 사용하면 관련 네트워크 보안 기능의 존재를 감지한 후 라이브러리 및 애플리케이션 코드가 다음 작업을 수행할 수 있습니다:
- 더 안전한 설정을 명시적으로 선택합니다(보안 수준이 낮은 기본 동작을 사용하는 이전 Python 유지 관리 릴리스에서 향상된 보안 기능을 사용할 수 있도록 합니다)
- 덜 안전한 설정을 명시적으로 선택합니다(보안 수준이 낮은 환경에서 최신 Python 기능 릴리스를 사용할 수 있도록 합니다)
- 해당 기능의 기본 설정을 확인합니다(이를 위해 Python 기능 릴리스를 확인하는 명시적인 Python 버전 검사가 필요할 수 있지만, 특정 유지 관리 릴리스를 검사할 필요는 없습니다)
기타 모듈(상위 수준 네트워킹 라이브러리 및 데이터 형식 처리 라이브러리 등)에 대한 보안 관련 변경 사항은 Python 패키지 색인에서 백포트 및 새 모듈로 계속 제공됩니다. 변화하는 개발 요구 사항을 처리하기 위해 Python 2 표준 라이브러리와 독립적으로 계속 발전해야 하는 소프트웨어를 다루는 데 독립 배포가 여전히 선호되는 접근 방식이기 때문입니다. 안전한 네트워킹 인프라를 특별히 고려할 가치가 있게 만드는 특성을 검토하려면 Motivation and Rationale 섹션을 참조하십시오.
OpenSSL 호환성
이 제안에 따라 Python 2.7 유지 관리 릴리스에서 OpenSSL을 더 최신 기능 릴리스로 업그레이드할 수 있습니다. Linux 및 대부분의 기타 POSIX 시스템에서는 CPython이 기본적으로 시스템에서 제공하는 OpenSSL 라이브러리에 동적으로 링크하므로 사용되는 OpenSSL의 특정 버전이 이미 달라집니다.
Windows 바이너리 설치 프로그램의 경우 _ssl 및 _hashlib 모듈이 OpenSSL에 정적으로 링크되며 관련 기호는 내보내지지 않습니다. Marc-Andre Lemburg는 egenix-pyopenssl 바이너리에서 최신 OpenSSL 릴리스로 업데이트해도 보고된 호환성 문제가 발생하지 않았다고 밝혔습니다 [3]
Mac OS X 바이너리 설치 프로그램은 역사적으로 다른 POSIX 설치와 동일한 정책을 따랐으며 Apple이 제공하는 OpenSSL 라이브러리에 동적으로 링크되었습니다. 그러나 Apple은 이제 이러한 크로스 플랫폼 라이브러리의 업데이트를 중단하고, 대신 크로스 플랫폼 개발자조차 해당 플랫폼에서 최신 보안 인프라에 액세스하려면 Mac OS X 전용 인터페이스를 채택하도록 요구하고 있습니다. 따라서 이 PEP와는 독립적으로 Mac OS X 바이너리 설치 프로그램은 이미 더 최신 버전의 OpenSSL을 정적으로 링크하도록 전환될 예정이었습니다 [4]
기타 고려 사항
유지 관리 가능성
Alex Gaynor와 Donald Stufft를 비롯한 여러 개발자는 이 정책이 다루는 기능 백포트를 수행하고, 그 결과 Python 2 계열에서 발생하는 추가 유지 관리 부담을 지원하는 데 관심을 표명했습니다.
Steve Dower와 Brian Curtin은 Windows 설치 프로그램 제작을 돕겠다고 제안했으며, 이에 따라 Martin von Löwis는 2.7 Windows 설치 프로그램 유지 관리 업무에서 물러날 기회를 얻게 되었습니다.
이 PEP는 주로 그들이 이 작업을 수행하는 데 필요한 합의를 이끌어 내는 데 관한 것입니다. 다른 핵심 개발자들에게 이 정책 변경은 영향을 받는 모듈에 특별히 관심이 있는 개발자들의 결과 패치를 잠재적으로 검토하는 것 외에는 추가적인 노력을 요구하지 않아야 합니다.
보안 릴리스
이 PEP는 보안 릴리스 처리 방식에 어떠한 변경도 제안하지 않으며, 보안 릴리스는 앞으로도 중요한 보안 수정 사항만 포함하는 소스 전용 릴리스로 계속 제공됩니다.
그러나 라이브러리 및 애플리케이션 개발자를 위한 권고 사항은 보안 수정 전용 모드에 있거나 핵심 개발 팀에 의해 “수명 종료”로 선언된 추가 Python 릴리스 시리즈에 이러한 변경 사항을 적용하기로 선택한 상업적 재배포자를 수용하도록 의도적으로 설계되었습니다.
재배포자가 해당 선택지를 사용할지는 개별 재배포자에게 달려 있습니다.
통합 테스트
서드파티 통합 테스트 서비스는 사용자가 여러 Python 2.7 유지보수 릴리스(최소 2.7.6 및 2.7.7+)를 대상으로 테스트할 수 있는 기능을 제공해야 합니다. 이를 통해 이 제안에서 다루는 기능이 Python 2.7 시리즈로 백포트된 이후에도 라이브러리, 프레임워크 및 애플리케이션이 기존 보안 인프라의 처리를 올바르게 테스트할 수 있도록 해야 합니다(소프트웨어의 보안 민감도에 따라 실패하거나 정상적으로 성능을 저하하는 방식으로).
낮은 보안 환경과 낮은 위험 허용도에 대한 처리
좋든 나쁘든(대체로 나쁘지만), 유지보수 릴리스에서 회귀가 발생할 위험이 조금 증가하는 것보다 잠재된 보안 결함의 위험을 더 많이 감수하는 일부 환경이 존재합니다. 이 제안은 면제 대상 모듈과 관련하여 이러한 환경을 대부분 고려 대상에서 제외합니다. 공용 인터넷에 연결된 소프트웨어에는 이 접근 방식이 전혀 적절하지 않으며, 심층 방어 보안 원칙에 따르면 대부분의 사설 네트워크에도 적절하지 않습니다.
다운스트림 재배포자는 여전히 이러한 환경에 맞추기로 선택할 수 있지만, 보안 관련 모듈을 다운그레이드하고 관련 회귀 테스트를 수행하는 과정은 직접 처리해야 합니다. CPython의 주요 지속적 통합 인프라는 이 시나리오를 다루지 않습니다.
동기와 근거
이 PEP의 작성은 주로 Python 2 시리즈의 노후화된 SSL 지원으로 인해 촉발되었습니다. 2014년 3월 기준으로 Python 2.7 SSL 모듈은 출시된 지 4년에 가까워지고 있으며, 여전히 널리 사용되는 Python 2.6 릴리스의 SSL 지원은 6년 전에 기능 집합이 고정되었습니다.
이는 공용 인터넷을 통해 작동하는 보안 네트워킹 소프트웨어에 양심적으로 권고할 수 있는 기반을 제공하기에는 그저 너무 오래되었으며, 특히 고도화된 지속적 보안 위협이 이전에 파악된 것보다 훨씬 더 광범위하고 대상을 가리지 않고 확산되고 있다는 사실이 점점 더 명확해지는 시대에는 더욱 그렇습니다. 당시에는 합리적인 보안 인프라였지만 최신 기술 수준은 이미 발전했으며, 어떤 이유로든 현재 Python 3으로 마이그레이션할 수 없는 사용자를 위해 더 최신의 네트워크 보안 인프라를 효과적으로 제공할 방법을 조사해야 합니다.
Linux 플랫폼에서는 시스템 OpenSSL 설치를 사용하여 이러한 우려 중 상당수를 해결할 수 있지만 전부를 해결하지는 못합니다(특히 소프트웨어가 일부 더 높은 수준의 보안 설정을 명시적으로 요구하기가 여전히 어렵습니다). PyOpenSSL이나 Pycurl과 같은 서드파티 라이브러리를 사용하면 표준 라이브러리 지원을 우회할 수 있지만, 이러한 라이브러리는 배포하기 어려운 종속성일 수 있고 많은 사용자가 이를 필요로 할 수 있다는 사실을 알지 못하기 때문에 여전히 보안 문제가 발생합니다. 잠재적으로 순진한 사용자에게 이러한 라이브러리를 얻고 사용하는 방법을 설명하기보다는, 포함된 배터리를 바로 수정하는 편이 더 나아 보입니다.
python.org에 게시된 Windows 및 Mac OS X용 바이너리 설치 프로그램의 경우 사용되는 OpenSSL 버전은 전적으로 Python 핵심 개발 팀의 통제하에 있지만, 현재는 해당 Python 기능 릴리스와 함께 처음 제공된 버전에 대한 OpenSSL 유지보수 릴리스로 제한되어 있습니다.
인기가 높아지면 책임도 커지며, 이 제안은 Python의 인기와 채택도가 Python 개발 커뮤니티를 넘어서는 중대한 영향을 일부 설계 및 정책 결정이 미칠 만큼 충분히 높은 수준이라는 사실을 인정하는 것을 목표로 합니다.
한 가지 예로 Python 2 ssl 모듈은 서버 이름 표시(Server Name Indication) 표준을 지원하지 않습니다. 서드파티 requests 클라이언트 라이브러리를 사용하여 SNI 지원을 얻을 수는 있지만, 현재 실제로 그렇게 하려면 requests와 내장된 종속성뿐만 아니라 추가 라이브러리도 여섯 개 이상 사용해야 합니다. 따라서 Python 2 시리즈의 지원 부족은 서버에서 SNI를 효과적으로 사용하는 데 장애가 됩니다. Python 2 클라이언트가 이를 올바르게 처리하지 못하는 경우가 자주 발생하기 때문입니다.
또 다른 더 중요한 예는 Python 2 표준 라이브러리에 SSL 호스트 이름 매칭이 없다는 것입니다. Python 2에서 이 기능을 얻으려면 현재 requests 또는 backports.ssl_match_hostname과 같은 서드파티 라이브러리에 의존해야 합니다.
Python 2 시리즈에는 타이밍 공격에 강한 hmac.compare_digest() 함수와 동등한 표준 라이브러리 기능이 없으므로, 보안에 민감한 비교에 대한 원격 타이밍 공격에도 Python 3 시리즈보다 여전히 더 취약합니다. 적절한 보안 비교 함수는 서드파티 확장 기능으로 구현할 수 있지만, 많은 사용자는 이 문제를 전혀 고려하지 않고 대신 일반적인 동등성 비교를 사용합니다.
- 표준 라이브러리 솔루션이 그 문제를 자동으로 해결하지는 않지만,
문제가 지적되면 실제로 해결 장벽을 훨씬 낮추기는 does 합니다.
Python 2.7은 핵심 개발 팀이 제공한 유일한 장기 유지 보수 릴리스이며, 역사적으로 더 짧았던 유지 보수 기간 동안 작동했던 것들이 이처럼 더 긴 지원 기간에는 작동하지 않는 경우가 생기는 것은 자연스럽습니다. 이 PEP에서 설명하는 문제의 구체적인 경우에는, 기존 인터페이스의 하위 호환성을 유지하면서도 네트워크 보안 관련 모듈의 장기 유지 보수를 위해서는 새로운 기능을 추가할 수 있는 능력이 필요합니다.
이 내용에 익숙한 분이라면, 이 PEP에서 설명하는 접근 방식을 Red Hat이 장기 오픈 소스 지원 약정을 처리하는 방식과 비교해 볼 가치가 있습니다. 10년간 지원을 받는 것은 RHEL 6.0 릴리스 자체가 아니라 전체 RHEL 6 시리즈입니다. 이 시리즈에 속한 개별 RHEL 6.x 포인트 릴리스는 기존 소프트웨어에 대한 엄격한 하위 호환성 보장을 충족하면서 보안 향상을 포함한 매우 다양한 새로운 기능을 제공받습니다. 이 PEP에서 다루는 제안은 장기 유지 보수에 대한 우리의 접근 방식을 이러한 선례에 더욱 부합하도록 합니다. 엄격한 하위 호환성 요구 사항은 유지하되, 새로운 기능 추가 제한에 대해서는 예외를 둡니다.
현재까지 다운스트림 재배포자는 “Python 유지 보수 릴리스에는 새로운 기능을 추가하지 않는다”라는 업스트림 정책을 준수해 왔습니다. 이 PEP는 네트워크 보안 관련 기능의 경우 더 세분화된 정책이 적절하다는 점을 명시적으로 받아들이며, 여기서 설명하는 구체적인 변경 사항은 Red Hat Enterprise Linux와 그 다운스트림 파생판에 잠재적으로 적합하도록 의도적으로 설계되었습니다.
왜 이러한 변경 사항입니까?
이 제안에 포함할 기능을 고려하기 위한 핵심 요구 사항은 Python으로 작성된 특정 애플리케이션과 해당 애플리케이션이 실행되는 시스템을 넘어서는 보안 영향을 가져야 한다는 것이었습니다. 따라서 네트워크 보안 프로토콜, 암호 저장소 및 관련 암호화 인프라에 초점을 맞춥니다. Python은 웹 서비스와 클라이언트 개발에 널리 선택되므로, 널리 사용되는 Python 버전의 기능은 다른 서비스의 보안 설계에도 영향을 미칩니다. 이러한 서비스 자체는 더 최신 버전의 Python이나 다른 개발 언어를 사용할 수 있지만, 이전 버전의 Python으로 작성된 클라이언트 또는 서버와 상호 운용해야 할 수 있습니다.
이 요구 사항의 의도는 이 정책의 도입이 유지 보수 릴리스의 안정성과 호환성에 미칠 수 있는 영향을 최소화하면서도 Python 2.7의 특정 측면과 관련된 몇 가지 핵심 보안 문제를 해결하는 것이었습니다. 최종 사용자가 동일한 릴리스 시리즈 내의 새로운 기능 릴리스로 업데이트할 때만큼 새로운 Python 2.7 유지 보수 릴리스로 업데이트하는 데 신중해진다면 이는 매우 역효과를 낳을 것입니다.
ssl 모듈 변경 사항은 Python 2 시리즈를 지난 4년간의 네트워크 보안 표준 발전에 맞추고, 서버와 클라이언트 모두에서 이러한 표준이 광범위하게 채택되도록 쉽게 하기 위해 이 제안에 포함되었습니다. 마찬가지로 hashlib의 해시 알고리즘 가용성 표시자는 애플리케이션이 Python 2와 3 모두에서 적절한 해시 정의를 감지하고 사용할 수 있도록 하기 위해 포함되었습니다.
hmac.compare_digest()와 hashlib.pbkdf2_hmac()은 Python 2 서버 애플리케이션에서 안전한 암호 저장 및 검사를 더 쉽게 하도록 장벽을 낮추기 위해 포함되었습니다.
os.urandom() 변경 사항은 암호화 사용 사례에 필요한 고품질 난수 제공 작업을 운영 체제 공급업체에 맡기도록 사용자를 더욱 장려하기 위해 이 제안에 포함되었습니다. 충분히 무작위적이지 않은 난수를 사용하면 모든 암호화 시스템이 손상될 가능성이 있으며, 운영 체제 개발자는 일반적인 Python 애플리케이션 런타임보다 이 문제를 적절히 해결할 수 있는 도구를 더 많이 보유하고 있습니다.
거부된 대안: 개발자에게 Python 3으로 이전하도록 권고하십시오
이 대안은 현재의 상태를 나타냅니다. 안타깝게도 실제로는 실행 불가능한 것으로 드러났습니다. 하위 호환성의 영향으로 인해 대규모 애플리케이션과 통합 프로젝트에서 이는 간단하지 않은 마이그레이션 과정이 되기 때문입니다. 마이그레이션 도구는 한 번에 모두 처리하는 대신 코드를 Python 2와 Python 3의 넓은 공통 부분 집합에서 실행되도록 업데이트하여 대규모 애플리케이션도 기회가 있을 때 점진적으로 마이그레이션할 수 있는 수준까지 발전했지만, 상용 환경에서는 최신 기술을 사용하는 일이 우선순위가 아닌 경우가 많습니다.
이전에는 이를 감수할 수 있는 문제로 여겼습니다. 영향을 받는 개발자가 직면해야 하는 불행한 문제이기는 했지만, 인프라 현대화를 추진해야 한다고 관리 계층을 설득하는 것은 개발자와 관리 계층 사이의 문제로 보았으며, Python 3 시리즈가 발전함에 따라 이러한 주장은 자연스럽게 더욱 설득력을 얻을 것이기 때문입니다.
그러나 이제 Python 2 표준 라이브러리의 한계가 인터넷 보안 표준의 발전에 미칠 수 있는 영향을 충분히 인식하고 있으므로, Python 3에서 이미 제공되는 네트워크 보안 향상 기능에 접근하기 위해 플랫폼 및 애플리케이션 개발자가 오직 애플리케이션의 유니코드 정확성에 남아 있는 모든 결함을 해결할 것을 기대하는 것이 합리적이라고 더 이상 생각하지 않습니다.
Ubuntu(그리고 어느 정도 Debian도)는 모든 기본 시스템 서비스와 스크립트를 Python 3으로 포팅하고 기본 배포 이미지에서 Python 2를 제거하는 데 전념하고 있지만(아카이브에서는 제거하지 않음), 이는 막대한 작업이며 Ubuntu 14.04 LTS 릴리스까지 완료되지 않을 것입니다(적어도 데스크톱 이미지에서는 그렇고, 모바일 및 서버 이미지에서는 달성될 수도 있습니다).
Fedora는 마이그레이션을 위해 훨씬 더 많은 작업을 해야 하며, 관련 인프라 구성 요소를 마이그레이션하는 데 상당한 시간이 걸릴 것입니다. Red Hat도 안정적인 플랫폼에서 사용자가 더 최신 버전의 Python을 쉽게 사용할 수 있도록 적극적으로 작업하고 있지만, 이러한 노력이 최종 사용자의 버전 선택에 영향을 미치기 시작하려면 시간이 걸릴 것이며, 이러한 변경 사항은 필연적으로 통합 시스템 Python에서 실행되는 핵심 플랫폼 인프라에도 도움이 되지 않습니다.
OpenStack의 Python 3 마이그레이션도 아직 초기 단계이며, 광범위하고 비교적 견고한 자동화 테스트 스위트를 갖춘 프로젝트임에도 불구하고 Python 2/3 호환 코드베이스로 완전히 마이그레이션하는 데는 상당한 시간이 걸릴 만큼 규모가 큽니다.
그리고 이는 Python을 많이 사용하는 가장 유명한 오픈 소스 프로젝트 중 단 세 가지에 불과합니다. Python 2에서 Python 3으로의 마이그레이션을 지원하는 데 필요한 종류의 자동화된 회귀 테스트 스위트가 없는 레거시 코드가 대량으로 존재할 가능성을 고려하면, 마이그레이션보다 재구현(아마 Python 3으로 구현하는 경우에도)이 더 쉬운 사례가 많을 것입니다. 이 PEP의 핵심 요점은 이러한 상황이 영향을 받는 애플리케이션의 개발자와 사용자에게만 영향을 미치는 것이 아니라는 점입니다. 오래된 네트워크 보안 인프라를 갖춘 클라이언트와 서버가 존재하면, 보안 네트워크 서비스 개발자는 이를 보안 설계의 일부로 고려해야 하며, 이는 더 나은 보안 표준의 채택을 방해하는 문제가 됩니다.
Terry Reedy가 지적했듯이, 현재 상태를 고수하려 한다면 상용 재배포자가 고객을 대신하여 어쨌든 이와 비슷한 작업을 시도할 가능성이 높지만, 잠재적으로 일관되지 않고 임의적인 방식으로 진행될 것입니다. 범위 정의 프로세스를 업스트림 프로젝트에 포함하면 상황을 해결하기 위해 취하는 접근 방식에 영향을 미칠 수 있는 더 나은 위치에 서게 되며, 재배포자 간에 어느 정도 일관성을 확보하는 데도 도움이 됩니다.
문제가 실제로 존재하므로 something이 변경되어야 하며, 이 PEP에서는 이러한 상황에 대처하기 위한 제가 선호하는 접근 방식을 설명합니다.
거부된 대안: Python 2.8을 만들고 릴리스하기
충분한 기업 지원이 있다면 Python 2.8을 만들고 릴리스하는 것이 아마 가능할 것입니다(그러한 프로젝트가 자원봉사자만으로 달성 가능할 만큼 충분한 관심을 얻을 가능성은 매우 낮습니다). 그러나 이는 실제로 문제를 해결하지 못합니다. 목표는 Python 2를 사용하는 통합 제품과 배포 환경에 향상된 보안 기능을 도입하는, relatively low impact방식이기 때문입니다.
새로운 Python 기능 릴리스로 업그레이드하려면 핵심 개발 팀의 작업량이 늘어날 뿐만 아니라, 대부분의 잠재적인 최종 사용자가 아예 건너뛸 가능성이 높은 더욱 큰 영향을 미치는 업데이트가 필요합니다.
Python 2.8 릴리스를 만들려고 하면 Python 3의 여러 추가 기능(예: tracemalloc 및 개선된 코루틴 지원)을 백포트하자는 제안도 제기될 것이며, 이로 인해 Python 2.7에서 이 가상의 2.8 릴리스로 마이그레이션하는 일이 더욱 위험하고 큰 영향을 미치게 됩니다.
이는 권장되는 접근 방식이 아닙니다. 원래 목표인 Python 2 계열에서 노후화된 네트워크 보안 인프라가 현재 광범위하게 사용되는 상황을 없애는 데 실제로는 덜 효과적인 결과를 위해 상당한 추가 작업이 필요하기 때문입니다.
또한 Red Hat 플랫폼에서 이 문제를 실제로 해결하겠다고 약속할 수는 없지만, Python 2.8이 제가 이 문제를 해결하려고 시도하는 데 조금이라도 도움이 될 것이라는 생각만큼은 can단언하여 배제할 수 있습니다.
거부된 대안: PyPI를 통해 보안 향상 기능 배포하기
이는 처음에는 매력적이고 관리하기 쉬운 접근 방식처럼 보이지만, 실제로는 몇 가지 중대한 문제를 안고 있습니다.
첫째, 이는 다양한 POSIX 플랫폼(Mac OS X 포함)과 Windows에서 기본 운영 체제와 통합되는 복잡한 저수준 크로스 플랫폼 코드입니다. CPython BuildBot 팜은 이미 이러한 환경에서 지속적 통합을 처리하도록 설정되어 있지만, 무료로 이용할 수 있는 대부분의 지속적 통합 서비스는 Linux만 제공하며, Windows는 유료로 이용할 수 있을 뿐일 수 있습니다. 이러한 서비스는 대부분 Python 및 기타 동적 언어가 제공하는 추상화 계층에서 실행되는 소프트웨어와 JVM이 제공하는 더욱 포괄적인 추상화에서 실행되는 소프트웨어에는 상당히 잘 작동하지만, 여기에서 다루는 종류의 코드에는 충분하지 않습니다.
네트워크 보안 지원에 필요한 OpenSSL 의존성도 아직 pip 기반 소프트웨어 배포 생태계에서 제대로 처리되지 않는 종류의 “complex binary dependency”에 해당합니다. 서드파티 바이너리 의존성에 의존하면 pip를 PyPy와 같은 다른 인터프리터에서 실행할 때 잠재적인 호환성 문제가 발생합니다.
이 아이디어의 또 다른 실질적인 문제는 pip자체가 표준 라이브러리의 ssl 지원에 의존한다는 사실입니다(requests의 번들 사본에서 일부 추가 지원을 받으며, 이 사본은 다시 backport.ssl_match_hostname을 번들로 포함합니다). 따라서 모든 대체 모듈도 pip 안에 번들로 포함해야 합니다. 이는 극복할 수 없는 어려움을 초래하지는 않지만(벤더링해야 할 또 하나의 의존성일 뿐입니다), OpenSSL 사본을 하나 더 최신 상태로 유지해야 would한다는 의미입니다.
이 접근 방식에는 다른 모든 “improve security by renaming things” 접근 방식과 동일한 결함도 있습니다. 즉, 도움이 가장 필요한 사용자를 완전히 놓치고, 사용자의 인프라에서 지원할 때 올바른 일을 하도록 권장하는 데 상당한 장벽을 만듭니다(“use this other module”은 “turn on this higher security setting”보다 훨씬 큰 영향을 미치는 변경이기 때문입니다). 표준 라이브러리의 노후화된 SSL 인프라를 외부 모듈로 대체하기 위해 더 이상 사용되지 않는 것으로 지정하는 것은, 이를 현재 위치에서 업그레이드할 때 발생하는 회귀 위험이 약간 증가하는 것을 받아들이는 것보다 사용자에게 더욱 적대적일 것입니다.
마지막으로, 결코 덜 중요한 것은 아니지만, 이 접근 방식은 Python 2.8 릴리스를 만드는 아이디어와 동일한 문제를 안고 있습니다. 즉, 실제 문제를 해결하지 못할 가능성이 높습니다. Python의 상업적 재배포자는 Python과 기존의 추가 패키지 모음을 재배포하도록 구성되어 있습니다. 기존 패키지 모음에 새 패키지를 추가하는 작업은 can 수행할 수 있지만, 모든 재배포자에게 일일이 접근하여 그에 맞게 재패키징 프로세스를 업데이트해 달라고 요청해야 합니다. 이와 대조적으로 이 PEP에서 설명하는 접근 방식에서는 재배포자가 제공된 네트워크 보안 인프라를 의도적으로 다운그레이드하여 보안 향상 기능을 opt out하도록 해야 하며, 대부분의 재배포자는 그렇게 하지 않을 가능성이 높습니다.
거부된 변형: “legacy SSL infrastructure” 브랜치 제공하기
이 PEP의 이전 버전에는 Python 2.7.6 네트워크 보안 인프라의 기능 집합을 정확히 보존하는 2.7-legacy-ssl 브랜치라는 개념이 포함되어 있었습니다.
제 의견으로는 실제로 이를 원하는 사람은 거의 확실히 실수하고 있는 것이며, 특정 상황에서 정말로 이를 원한다고 고집한다면 직접 만들거나 다운스트림 재배포자가 대신 만들도록 마련해도 됩니다.
그러한 재빌드가 공개적으로 제공된다면, 더욱 최신 네트워크 보안 인프라를 포함하는 공식 Python 2.7 릴리스와 명확히 구별할 수 있도록 “Python 2.7 with Legacy SSL”이라고 불러야 합니다.
이 PEP를 구현하는 첫 번째 Python 2.7 유지보수 릴리스 이후에는 Python 2.7.6 및 이전 릴리스를 “Python 2.7 with Legacy SSL”이라고 부르는 것도 적절합니다.
거부된 변형: 특정 모듈을 Python 3과 완전히 동기화하기
이 PEP의 이전 버전에서는 hmac, hashlib 및 ssl 모듈을 Python 3의 대응 모듈과 완전히 동기화할 것을 제안했습니다.
이 접근 방식은 예외를 정당화하는 설득력 있는 근거를 구축하기에는 너무 모호한 것으로 드러났으며, 따라서 현재의 더욱 명시적인 제안으로 대체되었습니다.
거부된 변형: 제한 없는 백포트 정책
이 PEP의 이전 버전에서는 인터넷의 전반적인 보안에 영향을 미치는 향후 Python 3 개선 사항과 관련하여 일반적인 정책 변경을 제안했습니다.
이러한 접근 방식은 불필요한 불확실성을 초래했으므로, 구체적이고 명확한 변경 사항을 백포트하는 제안으로 단순화했습니다. 향후 기능 백포트 제안에서는 이 PEP를 선례로 참조할 수 있지만, Python 2.7 장기 지원 릴리스에 각 기능을 추가하는 것에 대해서는 여전히 구체적인 근거를 제시해야 합니다.
이해관계 공개입니다.
이 PEP의 작성자는 현재 Red Hat에서 테스트 자동화 도구를 개발하고 있습니다. 이 제안이 채택된다면, 그 결과로 생기는 기회를 Red Hat이 활용하여 Python 생태계의 전반적인 보안을 개선하도록 적극적으로 권장할 것입니다. 그러나 이 사안에서 Red Hat을 대표하여 발언하는 것은 아니며, Red Hat을 대신하여 어떠한 약속도 할 수 없습니다.
감사의 말입니다.
Python 3 계열에서 Python의 SSL 지원을 크게 개선하기 위해 노력한 Christian Heimes와 다른 분들께 감사드립니다. 또한 SSL 모듈에서 제공하는 기본 설정의 의미와, 2010년(Python 2.7) 또는 심지어 2008년(Python 2.6)에 정의된 SSL 인프라의 사용을 허용하는 것이 웹 전체의 보안에 미칠 수 있는 영향을 더 잘 이해하도록 도와주신 다양한 Python 커뮤니티 구성원들께도 감사드립니다.
Python 3.4의 모듈 전체를 백포트하는 것보다 이 제안을 더 세분화할 수 있도록 해 준, 보다 제한적인 필수 보안 기능 집합을 식별해 주신 Donald Stufft와 Alex Gaynor에게 감사드립니다 ([7], [8]).
Christian과 Donald는 이 제안의 예비 초안에 대해서도 귀중한 의견을 제공했습니다.
또한 python-dev 메일링 리스트 스레드의 참여자들 ([1], [2], [5], [6])과, 몬트리올에서 열린 PyCon 2014에서 이 사안에 관해 논의한 여러 분들께도 감사드립니다.
참고 문헌입니다.
Copyright
This document has been placed in the public domain.