วันอาทิตย์ที่ 29 เมษายน พ.ศ. 2555

ACL : Access Control Lists

หลังจากที่ทำความเข้าใจกับ Apache บน Mac (Lion) เรียบร้อยแล้ว. ปัญหาที่ค้างไว้คือ DocumentRoot ที่อยู่ที่ /Library/Webserver/Documents คือโฟลเดอร์นี้มันเป็นของ root ทำให้เวลาจะสร้างไฟล์ในโฟลเดอร์นี้ไม่สะดวก, มันสร้างไฟล์ใหม่ไม่ได้ด้วยยูสเซอร์ที่ทำงานอยู่. และผมก็ไม่อยากไปเปลี่ยนคอนฟิกไฟล์ด้วย.

toybox2:Documents poonlap$ pwd
/Library/WebServer/Documents
toybox2:Documents poonlap$ ls -la .
total 80
drwxr-xr-x+ 7 root  wheel    238 Apr 29 08:40 ./
drwxr-xr-x  5 root  wheel    170 Jul  8  2011 ../
-rw-r--r--  1 root  wheel   3726 Jun 26  2011 PoweredByMacOSX.gif
-rw-r--r--  1 root  wheel  31958 Jun 26  2011 PoweredByMacOSXLarge.gif
-rw-r--r--  1 root  wheel     13 Apr 29 01:03 index.html
-rw-r--r--  1 root  wheel     44 Jul  8  2011 index.html.en
drwxr-xr-x  3 root  wheel    102 Jun 25  2011 postgresql/


ในระบบยูนิกซ์ที่จัดการ permission ของไฟล์และโฟลเดอร์อย่างง่ายๆให้เขียนได้, อ่านได้ โดยแบ่งเป็นประเภท เจ้าของ (owner), กรุ๊ป (group) และอื่นๆ (other) ก็ใช้กับกรณีได้เหมือนกัน. ถ้าจะทำให้ยูสเซอร์ไปเขียนหรือสร้างไฟล์ต่างๆในโฟลเดอร์นี้ให้สะดวกมีหลายทาง

  1. ทำตัวเองให้เป็น root เช่น sudo -s แล้วไปเขียน (ไม่สะดวกและไม่ปลอดภัย)
  2. เปลี่ยน DocumentRoot ในคอนฟิกไฟล์ Apache (อันนี้อยากจะทิ้งคอนฟิกไว้อย่างนั้น, เลยไม่ทำ)
  3. ทำยูสเซอร์ตัวเองให้อยู่ในกลุ่ม wheel และไปแก้ chmod ให้กรุ๊ป wheel ทำอะไรกับโฟลเดอร์นั้นก็ได้ (ไม่อยาก assign ตัวเองในกลุ่ม wheel)
  4. ACL : Access Control Lists น่าจะเป็นทางออกที่ดีที่สุด.
หลังจากที่อ่าน man chmod แล้วก็เลยทำแบบนี้
toybox2:WebServer poonlap$ sudo chmod +a "poonlap allow delete_child,add_file" Documents/
toybox2:WebServer poonlap$ ls -eld Documents/
drwxr-xr-x+ 7 root  wheel  238 Apr 29 08:40 Documents//
 0: user:poonlap allow add_file,delete_child
toybox2:WebServer poonlap$ cd Documents/
toybox2:Documents poonlap$ touch testfile
toybox2:Documents poonlap$ rm testfile 

ทีนี้เฉพาะยูสเซอร์ poonlap ก็สามารถทำอะไรกับ /Library/Webserver/Document ได้แล้ว.

ทดสอบ Apache ที่มากับเครื่อง Macbook (Lion)

เครื่อง Macbook ทั้งหลายที่มี Darwin เป็นระบบปฏิบัติการมันก็เป็น UNIX ดีๆนี่เอง. แต่ก่อนผมมองพวก Mac เป็นแฟชั่น, พวกดีไซน์เนอร์ชอบใช้. เดี๋ยวนี้รู้สึกจะเปลี่ยนไปแล้วตั้งแต่มาเป็น Darwin ได้รับความสนใจจาก developer, โปรแกรเมอร์มากขึ้น. ใน Max OSX (Lion) จะมี infrastructure เครื่องมือต่างๆสำหรับพัฒนาเว็บมาด้วยพร้อมโดยไม่ต้องไปลงพวก Apache, php หรือ database server เองให้เสียเวลา. ไม่ต้องใช้ Macport หรือ fink.

