Damrongsak Reetanon
3 min readDec 17, 2017

เปลี่ยน DocumentRoot ของ httpd ใน RHEL/CentOS 7

คำถามต่อเนื่องจากเรื่องของการย้ายพอร์ทในการให้บริการของ httpd ไปให้บริการที่พอร์ทอื่น ก็มาถึงคำถามที่ต้องการย้าย DocumentRoot บ้าง โดยการย้าย DocumentRoot มีงานอยู่ 2 ส่วนที่ต้องทำ ก็คือการแก้ไข configuration ของ httpd เอง และ การแก้ไข context เพื่อให้เป็นไปตามข้อกำหนดของ SELinux

DocumentRoot คืออะไร

เวลาที่เราเปิด browser แล้วพิมพ์ http://www.plearn.zone เครื่องของเราก็จะไปร้องขอไปที่ server ปลายทางเพื่อขอบริการ http จากเครื่องปลายทาง เมื่อ server รับคำร้องเพื่อจะให้บริการ คำถามคือ server จะไปอ่านข้อมูลจากที่ไหนเพื่อตอบกลับไป … คำตอบก็คือ จะไปอ่านข้อมูลจาก directory ที่กำหนดโดยตัวแปร DocumentRoot ซึ่งค่าปกติของ httpd สำหรับ RHEL/CentOS จะถูกกำหนดไว้ที่ /var/www/html

เราจะทำอะไรในบทความนี้

จากเดิมที่ DocumentRoot ถูกกำหนดค่าไว้เป็น /var/www/html เราจะย้ายไปที่ /data/www

0. สถานะปกติของระบบหลังจากติดตั้ง httpd ตามค่าปกติ

#- SELinux ถูกเปิดใช้งานอยู่ตามปกติ
[root@web-server ~]# getenforce
Enforcing

#- DocumentRoot ที่ถูกกำหนดไว้ที่ /var/www/html ถูกตั้งค่าไว้ที่ /etc/httpd/conf/httpd.conf
[root@web-server ~]# grep ^DocumentRoot /etc/httpd/conf/httpd.conf
DocumentRoot “/var/www/html”
#- เรียกดู index.html ด้วยคำสั่ง curl
[root@web-server ~]# curl http://localhost/index.html
Original DocumentRoot
  1. เปลี่ยน DocumentRoot มาที่ /data/www
#- สร้าง /data/www และ index.html
[root@web-server ~]# mkdir -p /data/www
[root@web-server ~]# echo "DocumentRoot at /data" > /data/www/index.html
#- เปลี่ยน DocumentRoot มาที่ /data/www
[root@web-server ~]# sed -i 's/^DocumentRoot.*/DocumentRoot "\/data\/www"/g' /etc/httpd/conf/httpd.conf
[root@web-server ~]# grep ^DocumentRoot /etc/httpd/conf/httpd.conf
DocumentRoot "/data/www"
#- restart เพื่อให้ httpd อ่านค่า configuration ใหม่ที่ได้แก้ไข
[root@web-server ~]# systemctl restart httpd
#- เรียกดู index.html ด้วยคำสั่ง curl พบว่าไม่สามารถเรียกดูได้ มีรายงายความผิดพลาดว่า ไม่สามารถเข้าถึง index.html ได้
[root@web-server ~]# curl http://localhost/index.html
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /index.html
on this server.
</p>
</body></html>
#- ทดสอบอ่านข้อมูล /data/www/index.html ด้วยผู้ใช้ apache ซึ่งเป็นผู้ใช้ที่ httpd ใช้ในการเข้าถึง index.html พบว่าสามารถอ่านข้อมูลได้ตามปกติ
[root@web-server ~]# sudo -u apache cat /data/www/index.html
DocumentRoot at /data
#- เพิ่มเติมค่าใน httpd.conf ในส่วนของ directive <Directory> และ restart อีกครั้ง สามารถหาข้อมูลเพิ่มเติมได้จาก apache directory directive
[root@web-server ~]# sed -i '/<\/Directory>/ a <Directory "\/data/www">\n AllowOverride None\n Require all granted\n<\/Directory> ' /etc/httpd/conf/httpd.conf
[root@web-server ~]# systemctl restart httpd
[root@web-server ~]# curl http://localhost/index.html
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /index.html
on this server.
</p>
</body></html>
#- พบว่ามี log ที่เกิดจาก SELinux มีการ denied ที่เกี่ยวข้องกับ /data/www/index.html
[root@web-server ~]# grep -E 'denied.*index\.html' /var/log/audit/audit.log
type=AVC msg=audit(1513451669.153:174): avc: denied { getattr } for pid=1290 comm="httpd" path="/data/www/index.html" dev="dm-0" ino=67221313 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=file
type=AVC msg=audit(1513451669.153:175): avc: denied { getattr } for pid=1290 comm="httpd" path="/data/www/index.html" dev="dm-0" ino=67221313 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=file

