1. 개요
HAProxy에서 TLS(SSL) 인증서를 종료(SSL termination)하도록 구성하면, 클라이언트와 HAProxy 사이의 통신은 HTTPS로 처리하고 HAProxy와 백엔드 웹 서버 사이의 통신은 HTTP로 전달할 수 있습니다. 이 방식은 인증서 관리를 HAProxy 한 곳에서 처리할 수 있어 운영이 단순해지는 장점이 있습니다.
아래 예시는 기존 인증서 파일을 하나의 PEM 파일로 합친 뒤, HAProxy의 443 포트 바인딩에 인증서를 적용하는 흐름입니다.
2. 인증서 적용
2.1. 인증서 생성
기존 key, crt 파일을 이용하여 하나의 pem 파일로 생성합니다. HAProxy에서 crt 옵션으로 사용할 인증서 파일은 일반적으로 개인키와 인증서를 함께 포함한 PEM 형식이어야 합니다.
$ cat myserver.key myserver.crt > myserver.pem
중간 인증서가 필요한 환경이라면 서버 인증서 뒤에 체인 인증서를 함께 포함해야 클라이언트에서 인증서 체인 오류가 발생하지 않습니다. 생성 후에는 파일 권한이 불필요하게 넓게 열려 있지 않은지도 확인하는 것이 좋습니다.
3. HAProxy 설정 변경
3.1. mode
HAProxy에서 인증서를 처리하므로 프론트엔드 설정은 mode tcp가 아니라 mode http로 변경합니다. HTTP 모드로 동작해야 헤더 추가, 리다이렉트, ACL 같은 HTTP 기반 기능을 사용할 수 있습니다.
3.2. 인증서 파일 설정
bind 절에 ssl 옵션과 인증서 위치를 추가합니다.
bind *:443 ssl crt /where/ssl/myserver.pem
3.3. 백엔드
SSL 종료를 HAProxy에서 수행한다면 백엔드 웹 서버는 HTTPS가 아니라 HTTP 포트로 받도록 구성합니다. 즉, 클라이언트 요청은 HTTPS로 들어오지만 HAProxy가 복호화한 뒤 내부 백엔드로는 HTTP 요청을 전달합니다.
애플리케이션에서 원래 요청이 HTTPS였는지 판단해야 한다면, 아래와 같이 프록시 헤더를 전달하고 애플리케이션 또는 웹 서버에서 해당 헤더를 신뢰하도록 설정해야 합니다.
3.4. X-Forwarded-Proto
reqadd X-Forwarded-Proto:\ https
위 설정은 백엔드로 전달되는 요청에 X-Forwarded-Proto: https 헤더를 추가하기 위한 설정입니다. 이 헤더를 이용하면 백엔드 애플리케이션이 원래 요청 프로토콜을 HTTPS로 인식할 수 있습니다.
설정 변경 후에는 HAProxy 설정 문법 검사를 먼저 수행하고, 적용 후에는 브라우저 또는 curl로 HTTPS 접속이 정상 동작하는지 확인합니다. 또한 백엔드 로그나 애플리케이션에서 X-Forwarded-Proto 값이 기대한 대로 전달되는지도 함께 확인하는 것이 좋습니다.