웹 사이트의 비밀 값을 환경 변수로 사용하면 어떤 이점이 있습니까?


24

https://12factor.net/config 의 devops 지침 은 웹 사이트 비밀 (데이터베이스 암호, API 키 등)을 환경 변수에 넣도록 제안합니다. 버전 제어에서 무시한 텍스트 파일 (JSON, XML, YAML, INI 등)을 사용하는 대신 어떤 이점이 있습니까?

.bash_profile 및 웹 서버 구성에서 환경 변수를 처리하는 것보다 비밀로 구성 파일을 복사하는 것이 훨씬 쉽다는 것을 알았습니다. 내가 뭔가를 그리워합니까?


1
이론적으로 메모리보다 파일을 읽는 것이 더 쉽기 때문에 공격 표면이 더 크고 복잡성이 더 작을 수 있습니다.
Florin Asăvoaie

필자의 개발자 규칙은 환경 변수에 설정을 저장하는 것이 도커와 같은 환경에서만 수행하는 것이 가장 좋습니다. 컨테이너 VM 외부에서 12factor.net의 다른 모든 지점과 구성 파일 사용을 승인 / 선호합니다. 정기적 인 서버 배포에서 환경 변수의 안전하지 않은 특성을 좋아하는 사람은 없었습니다.
Corey Ogburn

답변:


21

저자는 비록 이견이 있지만 이의를 제시합니다. 그들의 주요 주장은 실수로 구성 파일을 체크인하는 것이 쉽고 구성 파일은 다양한 형식을 가지며 시스템 주위에 흩어져있을 수 있다는 것입니다 (세 가지 모두 인증 토큰 및 자격 증명과 같은 보안 관련 구성에 가장 적합한 인수입니다).

내 경험에 비추어 볼 때 본질적으로 다음과 같은 세 가지 장점과 단점이 있습니다.

구성 파일에 데이터를 저장하십시오.

이 접근 방식을 사용할 때는 저장소 자체와 이상적으로 격리하고 앱이 콘텐츠를 저장하는 영역 밖에 있는지 확인해야합니다.

장점 :

  • SELinux 또는 AppArmor와 같은 시스템을 사용하여 전반적인 시스템 보안을 향상시키는 경우 액세스를 격리하고 제어하기가 매우 쉽습니다.
  • 일반적으로 비 기술적 인 사용자가 쉽게 변경할 수 있습니다 (게시 된 소프트웨어에는 이점이지만 반드시 조직에 맞는 소프트웨어에는 적합하지 않음).
  • 대규모 서버 그룹에서 쉽게 관리 할 수 ​​있습니다. 구성 배포를위한 모든 종류의 도구가 있습니다.
  • 사용중인 정확한 구성이 무엇인지 쉽게 확인할 수 있습니다.
  • 잘 작성된 앱의 경우 일반적으로 구성 파일을 업데이트 한 다음 특정 신호를 앱 (보통 SIGHUP)으로 보내 서비스를 중단하지 않고 구성을 변경할 수 있습니다.

단점 :

  • 데이터를 안전하게 유지하려면 적절한 계획이 필요합니다.
  • 다른 형식을 배워야 할 수도 있습니다 (요즘에는 걱정할 것이 많지 않으며 일반적으로 비슷한 구문을 가지고 있습니다).
  • 정확한 저장소 위치는 앱에서 하드 코딩되어 배포가 문제가 될 수 있습니다.
  • 구성 파일을 구문 분석하는 데 문제가있을 수 있습니다.

환경 변수에 데이터를 저장하십시오.

일반적으로 이것은 시작 스크립트에서 환경 변수 및 값 목록을 소싱하여 수행되지만 경우에 따라 프로그램 이름 앞에 명령 행에 표시 될 수도 있습니다.

장점 :

  • 구성 파일을 구문 분석하는 것과 비교하여 환경 변수에서 값을 가져 오는 것은 거의 모든 프로그래밍 언어에서 사소한 것입니다.
  • 실수로 구성을 게시하는 것에 대해 걱정할 필요가 없습니다.
  • 이 방법은 흔하지 않기 때문에 모호성으로 어느 정도 보안을 얻을 수 있으며, 앱을 해킹하는 대부분의 사람들은 환경 변수를 즉시 고려하지 않을 것입니다.
  • 응용 프로그램 자체에서 액세스를 제어 할 수 있습니다 (자식 프로세스를 생성 할 때 환경을 쉽게 제거하여 중요한 정보를 제거 할 수 있음).

