목차 (INDEX)
개요
[Certbot / Let's encrypt] SSL인증서 적용하기 의 연장선에서, 이번에는 Name-based VirtualHost에서 여러개의 도메인을 Redirect하는 설정을 추가하겠습니다. .htaccess설정으로 Redirect하기도 하지만, 여기서는 NameVirtualHost에 설정하는 것을 전제로 합니다.
준비 / 현재 상태
- CentOS7 / Apache 2.4.6
- example.com : DocumentRoot로 '/var/www/html/', Default 디렉토리를 사용하는 호스트 = 주호스트
- naruhodo.cf : DocumentRoot로 '/var/www/html/naruhodo.cf' 디렉토리를 사용하는 호스트
- Let's encrypt 인증서 설치를 완료한 상태
- 기존에 http로 서비스하던 여러개의 도메인을 모두 https로 전환하려는 중입니다.
- 기존 서비스들은 htaccess의 Basic인증을 걸어둔 상태로 작업 예정
301 Redirect 설정하기
보통 /etc/httpd/conf.d/ 아래에서 설정을 하는데, 각각의 파일들을 살펴보면서 작업합니다.
[root@centos7 conf.d]# ll
-rw-r--r-- 1 root root 10501 May 21 20:04 ssl.conf << mod_ssl 모듈을 설치하면 생깁니다. ssl의 기본설정
-rw-r--r-- 1 root root 228 May 21 18:46 vhost-00.conf << global적용 (80,443포트를 모두 deny)
-rw-r--r-- 1 root root 1231 May 21 20:18 vhost-example.com.conf << Default DocumentRoot 사용하는 도메인
-rw-r--r-- 1 root root 1098 May 21 20:06 vhost-naruhodo.cf.conf << 서비스용 도메인
-rw-r--r-- 1 root root 374 May 21 18:07 vhost-z-123.123.123.10.conf << ip로 접속 시도할 경우에도 표시
-rw-r--r-- 1 root root 841 May 20 19:48 welcome.conf << 표시할 페이지가 없을 때 보여지는 페이지 설정파일
[root@centos7 conf.d]#
새로 생성하거나 확인/편집해야 할 파일과 내용입니다.
- httpd.conf : (확인/편집) ServerName 설정
- ssl.conf : (확인/편집) 443포트 활성화, ServerName, SSL인증키 등을 적용
- vhost-example.com.conf : (생성 or 확인/편집) example.com 도메인을 위한 설정파일
- vhost-naruhodo.cf.conf : (생성 or 확인/편집) naruhodo.cf 도메인을 위한 설정파일
① httpd.conf
[root@centos7 conf.d]# vi /etc/httpd/conf/httpd.conf
# If your host doesn't have a registered DNS name, enter its IP address here.
#
ServerName example.com:80 << 추가 or 확인
또는
ServerName www.example.com:80 << 추가 or 확인
※ 설정 확인 후 재기동
[root@centos7 conf.d]# httpd -t
Syntax OK
[root@centos7 conf.d]# systemctl restart httpd
위 설정과는 별도로 Name-based VirtualHost설정을 할 경우, 여기의 주호스트 설정이 사라지기 때문에 ServerName과 DocumentRoot를 동일하게 하여 VirtualHost를 생성해 주어야 합니다.
또한, VirtualHost 블록은 적힌 순서대로 또는 파일로 분리했을 경우 파일 이름순으로 적용되므로 주호스트를 가장 앞쪽에 배치시키는 것이 좋습니다.
② ssl.conf
Listen 443 https << 확인/편집
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout 300
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin
DocumentRoot "/var/www/html/" << 확인/편집
ServerName example.com:443 << 확인/편집
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel info
SSLEngine on << 확인/편집
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4
SSLCertificateFile /etc/letsencrypt/live/www.example.com/cert.pem << 추가
SSLCertificateKeyFile /etc/letsencrypt/live/www.example.com/privkey.pem << 추가
SSLCertificateChainFile /etc/letsencrypt/live/www.example.com/chain.pem << 추가
Include /etc/letsencrypt/options-ssl-apache.conf << 추가
SSLOptions +StdEnvVars
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
CustomLog logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
※ 설정 확인 후 재기동
[root@centos7 conf.d]# httpd -t
Syntax OK
[root@centos7 conf.d]# systemctl restart httpd
④ vhost-example.com.conf
가상호스트를 사용하면 주호스트 설정이 없어지므로 여기에서 다시 설정해 줍니다.
80과 443을 나눠서 2개의 파일로 관리했었는데, 직관적이지 못해서 하나의 파일로 합칩니다.
최소한의 설정은 엔진을 ON한 다음에 원하는 rule을 기술하는 것인데,
실제로는 변수값을 제대로 가져오지 못하는 경우가 생길 수 있기에, 조건들을 필요에 따라서 추가해줄 필요가 생깁니다.
RewriteEngine on
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
작성(동작) 흐름은 RewriteEngine을 ON > rule이 작동할 조건지정 > 조건에 따른 rule 실행 입니다.
[root@centos7 conf.d]# vi vhost-example.com.conf
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
<Directory "/var/www/html">
Options Indexes FollowSymLinks
AllowOverride AuthConfig Limit
Order allow,deny
Allow from all
</Directory>
DocumentRoot /var/www/html
ErrorLog logs/virtual-error_log
CustomLog logs/virtual-access_log combined env=!no_log
※ Redirectt 설정 ↓↓↓↓↓↓
RewriteEngine on
RewriteMap lowercase int:tolower << 변수들을 소문자로 바꿉니다
RewriteCond "${lowercase:%{HTTPS}}" !on << https라는 변수값이 off 이거나
RewriteCond "${lowercase:%{REQUEST_SCHEME}}" !https << request_scheme값이 https가 아니거나
RewriteCond "${lowercase:%{SERVER_PORT}}" !443 << server_port값이 443이 아니거나
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L] << 모두 https://www.example.com으로 Redirect
※ Redirectt 설정 ↑↑↑↑↑↑
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
AddDefaultCharset UTF-8
※ Redirect될 URL이 https://www.example.com 인 경우, www.example.com 으로 발행된 인증서를 입력해 줍니다.
↓↓↓↓↓↓↓
SSLCertificateFile /etc/letsencrypt/live/www.example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateChainFile /etc/letsencrypt/live/www.example.com/chain.pem
DocumentRoot /var/www/html
ErrorLog logs/virtual-ssl-error_log
CustomLog logs/virtual-ssl-access_log combined env=!no_log
</VirtualHost>
[root@centos7 conf.d]#
※ 설정 확인 후 재기동
[root@centos7 conf.d]# httpd -t
Syntax OK
[root@centos7 conf.d]# systemctl restart httpd
Redirect 결과
try🐶everything backend$ curl -I http://example.com
HTTP/1.1 301 Moved Permanently
Date: Wed, 22 May 2019 06:04:54 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/5.4.45
Location: https://www.example.com << OK !!
Content-Type: text/html; charset=iso-8859-1
try🐶everything backend$ curl -I http://www.example.com
HTTP/1.1 301 Moved Permanently
Date: Wed, 22 May 2019 06:04:59 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/5.4.45
Location: https://www.example.com << OK !!
Content-Type: text/html; charset=iso-8859-1
⑤ vhost-naruhodo.cf.conf
[root@centos7 conf.d]# cat vhost-naruhodo.cf.conf
<VirtualHost *:80>
ServerName naruhodo.cf
ServerAlias www.naruhodo.cf
<Directory "/var/www/html/naruhodo.cf">
Options Indexes FollowSymLinks
AllowOverride AuthConfig Limit
Order allow,deny
Allow from all
</Directory>
DocumentRoot /var/www/html/naruhodo.cf
ErrorLog logs/virtual-error_log
CustomLog logs/virtual-access_log combined env=!no_log
※ Redirectt 설정 ↓↓↓↓↓↓ (간단하게 기술하기)RewriteEngine on
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
※ Redirectt 설정 ↑↑↑↑↑↑
</VirtualHost>
<VirtualHost *:443>
ServerName naruhodo.cf
ServerAlias www.naruhodo.cf
AddDefaultCharset UTF-8
SSLCertificateFile /etc/letsencrypt/live/www.naruhodo.cf/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.naruhodo.cf/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateChainFile /etc/letsencrypt/live/www.naruhodo.cf/chain.pem
DocumentRoot /var/www/html/naruhodo.cf
ErrorLog logs/virtual-ssl-error_log
CustomLog logs/virtual-ssl-access_log combined env=!no_log
</VirtualHost>
※ 설정 확인 후 재기동[root@centos7 conf.d]# httpd -t
Syntax OK
[root@centos7 conf.d]# systemctl restart httpd
Redirect 결과
try🐶everything backend$ curl -I http://naruhodo.cf
HTTP/1.1 301 Moved Permanently
Date: Wed, 22 May 2019 03:07:11 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/5.4.45
Location: https://www.naruhodo.cf << OK !!
Content-Type: text/html; charset=iso-8859-1
try🐶everything backend$ curl -I http://www.naruhodo.cf
HTTP/1.1 301 Moved Permanently
Date: Wed, 22 May 2019 03:07:19 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/5.4.45
Location: https://www.naruhodo.cf << OK !!
Content-Type: text/html; charset=iso-8859-1
try🐶everything backend$
이상으로, Name-based VirtualHost설정으로 https로 redirect를 해 보았습니다.
가상호스트의 동작방식이,
여러개의 <VirtualHost>블럭에서 앞에서부터 순차적으로 적용되고,
파일을 도메인별로 분리했을 경우에도 파일이름순으로 앞에서부터
순차적으로 적용된다는 점에 주의해야 합니다.
[2019/05/24] 내용추가
위에서 설정한 SSL인증서의 FQDN과 브라우저에 입력하는 URL의 FQDN이 서로 다를 경우, 경고와 함께 제대로 표시되지 않는다.
예)
적용된 SSL인증서 : www.naruhodo.cf
브라우저로 접속: http://naruhodo.cf ⇒ https://naruhodo.cf (https로 전환되지만, 인증서가 다르다는 경고가 뜬다)
naruhodo.cf로 접속하는 경우에는 그 앞에 www.을 자동으로 붙여서 https로 전환시키는 예제
↓↓↓↓↓
</VirtualHost>
...
RewriteEngine on
RewriteMap lowercase int:tolower
RewriteCond "${lowercase:%{HTTPS}}" !on
RewriteCond "${lowercase:%{REQUEST_SCHEME}}" !https
RewriteCond "${lowercase:%{SERVER_PORT}}" !443
RewriteCond "${lowercase:%{HTTP_HOST}}" "^naruhodo\.cf$" << naruhodo.cf를 입력하면
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}$1 [R=301,L] << 앞에 www. 을 붙여서 처리
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L] << 그외는 입력한 도메인을 그대로 https화
...
</VirtualHost>
수정전)
try🐶everything ~$ curl -I http://naruhodo.cf
HTTP/1.1 301 Moved Permanently
Date: Fri, 24 May 2019 05:01:35 GMT
Server: Apache/2.4.39 (Unix) OpenSSL/1.1.1b
Location: https://naruhodo.cf/
Content-Type: text/html; charset=iso-8859-1
try🐶everything ~$
수정후)
try🐶everything ~$ curl -I http://naruhodo.cf
HTTP/1.1 301 Moved Permanently
Date: Fri, 24 May 2019 05:02:53 GMT
Server: Apache/2.4.39 (Unix) OpenSSL/1.1.1b
Location: https://www.naruhodo.cf/
Content-Type: text/html; charset=iso-8859-1
참고:
* 정규표현 확인툴입니다. 작성하면서 곧바로 결과를 볼 수 있어서 편리하더군요.
https://weblabo.oscasierra.net/tools/regex/
* Name-based Virtual Host Support
https://httpd.apache.org/docs/2.4/vhosts/name-based.html