วันนี้เลยอยากลอง Apache ก่อนว่าเป็นอย่างไรใน Mac. ลองผิดลองถูกเองจะได้รู้ว่ามันเป็นอย่างไร.

จาก terminal จะมีคำสั่ง apachectl ไว้เปิดปิดเซิร์ฟเวอร์. วิธีเช็คง่ายๆคือเปิดเบราเซอร์ แล้วใส่ที่อยู่เป็น localhost ถ้าเว็บเซิร์ฟเวอร์ในเครื่องไม่ได้รันอยู่ มันก็เปิดไม่ได้.

$ sudo apachectl start

แล้วลองไปที่ http://localhost ใหม่ควรจะเห็นเป็นแบบนี้.


เช็คจากโปรเซสประกอบด้วย จะเห็นว่ามีโปรเซสชื่อ httpd อยู่ด้วย.

toybox2:Documents poonlap$ ps -ef | grep http
    0  1562     1   0  7:49AM ??         0:00.09 /usr/sbin/httpd -D FOREGROUND
   70  1564  1562   0  7:49AM ??         0:00.00 /usr/sbin/httpd -D FOREGROUND
  501  1566   941   0  7:49AM ttys001    0:00.00 grep http

ต่อไปคงต้องหาว่า DocumentRoot มันอยู่ที่ไหน แต่คงต้องหาก่อนว่า config ไฟล์ของ Apache บน Mac มันอยู่ที่ไหน. โดยปกติ command line บนยูนิกซ์มันจะมี option ที่คล้ายๆกันเช่น -h หมายถึง help ก็เลยลอง -he ดูก่อนเผื่อจะมี hint อะไรบ้าง.

toybox2:sbin poonlap$ sudo apachectl -h
Usage: /usr/sbin/httpd [-D name] [-d directory] [-f file]
                       [-C "directive"] [-c "directive"]
                       [-k start|restart|graceful|graceful-stop|stop]
                       [-v] [-V] [-h] [-l] [-L] [-t] [-T] [-S]
Options:
  -D name            : define a name for use in  directives
  -d directory       : specify an alternate initial ServerRoot
  -f file            : specify an alternate ServerConfigFile
  -C "directive"     : process directive before reading config files
  -c "directive"     : process directive after reading config files
  -e level           : show startup errors of level (see LogLevel)
  -E file            : log startup errors to file
  -v                 : show version number
  -V                 : show compile settings
  -h                 : list available command line options (this page)
  -l                 : list compiled in modules
  -L                 : list available configuration directives
  -t -D DUMP_VHOSTS  : show parsed settings (currently only vhost settings)
  -S                 : a synonym for -t -D DUMP_VHOSTS
  -t -D DUMP_MODULES : show all loaded modules 
  -M                 : a synonym for -t -D DUMP_MODULES
  -t                 : run syntax check for config files
  -T                 : start without DocumentRoot(s) check

หลังจากอ่านแล้วก็คงต้องเดา(แบบมีเหตุผล)ว่าน่าจะลอง option -V ต่อ

toybox2:sbin poonlap$ sudo apachectl -V
Server version: Apache/2.2.21 (Unix)
Server built:   Nov 15 2011 15:12:57
Server's Module Magic Number: 20051115:30
Server loaded:  APR 1.4.2, APR-Util 1.3.10
Compiled using: APR 1.4.2, APR-Util 1.3.10
Architecture:   64-bit
Server MPM:     Prefork
  threaded:     no
    forked:     yes (variable process count)