2. แก้ไขการ denied ที่เกิดขึ้นจาก SELinux กำหนดให้ httpd สามารถอ่านเขียนไฟล์ได้เฉพาะที่มี context เป็น httpd_sys_content_t

#- แสดง context ของ directory และไฟล์ใน /data/www
[root@web-server ~]# ls -laZ /data/www
drwxr-xr-x. root root system_u:object_r:default_t:s0 .
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 ..
-rw-r--r--. root root system_u:object_r:default_t:s0 index.html
-rw-r--r--. root root system_u:object_r:default_t:s0 test.html
#- ใช้คำสั่ง chcon เพื่อให้ context ของ /data/www เหมือนกับ /var/www/html
[root@web-server ~]# chcon -Rv --reference=/var/www/html /data/www
changing security context of ‘/data/www/index.html’
changing security context of ‘/data/www/test.html’
changing security context of ‘/data/www’
[root@web-server ~]# ้้้ls -laZ /data/www
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 .
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 ..
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 test.html
#- เรียกดู index.html ด้วยคำสั่ง curl
[root@web-server ~]# curl http://localhost/index.html
DocumentRoot at /data

3. แก้ไขให้ /data/www มี context ที่ให้ httpd เข้าถึงได้อย่างถาวร เพื่อป้องกันการ relabel ทั้ง filesystem แล้วทำให้ context ถูกแก้ไขกลับเป็นค่าเดิม

#- ติดตั้ง package policycoreutils-python เพื่อต้องการเรียกใช้งานคำสั่ง semanage
[root@web-server ~]# yum install -y policycoreutils-python
Loaded plugins: fastestmirror
.... truncated outputInstalled:
policycoreutils-python.x86_64 0:2.5-17.1.el7
Complete!#- แก้ไข policy ในส่วนของ context ของ /data/www
[root@web-server ~]# semanage fcontext -a -t httpd_sys_content_t "/data/www(/.*)?"
#- ทดสอบแก้ไข context และเรียกค่าด้วยคำสั่ง restorecon
[root@web-server ~]# chcon -Rv --reference=/tmp /data/www
changing security context of ‘/data/www/index.html’
changing security context of ‘/data/www/test.html’
changing security context of ‘/data/www’
[root@web-server ~]# restorecon -Rv /data/www
restorecon reset /data/www context system_u:object_r:tmp_t:s0->system_u:object_r:httpd_sys_content_t:s0
restorecon reset /data/www/index.html context system_u:object_r:tmp_t:s0->system_u:object_r:httpd_sys_content_t:s0
restorecon reset /data/www/test.html context system_u:object_r:tmp_t:s0->system_u:object_r:httpd_sys_content_t:s0
#- สามารถเรียกใช้งานได้ตามปกติ
[root@web-server ~]# curl http://localhost/index.html
DocumentRoot at /data

Damrongsak Reetanon
Damrongsak Reetanon

Written by Damrongsak Reetanon

OpenSource |Cloud Computing|Automation|DevOps

Responses (1)