단점

  • 대부분의 UNIX 시스템에서는 프로세스 환경 변수에 쉽게 액세스 할 수 있습니다. 일부 시스템은이를 완화 할 수있는 방법을 제공 하지만 (예 : LInux 의 hidepid마운트 옵션 /proc) 기본적으로 활성화되어 있지 않으며 프로세스를 소유 한 사용자의 공격으로부터 보호하지 않습니다.
  • 위에서 언급 한 보안 문제를 올바르게 처리하는 경우 사용중인 정확한 설정을 확인하는 것은 쉽지 않습니다.
  • 자식 프로세스가 생성 될 때 환경을 제거하려면 앱을 신뢰해야합니다. 그렇지 않으면 정보가 유출됩니다.
  • 앱을 완전히 다시 시작하지 않으면 구성을 쉽게 변경할 수 없습니다.

명령 행 인수를 사용하여 데이터를 전달하십시오.

진지하게, 모든 비용으로 이것을 피하십시오, 그것은 안전하지 않으며 유지하기 위해 엉덩이에 고통입니다.

장점 :

  • 대부분의 언어에서 환경 변수보다 구문 분석이 훨씬 간단합니다.
  • 자식 프로세스는 데이터를 자동으로 상속하지 않습니다.
  • 응용 프로그램을 개발할 때 특정 구성을 빠르게 테스트 할 수있는 쉬운 방법을 제공합니다.

단점 :

  • 환경 변수와 마찬가지로 대부분의 시스템에서 다른 프로세스의 명령 줄을 쉽게 읽을 수 있습니다.
  • 구성을 업데이트하는 것이 매우 지루합니다.
  • 구성 길이에 대한 제한을 설정합니다 (때로는 1024 자까지).

1
중요하지 않은 점은 수동으로 암호를 제공하지 않고 서버를 무인 (재) 부트하는 것입니다. 결국 암호는 디스크의 어딘가에 있습니다
PlasmaHH

7
대부분의 UNIX 시스템에서는 중요한 권한 없이도 거의 모든 프로세스 환경 변수를 읽을 수 있습니다. -당신은 그것을 확장 할 수 있습니까? / proc / #### / environ 파일은 소유자 만 읽을 수 있으므로 루트이거나 sudo가 있어야합니다.
rrauenza

이 env 구성 트렌드 중 일부는 표준 컨테이너를 사용하고 컨테이너에 env 변수를 전달하여 구성하는 docker와 같은 것에서 비롯된 것 같습니다.
rrauenza

@rrauenza 프로세스의 소유권은 계정별로 물건을 분리하는 데 아주 좋은 작업을 수행하지 않는 한 중요한 특권이 아니며 소유자가 아닌 경우 실제로 CAP_SYS_ADMIN 기능 (루트가 암시 적으로 보유 함) 만 필요합니다. 또한 환경 변수에 관해서는 아마도 맞지 만 Docker에서도 한계가 있습니다.
오스틴 Hemmelgarn

3
@rrauenza가 만드는 요점에 동의합니다. 대답은 꽤나 훌륭하지만 중요한 권한없이 프로세스 환경 변수를 정확하게 읽을 수있는 방법에 대해 설명하고 싶습니다 . " 그리고 실제로는 CAP_SYS_ADMIN 기능 만 필요합니다 (루트 적으로 암시 적으로 가지고 있음) ...", 악의적 인 에이전트가 루트 권한을 가지고 있다면 추가 논의가 필요하지 않으며 CAP_SYS_ADMIN도 루트 권한 일 수 있습니다 ( man7.org/linux 참조) . /man-pages/man7/capabilities.7.html , CAP_SYS_ADMIN커널 개발자를위한 메모 )
Nubarke

13

환경 변수는 웹 서버의 모든 하위 프로세스에서 상속됩니다. 서버에 연결되는 모든 세션과 그에 의해 생성 된 모든 프로그램입니다. 비밀은 모든 프로세스에 자동으로 공개됩니다.