Server compiled with....
 -D APACHE_MPM_DIR="server/mpm/prefork"
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_FLOCK_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=128
 -D HTTPD_ROOT="/usr"
 -D SUEXEC_BIN="/usr/bin/suexec"
 -D DEFAULT_PIDLOG="/private/var/run/httpd.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_LOCKFILE="/private/var/run/accept.lock"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="/private/etc/apache2/mime.types"
 -D SERVER_CONFIG_FILE="/private/etc/apache2/httpd.conf"

โอเค ตอนนี้เรารู้แล้วว่า config ไฟล์ของ Apache นี้อยู่ที่ /private/etc/apace2/httpd.conf และเข้าไปดูในไฟล์แล้ว, ดูเหมือน DocumentRoot ของเราจะเป็น /Library/WebServer/Documents. ทีนี้เลยลองเขียน index.html ง่ายๆในไดเรกทอรี่นั้น.

toybox2:Documents poonlap$ cat /Library/WebServer/Documents/index.html
Hello World!

แล้วลองเปิดเบราเซอร์ดูอีกครั้ง. ปรากฏว่ายังใช้ไม่ได้. ในเบราเซอร์บอกว่า 404 Not found เหมือนเดิม.
โอเค ไม่เป็นไรลองหาข้อมูลในเว็บเพิ่มเติมพบว่าการเปิดใช้ Apache ใน Mac ทำได้โดยไปที่ System Preference > Sharing แล้วเลือก Web sharing.


แล้วไปดูที่เบราเซอร์ใหม่อีกครั้ง. คราวนี้ใช้ได้แล้ว.


เลยสงสัยว่าทำไมตอนแรกใช้ไม่ได้. เลยลองดูโปรเซสอีกทีว่าเป็นอย่างไรหลังเปิด Web sharing.

toybox2:Documents poonlap$ ps -ef | grep http
    0  1588     1   0  8:03AM ??         0:00.08 /usr/sbin/httpd -D FOREGROUND -D WEBSHARING_ON
   70  1590  1588   0  8:03AM ??         0:00.00 /usr/sbin/httpd -D FOREGROUND -D WEBSHARING_ON
   70  1595  1588   0  8:05AM ??         0:00.00 /usr/sbin/httpd -D FOREGROUND -D WEBSHARING_ON
  501  1605   941   0  8:13AM ttys001    0:00.00 grep http

ทำให้รู้ว่า, ถ้ารัน apachectl จากบรรทัดคำสั่ง โปรเซสมันจะเป็นแค่ httpd -D FOREGROUND แต่ถ้าเปิด Web sharing โปรเซสจะมี -D WEBSHARING_ON ต่อท้ายด้วย. เลยต้องกลับไปดูใหม่ว่า -D มันคืออะไร.

-D name            : define a name for use in  directives

มันเป็นคำที่ตั้งไว้ให้ใช้กับ ifdefine ใน config ไฟล์. ดังนั้นเลยต้องกลับดูใน config ไฟล์ใหม่


#
# DocumentRoot: The directory out of which you will serve your
# documents. By default, all requests are taken from this directory, but
# symbolic links and aliases may be used to point to other locations.
#
DocumentRoot "/Library/WebServer/Documents"

ทำให้รู้ว่า DocumentRoot อยู่ที่ /Library/WebServer/Documents จริง, ก็ต่อเมื่อมีตั้ง WEBSHARING_ON เท่านั้น. ถ้ารัน apache จากบรรทัดคำสั่งเอง, มันจะเป็น -D FOREGROUND ซึ่งไม่มีกำหนดไว้ในไฟล์คอนฟิก, เลยทำให้ไม่มี DocumenetRoot.

สรุป​สั้น

  • เปิด Web sharing จาก System preferences
  • คอนฟิกไฟล์อยู่ที่ /private/etc/apache2/httpd.conf หรือ /etc/apache2/httpd.conf ก็ได้เพราะมี soft link จาก /etc ไปที่ /private/etc.
  • Apache ใน Mac Lion มีการใช้ -D ทำให้ต้องดูคอนฟิกไฟล์ดีๆ
  • ทางที่ดีควรไปเปลี่ยน Document ในคอนฟิกไฟล์ใหม่เลยเพราะรู้สึกว่าสถานที่ไม่ค่อยสะดวกเท่าไรนัก