Apache 에서 HTTPS 는 mod_ssl 이 담당한다. 인증서 · 키 파일을 준비하고 443 가상 호스트를 정의한 뒤 방화벽을 여는 순서로 진행한다.
배포판마다 경로가 다르다.
| 항목 | RHEL 계열 | Debian · Ubuntu |
|---|---|---|
| 패키지 | httpd, mod_ssl |
apache2 (mod_ssl 포함) |
| 서비스 | httpd |
apache2 |
| SSL 설정 | /etc/httpd/conf.d/ssl.conf |
/etc/apache2/sites-available/default-ssl.conf |
| 로그 | /var/log/httpd/ |
/var/log/apache2/ |
# RHEL 계열
dnf install -y httpd mod_ssl
# Debian 계열 - 모듈과 사이트를 활성화해야 한다
apt install -y apache2
a2enmod ssl headers
a2ensite default-ssl
운영에는 공인 CA 또는 사내 CA 발급 인증서를 쓴다. 시험용 자체 서명은 다음처럼 만든다.
mkdir -p /etc/pki/tls/private /etc/pki/tls/certs
openssl req -x509 -newkey rsa:2048 -nodes -days 365 \
-keyout /etc/pki/tls/private/server.key \
-out /etc/pki/tls/certs/server.crt \
-subj "/C=KR/O=Example/CN=www.example.com" \
-addext "subjectAltName=DNS:www.example.com,DNS:example.com"
chmod 600 /etc/pki/tls/private/server.key
-addext subjectAltName 은 빠뜨리면 안 된다. 브라우저는 CN 이 아니라 SAN 으로 이름을 검증하므로 SAN 이 없으면 자체 서명이라도 이름 오류가 먼저 난다.
<VirtualHost *:443>
ServerName www.example.com
DocumentRoot /var/www/html
SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/fullchain.crt
SSLCertificateKeyFile /etc/pki/tls/private/server.key
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite HIGH:!aNULL:!MD5
SSLHonorCipherOrder off
ErrorLog /var/log/httpd/example_ssl_error.log
CustomLog /var/log/httpd/example_ssl_access.log combined
</VirtualHost>
SSLCertificateFile 에는 서버 인증서와 중간 CA 를 이어 붙인 fullchain 을 지정한다. Apache 2.4.8 부터 SSLCertificateChainFile 은 필요 없고 한 파일로 처리한다. 중간 CA 를 빠뜨리면 일부 클라이언트에서만 신뢰 실패가 나며, 증상은 인증서 체인이 끊길 때 와 같다.
SSLCACertificateFile 은 서버 체인이 아니라 클라이언트 인증서를 검증할 CA 를 지정하는 항목이다. 용도가 다르므로 여기에 체인을 넣어도 문제는 해결되지 않는다.
<VirtualHost *:80>
ServerName www.example.com
RedirectPermanent / https://www.example.com/
</VirtualHost>
ACME(HTTP-01)로 인증서를 갱신한다면 /.well-known/acme-challenge/ 는 리다이렉트에서 빼거나, 80 → 443 리다이렉트를 유지하되 검증 경로가 살아 있는지 확인한다.
HSTS 를 적용하면 브라우저가 이후 접속을 HTTPS 로 강제한다. 인증서가 만료되면 사용자가 우회할 수 없으므로 갱신 자동화를 갖춘 뒤 켠다.
Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
# 문법 검사
apachectl configtest
systemctl restart httpd
systemctl enable httpd
# 방화벽
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
# 실제 응답 확인
openssl s_client -connect www.example.com:443 -servername www.example.com </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates
curl -I https://www.example.com/
기동에 실패하면 로그부터 본다. 키 파일 권한, 인증서와 키의 불일치, 이미 443 을 쓰는 다른 프로세스가 흔한 원인이다.
journalctl -u httpd -n 50 --no-pager
ss -lntp | grep ':443'
SELinux 가 켜진 RHEL 계열에서 기본 경로가 아닌 곳에 인증서를 두면 읽지 못한다. /etc/pki/tls/ 아래를 쓰거나 컨텍스트를 맞춘다.
restorecon -Rv /etc/pki/tls