2022. 7. 19. 12:01ㆍWeb Server/Oracle Linux 8
이번 포스팅에서는 RedHat 8 기반의 OS인 Oracle Linux 8에서 웹서버에 TLS 1.3 을 설정하는 방법에 대해 알아볼 것입니다.
가상호스팅에 관련된 자세한 정보나 인증서 관련된 설정은 사전에 이미 세팅이 되어있다는 가정하에 진행될 예정이니, 만일 가상 호스트 설정이나 무료 SSL/TLS 인증서 설치에 관해 알고 싶다면 이전 포스팅을 함께 참고하시기 바랍니다.
[Apache 2.4] VirtualHost(가상호스트) 설정하기
[Apache 2.4] VirtualHost에 SSL/TLS 인증서 설정하기
[Apache 2.4] Let's Encrypt CA의 무료 SSL/TLS 인증서 발급 및 적용하기
1. Apache 설치
dnf를 이용하여 httpd를 설치합니다. httpd(Apache 웹서버)를 설치할 경우 연관 패키지인 httpd-filesystem, httpd-tools, mod_ssl 도 함께 설치 됩니다.
sudo dnf install httpd
TLS 1.3은 최소 Apache 2.4.37 이상 버전과 openssl 1.1.1 이상 버전에서 지원됩니다.
CentOS 7 에서 yum을 통해 간단히 설치할 수 있었던 Apache 웹서버가 2.4.6 버전이었던것과 달리 Oracle Linux 8에서 dnf를 통해 설치한 httpd 버전은 2.4.37이므로 압축파일로 직접 설치할 필요없습니다.
httpd 버전 확인
httpd -version
Server version: Apache/2.4.37 (Oracle Linux) Server built: Jun 22 2022 14:35:4
openssl 버전 확인
openssl version
OpenSSL 1.1.1k FIPS 25 Mar 2021
현재 설치된 openssl에서 지원하고 있는 TLSv1.3 종류 확인
openssl ciphers -v | grep TLSv1.3
TLS_AES_256_GCM_SHA384 TLSv1.3 Kx=any Au=any Enc=AESGCM(256) Mac=AEAD TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any Au=any Enc=CHACHA20/POLY1305(256) Mac=AEAD TLS_AES_128_GCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESGCM(128) Mac=AEAD TLS_AES_128_CCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESCCM(128) Mac=AEAD
2. 방화벽 설정
2.1. 방화벽 데몬 활성화 여부 확인
방화벽 데몬이 현재 활성화 상태인지 확인합니다.
running으로 출력될 경우 정상적으로 실행되고 있는 상태입니다.
sudo firewall-cmd --state
running
2.2. 방화벽 리스트 확인
웹서비스를 이용하기 위해서 80/tcp, 443/tcp 포트가 개방되어있어야 합니다.
먼저 현재 방화벽 리스트를 확인해봅니다.
80/tcp, 443/tcp 는 기존에 Well Known Port로 정의된 서비스로 각각 http, https 라는 서비스로 등록할 수 있습니다.
참고 IANA의 Service Name and Transport Protocol Port Number Registry
sudo firewall-cmd --list-all
public (active) target: default icmp-block-inversion: no interfaces: ens3 sources: services: ssh ports: protocols: forward: no masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
2.3. 방화벽에 http, https 서비스 등록
http, https 서비스를 위해 방화벽에 http와 https를 등록합니다.
sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --permanent --add-service=https
--permanent
속성을 사용할 경우에는 반드시 --reload
도 실행해줘야합니다.
sudo firewall-cmd --reload
서비스 등록 및 리로드 후 다시 리스트를 확인해보면, http, https 서비스가 등록된 것을 확인할 수 있습니다.
sudo firewall-cmd --list-all
public (active) target: default icmp-block-inversion: no interfaces: ens3 sources: services: http https ssh ports: protocols: forward: no masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
++ 만일, 서버가 AWS나 Oracle Cloud와 같은 클라우드 서버에서 서비스 중이라면, 각 클라우드 서버에서 제공하고 있는 보안 규칙에도 방화벽 설정을 추가해 줘야 합니다.
3. DNS 설정
호스팅 회사로부터 도메인을 구입하면, 기본적으로 호스팅 업체에서 네임서버를 제공합니다.
기본적으로 제공하고 있는 네임서버를 이용할 것이라면 호스팅 사이트에서 DNS를 설정하면 되고,
클라우드서버나 다른 곳에서 DNS를 관리하고 싶다면, 호스팅 사이트에 설정된 네임서버 정보를 수정해야합니다.
예를들면, 호스팅 케이알의 경우, 아래와 같이 호스팅케이알에서 제공하고 있는 기본 네임서버가 있습니다.
호스팅케이알을 통해 DNS설정을 하고 싶다면 네임서버를 변경하지 않고, 그대로 이용하면 되고, 아래에
도메인을 구인한 후, 기본적으로 도메인을 구입한 사이트에서 DNS A 레코드를 추가해주면 됩니다.
nslookup -q=A api.chaeking.com
Server: dns.opendns.com Address: 208.67.222.222 Non-authoritative answer: Name: api.chaeking.com Address: 130.162.146.82
Mac이나 Linux에서는 host 명령어로 더 간단하게 DNS를 조회할 수 있습니다.
host -t a api.chaeking.com
api.chaeking.com has address 130.162.146.82
4. 아파치 설정
4.1. 가상호스트 파일 추가
/etc/httpd
하위에 가상호스트 관련 설정을 담을 sites-enabled 디렉토리를 만들고, 안에 새로 추가할 서버 설정을 해줍니다.
cd /etc/httpd sudo mkdir sites-enabled sudo vim api.chaeking.com.conf
<VirtualHost *:443> ServerName api.chaeking.com CustomLog "/var/log/httpd/chaeking-api/access_log" common ErrorLog "/var/log/httpd/chaeking-api/error_log" SSLEngine on SSLProxyEngine on SSLProtocol all -SSLv3 SSLCertificateFile /etc/letsencrypt/live/chaeking.com/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/chaeking.com/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/chaeking.com/chain.pem RequestHeader set X-Forwarded-Proto "https" RequestHeader set X-Forwarded-Port "443" ProxyPreserveHost on ProxyPass / http://127.0.0.1:8080/ nocanon ProxyPassReverse / http://127.0.0.1:8080/ ProxyRequests off AllowEncodedSlashes NoDecode <Proxy http://127.0.0.1:8080/*> Order deny,allow Allow from all </Proxy> </VirtualHost> <VirtualHost *:80> ServerName api.chaeking.com RewriteEngine on RewriteCond %{HTTPS} off RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R,L] </VirtualHost>
※ 가상 호스트 관련 설정에 대해 자세히 알고 싶다면 아래 문서를 참고해주세요.
[Apache 2.4] VirtualHost(가상호스트) 설정하기
[Apache 2.4] VirtualHost에 SSL/TLS 인증서 설정하기
설정파일에 정의한 로그파일은 미리 생성해둬야 합니다.
sudo mkdir /var/log/httpd/chaeking-api sudo touch /var/log/httpd/chaeking-api/access_log /var/log/httpd/chaeking-api/error_log
4.2. 아파치에 가상호스트 파일 포함시키기
먼저 기본적으로 정의되어있는 아파치 설정파일을 백업한 후 설정파일을 수정합니다.
cd /etc/httpd/conf sudo cp httpd.conf httpd.conf.ori
기본적으로 include 되고 있던 conf.d 하위에는 아파치에서 기본적으로 제공하고 있는 인덱스 페이지 및 ssl 기본 설정들이 들어있습니다.
관련 설정은 이제 필요없으니 주석처리하고, 새로 추가하는 VirtualHost를 서비스하기 위해 443 포트 및 sites-enable 폴더 하위 conf 파일을 포함시킵니다.
sudo vim httpd.conf
Listen 80 Listen 443 ... #IncludeOptional conf.d/*.conf IncludeOptional sites-enabled/*.conf
5. SELinux 관련 설정
DNS, 방화벽 설정도 모두 마쳤으나 여전히 api가 작동되지 않을 수도 있습니다.
https api.chaeking.com https: error: SSLError: HTTPSConnectionPool(host='www.chaeking.com', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)'))) while doing a GET request to URL: https://www.chaeking.com/
HTTPie 실행 결과
VirtualHost 에 설정했던 로그 파일을 열어보면 access_log에 503 상태코드가, error_log에는 Permission denied가 출력되어있는 것을 확인할 수 있습니다.
59.6.230.229 - - [02/Jun/2022:01:33:56 +0000] "GET / HTTP/1.1" 503 299 59.6.230.229 - - [02/Jun/2022:01:33:56 +0000] "GET /favicon.ico HTTP/1.1" 503 299
access_log
[Thu Jun 02 01:33:56.195639 2022] [proxy_http:error] [pid 2731753:tid 139648066819840] [client 59.6.230.229:58122] AH01114: HTTP: failed to make connection to backend: 127.0.0.1, referer: https://api.chaeking.com/ [Thu Jun 02 01:33:59.782430 2022] [proxy:error] [pid 2731753:tid 139647975945984] (13)Permission denied: AH00957: HTTP: attempt to connect to 127.0.0.1:8080 (127.0.0.1) failed
error_log
이는 Redhat 8 기반의 Oracle Linux 8의 강화된 보안 정책 때문일 수 있습니다.
기본적으로 Oracle Linux 8 에서는 SELinux가 활성화 되어있는데, httpd 프로세스의 네트워크 연결 허용 여부에 관한 설정값인 httpd_can_network_connect 가 off로 설정되어있다면 네트워크 연결이 되지 않습니다.
getsebool 명령어를 이용하여 httpd_can_network_connect 설정값을 조회해봅니다.
getsebool httpd_can_network_connect
httpd_can_network_connect --> off
httpd 프로세스가 네트워크 연결을 허용하도록 설정을 합니다. (on 대신 1을 써도 됩니다)
sudo getsebool -P httpd_can_network_connect on
다시 httpd_can_network_connect 설정값을 조회하면 on으로 변경된 것을 확인할 수 있습니다.
getsebool httpd_can_network_connect
httpd_can_network_connect --> on
6. TLS 1.3 인증서 확인
다시 HTTPie로 api를 조회해봅니다.
이번에는 정상적으로 api가 작동되는것을 확인할 수 있습니다.
웹브라우저로 접속했을 경우에도 https 보안접속과 TLS 1.3이 잘 설정된 것을 확인할 수 있습니다.