728x90

브라우저의 인증서 정책이 나날이 변화하고 있습니다. 
내년부터 시행될 인증서 유효기간 200일 정책을 비롯하여 
Root 인증서의 유효기간 단축 등 이벤트가 넘쳐나고 있습니다.

오늘 포스팅을 Root 인증서의 유효기간 단축으로 인해
내년부터 영향권에 들어가는 GlobalSign 인증서 처리 관련한
Cross-Signed Root 인증서 관련 이야기입니다.

사실, 이 포스팅은 제 스스로 Cross-Signed Root 인증서가
어떻게 Root 인증서의 교체를 부드럽게 넘길 수 있게 해주는 것인지
잘 이해하지 못한 부분들을 정리해보는 글이라 보셔도 무방합니다.

크로스 싸인 루트 인증서(Cross-signed Root Certificate)

신뢰할 수 있는 루트 인증서는 보통 TLS Client에 탑재되어 있습니다. 
가장 널리 사용되는 TLS Client의 하나인 웹 브라우저가 대표적이고
Java의 truststore가 아마도 그 다음 정도로 익히 들어보셨을 TLS Client 입니다.

웹 브라우저는 물론이고 자바 애플리케이션도 
truststore에 미리 저장되어 있는 신뢰 할 수 있는 루트 인증서를 바탕으로
TLS 혹은 SSL과 관련된 모든 절차를 수행합니다. 

그런데 모든 인증서는 유효 기간이 정해져 있을뿐 아니라
루트 인증서의 Private Key가 유출되는 것과 같은 사고가 발생하면
제 아무리 루트 인증서라 하더라도 폐기가 필요합니다.
여기서 폐기는 truststore 에서의 삭제 및 해당 루트 인증서로 싸이닝된
모든 인증서의 폐기를 의미합니다. 

간혹 이런 일이 발생하기도 합니다.
이럴때 부작용을 막기 위해 "크로스 싸인 루트 인증서"가 활용됩니다.
이름 그대로 "다른 루트 인증서를 이용해 싸이닝한 루트 인증서"라는 의미입니다.

이렇게 싸이닝된 "크로스 싸인 루트 인증서"를 이용하면
루트 인증서의 교체에 필요한 작업과 절차를 부드럽게 적용할 수 있다고 하는데요
과연 이 절차는 어떻게 "부드럽게" 진행되는 것인지 궁금했습니다.

사실 Let's Encrypt 에서 비슷한 일이 몇 년전 있었지만 제대로 이해하지 못하고 넘어갔었습니다.
이번엔 제대로 이해해 보고자 공부(라고 쓰고 AI와 티키타카 했다고 읽습니다)해봤습니다.

신뢰 체인(Chain of Trust)

크로스 싸인 루트 인증서의 동작을 이해하기 위해서는 
TLS Client가 신뢰 체인(Chain of Trust)를
어떻게 만들고 검증하는지  이해해야 합니다.

TLS 세계에서의 일반적인 신뢰체인은 다음과 같습니다. 
- Root 인증서 : Self Signed 로 만들어진 최상위 인증기관의 검증된 인증서 
- Intermediate 인증서 : Root 인증서와 Leaf 인증서를 연결해주는 중간 인증서 
- Leaf 인증서 : 실제 도메인(예: www.naver.com)에 대해 발급된 최종 사용자용 인증서  

TLS 인증서는 보통 3단계로 구성되어 있고
이 흐름을 신뢰체인이라고 생각하면 됩니다.
이 포스팅에서 다루는 내용은 위 그림을 기준을 봤을 때
Root Certificate의 교체가 필요한 상황을 가정하고 있습니다.
(GlobalSign의 경우도 이 경우입니다)

크로스 싸인 루트 인증서 존재 유무에 따른 신뢰체인 검증 흐름

크로스 싸인 루트 인증서는 "새로운 루트 인증서를 기존 루트 인증서로 서명한" 인증서 입니다.
이 루트 인증서를 이용해 "원래의" 루트 인증서 변경에 따른
위험을 줄이고 점진적인 마이그레이션을 추구하는 것이 크로스 싸인 루트 인증서 사용의 목적입니다.

기존 흐름)
Leaf 인증서 - Intermediate 인증서 - Legacy Root 인증서
새로운 흐름)
Leaf 인증서 - Intermediate 인증서 - Cross-Signed Root 인증서 - Legacy Root 인증서

기존 흐름의 Intermediate 인증서는 Legacy Root 인증서로 싸이닝 되어 있습니다
오래된(=truststore가 업데이트 되지 않은) 브라우저 등은
Legacy Root 인증서를 이용해서 Intermediate 인증서를 검증합니다. 