텍스트 파일에 비밀을 유지하는 경우 서버 프로세스에서 읽을 수 있어야하며 모든 하위 프로세스에서도 읽을 수 있어야합니다. 그러나 최소한 프로그램은 가서 찾아야합니다. 자동으로 제공되지 않습니다. 또한 일부 하위 프로세스가 다른 계정으로 실행되도록하고 해당 계정에서만 비밀을 읽을 수있게 만들 수 있습니다. 예를 들어 suEXEC 는 Apache에서이를 수행합니다.


1
"이것은 서버에 연결되는 모든 세션입니다"는 잘못된 진술입니다. 서버에 대한 http 세션을 열고 서버의 환경 변수에 액세스 할 수 없으며 루트 액세스 권한이 없거나 웹 서버 프로세스를 소유하지 않는 한 해당 서버의 쉘에 로그인하여 가져올 수 없습니다.
Segfault

다른 조치를 취하지 않으면 웹 서버에서 생성 된 모든 프로세스는 환경을 상속합니다. HTML 페이지에는 해당 정보를 사용할 수있는 기능이 없지만 스크립트가 있습니다.
Andrew Schulman

정답이지만이 답변은 특히 세션 이라는 용어와 관련하여 일부 수정 / 관심과 관련이 있습니다. 처음 읽었을 때, 환경 변수의 사용을 나쁜 시각으로 그려서 외부 클라이언트에게 정보 공개 가능성을 제안하는 것처럼 보입니다. 또한, suexec를 비교 양보의 제한 설정을 할 수 ENV는-바르 당 처리 예를 들어, 설정 (라를 ENV-바르 MYVAR=foo /path/to/some/executable) 프로세스에 전파를 제한하고 그것의 아이들 만 - 필요한 마스터 데몬 / 리셋을 문질러 수있는 및 / 수정 자식 프로세스의 환경.
shalomb

2

환경 변수 또는 파일과 관련하여 보안 관련 트레이드 오프가 발생하더라도 보안 이이 권장 사항의 주요 원동력이라고 생각하지 않습니다. 12factor.net의 저자는 Heroku PaaS의 개발자이기도합니다. 모든 사람이 환경 변수를 사용하게하면 개발이 약간 단순화 될 것입니다. 다양한 구성 파일 형식과 위치가 매우 다양하므로 모든 구성 파일 형식과 위치를 지원하기가 어려웠을 것입니다. 환경 변수는 비교하기 쉽습니다.

대화 중 일부를 추측하는 데 많은 상상력이 필요하지 않습니다.

개발자 A : "이 비밀 설정 파일 UI가 너무 복잡합니다. json, xml 및 csv 간을 전환하는 드롭 다운이 실제로 필요합니까?"

개발자 B : "아, 모두가 앱 구성에 환경 변수를 사용한다면 인생은 너무나 웅장 할 것입니다."

개발자 A : "실제로 보안 관련 이유가 몇 가지 있습니다. 환경 변수가 실수로 소스 제어에 체크인되지 않을 것입니다."

개발자 B : "데몬을 시작하는 스크립트 또는 구성 파일로 환경 변수를 설정하지 않습니까?"

개발자 A : "Heroku에는 없습니다! UI에 입력하도록하겠습니다."

개발자 B : "아, 12factor.net에 대한 도메인 이름 경고가 막 나갔습니다." 1


1 : 출처 : 구성


1

TL; DR

구성 파일 대신 환경 변수를 사용하는 데는 여러 가지 이유가 있지만 간과해야 할 가장 일반적인 두 가지 이유는 대역 외 구성 의 유틸리티 값 과 서버, 응용 프로그램 또는 조직 역할 간의 향상된 분리 입니다. 가능한 모든 이유에 대한 철저한 목록을 제시하기보다는이 두 가지 주제에 대해서만 답변하고 보안에 미치는 영향에 대해 간략하게 설명합니다.

대역 외 구성 : 소스 코드에서 비밀 분리

모든 비밀을 구성 파일에 저장하는 경우 해당 비밀을 각 서버에 분배해야합니다. 즉, 코드와 함께 비밀을 수정 제어로 확인하거나 비밀에 대해 완전히 별도의 저장소 또는 배포 메커니즘을 갖습니다.

