Linux Apache 서버 구성 실습 3
Linux Apache 서버 구성 실습 3입니다. DNS zone, 이름 기반 VirtualHost, ServerName, apachectl -S, curl --resolve와 Windows DNS 테스트를 정리했습니다.
Linux Apache 서버 구성 실습 3: 도메인 이름 기반 Virtual Host
이 실습은 같은 Apache 서버와 같은 IP 주소에서 Host header 값에 따라 서로 다른 DocumentRoot를 보여주는 이름 기반 virtual host 구성이다. 이전 실습의 IP 기반 virtual host와 다르게, DNS에서 여러 도메인 이름을 같은 웹 서버 IP로 보내고 Apache가 ServerName, ServerAlias로 사이트를 구분한다.
실습 환경은 네임서버 192.168.10.192, Apache 서버 192.168.10.193, 테스트 Windows 클라이언트 192.168.10.195 흐름이었다. 여기서는 그 구조를 유지하면서 BIND zone, Apache vhost, 클라이언트 검증까지 명령어 중심으로 정리한다.
실습 구조
| 구분 | 값 | 역할 |
|---|---|---|
| DNS 서버 | 192.168.10.192 | www.st12.abc, www.st12.def 이름 해석 |
| Apache 서버 | 192.168.10.193 | 같은 IP에서 두 사이트 제공 |
| Client | 192.168.10.195 | DNS와 웹 접속 테스트 |
| site abc | /home/httpd/st12-abc | www.st12.abc DocumentRoot |
| site def | /home/httpd/st12-def | www.st12.def DocumentRoot |
1. DNS zone 추가
먼저 DNS 서버에서 두 도메인이 Apache 서버 IP로 해석되도록 zone을 만든다. BIND 기준으로 /etc/named.conf에 zone을 추가한다.
zone "st12.abc" IN {
type master;
file "st12.abc.zone";
allow-update { none; };
};
zone "st12.def" IN {
type master;
file "st12.def.zone";
allow-update { none; };
};zone 파일은 /var/named 아래에 둔다. SOA serial은 수정할 때마다 증가시킨다.
$TTL 300
@ IN SOA ns1.st12.abc. admin.st12.abc. (
2026062301 ; serial
3600 ; refresh
900 ; retry
604800 ; expire
300 ) ; minimum
IN NS ns1.st12.abc.
ns1 IN A 192.168.10.192
www IN A 192.168.10.193$TTL 300
@ IN SOA ns1.st12.def. admin.st12.def. (
2026062301
3600
900
604800
300 )
IN NS ns1.st12.def.
ns1 IN A 192.168.10.192
www IN A 192.168.10.193파일 권한과 문법을 확인한 뒤 BIND를 reload한다.
sudo chown root:named /var/named/st12.abc.zone /var/named/st12.def.zone
sudo chmod 640 /var/named/st12.abc.zone /var/named/st12.def.zone
sudo named-checkconf /etc/named.conf
sudo named-checkzone st12.abc /var/named/st12.abc.zone
sudo named-checkzone st12.def /var/named/st12.def.zone
sudo systemctl reload named
sudo systemctl status named --no-pager2. DNS 응답 확인
Apache 설정을 만지기 전에 이름이 같은 IP로 풀리는지 먼저 확인한다.
dig @192.168.10.192 www.st12.abc +short
dig @192.168.10.192 www.st12.def +short
nslookup www.st12.abc 192.168.10.192
nslookup www.st12.def 192.168.10.192두 질의 모두 192.168.10.193을 반환해야 한다. DNS가 실패하면 Apache 설정이 맞아도 브라우저에서는 원하는 사이트로 들어갈 수 없다.
3. Apache vhost include 확인
소스 설치 Apache 기준으로 /app/apache/conf/httpd.conf에서 vhost include가 켜져 있어야 한다.
grep -n "httpd-vhosts.conf" /app/apache/conf/httpd.conf주석 처리되어 있으면 다음 줄을 활성화한다.
Include conf/extra/httpd-vhosts.confApache 2.4에서는 오래된 NameVirtualHost 지시어를 따로 넣지 않는다. <VirtualHost *:80>와 ServerName으로 충분하다.
4. 사이트 디렉터리 생성
sudo mkdir -p /home/httpd/st12-abc /home/httpd/st12-def
cat <<'EOF' | sudo tee /home/httpd/st12-abc/index.html
www.st12.abc name based virtual host
EOF
cat <<'EOF' | sudo tee /home/httpd/st12-def/index.html
www.st12.def name based virtual host
EOF
sudo chown -R daemon:daemon /home/httpd/st12-abc /home/httpd/st12-def
sudo chmod -R 755 /home/httpd/st12-abc /home/httpd/st12-def5. httpd-vhosts.conf 작성
/app/apache/conf/extra/httpd-vhosts.conf에 다음처럼 두 vhost를 넣는다. 같은 IP와 port를 쓰지만 ServerName이 다르다.
<VirtualHost *:80>
ServerName www.st12.abc
DocumentRoot "/home/httpd/st12-abc"
ErrorLog "logs/st12-abc-error.log"
CustomLog "logs/st12-abc-access.log" common
<Directory "/home/httpd/st12-abc">
Require all granted
AllowOverride None
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerName www.st12.def
DocumentRoot "/home/httpd/st12-def"
ErrorLog "logs/st12-def-error.log"
CustomLog "logs/st12-def-access.log" common
<Directory "/home/httpd/st12-def">
Require all granted
AllowOverride None
</Directory>
</VirtualHost>6. 문법 검사와 적용
sudo /app/apache/bin/apachectl configtest
sudo /app/apache/bin/apachectl -S
sudo systemctl reload apache-custom
sudo systemctl status apache-custom --no-pagerapachectl -S 출력에서 namevhost www.st12.abc, namevhost www.st12.def가 같은 *:80 아래에 잡히면 Apache 쪽 매핑은 정상이다.
7. curl로 Host header 검증
DNS가 아직 클라이언트에 반영되지 않았을 때는 curl --resolve로 이름과 IP를 강제로 묶어 테스트할 수 있다.
curl --resolve www.st12.abc:80:192.168.10.193 http://www.st12.abc/
curl --resolve www.st12.def:80:192.168.10.193 http://www.st12.def/DNS를 통해 테스트할 때는 클라이언트 DNS를 192.168.10.192로 맞춘 뒤 확인한다.
Resolve-DnsName www.st12.abc -Server 192.168.10.192
Resolve-DnsName www.st12.def -Server 192.168.10.192
Invoke-WebRequest http://www.st12.abc/ -UseBasicParsing
Invoke-WebRequest http://www.st12.def/ -UseBasicParsing8. 문제가 생길 때 보는 순서
| 증상 | 확인할 지점 |
|---|---|
| 두 도메인이 같은 화면으로만 열림 | ServerName 오타, vhost include 누락, 첫 번째 vhost만 매칭되는 상황 |
| 브라우저에서 이름 해석 실패 | 클라이언트 DNS 주소, BIND zone serial, named-checkzone 결과 |
| 403 Forbidden | <Directory>의 Require all granted, 디렉터리 권한 |
| 접속 불가 | Apache listen, 방화벽 80/tcp, 서버 IP, route |
마무리
이름 기반 virtual host는 DNS와 Apache 설정이 같이 맞아야 완성된다. DNS는 여러 이름을 같은 IP로 보내고, Apache는 요청의 Host header를 보고 어떤 DocumentRoot를 선택할지 결정한다. 검증은 항상 dig, apachectl -S, curl --resolve 순서로 나누어 보면 원인을 빠르게 좁힐 수 있다.