반면 새로운 흐름에서의 Intermediate 인증서는 
Cross-Signed Root 인증서를 이용해 싸이닝 되어 있고 
Cross-Signed Root 인증서는 Legacy Root 인증서를 이용해 싸이닝 되어 있습니다.

여기서 중요한 것은 Cross-Signed Root 인증서는
Legacy Root 를 개체할 새로운 Root 인증서를 지칭한다는 것입니다. 
즉, 새로운 흐름에서 Intermediate 인증서는 
기존 흐름에서의 Intermediate 인증서와 달리
새로운 Root 인증서로 싸이닝된 인증서라는 점입니다. 

차이는 뭘까요?
Legacy Root 인증서가 만료 혹은 더이상 유효하지 않은 경우를 생각합시다.
Legacy Root 인증서가 무효화되면 기존 흐름은 더이상 유효하지 않습니다.
하지만 새로운 흐름은 문제 없이 인증이 됩니다. 

왜일까요?

TLS Client 는 똑똑합니다

이러한 변화가 가능한 이유는 브라우저를 비롯한 현대적인 TLS Client의 똑똑함(?)에 기인합니다. 
새로운 truststore를 탑재한, 혹은 탑재당한 TLS Client는
"새로운 흐름"을 검증하는 과정에서 "Legacy Root 인증서"를 통한 검증 단계를 거치지 않습니다.

즉, Intermediate 인증서가 Cross-Signed Root 인증서의 내용물인
새로운 Root 인증서를 이미 truststore에 보유중이라는 것을 인지한 순간
이후의 검증 단계는 이용하지 않게 됩니다. 

정리

복잡하게 설명했지만 정리는 간단합니다.
크로스 싸인 루트 인증서가 모든 이야기의 핵심입니다. 
Legacy Root 인증서로 싸이닝된 크로스 싸인 루트 인증서는
상황에 따라 상위의 Legacy Root 인증서 검증까지 가고, 가지 않고가 핵심입니다.

이 동작을 통해 크로스 싸이닝이 루트 인증서의 이전을 안전하게 지원하고
실제 TLS Client 역할을 수행하는 주체들이
truststore를 업데이트 하는 동안 발생할 수 있는 문제를 해결해 주는 것입니다.

 

728x90
728x90

리눅스는 참 요물입니다.
확장 가능한 지점들이 참 많아서 매력적이기도 하구요. 
최근에 기본적인 쉘 인증 이외에 
MFA 적용 방법을 찾다가 PAM을 처음 접해봤습니다. 

What is PAM?
Pluggable Authentication Module의 약어로 리눅스 시스템이 사용자 인증에 대한 정책을 정의하고 인증 방법 및 절차에 대한 구성을 할 수 있게 해주는 모듈. 이름에 적혀 있는 것처럼 Pluggable이기 때문에 3rd party의 다양한 인증, 인가 솔루션들을 연동하는 지점이 되기도 함 

PAM 의 기본 구성 

PAM은 다양한 서버의 기능별로 구성이 가능합니다. 
/etc/pam.d/ 경로 하위에는 인증을 요구하는 
여러가지 서버, 애플리케이션에 대한 구성 파일이 존재합니다. 
가령, 쉘 접근의 인증과 관련된 구성은 /etc/pam.d/sshd 에 위치하고 있습니다. 
ChatGPT 가 알려준 sshd PAM 구성 파일은 다음과 같을 수 있습니다.

#%PAM-1.0
auth       required     pam_sepermit.so
auth       include      password-auth
account    required     pam_nologin.so
account    include      password-auth
password   include      password-auth
session    optional     pam_keyinit.so force revoke
session    include      password-auth

암호처럼 보이는 이 문서는 컬럼별로 다음과 같이 이해하면 됩니다.

# Module Type   # Control Flag    # Module Name        # Module Argument
auth            required          pam_sepermit.so
account         required          pam_nologin.so
password        include           password-auth
session         optional          pam_keyinit.so       force revoke

 

Module Type

모듈의 타입은 크게 4가지가 있습니다. 
인증을 요청하고 검증하는 방법을 정의하는 auth 
계정에 대한 접근 통제 및 정책을 관리하는 account
비빌번호 갱신 등에 관한 내용을 관리하는 password
인증 전후 수행해야 하는 일을 정의하는 session

Control Flag

제어 플레그는 지정된 모듈을 반드시 수행해야 하는지 
아니면 옵셔널하게 수행해야 하는지 등을 정의합니다. 

Module Name

모듈 이름은 실행할 모듈의 이름입니다. 
리눅스에 내장된 모듈도 있을 수 있고 
서드파티 사업자가 제공했거나 
직접 만든 모듈을 지정할 수도 있습니다. 