비밀을 암호화해도이 문제를 해결하는 데 도움이되지는 않습니다. 키 관리 및 배포에 대해 걱정해야하므로 문제를 한 번에 제거하면됩니다.

간단히 말해서, 환경 변수는 개발과 작업을 분리하려는 경우 서버 별 또는 애플리케이션 별 데이터를 소스 코드에서 이동하는 방법입니다. 소스 코드를 게시 한 경우 특히 중요합니다!

분리 향상 : 서버, 응용 프로그램 및 역할

비밀을 유지하기위한 구성 파일을 확실히 가질 수 있지만 비밀을 소스 코드에 저장하면 특정성에 문제가 있습니다. 각 비밀 세트에 대해 별도의 브랜치 또는 저장소가 있습니까? 올바른 비밀 세트가 올바른 서버에 도달하게하려면 어떻게해야합니까? 또는 어느 곳에서나 동일한 "비밀"(또는 하나의 파일에 모두있는 경우 모든 곳에서 읽을 수 있음)을 가지고있어 시스템 보안 제어에 실패하는 경우 더 큰 위험을 구성하여 보안을 줄입니까?

각 서버 또는 응용 프로그램마다 고유 한 비밀을 유지하려면 환경 변수가 많은 파일을 관리해야하는 문제로 해결됩니다. 새 서버, 응용 프로그램 또는 역할을 추가하는 경우 새 파일을 만들거나 이전 파일을 업데이트 할 필요가 없습니다. 문제가되는 시스템의 환경 만 업데이트하면됩니다.

보안에 관한 생각

커널 / 메모리 / 파일 보안에 대한 철저한 탐색은이 답변의 범위를 벗어나지 만, 제대로 구현 된 시스템 별 환경 변수는 "암호화 된"비밀보다 안전하지 않다는 점을 지적 할 가치가 있습니다. 어느 경우 에나, 목표 시스템은 암호 해독 된 비밀 을 사용하기 위해 어느 시점에서 메모리에 여전히 보유해야 합니다.

주어진 노드의 휘발성 메모리에 값을 저장하면 오프라인으로 복사 및 공격 할 수있는 온 디스크 파일이 없다는 점도 지적 할 가치가 있습니다. 이것은 일반적으로 메모리 내 비밀에 대한 이점으로 간주되지만 확실히 결정적인 것은 아닙니다.

환경 변수와 다른 비밀 관리 기술의 문제는 절대적 문제보다는 보안 및 유용성 트레이드 오프 에 관한 것입니다. 귀하의 마일리지가 다를 수 있습니다.


2
구성 파일에 대해 언급 한 모든 단점이 환경 변수에도 적용되기 때문에 이는 설득력이 없습니다. 환경 변수 구성 데이터입니다. 그들은 마술처럼 스스로를 설정하지 않습니다. 그것들은 각 시스템에 배포되어야하며, 어떤 종류의 구성 메커니즘을 사용하여 설정해야합니다.
jpaugh

@jpaugh 당신은 밀짚 남자 논쟁을하고 내가 말하지 않은 것을 공격하고 있습니다. 내가 해결하는 문제는 대역 외 구성 및 데이터 분리입니다. 명확하게 설명했듯이 원하는 방식으로 이러한 작업을 수행 할 수 있습니다. 원하는 경우 코드와 함께 비밀을 GitHub에 공개적으로 게시 할 수 있지만 일반적인 경우에는 분명히 현명하지 않은 것처럼 보입니다. 그러나, 당신 의 절충이 필요 확인할 수 있습니다 당신의 시스템은 주어진 위협 모델 내에서 제대로 작동 할 수 있습니다.
CodeGnome

2
다른 구성 데이터만큼이나 환경 변수에 적용된다는 점을 제외하고는 모든 사항이 정확합니다. 환경 변수를 파일에 저장하면 커밋 할 수 있습니다. 파일을 대역 외로 보내면 파일을 입력하는 것보다 파일을 작성하는 것이 더 쉽습니다. 그러나 입력을 선호한다면 대신 JSON 객체를 입력하고 stdin에서 읽으십시오. 실제로는 명령 줄보다 안전합니다.
jpaugh

1

개인적으로 환경 변수 는 쉘에서 시작한 모든 프로세스에 .bashrc표시되므로 환경 변수를 설정하지 말고 데몬 / 감독자 수준 (init / rc 스크립트, systemd config)에서 범위를 설정하여 필요한 범위로 제한하는 것이 좋습니다. .

별도의 팀이 작업을 관리하는 경우 환경 변수는 작업이 구성 파일 / 포맷에 대해 알 필요없이 및 / 또는 콘텐츠를 관리 할 필요없이 응용 프로그램의 환경을 설정하기위한 쉬운 인터페이스를 제공합니다. 운영 팀이 운영 요구 (배치 용이성, 확장 성, 보안 등)에 따라 배포 시스템 (OS, 감독자 프로세스)을 선택할 수있는 다중 언어 / 멀티 프레임 워크 설정에서 특히 그렇습니다.

코드가 다른 환경을 통과함에 따라 CI / CD 파이프 라인도 고려해야 합니다.(예 : 개발, 테스트 / qa, 준비, 프로덕션) 환경 관련 사항 (배포 영역, 데이터베이스 연결 세부 정보, 자격 증명, IP 주소, 도메인 이름 등)은 전용 구성 관리 도구 / 프레임 워크에 의해 가장 잘 설정되고 응용 프로그램에서 사용됩니다. 환경의 프로세스 (DRY에서 한 번 작성하고 어디서나 실행). 전통적으로 개발자가 이러한 운영 문제를 관리하는 경향이있는 경우 코드 외의 구성 파일 또는 템플릿을 체크인 한 다음 운영 요구 사항이 변경 될 때 대안 및 기타 복잡성을 추가하는 경향이 있습니다 (예 : 새로운 환경 / 배치 / 사이트가 등장하면 확장 성 / 보안 무게,

  • Env-var는 규모에 따라 구성 / 복잡성을 단순화합니다.
  • Env-vars 는 응용 프로그램 의 비 코드 관련 측면을 담당하는 팀 과 표준 (비표준이 아닌 경우)의 구속력없는 방식 으로 운영 구성을 정식으로 배치합니다 .
  • Env-vars는 애플리케이션을 지원하는 마스터 / 수퍼바이저 프로세스 (예 : god, monit, supervisord, sysvinit, systemd 등) 및 운영 시스템 (운영 체제, 컨테이너 이미지 등) 등을 운영 요구 사항으로 교체 할 수 있습니다. 진화 / 변화. 오늘날 모든 언어 프레임 워크에는 일부 프로세스 런타임이 있지만 운영 환경이 열등하고 개발 환경에 더 적합하거나 다국어 / 다중 프레임 워크 프로덕션 환경에서 복잡성을 증가시키는 경향이 있습니다.

생산을 위해, 나는에 ENV가-바르 응용 프로그램 설정 호의를 EnvironmentFile 등을 /etc/default/myapplication.conf그가 구성 관리에 의해 배치 만 읽을 설정 root하는 등의 systemd전용에서 응용 프로그램 산란 (또는 그 문제에 대한 다른 것) Deprivileged 시스템 사용자 A의 개인 그룹 . 에 대한 전용 사용자 그룹으로 뒷받침 ops하고 sudo-이 파일은 기본적으로 세계로 읽을 수 있습니다. 이는 개발자 / 테스터가 dev / qa / test 환경에서 자신의 EnvironmentFile을 드롭 할 수 있도록하면서 Dev + Ops의 모든 장점을 지원하는 12 개 요소를 준수하며 적절한 보안의 모든 이점을 제공합니다.


0

개발자의 관점에서 환경 변수에 구성 데이터를 저장하면 개발, QA 및 프로덕션과 같은 다양한 환경 간의 배포가 단순화되고 개발자가 잘못된 구성 파일 배포에 대해 걱정할 필요가 없습니다.

Azure 웹 앱은이 패턴을 사용하는 옵션을 제공하며 매우 잘 작동합니다.

또한 잠재적으로 민감한 데이터를 소스 제어에서 제외시킵니다. 소스 제어에서 해당 파일을 무시하는 것은 실제로는 가능하지 않습니다 (적어도 .NET에서는) 해당 파일에 많은 상용구 구성이 있기 때문에.

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