Module Argument 

모듈 실행시 필요한 매개변수를 전달할 수도 있습니다. 
이는 필수는 아니며 모듈에 따라 달라지게 됩니다. 


https://medium.com/@avirzayev/linux-pam-how-to-create-an-authentication-module-cc132115bdc5

728x90
728x90

여러 보안 도구들은 패키지를 최신 버전으로 유지할 것을 강요(?)합니다.
아무래도 노출된 취약점들이 구버전 패키지에 대한 경우가 많기 때문이죠.
어김 없이 기억력은 쇠퇴하고 또 한번 yum 으로 패키지 설치에 실패하여 기록을 남겨둡니다.


yum 업데이트시 에러 : Error unpacking rpm package...

보통은 yum 으로 패키지 설치가 잘 됩니다. 
권한 문제가 있더라도 sudo로 왠만하면 설치가 됩니다. 
하지만 간혹 이유 없이 되지 않을때가 있습니다. 
다음과 같은 에러와 함께...

$ sudo yum update openssh-clients
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
Resolving Dependencies
...
...
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Updating   : openssh-clients-7.4p1-23.el7_9.x86_64                                                            1/2
Error unpacking rpm package openssh-clients-7.4p1-23.el7_9.x86_64
error: unpacking of archive failed on file /etc/ssh/ssh_config: cpio: rename

압축 해제가 되지 않았다의 메세지가 눈에 보입니다. 
그리고 특정한 경로의 파일도 언급됩니다. 
원인이 뭘까요? 정답은 파일의 속성 문제였습니다.

속성 확인 : lsattr / 속성 교체 : chattr

파일의 속성을 확인하는 명령은 lsattr입니다.
아마도 불변(immutable) 속성이 지정되어 있어서 
파일의 교체가 실패했을 거라고 추정이 됩니다.

확인하고 교체해 보겠습니다.

$ sudo lsattr /etc/ssh/ssh_config
----i----------- /etc/ssh/ssh_config
$ sudo chattr -i /etc/ssh/ssh_config
$ sudo lsattr /etc/ssh/ssh_config
---------------- /etc/ssh/ssh_config

네, 이후 yum 명령으로 업데이트가 잘 되는 것을 확인할 수 있었습니다. 
아마도 어떤 이유로든 immutable 이 지정된 것일 수 있으니
관리자와 싸우지 않기 위해 다시 속성을 걸어줍니다.

$ sudo chattr +i /etc/ssh/ssh_config
$ sudo lsattr /etc/ssh/ssh_config
----i----------- /etc/ssh/ssh_config

뺄때 -i 였으니 본능적으로 +i 를 하니 잘 수행됩니다. 
다시 immutable 상태가 되었으니 작업을 마무리하고 커피 한잔...

#linux #lsattr #chattr #immutable #yum #yum_error

728x90
728x90

리눅스는 모든 것을 파일처럼 취급합니다.
실제 파일은 물론이고 주변 장치도 파일처럼 취급합니다. 
가령 dev 디렉터리는 device의 약어로 하위에 연결된 장치들이 파일처럼 위치하게 됩니다.

이것은 입력, 출력에도 동일하게 해당됩니다. 
입력과 출력은 입력 스트림, 출력 스트림의 약어로 
입력 스트림의 대표적인 것은 키보드이고
출력 스트림의 대표적인 것은 모니터입니다.

입력 스트림은 stdin(standard input)이며 
출력 스트림은 stdout(standard output)입니다. 
에러도 출력 스트림이지면 특별히 stderr(standard error)로 정의해 두었습니다.

이 각각도 파일처럼 취급되기 때문에 
파일에 접근할 때 사용하는 파일 디스크립터(File Descriptor)가 할당되어 있습니다. 
stdin, stdout, stderr은 시스템의 기본적인 입출력 스트림이기 때문에 
파일 디스크립터가 고정값으로 지정되어 있습니다. 

stdin = FD0
stdout = FD1
stderr = FD2

파일 디스크립터를 이용하면 재지정(redirect)을 할 수 있습니다.
가령 stderr을 stdout 으로 보내고 싶으면 2>1 이 됩니다.

$ curl https://www.google.com 2> response.txt

재지정의 기본 값은 1이기 때문이 1> 과 > 는 동일한 의미가 됩니다. 
입출력 스트림의 파일 디스크립터는 사용하는 프로그램이 
어떤 출력으로 어떤 값을 내보내는지를 이용하여
다른 애플리케이션 등으로 연동할 때 유용하게 쓸 수 있습니다.

#리눅스 #기본명령어 #스트림 #입출력스트림 #파일디스크립터 #fd #stdin #stdout #stderr

728x90

+ Recent posts