บันทึกการติดตั้งแพกเกจต่าง ๆ
มีงานที่ต้องแปลงไฟล์ภาพ tif เป็น pdf ถ้าหากเป็นภาพหน้าเดียว ก็สามารถแปะลงใน OpenOffice Writer แล้วส่งออกเป็น pdf ได้
แต่ถ้าหากเป็นเอกสารหลายหน้า จะไม่สามารถทำได้
จึงคิดว่าน่าจะใช้วิธีสร้างเครื่องพิมพ์เทียมให้ส่งออกเป็น pdf ดีกว่า ซึ่งจะทำให้สามารถใช้งานได้หลากหลายกว่า ไม่ใช่กับเฉพาะไฟล์ภาพ tif อย่างเดียว
ค้นไปค้นมา ปรากฎว่าแพกเกจ cups เขาทำมาให้อยู่แล้ว ชื่อ cups-pdf ลงเสร็จแล้วก็สามารถใช้งานได้เลย
$ sudo aptitude install cups-pdf
งานต่อมาคือเพิ่มเครื่องพิมพ์
System -> Administration -> Printing
โดยเพิ่มเครื่องพิมพ์เป็น Virtual PDF Printer
และให้ไดรเวอร์เป็น Generic -> Postcript color printer
เสร็จเรียบร้อยแล้ว
สำหรับ tif แบบหลายหน้า สามารถใช้ Document Viewer คือ Evince เปิดเอกสาร แล้วพิมพ์ผ่านเครื่องพิมพ์ postscript-color-printer อันใหม่นี้ได้เลย โดยไฟล์ pdf ที่ได้ จะไปอยู่ในไดเรกทอรี่บ้านของเรา ~/PDF
update-เพิ่มเติมคำสั่ง gs
$ gs -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile=filename.pdf -- filename.prn
เพิ่มเติม -sDEVICE
png = png16m
แต่คุณภาพไม่ค่อยดี สู้เป็น pdfwrite ไม่ได้ (เอามาแก้ใน gimp ได้)
ดูรายละเอียดของ DEVICE ได้จากคำสั่ง gs --help
เพิ่มเติมสำหรับวินโดวส์
หากต้องการทำต้นฉบับหนังสือเพื่อส่งโรงพิมพ์ ให้เลือกเครื่องพิมพ์เป็นพวก Image Setter เช่น Scitex เป็นต้น
จะไม่มีปัญหาเรื่องพิมพ์ตกขอบทำให้ขอบขาด
$ gs -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile=output.pdf -c "<< /PageSize [843 596] >> setpagedevice" -- source.ps
ตัวอย่างข้างต้นเป็นขนาด A4 แบบ landscape
(เอาขนาดเป็น นิ้ว คูณด้วย 72
หรือเป็น มิลลิเมตร คูณด้วย 2.8387)
จาก:
Ghostscript:
Taking PDF Creation to the Next Level
หมายเหตุ
หากต้องการ crop ไฟล์ pdf ที่ผลิตออกมาแล้ว สามารถใช้คำสั่ง pdfcrop
จะใช้งานง่ายกว่า
$ gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=combined.pdf file1.pdf
file2.pdf
เอามาจาก Blog of Amorn Jiraseree-amornkun : วิธีรวมไฟล์ pdf หลายไฟล์เข้าด้วยกันในลินุกซ์
บันทึกการทำงานกับเทอร์มินัล
เทอร์มินัลของ GNOME ดือ gnome-terminal ยังใช้งานภาษาไทยกับ vim ได้ไม่ดีนัก
คือการเลื่อนเคอร์เซอร์ไม่ถูกตำแหน่ง และการคัดลอกข้อความด้วยเมาส์ก็ยังคัดลอกแบบผิด ๆ
การนี้ XTerm ใช้งานได้ดีกว่า แต่หน้าตาโบราณไปหน่อย และสีอักษรบนพื้นดำดูยากสักนิด
เลยทดลองปรับแต่งดูครับ
สำหรับเดเบียนติดตั้งด้วย
$ sudo aptitude install xterm xfonts-thai xfonts-thai-nectec xfonts-thai-poonlap xfonts-thai-vor
สำหรับผม ปรับแต่งให้เป็นพื้นขาว เลียนแบบ gnome-terminal และปรับแต่งตัวหนังสือให้ใหญ่ขึ้น และสีเข้มขึ้นเล็กน้อย
$ vi ~/.Xdefaults
!FONT *VT100.utf8Fonts.font: -misc-fixed-medium-r-normal--18-120-100-100-c-90-iso10646-1 !COLOR *VT100*foreground: grey10 *VT100*background: grey98 *VT100*color0: black *VT100*color1: red2 *VT100*color2: green4 *VT100*color3: yellow3 *VT100*color4: blue4 *VT100*color5: magenta4 *VT100*color6: cyan4 *VT100*color7: gray90 *VT100*color8: gray50 *VT100*color9: red1 *VT100*color10: green3 *VT100*color11: yellow2 *VT100*color12: rgb:5c/5c/ff *VT100*color13: magenta *VT100*color14: cyan3 *VT100*color15: white
ให้ระบบรับรู้ค่าใหม่ของเรา
$ xrdb .Xdefaults
เสร็จแล้ว เรียกใช้ด้วยคำสั่ง
$ xterm
เรียบร้อย ใช้งานภาษาไทยได้ดีแล้ว
หมายเหตุ
/etc/X11/rgb.txt
/etc/X11/apt-defaults/
ในไฟล์ XTerm
และ XTerm-color
เอามาจาก - Xterm Terminal Emulator Options
เอามาจาก ThaiLinuxCafe - bash tips
---
จิ๊กมาจากบล๊อกคุณพูนลาภเรื่อง คุณเปิด terminal กี่บาน?
ท่านเขียนไว้ดีมาก ๆ
screen เป็น virtual terminal มีประโยชน์มากในการใช้งานผ่าน ssh
ข้อดีคือเวลาเรากลับเข้าไปในงานที่ทำค้างอยู่ มันจะเห็นเหมือนกับเราทำที่จุดนั้นจริง ๆ
สมมุติเราคอมไพล์งานค้างไว้ ถ้ามีข้อผิดพลาด มันจะแสดงให้เห็นข้อผิดพลาดนั้นด้วย
ที่สำคัญคือมันเป็น text mode จึงทำงานเร็วและไม่เปลืองแบนด์วิธ
สั่งเริ่ม screen
$ screen
คีย์ลัดที่ใช้บ่อย
C-a c
= สร้างเชลล์ใหม่
C-a n
= ไปเทอร์มินัลถัดไป ( ที่ยัง attach อยู่ )
C-a p
= ไปเทอร์มินัลก่อนหน้า ( ที่ยัง attach อยู่ )
C-a d
= detach เชลล์ปัจจุบัน ( กลับมาด้วยคำสั่ง screen -r )
C-a "
= ดูเทอร์มินัลทั้งหมด ( คล้ายคำสั่ง screen -ls )
C-a 0
= ไปเทอร์มินัล 0
C-a 1
= ไปเทอร์มินัล 1
C-a S
= แบ่งเทอร์มินัลแบบแนวตั้ง
(*หมายเหตุ C-a
คือกด Ctrl+a )
ดูเชลล์ที่มี
$ screen -ls
ไป attach เชลล์ที่ถูก detach
ถ้ามีแค่เชลล์เดียว
$ screen -r
ถ้ามีหลายเชลล์
$ screen -r [pid.]tty[.host]
ปรับแต่งลักษณะของ screen ด้วยไฟล์ ~/.screenrc
$ vi ~/.screenrc
# ไม่เอาข้อความต้อนรับ startup_message off # ตั้งค่า scroll มากกว่าค่าปริยาย (100) defscrollback 1024 # ทำให้มีแถบ status ด้านล่าง hardstatus on hardstatus alwayslastline hardstatus string "%{.bW}%-w%{.rW}%n %t%{-}%+w %=%{..G} %H %{..Y} %m/%d %C%a " # ใช้ Ctrl+t แทน Ctrl+a escape ^Ta
ดูเพิ่มเติมได้ที่ gentoo-wiki: TIP Using screen
ถ้าใช้แล้วติดใจ อยากเวียนหัวเพิ่ม ให้ดู man screen
สมมุติว่าต้องการแก้ธีมของ drupal ที่เครื่อง server1.example.com
เราติดตั้ง drupal ไว้ที่ /var/www/drupal
สมมุติว่าเป็นธีม newsportal เหมือนของ debianclub
ไฟล์ที่ต้องการแก้ไขหลัก ๆ จะมีสองไฟล์ คือ style.css และ page.tpl.php
อยู่ใน /var/www/drupal/themes/newsportal/
เราจะเข้าถึง server1 ด้วยการใช้ ssh ปกติ
$ ssh server1.example.com
สั่งรัน screen
$ screen
กด Space bar ตามปกติ
ตอนนี้เราจะอยู่ในเทอร์มินัล 0 แต่ผมนิยมเว้นเทอร์มินัล 0 ไว้สำหรับงานจิปาถะชั่วคราว
และใช้เทอร์มินัล 1 ในการแก้ไขไฟล์ style.css
และใช้เทอร์มินัล 2 ในการแก้ไฟล์ page.tpl.php
กด C-a c
เพื่อสร้างเทอร์มินัล 1
$ cd /var/www/drupal/themes/newsportal
$ vi style.css
กด C-a c
เพื่อสร้างเทอร์มินัล 2
$ cd /var/www/drupal/themes/newsportal
$ vi page.tpl.php
หลังจากนี้เราสามารถสลับงานไปมาด้วยการกด C-a สองครั้ง
มันจะสลับไปมาระหว่างเทอร์มินัล 1 และ 2
ถ้าเราปิด ssh โดยไม่ออกจาก screen
เมื่อเข้ามาใหม่ เราสามารถเข้ามาที่งานที่ทำค้างไว้ได้เลย ด้วยคำสั่ง screen -r
หรือถ้าเราทำงานค้างไว้ที่ทำงาน และยังเปิด ssh ค้างอยู่
และเรากลับไปต่องานที่บ้าน เราสามารถช่วงชิง screen ที่ยังค้างอยู่ที่ทำงาน
มาด้วยคำสั่ง screen -d -r
จบแล้วครับ ใครมีทิป screen ดี ๆ แบ่งบ้างนะครับ
screen tip: screenrc และการสั่งงานด้วยบรรทัดคำสั่ง
norm
ใช้การแก้ไขไฟล์ ~/.screenrc
ดังนี้
# vi ~/.screenrc
sessionname norm screen top screen 1 tail -f /var/log/syslog screen 2 tail -f /var/log/dmesg
รัน screen
# screen
จะได้ผลตามต้องการ
จะใช้การทำงานผ่านสคริปต์ ดังนี้
สมมุติตั้งชื่อสคริปต์ว่า screen_monitor.sh
# vi screen_monitor.sh
#!/bin/bash screen -S norm -md bash screen -S norm -p0 -X stuff "screen bash " screen -S norm -p0 -X stuff "top " screen -S norm -p1 -X stuff "screen bash " screen -S norm -p1 -X stuff "tail -f /var/log/syslog " screen -S norm -p2 -X stuff "screen bash " screen -S norm -p2 -X stuff "tail -f /var/log/dmesg "
เปลี่ยนสิทธิ์และสั่งรัน
# chmod 755 screen_monitor.sh # ./screen_monitor.sh
จะไม่เห็นการเปลี่ยนแปลง เพราะเราสั่งให้ทำงานแบบเบื้องหลัง (-md
)
จะเข้าไปสู่ (attach
) การทำงานของ screen ได้ด้วยคำสั่ง
# screen -r norm
จบแล้วครับ
เอามาจาก debian : ทดลองติดตั้ง hylafax
HylaFAX เป็นแพกเกจที่ใช้ทำ Fax Server
ใช้งานได้เสถียรดี และสามารถรองรับงานใหญ่ได้
ติดตั้ง hylafax-server
# aptitude install hylafax-server
Major possible upgrade issues
<<<--- [Enter]
Which paper size should be the system default?
<<<--- a4
ติดตั้งโมเด็มเป็นแฟกซ์
# faxsetup
ตอบตามจริง ยกเว้นข้อมูลของเรา ตัวอย่างของผมคือ
...
Country code [1]? <<<--- 66
Area code [415]? <<<--- 2
Phone number of fax modem [+1.999.555.1212]? <<<--- ใส่เบอร์แฟกซ์เรา
Local identification string (for TSI/CIG) ["NothingSetup"]? <<<--- ชื่อร้านหรือหน่วยงาน
...
Protection mode for received facsimile [0600]? <<<--- 0755
Protection mode for session logs [0600]? <<<--- 0755
...
อันนี้ผมขี้เกียจเก็บข้อมูลผู้ใช้ เลยตั้งเป็นว่าสามารถใช้งานได้จากทุกเครื่อง โดยไม่ต้องมีชื่อผู้ใช้งาน
# vi /etc/hylafax/hosts.hfaxd
... ^.*@.*\.example\.com$
# /etc/init.d/hylafax restart
client ฝั่งวินโดวส์ ผมใช้ Whfc
ส่วน client ฝั่งลินุกส์ ยังหาตัวที่ใช้งานสะดวกยังไม่ได้ครับ
ปรับปรุง: 49-11-14
วันนี้ได้มีโอกาสทดสอบการติดตั้งจริงบน etch อีกครั้งนึง
ปรากฎว่าเกิดปัญหาตอนติดตั้ง คือ
หน้าจอขึ้นมาถาม Area code ไม่หยุด ต้องกด Ctrl+C เพื่อเบรก
ทำให้การติดตั้งไฟล์ไม่สมบูรณ์
(ยังไม่แน่ใจว่าเกิดจากแพกเกจ หรือฮาร์ดแวร์ครับ)
ผมแก้ไขดังนี้ครับ
ดาวน์โหลดแพกเกจจากต้นฉบับ (ไม่แน่ใจความถูกต้องของแพกเกจในเครื่องเรา)
# wget http://ftp.us.debian.org/debian/pool/main/h/hylafax/hylafax-server_4.3.0-9_i386.deb
แตกไฟล์โดยไม่ติดตั้ง ไปยัง / (root directory)
# dpkg-deb -x hylafax-server_4.3.0-9_i386.deb /
ปรับตั้งแพกเกจใหม่
# dpkg-reconfigure hylafax-server
หลังจากนั้นก็เริ่มขั้นตอนตามปกติคือ
# faxsetup
...
# /etc/init.d/hylafax restart
สร้างไฟล์ที่จะดักการทำงานตอนรับแฟกซ์ ชื่อ /etc/hylafax/FaxDispatch
แล้วเริ่มการทำงานใหม่ เพื่อให้ไฟล์ใหม่นี้ถูกคัดลอกไปไว้ในไดเรคทอรี่ของ hylafax
# vi /etc/hylafax/FaxDispatch
/usr/bin/tiff2ps -a $FILE | lpr -P $PRINTER_NAME
# /etc/init.d/hylafax restart
ใช้ความสามารถของ gs
--รอทดลอง--
เอามาจาก debian : ทดลองติดตั้ง hylafax
ต้องมีเซิร์ฟเวอร์ที่เป็น HylaFAX แล้ว ดูวิธีติดตั้งได้จากคราวก่อน
ติดตั้ง Pyla
$ sudo aptitude install python python-tk
$ wget http://www.teamsw.it/pyla/download/pyla1.1.7.1.tgz
$ tar xfz pyla1.1.7.1.tgz
$ sudo mv pyla /usr/local
$ /usr/local/pyla/pyla.py
-> ปรับตั้งโปรแกรม
ติดตั้งเครื่องพิมพ์เทียมให้ pyla
เอามาจาก Fun with CUPS and Pyla
หลักการคือเขาใช้ perl เขียนโปรแกรมทำหน้าที่เป็น socket คอยดูว่ามีข้อมูลเข้ามาทางพอร์ต 5691 หรือเปล่า ถ้ามี ก็จะเรียกใช้โปรแกรมนี้ซึ่งจะไปเรียกใช้ pyla อีกทีนึง
สร้างโปรแกรมเรียก pyla ชื่อ pyla-print เอาใส่ไว้ใน /usr/local/bin
$ sudo vi /usr/local/bin/pyla-print
#!/usr/bin/perl # Daniel E. Markle # 20031114 Revision 0.1 # This program starts up a daemon which will watch for a postscript file # coming in from CUPS, then launch pyla to send it as a fax. # Use it with the socket://localhost:5691 URL in cups. # Issues: # -security, make sure only localhost can see this port, it allows anyone # who can stream data to this port to popup pyla on your desktop # -must be ran as the user or the window may not pop up at the right # place, if at all # ***CONFIGURE ME HERE # Port to listen on, use socket://localhost: in cups my $MY_PORT = 5691; # Temporary file storage, this is a file not a folder my $TMP_FILE_NAME = "/tmp/cupsfaxtemp"; # Path to pyla.py my $PYLA_PATH = "/usr/local/pyla/pyla.py"; # Path to python binary # use this one for Linux my $PYTHON_PATH = "/usr/bin/python"; # use this one for OS X #my $PYTHON_PATH = "/usr/bin/pythonw"; # ***END CONFIGURATION # ----- You shouldn't need to touch anything beyond this point ----- use IO::Socket::INET; # check to make sure we can use the temp file open ( TMPFILE, ">", $TMP_FILE_NAME ) or die "Can not open temp file $TMP_FILE_NAME, " . "check to make sure it is not owned by another user"; close ( TMPFILE ); if ( !(-e $PYLA_PATH) ) { die "I do not see pyla at $PYLA_PATH"; } my $data; my $server = IO::Socket::INET->new ( LocalPort => $MY_PORT, Type => SOCK_STREAM, Reuse => 1, Listen => 1 ) or die "Could not start server process"; while ( my $job = $server->accept() ) { open ( TMPFILE, ">", $TMP_FILE_NAME ); while ( <$job> ) { print TMPFILE $_; } close ( TMPFILE ); close $job; `cat "$TMP_FILE_NAME" | "$PYTHON_PATH" "$PYLA_PATH" -i` }
ทำให้รันได้
$ sudo chmod 755 /usr/local/bin/pyla-print
สร้างโปรแกรมที่รันเป็น daemon คอยดูซอกเก็ต ชื่อ pyla-printd เอาใส่ไว้ใน /etc/init.d
$ sudo vi /etc/init.d/pyla-printd
#!/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin DAEMON=/usr/local/bin/pyla-print NAME=pyla-print DESC="Pseudo printer for Pyla" test -x $DAEMON || exit 0 case "$1" in start) echo -n "Starting $DESC: " start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \ --background --make-pidfile --exec $DAEMON -- $DAEMON_OPTS echo "$NAME." ;; stop) echo -n "Stopping $DESC: " start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \ --oknodo echo "$NAME." ;; restart|force-reload) echo -n "Restarting $DESC: " start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \ --oknodo sleep 1 start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \ --background --make-pidfile --exec $DAEMON -- $DAEMON_OPTS echo "$NAME." ;; *) N=/etc/init.d/$NAME echo "Usage: $N {start|stop|restart|force-reload}" >&2 exit 1 ;; esac exit 0
ทำให้รันได้ - สั่งรันเป็น daemon และให้เริ่มรันทุกครั้งที่เปิดเครื่อง
$ sudo chmod 755 /etc/init.d/pyla-printd
$ sudo /etc/init.d/pyla-printd restart
$ sudo update-rc.d pyla-printd defaults
ติดตั้งตัวจัดการเครื่องพิมพ์
$ sudo aptitude install cupsys-client
เพิ่มเครื่องพิมพ์เทียมให้ระบบ
$ sudo lpadmin -p pseudo-pyla -E -v socket://localhost:5691
หรือตั้งชื่อให้เรียกง่ายขึ้นว่า hylafax
เฉย ๆ ก็ได้
$ sudo lpadmin -p hylafax -E -v socket://localhost:5691
เมื่อทุกอย่างเรียบร้อย จะมีเครื่องพิมพ์ฃื่อ psuedo-pyla ขึ้นมา ถ้าเราพิมพ์มาที่เครื่องพิมพ์ตัวนี้ เขาจะมาเรียกใช้ pyla ให้ส่งแฟกซ์เอง
update
# vi /etc/hylafax/config.ttyS0
... RecvFileMode: 0666 ...
ปรับปรุง HylaFax Client
ปรับปรุงจากdebian: ทดลองทำ HylaFAX Client
ครั้งก่อนมีปัญหาว่า daemon ถูกรันด้วย root ใน runlevel ที่อยู่ในสถานะอักขระ (text mode) ซึ่งยังไม่มีการกำหนดค่าตัวแปรแวดล้อม $DISPLAY
แต่เวลาซอกเก็ตถูกเรียกใช้ จะถูกเรียกใช้ด้วยผู้ใช้ที่ runlevel ที่อยู่ในสถานะกราฟฟิก โดย gtk จะมาดูว่าต้องแสดงผลที่จอไหนจากตัวแปรแวดล้อม $DISPLAY
นี้ ทำให้โปรแกรมตาย
ซึ่งต้องแก้ปัญหาด้วยการใช้คำสั่ง $ sudo /etc/init.d/pyla-printd restart
จากเทอร์มินอล จึงจะหาย
ตอนใหม่นี้ เราจะไม่ตั้งให้เรียกจาก runlevel แล้ว แต่จะตั้งให้รันจาก gnome-session ของผู้ใช้เลย ทำให้แก้ปัญหาเรื่องต้องเริ่มเซอร์วิสใหม่ได้
แต่เพื่อป้องกันการสับสน จะขอเริ่มใหม่เลย
ต้องมีเซิร์ฟเวอร์ที่เป็น HylaFAX แล้ว ดูวิธีติดตั้งได้จากdebian: ลองติดตั้ง Hylafax
ติดตั้ง Pyla
$ sudo aptitude install python python-tk
$ wget http://www.teamsw.it/pyla/download/pyla1.1.7.1.tgz
$ tar xfz pyla1.1.7.1.tgz
$ sudo mv pyla /usr/local
$ /usr/local/pyla/pyla.py
-> ปรับตั้งโปรแกรม
ติดตั้งเครื่องพิมพ์เทียมให้ pyla
เอามาจาก Fun with CUPS and Pyla
หลักการคือเขาใช้ perl เขียนโปรแกรมทำหน้าที่เป็น socket คอยดูว่ามีข้อมูลเข้ามาทางพอร์ต 5691 หรือเปล่า ถ้ามี ก็จะเรียกใช้โปรแกรมนี้ซึ่งจะไปเรียกใช้ pyla อีกทีนึง
สร้างโปรแกรมเรียก pyla ชื่อ pyla-print เอาใส่ไว้ใน /usr/local/bin
$ sudo vi /usr/local/bin/pyla-print
#!/usr/bin/perl # Daniel E. Markle # 20031114 Revision 0.1 # This program starts up a daemon which will watch for a postscript file # coming in from CUPS, then launch pyla to send it as a fax. # Use it with the socket://localhost:5691 URL in cups. # Issues: # -security, make sure only localhost can see this port, it allows anyone # who can stream data to this port to popup pyla on your desktop # -must be ran as the user or the window may not pop up at the right # place, if at all # ***CONFIGURE ME HERE # Port to listen on, use socket://localhost: in cups my $MY_PORT = 5691; # Temporary file storage, this is a file not a folder my $TMP_FILE_NAME = "/tmp/cupsfaxtemp"; `touch "$TMP_FILE_NAME"; chmod 777 "$TMP_FILE_NAME"`; # Log file storage my $LOG_FILE_NAME = "/tmp/cupsfaxlog"; `touch "$LOG_FILE_NAME"; chmod 777 "$LOG_FILE_NAME"`; # Path to pyla.py my $PYLA_PATH = "/usr/local/pyla/pyla.py"; # Path to python binary # use this one for Linux my $PYTHON_PATH = "/usr/bin/python"; # use this one for OS X #my $PYTHON_PATH = "/usr/bin/pythonw"; # ***END CONFIGURATION # ----- You shouldn't need to touch anything beyond this point ----- use IO::Socket::INET; # check to make sure we can use the temp file open ( TMPFILE, ">", $TMP_FILE_NAME ) or die "Can not open temp file $TMP_FILE_NAME, " . "check to make sure it is not owned by another user"; close ( TMPFILE ); if ( !(-e $PYLA_PATH) ) { die "I do not see pyla at $PYLA_PATH"; } my $data; my $server = IO::Socket::INET->new ( LocalPort => $MY_PORT, Type => SOCK_STREAM, Reuse => 1, Listen => 1 ) or die "Could not start server process"; while ( my $job = $server->accept() ) { open ( TMPFILE, ">", $TMP_FILE_NAME ); while ( <$job> ) { print TMPFILE $_; } close ( TMPFILE ); close $job; `cat "$TMP_FILE_NAME" | "$PYTHON_PATH" "$PYLA_PATH" -i &> "$LOG_FILE_NAME"`; }
ทำให้รันได้
$ sudo chmod 755 /usr/local/bin/pyla-print
ตั้งให้ gnome-sessions รัน pyla-print
ทำผ่านเมนู System -> Preferences -> Sessions
แท็บ Startup Programs
กดปุ่ม
Add
Name: Pyla Print Daemon Command: /usr/local/bin/pyla-print Comment: Pyla Print Daemon (start by gnome-sessions)
ล๊อกเอาต์ และ ล๊อกอิน 1 ครั้ง
จัดการให้โปรแกรมตายตอนล๊อกเอาต์
เมนู System -> Preferences -> Sessions
แท็บ Current Sessions
เลือกบรรทัดที่เป็น pyla-print
เปลี่ยนปุ่ม Style เป็น Restart
เสร็จแล้ว
ติดตั้งตัวจัดการเครื่องพิมพ์
$ sudo aptitude install cupsys-client
เพิ่มเครื่องพิมพ์เทียมให้ระบบ ตั้งชื่อว่า hylafax
$ sudo lpadmin -p hylafax -E -v socket://localhost:5691
เมื่อทุกอย่างเรียบร้อย จะมีเครื่องพิมพ์ฃื่อ hylafax ขึ้นมา ถ้าเราพิมพ์มาที่เครื่องพิมพ์ตัวนี้ เขาจะมาเรียกใช้ pyla ให้ส่งแฟกซ์เอง
เพิ่มเติม
/usr/local/pyla/hylaproto.py
$ sudo vi /usr/local/pyla/hylaproto.py
... class Hylafax: ... def getqueue(self,queue,jfmt=JFMT,view='priv'): ... else: retlist[-1] = retlist[-1] + l + '\n' #wd's retlist.sort(reverse=True) return (1,retlist) def callback(self,str): ...
debootstrap เป็นแพกเกจที่ใช้ในการติดตั้งเดเบียนผ่านเครือข่าย
สามารถนำมาใช้ประโยชน์ได้เช่น การติดตั้งลินุกซ์ซ้อนเข้าในระบบเพื่อการทดลอง หรือการติดตั้งระบบเพิ่มเติมสำหรับงาน Virtualization
การใช้งาน ควรมี mirror ซึ่งอาจเป็น apt-proxy apt-cacher หรือ mirror แท้ ๆ อยู่ในเครือข่ายเราก่อน
รูปแบบใช้งานคือ
debootstrap [OPTION...] SUITE TARGET [MIRROR [SCRIPT]]
SUITE คือรุ่นของลินุกซ์ที่เราจะติดตั้ง สำหรับเดเบียนได้แก่ sarge หรือ etch เป็นต้น
TARGET คือพาร์ติชั่นที่เราเมานต์ไว้แล้วสำหรับการติดตั้ง
MIRROR คือคลังแพกเกจ เช่น apt-proxy หรือ mirror อื่น
รายละเอียดสามารถศึกษาได้เพิ่มเติมจาก man debootstrap
ก่อนหน้าที่จะรู้จักคำสั่ง aptitude การติดตั้งแพกเกจด้วยคำสั่ง apt-get นั้น เมื่อเราลบแพกเกจที่เราไม่ต้องการออกแล้ว จะเหลือแพกเกจลูกที่ไม่ถูกใช้งานอยู่เป็นจำนวนมาก เวลาเราต้องการทำการทดลองใหม่ เราจะไม่ทราบแน่ชัดถึงผลกระทบของแพกเกจใหม่กับแพคเกจลูกของใหม่กับของเก่า
ดังนั้นเพื่อให้ระบบสะอาดเหมือนกับการติดตั้งใหม่ เราจึงควรแบ่งพาร์ติชั่นไว้สำหรับการทดลองนี้โดยเฉพาะ ทุกครั้งที่ต้องการการทดลองใหม่ ๆ เราจะติดตั้งเดเบียนใหม่ลงในพาร์ติชั่นนี้เลย ด้วย debootstrap
สมมุติว่า mirror เราชื่อ www.example.com
เครื่องเราชื่อ server1
และสมมุติว่าแบ่งพาร์ติชั่นไว้ดังนี้
/dev/hda1 = /boot ขนาด 100M /dev/hda2 = / ขนาด 10G เป็นระบบปัจจุบัน /dev/hda3 = Extended /dev/hda5 = swap ขนาด 512M
เราจะติดตั้งระบบใหม่บน /dev/hda6 ให้มีขนาด 20G เพื่อใช้เป็น / (root) ของระบบใหม่
สร้างพาร์ติชั่นใหม่ คือ /dev/hda6 ขนาด 20G
# fdisk /dev/hda
Command (m for help): <<<--- n Command action l logical (5 or over) p primary partition (1-4) <<<--- l First cylinder (XXXX-XXXXX, default XXXXX):<<<--- {Enter} Last cylinder or +size or +sizeM or +sizeK (XXXX-XXXXX, default XXXXX):<<<--- +20G . Command (m for help): <<<--- w
สร้างระบบไฟล์เป็น ext3
# mkfs.ext3 /dev/hda6
สร้างจุดเมานต์ให้ /dev/hda6 สมมุติว่าชื่อ /mnt/disk
# mkdir -p /mnt/disk
ก่อนจะติดตั้ง ต้องเมานต์ /dev/hda6 ลงบน /mnt/disk ก่อน
# mount /dev/hda6 /mnt/disk
ติดตั้ง etch บน /mnt/disk ผ่าน debootstrap
# debootstrap etch /mnt/disk http://www.example.com:9999/debian
เมื่อติดตั้งเสร็จแล้ว จำเป็นต้องคัดลอกไฟล์ที่จำเป็นในการเริ่มต้นระบบไปยัง /mnt/disk และทำการแก้ไขตามจำเป็น
# cp /etc/hosts /mnt/disk/etc ; vi /mnt/disk/etc/hosts
# cp /etc/network/interfaces /mnt/disk/etc/network ; vi /mnt/disk/etc/network/interfaces
# cp /etc/hostname /mnt/disk/etc ; vi /mnt/disk/etc/hostname
# cp /etc/apt/sources.list /mnt/disk/etc/apt ; vi /mnt/disk/etc/apt/sources.list
# cp /etc/fstab /mnt/disk/etc ; vi /mnt/disk/etc/fstab
ตรงไฟล์ /mnt/disk/etc/fstab อย่าลืมเปลี่ยน /dev/hda2 เป็น /dev/hda6
สร้างสภาพแวดล้อม เพื่อใช้ในการ chroot ไปยัง /mnt/disk
# mount -t proc none /mnt/disk/proc
# mount -o bind /dev /mnt/disk/dev
# mount -t sysfs /sys /mnt/disk/sys
chroot ไปยัง /mnt/disk
# chroot /mnt/disk /bin/bash
เริ่มการติดตั้งแพกเกจที่จำเป็นและปรับตั้งระบบ
server1:/# aptitude update
server1:/# aptitude install locales console-data
server1:/# dpkg-reconfigure locales
server1:/# aptitude install initrd-tools usbutils pciutils bzip2 ssh grub udev yaird ssh
( ถ้าต้องการระบบ X-Window ด้วย
server1:/# aptitude install xorg gdm gnome
)
ติดตั้งเคอร์เนล
server1:/# aptitude install linux-image-686
อย่าลืมตั้งรหัสผ่านให้ root
server1:/# passwd
กันเหนียวด้วยการปรับตั้งระบบใหม่ทั้งหมด
server1:/# dpkg-reconfigure -a
ตอบค่าปริยายทั้งหมด ยกเว้นส่วนของ locales, tzconfig, dash ให้ตอบตามต้องการ
ออกจากสภาพ chroot
server1:/# exit
ยกเลิกการเมานต์ที่ผ่านมา
# umount /mnt/disk/proc
# umount /mnt/disk/dev
# umount /mnt/disk/sys
# ldconfig
# sync
(ถ้ายกเลิกเมานต์ไม่ผ่าน ไม่เป็นไร ให้ผ่านไปก่อน)
ปรับตั้งการบูต
# vi /boot/grub/menu.lst
แก้ไขลำดับการบูต
แก้จาก default 0 เป็น default 2
... default 2 ...
เติมลำดับการบูตให้กับเดเบียนใหม่ที่เราเพิ่งติดตั้งเสร็จ โดยต่อท้ายจากของเก่า
... title Etch-Experiment, kernel 2.6.18-3-386 root (hd0,5) kernel /vmlinuz root=/dev/hda5 ro initrd /initrd.img savedefault ...
เรียบร้อยแล้ว รีบูตใหม่ได้เลย
# reboot
ระบบใหม่จะเป็นเดเบียน Etch ใหม่แบบสะอาด ๆ
เมื่อจะทำการทดลองระบบใหม่ ถ้าจำเป็นต้องลงใหม่ก็ทำเหมือนเดิมครับ
สมมุติว่า mirror เราชื่อ www.example.com ได้ติดตั้ง apt-proxy สำหรับอูบุนตูไว้เรียบร้อยแล้ว
(เวลาใช้งานจาก apt-proxy ต้องระบุพอร์ตเป็น 9999)
และสมมุติว่าแบ่งพาร์ติชั่นไว้ดังนี้
/dev/hda1 = / เป็นเดเบียน Etch /dev/hda2 = ว่าง ขนาด 20G เตรียมสำหรับ Feisty /dev/hda3 = Extended /dev/hda5 = swap ขนาด 512M
เราจะติดตั้งระบบใหม่บน /dev/hda2 ให้มีขนาด 20G เพื่อใช้เป็น / (root) ของระบบใหม่
สร้างระบบไฟล์เป็น ext3
# mkfs.ext3 /dev/hda2
สร้างจุดเมานต์ให้ /dev/hda2 สมมุติว่าชื่อ /mnt/disk
# mkdir -p /mnt/disk
ก่อนจะติดตั้ง ต้องเมานต์ /dev/hda2 ลงบน /mnt/disk ก่อน
# mount /dev/hda2 /mnt/disk
ติดตั้ง debootstrap บน Etch
# aptitude install debootstrap
เนื่องจากแพกเกจ debootstrap ของ Etch ไม่มีสคริปต์สำหรับอูบุนตู Feisty
เราจึงต้องไปดาว์นโหลดแพกเกจ debootstrap ของ Feisty เอง เพื่อมาแตกเอาไฟล์สคริปต์นี้
# wget http://fr.archive.ubuntu.com/ubuntu/pool/main/d/debootstrap/debootstrap_0.3.3.2ubuntu3_all.deb
ถึงวันนี้ มิเรอร์ของไทย mirror.in.th ยังไม่อัปเดตครับ
แตกด้วย Archive Manager เฉพาะไฟล์ที่ชื่อ feisty แล้วนำไปใส่ไว้ใน /usr/lib/debootstrap/scripts
# cp feisty /usr/lib/debootstrap/scripts
เริ่มติดตั้ง Feisty บน /mnt/disk ผ่าน debootstrap
# debootstrap feisty /mnt/disk http://www.example.com:9999/debian
เมื่อติดตั้งเสร็จแล้ว จำเป็นต้องคัดลอกไฟล์ที่จำเป็นในการเริ่มต้นระบบไปยัง /mnt/disk และทำการแก้ไขตามจำเป็น
# cp /etc/hosts /mnt/disk/etc ; vi /mnt/disk/etc/hosts
# cp /etc/networks/interface /mnt/disk/etc/networks ; vi /mnt/disk/etc/networks/interface
# cp /etc/hostname /mnt/disk/etc ; vi /mnt/disk/etc/hostname
# cp /etc/apt/sources.list /mnt/disk/etc/apt ; vi /mnt/disk/etc/apt/sources.list
# cp /etc/fstab /mnt/disk/etc ; vi /mnt/disk/etc/fstab
ตรงไฟล์ /mnt/disk/etc/fstab อย่าลืมเปลี่ยน /dev/hda1 เป็น /dev/hda2
แก้ไขไฟล์ /etc/apt/sources.list
เป็นดังนี้
# vi /mnt/disk/etc/apt/sources.list
deb http://www.example.com:9999/ubuntu feisty main restricted universe multiverse deb-src http://www.example.com:9999/ubuntu feisty main restricted universe multiverse
สร้างสภาพแวดล้อม เพื่อใช้ในการ chroot ไปยัง /mnt/disk
# mount -t proc none /mnt/disk/proc
# mount -o bind /dev /mnt/disk/dev
# mount -t sysfs /sys /mnt/disk/sys
chroot ไปยัง /mnt/disk
# chroot /mnt/disk /bin/bash
เริ่มการติดตั้งแพกเกจที่จำเป็นและปรับตั้งระบบ
(CHROOT)# mount -a
(CHROOT)# aptitude update
(CHROOT)# aptitude install locales console-data localeconf
ปรับแต่ง locale ให้ด้วย
(CHROOT)# locale-def en_US.UTF-8
(CHROOT)# dpkg-reconfigure locales localeconf
ติดตั้งแพกเกจจำเป็นที่เหลือ
(CHROOT)# aptitude install initrd-tools usbutils pciutils bzip2 ssh grub udev yaird ubuntu-minimal ubuntu-standard
( ถ้าต้องการระบบ X-Window ด้วย
(CHROOT)# aptitude install ubuntu-desktop xorg gdm gnome
)
ติดตั้งเคอร์เนล
(CHROOT)# aptitude install linux-image-686
อย่าลืมตั้งรหัสผ่านให้ root
(CHROOT)# passwd
ปรับตั้งระบบใหม่ทั้งหมด
(CHROOT)# dpkg-reconfigure -a
ตอบค่าปริยายทั้งหมด ยกเว้นส่วนของ locales, tzconfig, dash ให้ตอบตามต้องการ
ออกจากสภาพ chroot
(CHROOT)# exit
ยกเลิกการเมานต์ที่ผ่านมา
# umount /mnt/disk/proc
# umount /mnt/disk/dev
# umount /mnt/disk/sys
# ldconfig
# sync
(ถ้ายกเลิกเมานต์ไม่ผ่าน ไม่เป็นไร ให้ผ่านไปก่อน)
ปรับตั้งการบูต
# vi /boot/grub/menu.lst
แก้ไขลำดับการบูต
แก้จาก default 0 เป็น default 2
... default 2 ...
เติมลำดับการบูตให้กับอูบุนตูใหม่ที่เราเพิ่งติดตั้งเสร็จ โดยต่อท้ายจากของเก่า
... title Ubuntu Feisty - Experiment, kernel 2.6.20-15-generic root (hd0,1) kernel /vmlinuz root=/dev/hda2 ro initrd /initrd.img savedefault ...
เรียบร้อยแล้ว รีบูตใหม่ได้เลย
# reboot
จะได้อูบุนตู Feisty ที่ติดตั้งผ่าน debootstrap
หมายเหตุ
$ sudo dpkg-reconfigure -a
$ sudo aptitude update && sudo aptitude dist-upgrade
บนเดเบียน สามารถเปิดใช้งานมอดูลด้วยคำสั่ง a2enmod MODULENAME
และปิดการใช้งานด้วยคำสั่ง a2dismod MODULENAME
# vi /etc/apache2/site-enables/example.com
<VirtualHost *:80> ServerAdmin webmaster@example.com ServerName www.example.com ServerAlias example.com <IfModule mod_cband.c> CBandExceededSpeed 1000 10 10 </IfModule> ... </VirtualHost>
# /etc/init.d/apache2 force-reload
# vi /etc/apache2/conf.d/charset
AddCharset TIS-620 .tis-620 .th AddCharset CP874 .cp874
... LoadModule wsgi_module modules/mod_wsgi.so
ที่มา: http://serverfault.com/questions/435926/cant-locate-api-module-structure-mod-wsgi
# aptitude update
# aptitude install apache2 apache2-doc apache2-mpm-prefork apache2-utils apache2.2-common
# aptitude install php5 php5-cgi php5-commonphp5-curlphp5-gd php5-mcrypt php5-mysql php5-odbc php5-pgsql php5-xmlrpc
# aptitude install libapache2-mod-php5
ช่วงนี้ aptitude ของ etch เป็นอะไรไม่รู้ ชอบติดตั้งไฟล์ไม่ครบ
(อาจเป็นที่ apt-proxy)
แก้ไขแพกเกจติดตั้งไฟล์ไม่ครบ โดยการแตกไฟล์โดยไม่ติดตั้ง ไปยัง /
# dpkg-deb -x /var/cache/apt/archives/apache2.2-common_2.2.3-3.1_i386.deb /
# aptitude install mysql-client-5.0 mysql-common mysql-server-5.0 phpmyadmin
บันทึกการเปิดโมดูลแบบน้อยสุด module-minimal
# a2enmod actions
# a2enmod alias
# a2enmod authz_host
# a2enmod cgi
# a2enmod dir
# a2enmod mime
# a2enmod php5
# a2enmod rewrite
# a2enmod status
# /etc/init.d/apache2 restart
บันทึกการเปิดใช้โมดูลแบบปกติ module-normal
# a2enmod alias
# a2enmod auth_basic
# a2enmod authn_file
# a2enmod authz_default
# a2enmod authz_groupfile
# a2enmod authz_host
# a2enmod authz_user
# a2enmod autoindex
# a2enmod cgi
# a2enmod dir
# a2enmod env
# a2enmod mime
# a2enmod mod_python
# a2enmod negotiation
# a2enmod php5
# a2enmod setenv
# a2enmod status
# /etc/init.d/apache2 restart
เอา php.ini จากตัวอย่างแบบ recommended มาใช้
# cp /usr/share/doc/php5/examples/php.ini-recommended /etc/php5/apache2/php.ini
แก้จะให้ใช้ได้กับ drupal
# vi /etc/php5/apache2/php.ini
... ; หน่วยความจำที่ยอมให้สคริปต์รันได้ ; เก่าเป็น 8M drupal แนะนำ 12M เราใช้ 16M กันเหนียว memory_limit = 16M ; Maximum amount of memory a script may consume (8MB) ... ; ตัวแปรเป็น global อัตโนมัติ ; อันนี้ก็กันเหนียว ตอนเขียนโค๊ดเรี่ยราดไว้หลายที่ เก่าเป็น Off เราแก้เป็น On register_globals = On ... ; ขนาดไฟล์ใหญ่สุด ที่ post ได้ ; อันนี้จำได้แม่น หน้าแตกเพราะเอา Bon Echo เข้าไม่ได้ เก่าเป็น 8M แก้เป็น 20M post_max_size = 20M ... ; adodb ไม่ต้องก็ได้ include_path = ".:/usr/share/php5:/usr/share/php4:/usr/share/php/adodb" ... ; ค่าแนะนำของ drupal session.save_handler = user ... ; ค่าแนะนำของ drupal session.cache_limiter = none ...
ส่วนของไซต์ ถ้ามีหลายไซท์ ควรแยกไฟล์ออกมาวางไว้ที่ /etc/apache2/site-available
เวลาจะเปิดใช้งานก็ใช้คำสั่ง a2ensite
เช่นไซต์ example.com
# vi /etc/apache2/sites-available/example.com
<VirtualHost *:80> ServerAdmin webmaster@example.com ServerName www.example.com DocumentRoot /var/www/www.example.com/ <Directory /> Options FollowSymLinks AllowOverride All </Directory> <Directory /swww2/var/www/www.thaitux.info/> Options Indexes FollowSymLinks MultiViews DirectoryIndex index.html index.php AllowOverride All Order allow,deny allow from all </Directory> ErrorLog /var/log/apache2/error.log LogLevel warn CustomLog /var/log/apache2/access.log combined ServerSignature On </VirtualHost>
เปิดใช้งานด้วยคำสั่ง
# a2ensite example.com
# /etc/init.d/apache2 restart
!!!BETA!!!
เอามาจาก
Debian Wiki - SubversionApache2SSLHowto
Bug#395823: apache2-ssl-certificate disappeared
ติดตั้ง apache2 กับ ssl
# aptitude install apache2 openssl
เปิดใช้โมดูล ssl
# a2enmod ssl
แก้ให้ apache2 ใช้พอร์ต https คือ 443
# vi /etc/apache2/ports.conf
... Listen 443
etch รุ่นล่าสุด ชุดคำสั่งสร้างกุญแจของ apache2 ชื่อ apache2-ssl-certificate หายไปแล้ว
ต้องสั่งเองทีละขั้น
# export RANDFILE=/dev/random
# mkdir -p /etc/apache2/ssl
# openssl req $@ -new -x509 -days 365 -nodes -out \
/etc/apache2/ssl/apache.pem -keyout /etc/apache2/ssl/apache.pem
กรอกข้อมูลตามปกติ
...
Country Name (2 letter code) [AU]: <<<--- TH
State or Province Name (full name) [Some-State]: <<<--- Bangkok
Locality Name (eg, city) []: <<<--- Bangkok
Organization Name (eg, company) [Internet Widgits Pty Ltd]: <<<--- Example Co.,Ltd.
Organizational Unit Name (eg, section) []: <<<--- computer
Common Name (eg, YOUR name) []: <<<--- webmaster
Email Address []: <<<--- webmaster@example.com
ป้องกันกุญแจ
# chmod 600 /etc/apache2/ssl/apache.pem
สร้างไฟล์ไซต์ ssl สมมุติชื่อไฟล์ว่า example-ssl โดยเอาโครงมาจากไฟล์ default
# cp /etc/apache2/sites-available/default /etc/apache2/sites-available/example-ssl
ปรับแก้
# vi /etc/apache2/sites-available/example-ssl
NameVirtualHost *:443 <VirtualHost *:443> ... SSLEngine on SSLCertificateFile /etc/apache2/ssl/apache.pem SSLProtocol all SSLCipherSuite HIGH:MEDIUM </VirtualHost>
(ตรงนี้ สามารถเปลี่ยนไดเรกทอรี่ของ ssl ไปยังจุดใดก็ได้ ตามที่เราต้องการ
เช่น ถ้าใช้ svn ไดเรกทอรี่จะเป็น /var/lib/svn/)
สั่งเปิดใช้ไซต์ที่สร้างขึ้น
# a2ensite example-ssl
สั่งเริ่ม apache2 ใหม่
# /etc/init.d/apache2 restart
debian: lenny/etch
package: apache2.2 (2.2.9-10+lenny1/2.2.3-4+etch6)
สมมุติว่าเซิร์ฟเวอร์ภายนอก ชื่อ www.example.com มีการติดตั้ง apache2 ไว้แล้ว
และเซิร์ฟเวอร์ภายใน ชื่อ internal.example.com มีการติดตั้ง apache2 ไว้แล้ว
ทำที่เครื่องเซิร์ฟเวอร์ภายนอกอย่างเดียว โดยใช้มอดูล proxy_http
# a2enmod proxy
# a2enmod proxy_http
# /etc/init.d/apache2 restart
ติดตั้งชื่อไฟล์ไซต์ใน sites-available
ว่า internal
# vi /etc/apache2/sites-available/internal
<VirtualHost *:80> ServerAdmin webmaster@internal.example.com ServerName internal.example.com ProxyRequests Off <Proxy *> Order Deny,Allow Allow from all </Proxy> ProxyPreserveHost On ProxyPass / http://internal.example.com/ ProxyPassReverse / http://internal.example.com/ </VirtualHost>
เปิดใช้งาน
# a2ensite internal
# /etc/init.d/apache2 reload
เสร็จแล้ว
ถ้าเราตั้งค่า dns ของภายนอกไว้แล้ว สามารถเรียกจากภายนอกผ่าน internal.example.com
เอามาจาก ThaiLinuxCafe: ทำ mirror ด้วย rsync อย่างง่าย
ต้องการ syncronize ไดเรคทอรี่ /var/www ของเครื่อง server1.example.com
มายังไดเรคทอรี่ /var/www ของเครื่อง mirror.example.com
ซึ่งมีข้อดีกว่าการคัดลอกธรรมดาด้วย cp หรือ scp ตรงที่
ถ้าเราลบไฟล์ใน server1 ไฟล์ใน mirror จะถูกลบตามไปด้วย
ทำให้ทั้งสองเครื่องมีความสดใหม่เหมือนกัน
# aptitude install rsync
# vi /etc/default/rsync
RSYNC_ENABLE=true
# dpkg-reconfigure rsync
server1:# useradd -m -s /bin/bash someuser
mirror:# rsync -avz -e ssh someuser@server1.example.com:/var/www/ /var/www/
<<<--- ใส่ค่า password ของ someuser
rsync จะทำการคัดลอกไฟล์ทั้งหมดใน /var/www ที่ someuser มีสิทธิในการอ่านทั้งหมด
มาที่ /var/www ของเครื่อง mirror
หมายเหตุ
ตรวจสอบเนื้อที่การใช้ไฟล์ด้วยคำสั่ง
# cd /var/www
# du -c | grep total
ต่อไปเป็นการทำให้ rsync ไม่ต้องถามรหัสผ่าน โดยการใช้ public key
mirror:# ssh-keygen -t dsa -b 1024
Enter file in which to save the key (/root/.ssh/id_dsa): <<<--- [Enter]
Enter passphrase (empty for no passphrase): <<<---[Enter]
Enter same passphrase again: <<<---[Enter]
คัดลอก key ไปยัง server1
mirror:# scp ~/.ssh/id_dsa.pub someuser@server1.example.com:/home/someuser/
Password: <<<--- ใส่ค่ารหัสผ่านของ someuser ( บน server1 )
ssh ไปยัง server1
mirror:# ssh server1.example.com -l someuser
Are you sure you want to continue connecting (yes/no)? <<<--- yes
Password: <<<--- ใส่ค่ารหัสผ่านของ someuser
ทำให้ key ที่สร้างไว้ ถูกใช้จาก rsync
someuser@server1:~$ mkdir ~/.ssh
someuser@server1:~$ chmod 700 ~/.ssh
someuser@server1:~$ mv id_dsa.pub ~/.ssh
someuser@server1:~$ cd ~/.ssh
someuser@server1:~/.ssh$ touch authorized_keys
someuser@server1:~/.ssh$ chmod 600 authorized_keys
someuser@server1:~/.ssh$ cat id_dsa.pub >> authorized_keys
someuser@server1:~/.ssh$ exit
ลบ known_hosts เก่าทิ้งก่อน
mirror:# rm .ssh/known_hosts
ทดสอบครั้งแรก
mirror:# rsync -avz --delete -e "ssh -i /root/.ssh/id_dsa" \
someuser@server1.example.com:/var/www/ /var/www/
Are you sure you want to continue connecting (yes/no)? <<<--- yes
เรียบร้อย ครั้งต่อไปเขาจะไม่ถามอีกแล้ว
เวลาจะใช้งาน ก็ใช้คำสั่งเดิม
mirror:# rsync -avz --delete -e "ssh -i /root/.ssh/id_dsa" \
someuser@server1.example.com:/var/www/ /var/www/
หรือ ถ้าใช้ชื่อเหมือนกัน ในที่นี้ someuser เป็น root เหมือนกันทั้งสองฝั่ง ย่อได้เป็น
mirror:# rsync -avz --delete --rsh=ssh root@server1.example.com:/var/www/ /var/www/
จบแล้วครับ
ต่อไปเป็นการให้ทำงานอัตโนมัติผ่าน cron
# crontab -e
... 0 0 * * * /usr/bin/rsync -azq --delete -e "ssh -i /root/.ssh/id_dsa" someuser@server1.example.com:/var/www/ /var/www/ ...
( พิมพ์ต่อกันเป็นบรรทัดเดียวกันนะครับ - ให้ทำการ sync ตอนเที่ยงคืน ทุกวัน )
จบแล้วครับ
# mkdir temp
# for i in *jpg; do convert $i -interlace line temp/$i ; done
# convert -adjoin `ls *.tif` newfile.pdf
$ convert x1.tif x2.tif x3.tif -adjoin newfile.tif
$ convert x.tif x%d.tif
$ convert x.tif /tmp/x.gif
$ convert /tmp/x.gif -depth 4 x.tif
$ convert x.tif /tmp/x.jpg
$ convert /tmp/x.jpg x.tif
$ convert x.tif -quality 100 /tmp/x%d.jpg
$ convert /tmp/*jpg -geometry 1654 -density 200 -compress lzw -depth 4 -adjoin x.tif
$ convert infile.jpg -level 40%,85%,0.5 -type bilevel -monochrome -compress group4 outfile.tif
$ convert infile.jpg -compress lzw -colors 8 outfile.tif
tiff2pdf
และรวมด้วย pdfjam
หมายเหตุ
ต้องลงแพกเกจ imagemagick ก่อน
# aptitude install imagemagick
ยังหาโปรแกรมที่ใช้แก้ไขภาพ tif แบบหลายหน้า แบบ Imaging for Windows บนลินุกซ์ไม่ได้
ก็คงต้องใช้แบบบรรทัดคำสั่งไปพลาง ๆ ก่อน
ขั้นตอนคือ
ต้องลง ImageMagick ก่อน
$ sudo aptitude install imagemagick
แตกไฟล์ tif แบบหลายหน้าออกมาเป็น แบบหน้าเดียวหลายไฟล์
$ convert image.tif x%d.tif
แก้ไขหน้าที่ต้องการจากไฟล์ที่แตกออกมาแล้ว ด้วย gimp สมมุติว่าเป็นหน้า 2
$ gimp x2.tif
เมื่อบันทึกเรียบร้อยแล้ว ก็รวมกลับเป็นไฟล์เดียวตามเดิม สมมุติว่ามีทั้งหมด 3 ไฟล์
$ convert x1.tif x2.tif x3.tif -adjoin newimage.tif
ถ้าจะให้บีบอัดด้วย
$ convert newimage.tif -compress lzw newimage.tif
$ convert newimage.tif -compress fax newimage.tif
สำหรับการบีบอัดมีพารามิเตอร์คือ None BZip Fax Group4 JPEG JPEG2000 Lossless LZW RLE และ Zip
ต้องทดลองเลือกใช้ดูให้เหมาะกับประเภทของภาพ
ลยไฟล์ย่อยทิ้ง
$ rm x?.tif
ดูผลได้ด้วย evince
$ evince newimage.tif
อ้างอิง : debian: บันทึก imagemagick - convert
*** โปรดระวัง - ไม่สามารถใช้กับไฟล์ tif ที่มีข้อมูล annotation ได้ ***
update
จากขั้นตอนข้างบน สามารถนำมาเขียนสคริปต์ทำให้ใช้คำสั่งเดียวได้ ดังนี้
สมมุติว่าจะต้องการแก้ไข image.tif ในหน้า 0 และหน้า 1 สั่งจากสคริปต์ว่า
$ d.edittif image.tif 0 1
gimp จะเปิดไฟล์ออกมา 2 ไฟล์ คือหน้าแรก และหน้าที่สอง
หลังจากบันทึกและปิด gimp แล้ว จะได้ไฟล์ image-new.tif ออกมาเป็นภาพที่แก้ไขแล้วพร้อมบีบอัดเรียบร้อย
เนื้อไฟล์ d.edittif มีดังนี้
$ sudo touch /usr/local/bin/d.edittif
$ sudo chmod 755 /usr/local/bin/d.edittif
$ sudo vi /usr/local/bin/d.edittif
#!/bin/bash # EDIT MULTIPLE PAGES TIF FILE # PREREQUIST: gimp imagemagick evince #NAME=${0##*/} NAME=`basename $0` USAGE=" Usage: $NAME FILE PAGE0 PAGE1 ... ex1: $NAME image.tif 0 1 = Edit file image.tif on PAGE0 and PAGE1" phelp() { echo "$NAME: edit multiple pages tif. $USAGE" } while getopts "h" opt; do case "$opt" in h) phelp; exit 0;; *) echo "$Usage" 1>&2; exit 2;; esac done shift $((OPTIND - 1)) if [ ! $2 ]; then phelp exit 1; fi TIF=$1 shift FILE=${TIF%.*} #STRIP FILENAME EDITFILE="" while [ $1 ]; do EDITFILE="$EDITFILE ~${FILE}$1.tif" shift done ALLFILE=`ls ~${FILE}*.tif` if [ -f $TIF ]; then echo "Process $TIF" /usr/bin/convert $TIF "~$FILE%d.tif" if [ -f "~${FILE}0.tif" ]; then #EDIT WITH gimp echo "Edit $EDITFILE" /usr/bin/gimp $EDITFILE #COMPRESS EACH TIF for i in $ALLFILE; do echo -n "IDENTIFY $i " if /usr/bin/identify -verbose $i | grep "Gray: 1-bits"; then /usr/bin/convert $i -compress fax $i else /usr/bin/convert $i -compress lzw $i fi done /usr/bin/convert $ALLFILE -adjoin -compress lzw "$FILE-new.tif" #COMPRESS & JOIN /usr/bin/evince "$FILE-new.tif" #VIEW NEW FILE rm $ALLFILE #DELETE ALL SPLIT FILE fi fi
ลองบนเดเบียน sid ครับ
ความจำเป็นบีบบังคับให้ต้องรีบหาโปรแกรมที่สามารถทำ Annotation ไฟล์ tif ให้ได้
จริง ๆ ก็มีโปรแกรมชื่อ Xournal ที่สามารถทำ annotate บน pdf ได้
ซึ่งเราอาจแปลง tif ไปเป็น pdf ก่อน แล้วจึงค่อยลงมือแก้ไข
แต่พบว่าในรุ่นปัจจุบันบน sid คือ 0.3.3 ยังทำ Text annotation ไม่ได้
และรุ่นล่าสุด 0.4 ความสามารถและการใช้งานยังค่อนข้างด้อยกว่าที่ Kodakimg ทำได้อยู่โข
แต่จากครั้งก่อนที่ทำ การแก้ไข multiple pages tif
คราวนี้เลยได้ความคิดว่าถ้าลองเปลี่ยนจาก Gimp มาเป็น Inkscape เราก็จะได้ความสามารถในการทำ annotation จาก inkscape ในแบบที่ก้าวหน้าสุด ๆ
มีปัญหาที่ต้องแก้คือ inkscape ไม่สามารถแก้ไขไฟล์แบบหลายหน้าได้ (แต่ในอนาคตคงมาแน่ ๆ เห็นอยู่ใน wishlist ลำดับต้น ๆ )
ทางแก้แบบชั่วคราวคือ กระจายไฟล์ลงในไดเรคทอรี่ชั่วคราวที่สร้างไว้ แล้วแก้ไขตามไฟล์ที่เราระบุ
อีกปัญหาคือเวลาแปลงกลับจาก svg มาเป็น tif แบบหลายหน้าแล้ว ข้อมูล annotation ที่เราทำไว้ จะถูกแปลงเป็นข้อมูล bitmap ฝังรวมกับไฟล์ tif ไปหมด
ทางแก้ชั่วคราวอีกเหมือนกันคือ ให้คงไดเรกทอรี่ชั่วคราวนี้ไว้ โดยไม่ลบไฟล์ทิ้งเลย เมื่อเวลาเราใช้คำสั่ง annotate ครั้งใหม่ เขาก็จะมาแก้ไขต่อจากที่เราเคยแก้เอาไว้ โดยต้องยอมรกรุงรังบ้าง
เนื้อแบตช์ไฟล์มีดังนี้
$ sudo vi /usr/local/bin/d.tifannotate
#!/bin/bash # ANNOTATE MULTIPLE PAGES TIF FILE # PREREQUIST: inkscape imagemagick evince #NAME=${0##*/} NAME=`basename $0` USAGE=" Usage: $NAME FILE PAGE0 PAGE1 ... ex1: $NAME image.tif 0 1 = Edit file image.tif on PAGE0 and PAGE1" phelp() { echo "$NAME: annotate multiple pages tif. $USAGE" } while getopts "h" opt; do case "$opt" in h) phelp; exit 0;; *) echo "$Usage" 1>&2; exit 2;; esac done shift $((OPTIND - 1)) if [ ! $2 ]; then phelp exit 1; fi TIF=$1 shift FILE=${TIF%.*} #STRIP FILENAME TEMPDIR="${FILE}~" EDITFILES="" while [ $1 ]; do EDITFILES="$EDITFILES ${FILE}$1.svg" shift done INKSCAPE=`which inkscape` IDENTIFY=`which identify` CONVERT=`which convert` VIEW=`which evince` if [ -f $TIF ]; then echo "Process $TIF" #TEST TEMP DIR EXIST if ! [ -d $TEMPDIR ]; then #CREATE TEMP DIR AND SPLIT tif INTO mkdir $TEMPDIR $CONVERT $TIF "${TEMPDIR}/$FILE%d.tif" #ENTER WORKING TEMP DIR pushd $TEMPDIR ALLFILE=`ls ${FILE}*.tif` #CONVERT TO svg for i in $ALLFILE; do $INKSCAPE -l "${i%.*}.svg" $i done else #ELSE; EDIT OLD svg pushd $TEMPDIR fi #ANNOTATE if [ -f "${FILE}0.svg" ]; then #ANNOTATE WITH inkscape echo "Edit $EDITFILES" $INKSCAPE $EDITFILES ALLSVG=`ls ${FILE}*.svg` #CONVERT ADJOIN $CONVERT $ALLSVG -adjoin -compress lzw "$FILE-new.tif" #COMPRESS & JOIN $VIEW "$FILE-new.tif" #VIEW NEW FILE mv "$FILE-new.tif" .. fi #EXIT WORK DIR popd #REMOVE DIR #rm -rf $TEMPDIR fi
$ sudo chmod 755 /usr/local/bin/d.tifannotate
เรียกใช้งานด้วยคำสั่ง... โปรแกรม ไฟล์tif หน้าที่ต้องการแก้ไข
$ d.tifannotate FILE.tif 0 1 ...
จะได้ไฟล์ที่ทำ annotate แล้วชื่อ FILE-new.tif
และไดเรกทอรี่ชั่วคราวชื่อ FILE~
เหลืออยู่ เพื่อใช้ในการแก้ไขครั้งต่อไป (แต่ถ้าไม่ได้ใช้แน่ ๆ ก็อาจเติมคำสั่งลบต่อท้ายแบตช์ไฟล์ หรือลบด้วยมือเอาทีหลังก็ได้ครับ)
กระท่อนกระแท่นหน่อย เพราะเป็นการทำเพื่อรอโปรแกรมลินุกซ์แนวนี้ในอนาคตตัวจริง ก็พอใช้งานได้ไปพลาง ๆ ก่อนครับ
อย่าลืม เปลี่ยนขนาดกระดาษไน inkscape ด้วย
แต่ติดใจการใช้งาน annotation บน inkscape จริง ๆ แฮะ
ลูกสาวให้ทำ msn ในลินุกซ์ให้ใช้ เคยอ่านผ่านตาที่ ubuntuclub.com
เลยทดลองดาวน์โหลด pidgin มาคอมไพล์เอง
คอมไพล์ครั้งแรกไม่ผ่าน ค้นเจอที่ ubuntuforum รวบรวมแพกเกจที่จำเป็นดังนี้
$ sudo aptitude install libgtk2.0-dev libxml-perl libssl-dev libnspr4-dev libnss3-dev
หลังจากนั้นก็คอมไพล์ตามปกติ ก็สามารถเล่นได้แล้ว
เอามาจาก
ThaiLinuxCafe - debian : ติดตั้ง dns อย่างง่าย
เรื่องของ DNS (Domain Name Server) เป็นเรื่องหลักของการใช้งานอินเตอร์เน็ต เนื้อหาซับซ้อนและทำความเข้าใจยาก
สำหรับในที่นี้ เราเอาแค่ติดตั้งพอใช้งานได้
โดยเราจะติดตั้งเครื่องเซิร์ฟเวอร์เพื่อทำหน้าที่เป็น DNS สำหรับใช้งานเครือข่ายภายใน
โครงร่างคือ
แพกเกจที่ทำหน้าที่ DNS ในเดเบียนชื่อ bind9 และแพกเกจที่เป็นโปรแกรมช่วยชื่อ dnsutils
งานปรับตั้งคือการสร้างไฟล์สำหรับให้ bind9 เรียกใช้ ดังนี้
เริ่มด้วย
ติดตั้ง DNS และโปรแกรมช่วย
# aptitude install bind9 dnsutils
ไปที่ไดเรกทอรี่ของการปรับตั้ง
# cd /etc/bind
เริ่มสร้างโซนไฟล์ ให้ชื่อว่า example.com.zone มีเนื้อไฟล์ดังนี้
# vi example.com.zone
$TTL 86400 @ IN SOA server1.example.com. root.server1.example.com. ( 51 ; serial (d. adams) 3H ; refresh after 3 hours 15M ; retry after 15 minutes 1W ; expire after 7 days 1D ) ; minimum TTL (Time To Live) of 1 days @ IN NS ns1.example.com. ; primary NS @ IN NS ns2.example.com. ; secondary NS ns1 IN CNAME server1 ; append or edit host ip here server1 IN A 192.168.1.1 ns2 IN A 192.168.1.2 client1 IN A 192.168.1.101 client2 IN A 192.168.1.102 client3 IN A 192.168.1.103
สร้างรีเวิร์สไฟล์ ให้ชื่อว่า example.com.reverse มีเนื้อไฟล์ดังนี้
# vi example.com.reverse
$TTL 86400 @ IN SOA server1.example.com. root.server1.example.com. ( 51 ; serial (d. adams) 3H ; refresh after 3 hours 15M ; retry after 15 minutes 1W ; expire after 7 days 1D ) ; minimum TTL (Time To Live) of 1 days @ IN NS ns1.example.com. ; primary NS @ IN NS ns2.example.com. ; secondary NS ; append or edit host name here 1 IN PTR server1.example.com. 2 IN PTR ns2.example.com. 101 IN PTR client1.example.com. 102 IN PTR client2.example.com. 103 IN PTR client3.example.com.
สร้างคอนฟิกไฟล์สำหรับโซน example.com ให้ชื่อว่า example.com.conf มีเนื้อไฟล์ดังนี้
# vi example.com.conf
zone "example.com" IN { type master; file "/etc/bind/example.com.zone"; allow-update { none; }; }; zone "1.168.192.in-addr.arpa" IN { type master; file "/etc/bind/example.com.reverse"; allow-update { none; }; };
เปลี่ยนสิทธ์ให้ bind เป็นเจ้าของไฟล์
# chown bind:bind example.com.*
บอกให้ bind9 เอาไฟล์ของเราไปใช้งาน โดยการเพิ่มลงในไฟล์ named.conf.local ดังนี้
# vi named.conf.local
... include "/etc/bind/example.com.conf";
เสร็จแล้วก็สั่งเริ่ม bind9 ใหม่
# /etc/init.d/bind9 restart
ถ้ามีข้อผิดพลาด ให้ดูที่ /etc/log/syslog
ทดสอบโดย
# nslookup server1.example.com
จะแสดงผลเป็น 192.168.1.1
Server: 192.168.1.1
Address: 192.168.1.1#53
Name: server1.example.com
Address: 192.168.1.1
ทดสอบย้อนกลับ
# nslookup 192.168.1.1
จะแสดงผลเป็น server1.example.com
Server: 192.168.1.1
Address: 192.168.1.1#53
1.1.168.192.in-addr.arpa name = server1.example.com.
หมายเหตุ
เนื้อหาไม่ค่อยถูกตามหลักการนะครับ เพราะมันยาก ถ้าจะให้รู้เรื่องจริง ๆ ต้องเข้าใจระบบอินเตอร์เน็ตพอสมควร
ในที่นี้เอาแค่พอใช้งานได้ครับ
อ้างอิงเพิ่มเติม
*** ยังเขียนไม่เสร็จ + ยังไม่ได้ตรวจทานซ้ำ ***
เป้า
สมมุติว่า
ติดตั้งแพกเกจ
# aptitude install bind9 dnsutils
ทำเรื่องติดคุก (chroot jail) จะย้ายคุกไปไว้ที่ /sys1/chroot/bind
# vi /etc/default/bind9
... # OPTIONS="-u bind" OPTIONS="-u bindinjail -t /sys1/chroot/bind" ...
สร้างผู้ใช้ชื่อ bindinjail ให้ใช้เชลล์ไม่ได้ อยู่ในกลุ่ม nogroup
# useradd -g nogroup -d /nonexistent -s /bin/false -u 65533 bindinjail
# passwd -l bindinjail
สร้างคุก
# mkdir -p /sys1/chroot/bind/{etc,dev,var/cache/bind,var/log,var/run/bind/run}
# mv /etc/bind /sys1/chroot/bind/etc
# ln -sf /sys1/chroot/bind/etc/bind /etc
# mknod /sys1/chroot/bind/dev/null c 1 3
# mknod /sys1/chroot/bind/dev/random c 1 8
# chmod 666 /sys1/chroot/bind/dev/null /sys1/chroot/bind/dev/random
# chown -R bindinjail:nogroup /sys1/chroot/bind/var/*
# chown -R bindinjail:nogroup /sys1/chroot/bind/etc/bind/
ทำให้ระบบเก็บปูมของ bind (system logging - syslogd)
# vi /etc/default/syslogd
... # SYSLOGD="" SYSLOGD="-a /sys1/chroot/bind/dev/log" ...
ปรับตั้งระบบปูมของ bind
# vi /sys1/chroot/bind/etc/bind/named.conf.local
... logging { channel "querylog" { file "/var/log/bind9-query.log"; print-time yes; }; category queries { querylog; }; }; ...
ปรับตั้งประวัติปูมของ bind
# vi /etc/logrotate.d/bind9-query
/sys1/chroot/bind/var/log/bind9-query.log { weekly missingok rotate 10 postrotate /etc/init.d/bind9 reload > /dev/null endscript compress notifempty }
# ln -sf /sys1/chroot/bind/var/log/bind9-query.log /var/log/bind9-query.log
แก้ไข options ให้มาใช้ pid ของคุก
# vi /sys1/chroot/bind/etc/bind/named.conf.options
... options { directory "/var/cache/bind"; pid-file "/var/run/named.pid"; ...
เสร็จขั้นต้น ทดสอบระบบครั้งแรก
# /etc/init.d/sysklogd restart
# /etc/init.d/bind9 restart
ต้องไม่มีรายงานข้อผิดพลาด
ต่อไปเป็นเรื่องการอัปเดตไอพี และการทำให้รองรับเครือข่ายภายในและภายนอก ผสมกัน
บอก bind ว่าเราจะใช้งาน dnssec
# vi /etc/bind/named.conf.options
... options { ... recursion yes; dnssec-enable yes; }; ...
สร้างไดเรกทอรี่มารองรับการทำงาน
# mkdir -p /sys1/chroot/bind/etc/bind/{internal,external}
สร้างกฎ acl สำหรับเครือข่ายภายใน ตั้งชื่อว่า internal (นอกจากนั้นจะถือว่าเป็น external ทั้งหมด)
และให้มาอ่านไฟล์คอนฟิกที่เราจะสร้างขึ้นภายหลัง ของโซน example.com และ example.org
# cd /sys1/chroot/bind/etc/bind
# vi named.conf.local
... acl internal { 127.0.0.0/8; 192.168.0.0/16; }; include "/etc/bind/example.com.conf"; include "/etc/bind/example.org.conf"; ...
สร้างไฟล์เปล่า ๆ กันเหนียวเผื่อทดสอบ จะได้มีไฟล์รองรับ
# touch /etc/bind/{example.com.conf,example.org.conf}
สร้างกุญแจ สำหรับอัปเดตไอพี example.com และ example.org
# dnssec-keygen -r /dev/urandom -a rsasha1 -b 1024 -n ZONE example.com
Kexample.com.+005+11187
และได้ไฟล์ Kexample.com.+005+11187.key และ Kexample.com.+005+11187.private
และกุญแจสำหรับอัปเดตโซน
# dnssec-keygen -r /dev/urandom -k -a rsasha1 -b 1024 -n ZONE example.com
ตัวอย่างได้ผลเป็น
Kexample.com.+005+09453
และได้ไฟล์ Kexample.com.+005+09453.key และ Kexample.com.+005+09453.private
สร้างไฟล์คอนฟิกของโซน example.com
# vi example.com.conf
view "internal" { match-clients { internal; }; zone "example.com" IN { type master; file "/etc/bind/internal/example.com.zone.signed"; key-directory "/etc/bind"; update-policy { grant example.com. subdomain example.com any; }; }; zone "0.168.192.in-addr.arpa" IN { type master; file "/etc/bind/internal/example.com.reverse.signed"; key-directory "/etc/bind"; update-policy { grant example.com. subdomain example.com any; }; }; }; view "external" { match-clients { any; }; zone "example.com" IN { type master; file "/etc/bind/external/example.com.zone.signed"; key-directory "/etc/bind"; update-policy { grant example.com. subdomain example.com any; }; }; };
สร้างโซนไฟล์ของ internal
# vi internal/example.com.zone
อันนี้ลองเปลี่ยนตามจริงนะครับ สมมุติว่าเครื่องนี้เอาชื่อ server1 เป็นหลัก แล้วใช้ชื่ออื่นคือ www, ns1, ftp, mail เป็นชื่อรอง
$TTL 86400 @ IN SOA server1.example.com. root.server1.example.com. ( 41 ; serial (d. adams) 3H ; refresh 15M ; retry 1W ; expiry 1D ) ; minimum @ IN NS ns1.example.com. ; primary NS @ IN NS ns2.example.com. ; secondary NS www IN CNAME server1 ns1 IN CNAME server1 ftp IN CNAME server1 mail IN CNAME server1 www IN A 192.168.1.1 ns2 IN A 192.168.1.2 work1 IN A 192.168.1.101 work2 IN A 192.168.1.102 work3 IN A 192.168.1.103 $INCLUDE /etc/bind/Kexample.com.+005+11187.key $INCLUDE /etc/bind/Kexample.com.+005+09453.key
ลงทะเบียนโซน example.com ของ internal
# cd internal
# dnssec-signzone -r /dev/urandom -t -g -o example.com example.com.zone /etc/bind/Kexample.com.+005+11187.private
example.com.zone.signed Signatures generated: 21 Signatures retained: 0 Signatures dropped: 0 Signatures successfully verified: 0 Signatures unsuccessfully verified: 0 Runtime in seconds: 0.063 Signatures per second: 331.151
# cd ..
เปลี่ยนเจ้าของและกลุ่ม
# chown -R bindinjail:nogroup *
เสร็จโซนไฟล์ของ internal
ทดสอบขั้นต้น
# /etc/init.d/bind9 restart
ต้องไม่มีรายงานข้อผิดพลาด
ทดสอบอัปเดต
# nsupdate -d -v -k Kexample.com.+005+09453.private
Creating key... > server 192.168.1.1 > zone example.com > update add testing.example.com. 3600 A 192.168.1.5 > show Outgoing update query: ;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 0 ;; flags: ; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0 ;; UPDATE SECTION: testing.example.com. 3600 IN A 192.168.1.5 > send Sending update to 192.168.1.1#53 Outgoing update query: ;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 43656 ;; flags: ; ZONE: 1, PREREQ: 0, UPDATE: 1, ADDITIONAL: 1 ;; ZONE SECTION: ;example.com. IN SOA ;; UPDATE SECTION: testing.example.com. 3600 IN A 192.168.1.5 ;; SIG0 PSEUDOSECTION: . 0 ANY SIG 0 5 0 0 20080223084852 20080223083852 9453 example.com. zpGfPIECwJ8V31lm7mlq7zMiKYSuh2TlIyOZgEUJjZUgYTRHYZrwi75Z mDaKAJGb7uG+r4SLmuFDRdjQQ1mvtZcuo8SK2yjHK59QzUoFnGJXz427 vRNj/do4DbMxMkJpJwqDiKU87lGiy+CXvpbQAm+4AeJutpCTsGnfhixx k4c= Reply from update query: ;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 43656 ;; flags: qr ra ; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0 > quit
ลองค้นดูอีกที
# nslookup testing.example.com localhost
Server: localhost Address: 127.0.0.1#53 Name: testing.example.com Address: 192.168.1.5
เสร็จ forward internal
ยังเขียนไม่เสร็จ หมดแรงก่อน ข้อเขียนข้างบนยังไม่ได้ตรวจทาน
- reverse internal example.com ทำเหมือนเดิม ยกเว้นตอนอัปเดตใช้คำสั่งเป็น
> update add 5.1.168.192.in-addr.arpa. 3600 IN PTR testing.example.com.
โดยอย่าให้มีคำสั่ง zone XXXX มาก่อนหน้า อัปเดตได้เลย
- forward external ทำเหมือนเดิม ---รอเขียนต่อ---
อ้างอิง
http://myrddin.org/howto/debian-bind9-chroot/
http://www.ops.ietf.org/dns/dynupd/secure-ddns-howto.html
http://garnser.blogspot.com/2008/02/how-to-enable-bind-with-dnssec-and.html
http://www.unixwiz.net/techtips/bind9-chroot.html
การตั้งให้ name server ให้บริการเครือข่ายภายในและภายนอก โดยใช้โดเมนเดียวกัน มีข้อดีตรงที่เราไม่จำเป็นต้องแยกโดเมนให้จำยาก และเมื่อเวลาลูกข่ายภายในสั่งค้น การค้นก็ไม่ต้องเปลืองแพ็กเก็ตออกสู่ภายนอก เพียงแต่การปรับตั้งยุ่งนิดนึง
# aptitude install bind9
สมมุติว่า
จะต้องมีไฟล์คอนฟิกคือ example.com.conf และ example.org.conf
มีโซนไฟล์คือ internal/example.com.zone กับ internal/example.org.zone และ external/example.com.zone กับ external/example.org.zone
ตามด้วยรีเวิร์สไฟล์คือ internal/example.com.reverse กับ internal/example.org.reverse และ external/example.com.reverse กับ external/example.org.reverse
เริ่มด้วย
# cd /etc/bind
เพิ่มกฎแยก internal และ external และให้อ่านไฟล์คอนฟิกของแต่ละโดเมนเข้ามาในระบบด้วย ผ่านไฟล์ named.conf.local
# vi named.conf.local
... acl internals { 127.0.0.0/8; 10.0.0.0/24; 192.168.1.0/24; }; include "/etc/bind/example.com.conf"; include "/etc/bind/example.org.conf";
สร้างไฟล์คอนฟิกของ example.com
# vi example.com.conf
view "internal" { match-clients { internals; }; zone "example.com" IN { type master; file "/etc/bind/internal/example.com.zone"; allow-update { none; }; }; zone "1.168.192.in-addr.arpa" IN { type master; file "/etc/bind/internal/example.com.reverse"; allow-update { none; }; }; }; view "external" { match-clients { any; }; zone "example.com" IN type master; file "/etc/bind/external/example.com.zone"; allow-update { none; }; }; zone "113.112.111.in-addr.arpa" IN { type master; file "/etc/bind/external/example.com.reverse"; allow-update { none; }; }; };
สร้างไฟล์คอนฟิกของ example.org
# vi example.org.conf
view "internal" { match-clients { internals; }; zone "example.org" IN { type master; file "/etc/bind/internal/example.org.zone"; allow-update { none; }; }; zone "0.0.10.in-addr.arpa" IN { type master; file "/etc/bind/internal/example.org.reverse"; allow-update { none; }; }; }; view "external" { match-clients { any; }; zone "example.org" IN type master; file "/etc/bind/external/example.org.zone"; allow-update { none; }; }; zone "213.212.211.in-addr.arpa" IN { type master; file "/etc/bind/external/example.org.reverse"; allow-update { none; }; }; };
อย่าลืมสร้างไดเรกทอรี่ก่อน
# mkdir internal external
ตัวอย่างสร้างโซนไฟล์ของ internal/example.com
# vi internal/example.com.zone
$TTL 86400 @ IN SOA ns1.example.com. root.ns1.example.com. ( 42 ; serial (d. adams) 3H ; refresh 15M ; retry 1W ; expiry 1D ) ; minimum @ IN NS ns1.example.com. ; primary NS @ IN NS ns2.example.com. ; secondary NS www IN CNAME ns1 ftp IN CNAME ns1 mail IN CNAME ns1 ; append or edit host file here ns1 IN A 192.168.1.1 ns2 IN A 192.168.1.2 work1 IN A 192.168.1.11 work2 IN A 192.168.1.12 ...
ตัวอย่างสร้างโซนไฟล์ของ external/example.com
# vi external/example.com.zone
$TTL 86400 @ IN SOA ns1.example.com. root.ns1.example.com. ( 42 ; serial (d. adams) 3H ; refresh 15M ; retry 1W ; expiry 1D ) ; minimum @ IN NS ns1.example.com. ; primary NS @ IN NS ns2.example.com. ; secondary NS www IN CNAME ns1 ftp IN CNAME ns1 mail IN CNAME ns1 ; append or edit host file here ns1 IN A 111.112.113.114
ตัวอย่างสร้างโซนไฟล์ของ internal/example.org
# vi internal/example.org.zone
$TTL 86400 @ IN SOA ns1.example.org. root.ns1.example.org. ( 42 ; serial (d. adams) 3H ; refresh 15M ; retry 1W ; expiry 1D ) ; minimum @ IN NS ns1.example.org. ; primary NS @ IN NS ns2.example.org. ; secondary NS www IN CNAME ns1 ftp IN CNAME ns1 mail IN CNAME ns1 ; append or edit host file here ns1 IN A 10.0.0.1 ns2 IN A 10.0.0.2 shop1 IN A 10.0.0.11 shop2 IN A 10.0.0.12 ...
ตัวอย่างสร้างโซนไฟล์ของ external/example.org
# vi external/example.org.zone
$TTL 86400 @ IN SOA ns1.example.org. root.ns1.example.org. ( 42 ; serial (d. adams) 3H ; refresh 15M ; retry 1W ; expiry 1D ) ; minimum @ IN NS ns1.example.org. ; primary NS @ IN NS ns2.example.org. ; secondary NS www IN CNAME ns1 ftp IN CNAME ns1 mail IN CNAME ns1 ; append or edit host file here ns1 IN A 211.212.213.214 ...
ตัวอย่างสร้างรีเวิร์สไฟล์ของ internal/example.com
# vi internal/example.com.reverse
$TTL 86400 @ IN SOA ns1.example.com. root.ns1.example.com. ( 42 ; serial (d. adams) 3H ; refresh 15M ; retry 1W ; expiry 1D ) ; minimum @ IN NS ns1.example.com. ; primary NS @ IN NS ns2.example.com. ; secondary NS ; ; host in network 192.168.1.0 ; append or edit host file here 1 IN PTR ns1.example.com. 2 IN PTR ns2.example.com. 11 IN PTR work1.example.com. 12 IN PTR work2.example.com. ...
ตัวอย่างสร้างรีเวิร์สไฟล์ของ external/example.com
# vi external/example.com.reverse
$TTL 86400 @ IN SOA ns1.example.com. root.ns1.example.com. ( 42 ; serial (d. adams) 3H ; refresh 15M ; retry 1W ; expiry 1D ) ; minimum @ IN NS ns1.example.com. ; primary NS @ IN NS ns2.example.com. ; secondary NS ; ; host in network 111.112.113.0 ; append or edit host file here 114 IN PTR ns1.example.com.
ตัวอย่างสร้างรีเวิร์สไฟล์ของ internal/example.org
# vi internal/example.org.reverse
$TTL 86400 @ IN SOA ns1.example.org. root.ns1.example.org. ( 42 ; serial (d. adams) 3H ; refresh 15M ; retry 1W ; expiry 1D ) ; minimum @ IN NS ns1.example.org. ; primary NS @ IN NS ns2.example.org. ; secondary NS ; ; host in network 10.0.0.0 ; append or edit host file here 1 IN PTR ns1.example.org. 2 IN PTR ns2.example.org. 11 IN PTR shop1.example.org. 12 IN PTR shop2.example.org. ...
ตัวอย่างสร้างรีเวิร์สไฟล์ของ external/example.org
# vi external/example.org.reverse
$TTL 86400 @ IN SOA ns1.example.org. root.ns1.example.org. ( 42 ; serial (d. adams) 3H ; refresh 15M ; retry 1W ; expiry 1D ) ; minimum @ IN NS ns1.example.org. ; primary NS @ IN NS ns2.example.org. ; secondary NS ; ; host in network 211.212.213.0 ; append or edit host file here 214 IN PTR ns1.example.org.
เปลี่ยนสิทธิ์ทั้งหมด
# chown bind:bind * -R
เสร็จแล้ว
# /etc/init.d/bind9 restart
หมายเหตุ
ตัวเลข serial ไม่ค่อยจำเป็นเท่าไหร่ เป็นตัวเลขอะไรก็ได้ แต่ถ้าเราทำเป็น dynamic dns จะต้องเป็นตัวเลขที่เพิ่มค่าขึ้นไปเรื่อย ๆ ให้มากกว่าค่าเดิม ไม่งั้นเขาไม่ยอมอัปเดตค่าไอพีให้
อ้างอิง
Two-in-one DNS server with BIND9
จะทดลองทำ DNS แบบยอมให้เปลี่ยนค่าไอพีได้
ขออนุญาตเริ่มใหม่ เพื่อให้บทความจบในตัว
เริ่มต้นด้วยการติดตั้ง bind9 ใหม่
# aptitude remove --purge bind9 dnsutils
# rm -rf /etc/bind
# aptitude install bind9 dnsutils
เนื่องจากต้องมีการเปลี่ยนค่าไอพีโดยใช้สิทธิ์ของผู้ใช้ชื่อ bind เราจึงควรสร้างไดเรกทอรีขึ้นมาเพื่อให้ผู้ใช้ bind มีสิทธิ์ในการเขียนไฟล์
# cd /etc/bind
# mkdir example.com
# chown bind:bind example.com
# cd example.com
สร้างกุญแจสำหรับใช้ในการอัปเดตค่าไอพี (โดยใช้อัลกอริธึม HMAC-MD5 ขนาด 512บิต ตั้งชื่อกุญแจว่า server1.example.com.)
# dnssec-keygen -a HMAC-MD5 -b 512 -n HOST server1.example.com.
ผลลัพธ์ของผมคือ
Kserver1.example.com.+157+49285
เราจะได้ไฟล์มาสองไฟล์ซึ่งมีลักษณะคือ K(ชื่อกุญแจ)+NNN+NNNNN
โดยมีนามสกุลเป็น .key และ .private
ตามตัวอย่างได้เนื้อไฟล์ Kserver1.example.com.+157+49285.key เป็น
server1.example.com. IN KEY 512 3 157 wLuCYKvKDqM2XJsqcspdycoJgLNJKUKga4bHANjE7FY0HCujucYhDUKt FD5wgGXGPCNVsZi7NOYDgVZSIJ8LbA==
และเนื้อไฟล์ Kserver1.example.com.+157+49285.private เป็น
Private-key-format: v1.2 Algorithm: 157 (HMAC_MD5) Key: wLuCYKvKDqM2XJsqcspdycoJgLNJKUKga4bHANjE7FY0HCujucYhDUKtFD5wgGXGPCNVsZi7NOYDgVZSIJ8LbA==
เราจะเอาค่า private key มาใช้ โดยสร้างไฟล์คอนฟิกขึ้นมา ตั้งชื่อว่า dnskeys.conf และนำเนื้อหาของกุญแจ private key มาใช้เป็นค่า secret
# vi dnskeys.conf
key server1.example.com. { algorithm hmac-md5; secret "wLuCYKvKDqM2XJsqcspdycoJgLNJKUKga4bHANjE7FY0HCujucYhDUKtFD5wgGXGPCNVsZi7NOYDgVZSIJ8LbA=="; };
เพิ่มไฟล์คอนฟิกของคีย์ลงใน named.conf.local
# vi ../named.conf.local
... include "/etc/bind/example.com/dnskeys.conf"; ...
งานต่อไปเป็นงานซ้ำของเก่าคือสร้างโซนไฟล์ และรีเวิร์สไฟล์ และคอนฟิกไฟล์ โดยปรับเปลี่ยนค่าคอนฟิกไฟล์ตรงคำสั่ง allow-update เท่านั้น
สร้างโซนไฟล์ชื่อ example.com.zone เหมือนเดิม
# vi example.com.zone
$TTL 86400 @ IN SOA server1.example.com. root.server1.example.com. ( 51 ; serial (d. adams) 3H ; refresh after 3 hours 15M ; retry after 15 minutes 1W ; expire after 7 days 1D ) ; minimum TTL (Time To Live) of 1 days @ IN NS ns1.example.com. ; primary NS @ IN NS ns2.example.com. ; secondary NS ns1 IN CNAME server1 ; append or edit host ip here server1 IN A 192.168.1.1 ns2 IN A 192.168.1.2 client1 IN A 192.168.1.101 client2 IN A 192.168.1.102 client3 IN A 192.168.1.103
สร้างรีเวิร์สไฟล์ชื่อ example.com.reverse เหมือนเดิม
# vi example.com.reverse
$TTL 86400 @ IN SOA server1.example.com. root.server1.example.com. ( 51 ; serial (d. adams) 3H ; refresh after 3 hours 15M ; retry after 15 minutes 1W ; expire after 7 days 1D ) ; minimum TTL (Time To Live) of 1 days @ IN NS ns1.example.com. ; primary NS @ IN NS ns2.example.com. ; secondary NS ; append or edit host name here 1 IN PTR server1.example.com. 2 IN PTR ns2.example.com. 101 IN PTR client1.example.com. 102 IN PTR client2.example.com. 103 IN PTR client3.example.com.
สร้างคอนฟิกไฟล์ชื่อ example.com.conf โดยกำหนดให้สามารถเปลี่ยนแปลงค่าไอพีได้ (allow-update)
# vi example.com.conf
zone "example.com" IN { type master; file "/etc/bind/example.com/example.com.zone"; allow-update { key "server1.example.com."; }; }; zone "1.168.192.in-addr.arpa" IN { type master; file "/etc/bind/example.com/example.com.reverse"; allow-update { key "server1.example.com."; }; };
เพิ่มค่าคอนฟิกไฟล์ให้ระบบรับรู้ โดยเติมลงใน named.conf.local
# vi ../named.conf.local
... include "/etc/bind/example.com/example.com.conf";
แก้ไขให้กรุ๊ป bind เขียนลงโซนไฟล์ รีเวิร์สไฟล์ และในไดเรกทอรี่นี้ได้ ทั้งนี้เพื่อประโยชน์ตอนอัปเดตค่าไอพี
# chmod g+w example.com.zone example.com.reverse
# chmod g+w ../example.com
เมื่อเสร็จเรียบร้อยแล้ว ก็สั่งเริ่ม bind9 ใหม่
# /etc/init.d/bind9 restart
ติดตั้ง ntpdate ซึ่งต้องใช้ตอนอัปเดตไอพี
# aptitude install ntpdate
จบการติดตั้งแค่นี้ครับ
ต่อไปเป็นการทดสอบการอัปเดตค่าไอพี
ก่อนอื่นต้องซิงก์เวลาก่อน ผมลองใช้เซิร์ฟเวอร์ที่ thaicert
# ntpdate -s -b clock.thaicert.nectec.or.th
อัปเดตโดยนำไฟล์ private key มาใช้
# nsupdate -k Kserver1.example.com.+157+49285.private -d
ทดลองเปลี่ยนค่า server1.example.com เป็น 192.168.1.4
server localhost zone example.com. update delete server1.example.com. update add server1.example.com. 60 IN A 192.168.1.4 send quit
ตัวอย่างหน้าจอภาพเครื่องทดสอบ
Sending update to 127.0.0.1#53 Outgoing update query: ;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 11566 ;; flags: ; ZONE: 1, PREREQ: 0, UPDATE: 2, ADDITIONAL: 1 ;; ZONE SECTION: ;example.com. IN SOA ;; UPDATE SECTION: server1.example.com. 0 ANY ANY server1.example.com. 60 IN A 192.168.1.4 ;; TSIG PSEUDOSECTION: server1.example.com. 0 ANY TSIG hmac-md5.sig-alg.reg.int. 1165632027 300 16 yjgvsLCdFobUj/p7lex21g== 11566 NOERROR 0 Reply from update query: ;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 11566 ;; flags: qr ra ; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 1 ;; TSIG PSEUDOSECTION: server1.example.com. 0 ANY TSIG hmac-md5.sig-alg.reg.int. 1165632027 300 16 j9mG82rwthDTBJyCopHyUw== 11566 NOERROR 0
ตรงฟิลด์ status ต้องเป็น NOERROR การทำงานจึงจะสมบูรณ์ครับ
ทดลองค้นค่า server1.example.com
# nslookup server1.example.com localhost
Server: localhost Address: 127.0.0.1#53 Name: server1.example.com Address: 192.168.1.4
เรียบร้อยแล้วครับ
หมายเหตุ
หมายเหตุ 2
ข้อเขียนนี้เป็นเพียงการทดลองเท่านั้น แต่ใจสู้เขียน ด้วยค้นหาวิธีการแบบง่าย ๆ ไม่พบ (step by step) เลยต้องทดลองเอง และต้องการบันทึกผลการทดลองที่สามารถใช้งานได้แล้ว ดังนั้นจึงยังไม่ทราบผลข้างเคียงเรื่องความปลอดภัย และความถูกต้องตามระเบียบแบบแผนที่ควรเป็น
จึงต้องการขอคอมเมนต์และคำแนะนำเพื่อให้ได้รู้เรื่องกันในวงกว้างครับ
(ก่อนหน้านี้ เวลาต้องการอัปเดตเลขไอพี ผมใช้สคริปต์ในการสร้างโซนไฟล์ และรีเวิร์สไฟล์ขึ้นมาใหม่ แลัวจึงสั่งเริ่ม bind9 ใหม่ จึงไม่มีปัญหาเรื่องความปลอดภัยมาเกี่ยว)
อ้างอิง
Postfix เป็นแพกเกจ Mail Server ที่ได้รับความนิยมมากกว่าแพกเกจของเดเบียนเอง (Exim)
ดูจาก debian-administration: Mail Server Poll
ผมแทบไม่รู้อะไรเกี่ยวกับ Postfix SASL และ TLS เลย
แต่ขออนุญาตบันทึกไว้รอศึกษาครับ
เอามาจาก tribulaciones: Postfix/SASL/TLS HowTo for Debian Sid and Sarge
# aptitude install postfix postfix-tls libsasl2-modules sasl2-bin openssl
ปรับตั้ง Postfix ให้ใช้ SASL
# vi /etc/postfix/main.cf
... # SASL SUPPORT FOR CLIENTS # # The following options set parameters needed by Postfix to enable # Cyrus-SASL support for authentication of mail clients. # smtpd_sasl_auth_enable = yes smtpd_sasl_security_options = noanonymous smtpd_sasl_local_domain = $myhostname broken_sasl_auth_clients = yes ... smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination ...
ปรับตั้ง SASL
# vi /etc/postfix/sasl/smtpd.conf
... pwcheck_method: auxprop mech_list: digest-md5 cram-md5 ...
สมมุติว่าเซิร์ฟเวอร์เราชื่อ mail.example.com เราจะสร้างผู้ใช้ชื่อ test
# saslpasswd2 -c -u mail.example.com -a smtpauth test
Password: <<<--- ใส่รหัสผ่านของ test
Again (for verification): <<<--- ใส่รหัสผ่านของ test
คำสั่งนี้จะสร้างไฟล์รหัสผ่านชือ /etc/sasldb2
เราต้องเปลี่ยนเจ้าของให้มีกรุ๊ปเป็น sasl
# chgrp sasl /etc/sasldb2
(เดเบียนเปลี่ยนให้เอง)
และเปลี่ยนผู้ใช้ postfix ให้มาอยู่ในกรุ๊ป sasl
# usermod -G sasl postfix
และเริ่ม postfix ใหม่
# /etc/init.d/postfix reload
ตรวจสอบได้โดยการใช้ telnet ตัวอย่างคือ
[root@mail root]# telnet localhost 25 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 220 mail.example.com ESMTP Postfix (Debian/GNU) EHLO client.example.com 250-mail.example.com 250-PIPELINING 250-SIZE 20480000 250-ETRN 250-AUTH DIGEST-MD5 CRAM-MD5 250-AUTH=DIGEST-MD5 CRAM-MD5 250-XVERP 250 8BITMIME QUIT 221 Bye Connection closed by foreign host.
ปรับตั้ง TLS
## TLS # smtpd_use_tls = yes smtpd_tls_auth_only = yes smtpd_tls_key_file = /etc/postfix/postfix-key.pem smtpd_tls_cert_file = /etc/postfix/postfix-cert.pem smtpd_tls_CAfile = /etc/postfix/cacert.pem smtpd_tls_received_header = yes smtpd_tls_session_cache_timeout = 3600s tls_random_source = dev:/dev/urandom
ตั้งค่าเริ่มต้นให้ openssl
# vi /etc/ssl/openssl.cnf
... countryName_default = TH stateOrProvinceName_default = Bangkok localityName_default = Bangkok 0.organizationName_default = example.com organizationalUnitName_default = admin ...
เอาสคริปต์ตัวอย่างมาใช้สร้างคีย์
# /usr/lib/ssl/misc/CA.sh -newca
CA certificate filename (or enter to create)
<<<--- [ENTER]
Making CA certificate ...
Generating a 1024 bit RSA private key
.......................................++++++
...++++++
writing new private key to './demoCA/private/./cakey.pem'
Enter PEM pass phrase: <<<--- ใส่รหัสผ่าน
Verifying - Enter PEM pass phrase: <<<--- ใส่รหัสผ่านอีกครั้ง
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [TH]: <<<--- [ENTER]
State or Province Name (full name) [Bangkok]: <<<--- [ENTER]
Locality Name (eg, city) [Bangkok]: <<<--- [ENTER]
Organization Name (eg, company) [example.com]: <<<--- ใส่ชื่อร้านหรือหน่วยงาน
Organizational Unit Name (eg, section) [admin]: <<<--- ชื่อย่อหน่วยงานย่อย
Common Name (eg, YOUR name) []: <<<--- ชื่อหน่วยงานปกติ
Email Address []: <<<--- อีเมลเรา
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: <<<--- [ENTER]
An optional company name []: <<<--- [ENTER]
Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/./cakey.pem: <<<--- รหัสผ่านให้เหมือน PEM
...
Write out database with 1 new entries
Data Base Updated
ไฟล์กุญแจ CA certificate จะอยู่ที่ /etc/ssl/demoCA/private/cakey.pem
เอาไฟล์ตัวอย่าง CA.sh มาปรับแก้
# cd /etc/ssl
# cp /usr/lib/ssl/misc/CA.sh CA-nodes.sh
เราจะแพตช์ให้ใช้กับของเรา ด้วยการสร้างไฟล์ชื่อ CA.patch
# vi CA.patch
--- /usr/lib/ssl/misc/CA.sh 2006-11-16 17:57:32.000000000 +0700 +++ /etc/ssl/CA-nodes.sh 2006-11-14:16:28:39.000000000 +0700 @@ -53,13 +53,13 @@ case $i in ;; -newcert) # create a certificate - $REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS + $REQ -new -nodes -x509 -keyout newkey.pem -out newcert.pem $DAYS RET=$? echo "Certificate is in newcert.pem, private key is in newkey.pem" ;; -newreq) # create a certificate request - $REQ -new -keyout newkey.pem -out newreq.pem $DAYS + $REQ -new -nodes -keyout newkey.pem -out newreq.pem $DAYS RET=$? echo "Request is in newreq.pem, private key is in newkey.pem" ;;
สั่งแพตช์
# patch -p3 < CA.patch
สร้างกุญแจจากไฟล์ที่แพตช์แล้ว
# ./CA-nodes.sh -newreq
Generating a 1024 bit RSA private key
........................++++++
...........++++++
writing new private key to 'newkey.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [TH]: <<<--- [ENTER]
State or Province Name (full name) [Bangkok]: <<<--- [ENTER]
Locality Name (eg, city) [Bangkok]: <<<--- [ENTER]
Organization Name (eg, company) [example.com]: <<<--- ใส่ชื่อร้านหรือหน่วยงาน
Organizational Unit Name (eg, section) [admin]: <<<--- ชื่อย่อหน่วยงานย่อย
Common Name (eg, YOUR name) []: <<<--- ชื่อหน่วยงานปกติ
Email Address []: <<<--- อีเมลเรา
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: <<<--- [ENTER]
An optional company name []: <<<--- [ENTER]
Request is in newreq.pem, private key is in newkey.pem
สั่งใช้กุญแจที่สร้าง
# ./CA-nodes.sh -sign
คัดลอกไฟล์กุญแจที่สร้างไว้ไปที่ /etc/postfix
# cp demoCA/cacert.pem /etc/postfix
# cp newreq.pem /etc/postfix/postfix-key.pem
# cp newcert.pem /etc/postfix/postfix-cert.pem
# cd /etc/postfix
# chown root:root postfix-key.pem ; chmod 400 postfix-key.pem
เริ่ม postfix ใหม่อีกครั้ง
# /etc/init.d/postfix reload
ต้องไม่มีรายงานข้อผิดพลาด
# aptitude install postfix postfix-tls libsasl2-modules openssl
ปรับตั้ง Postfix ให้ใช้ SASL
# vi /etc/postfix/main.cf
... # SASL for client side # smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd smtp_sasl_security_options = ...
ปรับแก้ให้ไฟล์รหัสผ่าน อ่านได้จาก root อย่างเดียว
# chown root:root /etc/postfix/sasl_passwd && chmod 600 /etc/postfix/sasl_passwd
สร้างไฟล์ข้อมูล sasl_passwd DB ด้วยคำสั่ง postmap
# postmap hash:/etc/postfix/sasl_passwd
ปรับตั้ง TLS
แก้ /etc/postfix/main.cf
# vi /etc/postfix/main.cf
... # Use TLS client side smtp_use_tls = yes ... # If we want also the client to issue a certificate, these lines are needed: smtp_tls_key_file = /etc/postfix/postfix-key.pem smtp_tls_cert_file = /etc/postfix/postfix-cert.pem smtp_tls_CAfile = /etc/postfix/cacert.pem ...
เสร็จแล้วด้วยความมึนงง :)
การติดตั้ง postfix ฉบับที่ให้ผลดีกว่า คือ
The Perfect Setup - Debian Sarge (3.1) - Page 4
บันทึก error
warning: database /etc/postfix/virtusertable.db is older than source file /etc/postfix/virtusertable
# postmap /etc/postfix/virtusertable
debian: lenny
ถ้าต้องการให้ url เป็น http://www.example.com/drupal5 และใช้กับ mysql ใช้คำสั่งเดียว
# aptitude install drupal5 phppgadmin
แล้วไปติดตั้งที่ http://www.example.com/drupal5/install.php ได้เลย
กรณีเรา จะติดตั้งบน postgresql-8.3 (เขาว่ารุ่นนี้มี Full Text Index ให้ใช้แล้ว)
ติดตั้ง postgresql ก่อน
# aptitude install postgresql
# su postgres
$ createuser -s -P admin
เอาไว้ใช้งาน phppgadmin
แก้ไขให้เรียกใช้งานจากลูกข่ายใด ๆ ก็ได้
# vi /etc/postgresql/8.3/main/postgresql.conf
listen_addresses = '*'
แก้ไขสิทธ์
# vi /etc/postgresql/8.3/main/pg_hba.conf
#local all all ident sameuser local all all md5 host all all 192.168.0.0/16 md5
ติดตั้ง apache2
# aptitude install apache2 php5 phppgadmin
(ต้องระบุ apache2 และ php5 เพราะ phppgadmin ดีเพน apache และ php4 ด้วย ถ้าระบุแบบนี้ เขาจะไม่ติดตั้ง apache และ php4 ซึ่งเราไม่ต้องการ โดยอัตโนมัติ )
# dpkg-reconfigure phppgadmin
# vi /etc/phppgadmin/apache.conf
# deny from all allow from 127.0.0.0/255.0.0.0 allow from all
เริ่ม apache2 ใหม่
# /etc/init.d/apache2 restart
ติดตั้ง drupal5
# aptitude install drupal5
Web server(s) that should be configured automatically: apache2 Configure database for drupal5 with dbconfig-common? Yes Database type to be used by drupal5: pgsql PostgreSQL application password for drupal5: DRUPAL5-PASSWORD
*** ยังไม่แน่ใจว่าเป็นบั๊กหรือไม่ เขาไม่ยอมโหลดส่วนขยาย pdo ทำให้ pdo_pgsql โหลดต่อไม่ได้ ***
แก้ไขเรื่อง pdo
# vi /etc/php5/apache2/php.ini
... extension=pdo.so ...
ไปที่ http://www.example.com/drupal5/install.php
ติดตั้งเสร็จแล้ว ไปต่อที่ http://www.example.com/drupal5 ได้เลย
หมายเหตุ
# vi /etc/drupal/5/apache.conf
Alias /content /usr/share/drupal5
# cd /etc/drupal/5/sites/default
# vi baseurl.php
<?php $base_url = 'http://www.example.com/content'; // NO trailing slash! ?>
# chgrp www-data baseurl.php
# /etc/init.d/apache2 restart
(แต่หากต้องการใช้ใน root คือ http://www.example.com เฉย ๆ ควรดาวน์โหลดและติดตั้ง drupal เองที่ /var/www
หรือแก้ไข /etc/apache2/site-enabled/default ให้ชี้มาที่ /usr/share/drupal5 อย่างใดอย่างหนึ่ง)
# a2enmod rewrite
# vi /etc/drupal/5/htaccess
... RewriteBase /content ...
# /etc/init.d/apache2 restart
# aptitude purge drupal5 apache2 libapache2-mod-php5 apache2.2-common php5-pgsql php5-gd
# aptitude purge postgresql-8.3
# rm -rf /etc/php5 /etc/apache2 /etc/postgresql /etc/phppgadmin
# aptitude install postgresql-8.3
# aptitude install drupal5 php5-pgsql
สรุป
ยังทำไม่ค่อยเป็นเท่าไหร่ ตอนเอาจริง ติดตั้งแบบดิบ ๆ จาก drupal สะดวกกว่า
เที่ยวนี้บันทึกเอาไว้ดู ว่าติดตั้งจากเดเบียนทำยังไง
ทดลองเกี่ยวกับ Virtualization
เดี๋ยวนี้ qemu พร้อม kqemu มีเป็นแบบแพกเกจเรียบร้อย การติดตั้งจึงต่างออกไปจากเดิม
สำหรับใน Feisty การติดตั้งเป็นดังนี้
ส่วนของ qemu
ติดตั้ง qemu
$ sudo aptitude install qemu
ส่วนของ kqemu
ติดตั้ง module-assistant
$ sudo aptitude install module-assistant
ติดตั้ง kqemu ผ่าน module-assistant
$ sudo m-a a-i kqemu
ใน Feisty ไม่ยอมสร้าง /dev/kqemu ให้ ต้องทำเอง
$ sudo mknod /dev/kqemu c 250 0
$ sudo chmod 666 /dev/kqemu
$ sudo modprobe kqemu
ส่วนของเน็ตเวิร์ก
สร้างตาราง nat ไว้รอก่อน
$ sudo iptables -t nat -D POSTROUTING -j MASQUERADE -o eth0
$ sudo iptables -t nat -A POSTROUTING -j MASQUERADE -o eth0
ติดตั้งแพกเก็จชื่อ uml-utilities
$ sudo aptitude install uml-utilities
เอาอินเทอร์เฟส tun ขึ้นมา
$ sudo modprobe tun
$ sudo chmod 666 /dev/net/tun
qemu จะใช้งานเน็ตเวิร์กผ่านอินเทอร์เฟส tap0 เราจึงต้องสร้าง tap0 ขึ้นมา สมมุติว่าเราชื่อ user1
$ sudo tunctl -u user1
เสร็จแล้ว
สมมุติว่าเรามีอิมเมจ winxp.img อยู่แล้ว สามารถเรียกใช้งาน qemu ด้วย
$ qemu -kernel-kqemu -hda winxp.img -net nic -net tap,ifname=tap0
บันทึกเกร็ดเพิ่มเติม
$ qemu-img create -f qcow winxp.qcow 5G
$ qemu-img create -b winxp.qcow -f qcow winxp.ovl
$qemu-img commit winxp.ovl
สรุปว่าสำหรับ qemu ตั้งแต่รุ่น 0.8.2 เป็นต้นไป ต้องทดลองดูหลาย ๆ แบบ ดูว่าแบบไหนดีที่สุด ไม่จำเป็นต้องเป็นตามคู่มือเสมอไป
หมายเหตุ
อ้างอิง
ทดลองใช้ qemu กับ usb
ในการสั่งรัน ต้องเติมพารามิเตอร์ -usbdevice host:XXXX:XXXX
ต่อท้ายคำสั่ง
ซึ่งค่านี้คือค่า Vender ID และ Product ID ตามลำดับ โดยหาได้จากคำสั่ง lsusb
ตัวอย่างของเครื่องผมคือ
ต้องการใช้งาน usb ใน qemu โดยมี Printer Epson Stylus Photo 830 และสแกนเนอร์ UMAX Astra 5650
ดูค่าไอดี
$ lsusb
Bus 005 Device 001: ID 0000:0000 Bus 004 Device 001: ID 0000:0000 Bus 003 Device 002: ID 04b8:0005 Seiko Epson Corp. Stylus Printer Bus 003 Device 001: ID 0000:0000 Bus 002 Device 001: ID 0000:0000 Bus 001 Device 002: ID 0461:0392 Primax Electronics, Ltd Bus 001 Device 001: ID 0000:0000
สั่งรัน qemu
$ qemu YOUR-PARAMETER -usbdevice host:04b8:0005 -usbdevice host:0461:0392
เสียง
ใช้คำสั่ง
$ qemu YOUR-PARAMETER -soundhw all
รุ่นนี้เป็นรุ่นปรับแก้บั๊กเรื่อง NumLock/CapsLock ไม่ยอมเปลี่ยน ตามที่เคยบันทึกไว้
แต่ผมลืมแพกเกจที่ต้องการก่อนติดตั้งหมดแล้ว ฝากดูเอาเองตอน debuild หรือ configure
วิธีสร้างแพกเกจเดเบียน
$ sudo aptitude install devscripts
$ apt-get source qemu
$ cd qemu-0.9.0+20070816
$ vi sdl.c
. . . if (ev->keysym.sym == SDLK_PAUSE) { /* specific case */ v = 0; if (ev->type == SDL_KEYUP) v |= 0x80; kbd_put_keycode(0xe1); kbd_put_keycode(0x1d | v); // kbd_put_keycode(0x45 | v); return; } if (kbd_layout) { keycode = sdl_keyevent_to_keycode_generic(ev); } else { keycode = sdl_keyevent_to_keycode(ev); } switch(keycode) { case 0x00: /* sent when leaving window: reset the modifiers state */ reset_keys(); return; case 0x2a: /* Left Shift */ case 0x36: /* Right Shift */ case 0x1d: /* Left CTRL */ case 0x9d: /* Right CTRL */ case 0x38: /* Left ALT */ case 0xb8: /* Right ALT */ if (ev->type == SDL_KEYUP) modifiers_state[keycode] = 0; else modifiers_state[keycode] = 1; break; //case 0x45: /* num lock */ //case 0x3a: /* caps lock */ /* SDL does not send the key up event, so we generate it */ // kbd_put_keycode(keycode); // kbd_put_keycode(keycode | 0x80); // return; } . . .
$ debuild -us -uc
จะได้แพกเกจเดเบียน ตามต้องการ
ติดตั้งด้วยคำสั่ง
$ sudo dpkg -i ../qemu_0.9.0+20070816-1_i386.deb
วิธีสร้างแพกเกจแบบทั่วไป
$ wget http://fabrice.bellard.free.fr/qemu/qemu-0.9.0.tar.gz
$ tar xfz qemu-0.9.0.tar.gz
$ cd qemu-0.9.0
$ configure --cc=gcc-3.4
$ make
$ checkinstall -D make install
$ make qemu-doc.html
$ make qemu-tech.html
$ make qemu.1
$ make qemu-img.1
$ sudo make install-doc
$ make tarbin
จะได้แพกเกจ qemu-0.9.0-i386.tar.gz ตามต้องการ โดยไฟล์จะมาอยู่ที่ไดเรกทอรี่ Home
Download
หากคร้านที่จะคอมไพล์เอง ดาวน์โหลดได้ที่นี่ครับ ฝากทดสอบบั๊กให้ด้วย
เมื่อได้ลองใช้งาน qemu แบบจริงจัง เจอปัญหาว่า Num Lock กับ Caps Lock มีอาการแปลก ๆ กดแล้วได้ผลบ้าง ไม่ได้ผลบ้าง
เลยลองถอด qemu ของดิสโตร แล้วดาวน์โหลด qemu รุ่นล่าสุดมาลองดูซอร์สโค๊ด
$ sudo aptitude remove qemu
$ wget http://fabrice.bellard.free.fr/qemu/qemu-0.9.0.tar.gz
$ tar xfz qemu-0.9.0.tar.gz
$ cd qemu-0.9.0
ค้นข้อมูลในกูเกิลดู พบว่าต้นตออยู่ที่ไฟล์ sdl.c
พบว่า qemu แก้ปัญหา sdl ไม่ยอมส่งรหัส Num Lock - Caps Lock ไปให้ระบบ ด้วยการเขียนโค๊ดส่งรหัสเอง
แต่ปัจจุบันนี้ sdl น่าจะแก้ปัญหานี้แล้ว แต่โค๊ดส่วนนี้ยังคงอยู่ เลยทดลองเติมคอมเมนต์ในโค๊ดส่วนนี้ดู
$ vi sdl.c
... //case 0x45: /* num lock */ //case 0x3a: /* caps lock */ /* SDL does not send the key up event, so we generate it */ // kbd_put_keycode(keycode); // kbd_put_keycode(keycode | 0x80); // return; ...
แล้วจึงคอมไพล์ใหม่ ด้วย gcc-3.4 ซึ่งต้องติดตั้งใหม่
$ sudo aptitude install gcc-3.4
$ ./configure --cc=gcc-3.4
$ make
$ sudo make install
ผลปรากฎว่า สามารถใช้คีย์ Num Lock และ Caps Lock ได้อย่างที่ควรจะเป็นครับ
ทดลองกับเดเบียน Lenny และอูบุนตู Feisty ไลบรารี libsdl1.2-dev ทั้งคู่
จะเอามาลองทดสอบ Windows XP
ใช้ซีพียูอินเทล E6300 (เป็น VT อันดับเบื้องต้นที่สามารถวิ่ง Unmodified OS ได้) แรม 1G
ติดตั้ง xen
$ sudo aptitude install xen-hypervisor-3.0.3-1-i386 xen-utils-common
ติดตั้ง Dom0
$ sudo aptitude install xen-linux-system-2.6.18-4-xen-686
บูตใหม่ด้วย Dom0
เตรียมติดตั้ง DomU ที่เป็น Windows XP
$ sudo aptitude install xen-ioemu-3.0.3-1
สร้างไฟล์คอนฟิกสำหรับ Windows XP
$ sudo vi /etc/xen/winxp.cfg
ติดตั้ง DomU ไว้บนพาร์ติชั่นของฮาร์ดดิสก์จริง ๆ คือ /dev/hda2
ติดตั้งเน็ตเวิร์กตามค่าปริยาย คือเป็นแบบบริดจ์
เนื้อไฟล์เป็นดังนี้
kernel = "/usr/lib/xen-3.0.3-1/boot/hvmloader" device_model ='/usr/lib/xen-3.0.3-1/bin/qemu-dm' builder='hvm' memory = 384 name = "winxp" vcpus=1 disk = ['phy:/dev/hda2,ioemu:hda,w','phy:/dev/hdb,hdb:cdrom,r'] boot='d' vif = [ 'type=ioemu, bridge=xenbr0' ] vnc=1 vncviewer=1 serial='pty' ne2000=0
ติดตั้ง VNC สำหรับดูหน้าจอ Windows XP
$ sudo aptitude install xtightvncviewer
เริ่มบูตเพื่อติดตั้ง DomU
$ sudo xm create winxp.cfg
เมื่อเคอร์เซอร์หลุดออกมาสู่ภาวะพร้อม ก็สั่งดูหน้าจอติดตั้ง Windows XP ด้วย xtightvncviewer
$ xtightvncviewer localhost
... ติดตั้งตามปกติ ...
หมายเหตุ
$ xtightvncviewer localhost
ใหม่boot = 'c'
ด้วยผลการทดลอง
Control Panel -> Mouse -> TAB-Pointer options -> ปิด Enhance pointer position
สรุป
ถึงแม้จะยังไม่สมบูรณ์แบบ แต่ก็น่าใช้มาก โดยเฉพาะถ้าต้องการความเร็วในการใช้งาน การติดตั้งก็ไม่ยากเหมือนแต่ก่อน
เสียดายที่ต้องใช้กับซีพียูที่มีโหมด Vitualize เท่านั้น (Intel-VT, AMD-Pacifica) และโอเอสก็ต้องเป็น 32bit ขึ้นไปแบบ Windows XP
ถ้าใช้กับ Win98 ได้นี่จะประหยัดไลเซ่นซ์วินโดวส์เก่า ๆ ได้เยอะเลย
อ้างอิง
หลังจากทดลอง Xen แล้ว พบว่ายังมีปัญหาเกี่ยวกับคีย์บอร์ดที่ค่อนข้างเอาแน่เอานอนไม่ได้ และปัญหาความไม่คุ้นเคยในการใช้เมาส์ผ่าน VNC
จึงได้มาทดลองใช้ VirtualBox
ซีพียูอินเทล E6300 หน่วยความจำ 1G
พบว่า
จึงบันทึกการปรับตั้งค่าไว้ดังนี้
มีปัญหาว่าบางครั้ง แม้จะแก้ไขให้เราอยู่ในกลุ่ม vboxusers แล้วก็ตาม แต่บางครั้งก็ยังไม่สามารถรันได้ จึงแก้ไขให้ /dev/vboxdrv เป็นโหมด 666 ผ่าน udev
$ sudo vi /etc/udev/rules.d/60-vboxdrv.rules
แก้จาก KERNEL=="vboxdrv", NAME="vboxdrv", OWNER="root", GROUP="vboxusers", MODE="0660"
แก้เป็น
KERNEL=="vboxdrv", NAME="vboxdrv", OWNER="root", GROUP="vboxusers", MODE="0666"
แก้ไขค่าเน็ตเวิร์ก tun ให้เป็น 666 เหมือนกัน
$ sudo vi /etc/udev/rules.d/020_permissions.rules
แก้เป็น
... KERNEL=="tun", MODE="0666" ...
สร้างสคริปต์สำหรับเน็ตเวิร์กแบบกำหนดเอง
$ vi ~/ifup-tap0
sudo iptables -t nat -D POSTROUTING -j MASQUERADE -o eth0 sudo iptables -t nat -A POSTROUTING -j MASQUERADE -o eth0 UNAME=$USER sudo tunctl -u $UNAME -t tap0 sudo ifconfig tap0 192.168.4.254 up
$ sudo chmod 755 ~/ifup-tap0
ตั้งค่าให้ VirtualBox ใช้เน็ตเวิร์กแบบ Host Interface
Setting -> Network -> Host Interface
Interface name : tap0
Setup application : ~/ifup-tap0
สำหรับ Windows XP เขาให้หน่วยความจำปริยายมาเป็น 128M แต่เรากำหนดเป็น 384M
ใน Windows XP ตั้งค่าให้ไอพีเป็น 192.168.1.4 และเกตเวย์เป็น 192.168.4.254
$ sudo mount -o loop,offset=0x$(hd -h 100000 IMAGE.vdi | grep "eb 52 90 4e 54 46 53" | cut -c 1-8) IMAGE.vdi /MOUNT/POINT
$ sudo mount -o loop,offset=0x$(hd -h 100000 IMAGE.vdi | grep "eb 3C 90" | cut -c 1-8) IMAGE.vdi /MOUNT/POINT
มีงานที่ต้องการทดสอบการแสดงผล ของ Safari/iBooks ใน iPhone/iPad (iOS) และ Mac (OS X) จึงต้องลง OS X เพื่อทดสอบ แอปที่จะใช้ คือ iBooks, iBooks Author และ Xcode ต้องการทรัพยากรเป็น Mavericks (10.9) แต่ Mavericks ไม่มีแผ่นขาย มีขายแต่ Snow Leopard (10.6.3) จึงต้องมีขั้นตอนเยอะหน่อย
host: Debian 3.12-1-amd64
cpu: Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz
ram: 8G
VirtualBox: Official 4.3
iBoot-Ivy-Bridge.iso
ไว้ (ถ้าบูตไม่ผ่าน ลองดาวน์โหลด iBoot ตัวอื่นดู)เอา VirtualBox สร้าง Virtual Machine ใหม่ดังนี้
Name: osx Type: Max OS X Version: Mac OS X (64 bit) Memory size: 2048 Hard drive: virtual hard drive 30.00GB VDI (VirtualBox Disk Image) (ค่าปริยาย 20G ไม่พอ) Storage on physical hard drive: Dynamically allocated
ตั้งค่าอื่น
System: Motherboard: ยกเลิก Enable EFI (special OSes only) Display: Video: Enable 3D Acceleration Storage: Controller: SATA -> Empty เปลี่ยน Attributes: Choose a virtual CD/DVD disk file: เปลี่ยนเป็น iBoot-Ivy-Bridge.iso ที่เตรียมไว้
ส่วนที่เหลือ ใช้ค่าปริยายทั้งหมด
เสร็จแล้วก็บูตเข้า iBoot ต่อด้วย Snow Leopard เพื่อติดตั้ง
ตอนบูตเข้า iBoot ให้ใส่แผ่น Snow Leopard ในซีดีรอม แล้วเปลี่ยน Devices เป็น Host Drive ATAPI แล้วกด F5 เพื่อรีเฟรช แล้วจึงบูตติดตึ้ง Snow Leopard
Devices -> CD/DVD devices -> Host Drive ATAPI (sr0) กด F5 บูตด้วย Mac OS X Install DVD
ติดตั้งตามปกติ ระหว่างติดตั้งต้องมีการสร้างพาร์ติชั่นด้วย
Utilities -> Disk Utility เลือก 32.21 GB VBOX HARDISK -> Partition -> + -> Name: osx Apply
ติดตั้งต่อจนเสร็จ
บูตเข้าระบบโดยต้องกลับไปใช้ iBoot-Ivy-Bridge
อีกครั้ง แล้วเลือกเข้า osx ที่ติดตั้งเสร็จแล้ว
ถ้าบูตไม่ขึ้น ให้ลองปิดและบูตใหม่
หลังติดตั้งเสร็จเรียบร้อย ให้อัปเดตระบบ เพื่อให้มี App Store
Apple -> Software Update
อัปเดตเสร็จ รีบูตใหม่ ระบบจะกลายเป็น 10.6.8 และมี App Store เรียบร้อย
ดาวน์โหลด Mavericks ผ่าน AppStore ขนาดประมาณ 5.3GB (5GiB)
เมื่อเสร็จ ไฟล์ที่ได้จะอยู่ที่ /Applications/Install OS X Mavericks.app
แปลงเป็น iso เพื่อจะนำไปติดตั้งในขั้นตอนต่อไป
เข้า Terminal
Applications -> Utilities -> Terminal
แล้วพิมพ์คำสั่งดังนี้
# Mount the installer image hdiutil attach /Applications/Install\ OS\ X\ Mavericks.app/Contents/SharedSupport/InstallESD.dmg -noverify -nobrowse -mountpoint /Volumes/install_app # Convert the boot image to a sparse bundle hdiutil convert /Volumes/install_app/BaseSystem.dmg -format UDSP -o /tmp/Mavericks # Increase the sparse bundle capacity to accommodate the packages hdiutil resize -size 8g /tmp/Mavericks.sparseimage # Mount the sparse bundle for package addition hdiutil attach /tmp/Mavericks.sparseimage -noverify -nobrowse -mountpoint /Volumes/install_build # Remove Package link and replace with actual files rm /Volumes/install_build/System/Installation/Packages cp -rp /Volumes/install_app/Packages /Volumes/install_build/System/Installation/ # Unmount the installer image hdiutil detach /Volumes/install_app # Unmount the sparse bundle hdiutil detach /Volumes/install_build # Resize the partition in the sparse bundle to remove any free space hdiutil resize -size `hdiutil resize -limits /tmp/Mavericks.sparseimage | tail -n 1 | awk '{ print $1 }'`b /tmp/Mavericks.sparseimage # Convert the sparse bundle to ISO/CD master hdiutil convert /tmp/Mavericks.sparseimage -format UDTO -o /tmp/Mavericks # Remove the sparse bundle rm /tmp/Mavericks.sparseimage # Rename the ISO and move it to the desktop mv /tmp/Mavericks.cdr ~/Desktop/Mavericks.iso
คัดลอก Mavericks.iso
บน Desktop มาสู่เครื่องจริง (อาจผ่าน usb หรือเน็ตเวิร์ค - ผมใช้ผ่านเน็ตเวิร์ค) เพื่อจะนำไปติดตั้งในขั้นตอนต่อไป
ปิดเครื่อง
จบขั้นแรก
หากต้องการทดสอบ Snow Leopard ต่อไปก็สามารถเก็บ Virtual Machine "osx" นี้ไว้ได้ แต่หากไม่ต้องการใช้แล้วก็ลบทิ้งได้เลย
เอา VirtualBox สร้าง Virtual Machine ใหม่ดังนี้
Name: osx64 Type: Max OS X Version: Mac OS X (64 bit) Memory size: 2048 Hard drive: virtual hard drive 30.00GB VDI (VirtualBox Disk Image) (ถ้าต้องใช้งานจริงจัง ควรเป็น 40G ขึ้นไป) Storage on physical hard drive: Dynamically allocated
คราวนี้ไม่ต้องใช้ iBoot แล้ว โดยจะใช้ Mavericks.iso
ที่ได้จากขั้นตอนก่อนหน้ามาทำเป็น virtual CD/DVD disk file
สำหรับบูตเพื่อติดตั้ง และไม่ต้องยกเลิก EFI แล้ว
ตั้งค่าอื่น
System: Processor: 2 CPU Display: Video: Video Memory: 32 MB (ใช้ค่าอื่นแล้วเปิด System Information ไม่ได้) Enable 3D Acceleration Storage: Controller: SATA -> Empty เปลี่ยน Attributes: Choose a virtual CD/DVD disk file: เปลี่ยนเป็น Mavericks.iso ที่เตรียมไว้
ก่อนจะบูต ให้บอก VirtualBox ว่าจะติดตั้งเป็น 64 บิต และเลือกหน้าจอเป็นขนาด 1440x900
เข้า Terminal ของลินุกซ์ แล้วพิมพ์ดังนี้
VM=osx64 N=4 #N can be one of 0,1,2,3,4,5 referring to the 640x480, 800x600, 1024x768, 1280x1024, 1440x900, 1920x1200 screen resolution respectively (5 may not worked). VBoxManage modifyvm "$VM" --firmware efi64 VBoxManage setextradata "$VM" VBoxInternal2/EfiGopMode $N VBoxManage setextradata "$VM" VBoxInternal2/SmcDeviceKey "ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc"
แล้วก็เริ่มสตาร์ท osx64 เพื่อติดต้้งได้เลย บูตครั้งแรกอาจนานหน่อยและมีรายงานความผิดพลาดเยอะ แต่ไม่ต้องสนใจ
วิธีติดตั้งเหมือนเดิม คือต้องพาร์ติชั่นก่อน แล้วติดตั้งต่อจนจบ
ตอนบูตครั้งแรก อย่าลืมเปลี่ยน virtual CD/DVD จาก Mavericks กลับเป็น Host Drive ATAPI (sr0)
จบแล้ว
SYSTEM
OS: Debian Linux 4.18.0-3-amd64
CPU: AMD Ryzen 7 1700 Eight-Core Processor
VirtualBox: virtualbox-5.2 : 5.2.20-125813~Ubuntu~bionic
STEP
1. CREATE VM
2. MODIFY VM
3. BOOT INSTALLER
4. BOOT NEW OS
5. CREATE NEXT VERSION CDR INSTALLER
6. FIX VirtualBox NOT SUPPORT apfs IN High Sierra/Mojave
1. CREATE VM
General
Machine -> New
Name="NAME OF VM"
Type=Mac OS X
Version=Mac OS X (64-bit)
Storage
HDD=NEW VDI DISK IMAGE (20-60G)
CD=CDR INSTALLER
2. MODIFY VM
RUN COMMANDS:
VM_RES="1280x960" #EXAMPLE NAME="NAME OF VM" #EXAMPLE VBoxManage modifyvm "$NAME" --usbxhci on --firmware efi --chipset ich9 --mouse usbtablet --keyboard usb --vram 128 --cpus 2 --memory 4096 --boot1 dvd --boot2 disk --boot3 none --boot4 none --cpu-profile "Intel Core i7-6700K" --cpuidset 00000001 000106e5 00100800 0098e3fd bfebfbff VBoxManage setextradata "$NAME" "CustomVideoMode1" "${VM_RES}x32" VBoxManage setextradata "$NAME" VBoxInternal2/EfiGraphicsResolution "$VM_RES" VBoxManage setextradata "$NAME" "VBoxInternal/Devices/efi/0/Config/DmiSystemProduct" "iMac11,3" VBoxManage setextradata "$NAME" "VBoxInternal/Devices/efi/0/Config/DmiSystemVersion" "1.0" VBoxManage setextradata "$NAME" "VBoxInternal/Devices/efi/0/Config/DmiBoardProduct" "Iloveapple" VBoxManage setextradata "$NAME" "VBoxInternal/Devices/smc/0/Config/DeviceKey" "ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc" VBoxManage setextradata "$NAME" "VBoxInternal/Devices/smc/0/Config/GetKeyFromRealSMC" 1 #FOR Snow Leopard: NUMBER OF CPU=1 VBoxManage modifyvm "$NAME" --usbxhci on --firmware efi --chipset ich9 --mouse usbtablet --keyboard usb --vram 128 --cpus 1 --memory 4096 --boot1 dvd --boot2 disk --boot3 none --boot4 none --cpu-profile "Intel Core i7-6700K" --cpuidset 00000001 000106e5 00100800 0098e3fd bfebfbff #FOR Sierra: SOLVE PARAVIRTUALIZATION BUG #https://gist.github.com/arobb/447a962af4f07ef81e79987d686275e5 #https://www.insanelymac.com/forum/topic/292170-how-to-spoof-real-mac-in-vmware/ VBoxManage setextradata "$NAME" "VBoxInternal/Devices/efi/0/Config/DmiBoardProduct" "Mac-F22589C8" VBoxManage setextradata "$NAME" "VBoxInternal/Devices/efi/0/Config/DmiSystemSerial" "CK1156I6DB6" VBoxManage modifyvm "$NAME" --paravirtprovider none #REVERT BACK WHEN FINISH INSTALLATION VBoxManage modifyvm "$NAME" --paravirtprovider default ##SOME USEFUL SETTINGS, DO NOT RUN ##BOOT SINGLE USER #VBoxManage setextradata "$NAME" VBoxInternal2/EfiBootArgs "-s" ##REVERT #VBoxManage setextradata "$NAME" VBoxInternal2/EfiBootArgs "" ##TURN OFF #VBoxManage setextradata "$NAME" VBoxInternal2/EfiBootArgs " " ##VERBOSE #VBoxManage setextradata "$NAME" VBoxInternal2/EfiBootArgs "-v" ##NO AMD, NO NVIDIA #VBoxManage setextradata "$NAME" VBoxInternal2/EfiBootArgs "-s agc=0 -amd_no_dgpu_accel nv_disable=1" ##DEBUG #VBoxManage setextradata "$NAME" VBoxInternal2/EfiBootArgs "-v debug=0x144" #IF MOUSE OR KEYBOARD DO NOT WORK, TRY TO ADD NEW USB FILTERS
3. BOOT INSTALLER
#STEP
#- ERASE DISK
#- INSTALL
#FOR Mavericks NETWORK MAY NOT WORK, JUST INSTALL LOCALLY, WILL WORK AFTER REBOOT.
4. BOOT NEW OS
5. CREATE NEXT VERSION CDR INSTALLER
#GET PACKAGES FROM SAFARI, DO NOT INSTALL:
#LION
https://itunes.apple.com/app/id444303913?mt=12
#MOUNTAIN LION
https://itunes.apple.com/app/id537386512?mt=12
#MAVERICKS
https://itunes.apple.com/app/id675248567?mt=12
#YOSEMITE
https://itunes.apple.com/app/id444303913?mt=12
#EL CAPITAN
https://itunes.apple.com/app/id1147835434?mt=12
#SIERRA
https://itunes.apple.com/app/id1127487414?mt=12
#HIGH SIERRA
https://itunes.apple.com/app/id1246284741?mt=12
#MOJAVE
https://itunes.apple.com/app/id1398502828?mt=12
#IF FAIL, DOWNLOAD FROM HERE
#http://osxdaily.com/2018/09/29/download-full-macos-mojave-installer/
#http://dosdude1.com/mojave/
#AFTER FINISH INSTALLATION, RE-DOWNLOAD FROM APPLE AGAIN, THEN RE-CREATE INSTALLER FROM MOJAVE
#SOME LINK ARE DEAD, PLEASE DOWNLOAD FROM "iTunes -> Purchased"
#START BUILD FILE="ElCapitan" #EXAMPLE APPDIR="/Applications/Install OS X El Capitan.app" #EXAMPLE SIZE=8000 #CREATE IMAGE AND MOUNT hdiutil create -o /tmp/$FILE -size ${SIZE}m -layout SPUD -fs HFS+J # -> /tmp/$FILE.dmg hdiutil attach /tmp/$FILE.dmg -noverify -nobrowse # -> /Volumes/untitled #***** asr METHOD ***** (<=Yosemite, El Capitan(CDR), Sierra) #MOUNT InstallESD hdiutil attach "$APPDIR/Contents/SharedSupport/InstallESD.dmg" # -> /Volumes/OS X Install ESD ESD="/Volumes/OS X Install ESD" #FOR <= Yosemite, Sierra: #RESTORE BaseSystem TO IMAGE asr restore -source "$ESD/BaseSystem.dmg" -target /Volumes/untitled -noprompt -noverify -erase #/Volumes/untitled -> /Volumes/OS X Base System #COPY PACKAGES rm "/Volumes/OS X Base System/System/Installation/Packages" cp -av "$ESD/Packages" "/Volumes/OS X Base System/System/Installation/" #FOR >= Yosemite: cp -av "$ESD/BaseSystem.dmg" "/Volumes/OS X Base System/" cp -av "$ESD/BaseSystem.chunklist" "/Volumes/OS X Base System/" #FOR >= El Capitan(CDR): cp -av "$ESD/AppleDiagnostics.dmg" "/Volumes/OS X Base System/" cp -av "$ESD/AppleDiagnostics.chunklist" "/Volumes/OS X Base System/" #UNMOUNT ALL hdiutil detach "/Volumes/OS X Base System" hdiutil detach "$ESD" #***** createinstallmedia METHOD ***** (El Capitan(VDI), High Sierra, Mojave) #CREATE INSTALLER TO IMAGE #FOR El Capitan(VDI) (USE VDI INSTEAD OF CDR - NEED WRITABLE MEDIA WHEN INSTALL), >= High Sierra: sudo "$APPDIR/Contents/Resources/createinstallmedia" --volume /Volumes/untitled/ --applicationpath "$APPDIR" --nointeraction #/Volumes/untitles -> /Volumes/Install OS X XXX #UNMOUNT BASE hdiutil detach "/Volumes/Install XXX" #***** END 2 METHOD ***** #RESIZE IMAGE FOR BEST FIT hdiutil resize -size `hdiutil resize -limits /tmp/$FILE.dmg | tail -n 1 | awk '{ print $1 }'`b /tmp/$FILE.dmg #CONVERT IMAGE TO CDR hdiutil convert /tmp/$FILE.dmg -format UDTO -o /tmp/$FILE # -> /tmp/$FILE.cdr #COPY TO HOST scp /tmp/$FILE.cdr USER1@HOST1:/WHERE/TO/STORE/IMAGE
6. FIX VirtualBox NOT SUPPORT apfs IN High Sierra/Mojave
#FOR Mojave FIRST BOOT fs1: cd macOS\ Install\ Data cd Locked\ Files cd Boot\ Files boot.efi #PREPARE apfs DRIVER FOR NEXT BOOT #https://github.com/acidanthera/AppleSupportPkg #AT Debian HOST mkdir /tmp/tmp cd /tmp/tmp wget https://github.com/acidanthera/AppleSupportPkg/releases/download/2.0.5/AppleSupport-v2.0.5-RELEASE.zip unzip AppleSupport-v2.0.5-RELEASE.zip cd Drivers/ genisoimage -o ../driver.iso . #ATTACH /tmp/tmp/driver.iso TO Mojave GUEST OPTICAL DRIVE STORAGE #BOOT Mojave GUEST fs1: load APFSDRIV.EFI load USBKBDXE.EFI load APPLEUIS.EFI map -r fs1: cd System\Library\CoreServices boot.efi #IF FAILED, TRY TO LOAD JUST APFSDRIV.EFI #AFTER FINISH INSTALLATION, CREATE startup.nsh FOR NEXT BOOT #https://forums.virtualbox.org/viewtopic.php?f=22&t=88258&sid=20c97a3fb77e1578f58f3b1fd74460eb&start=15 #https://github.com/img2tab/okiomov/blob/master/macos_okiomov.sh #AT Mojave GUEST diskutil list sudo mkdir /Volumes/efi sudo mount -t msdos /dev/disk1s1 /Volumes/efi mkdir -p /Volumes/efi/EFI/DRIVERS cp -av /Volumes/CDROM/* /Volumes/efi/EFI/DRIVERS/ ls /Volumes/efi/EFI/DRIVERS/ >> /Volumes/efi/startup.nsh vi /Volumes/efi/startup.nsh
load fs0:\EFI\DRIVERS\APFSDRIV.EFI load fs0:\EFI\DRIVERS\USBKBDXE.EFI load fs0:\EFI\DRIVERS\APPLEUIS.EFI map -r for %a run (1 5) fs%a: cd "macOS Install Data\Locked Files\Boot Files" boot.efi cd "System\Library\CoreServices" boot.efi endfor
#SHUTDOWN GUEST AND DETACH driver.iso #IF FAILED, TRY TO LOAD JUST APFSDRIV.EFI
##### SOME USEFUL LINK/COMMANDS #####
#IF BOOT FAILED, TRY TO BOOT...
#FROM: fs1:>macOS Install Data\Locked Files\Boot Files\boot.efi
#OR: fs1:>System\Library\CoreServices\boot.efi
#CREATE BOOTABLE INSTALLER
#https://support.apple.com/th-th/HT201372
#SOLVE "Install macOS High Sierra.app does not appear to be a valid OS installer application."
#https://www.reddit.com/r/MacOS/comments/7470rb/install_macos_high_sierraapp_does_not_appear_to/
sudo cp -av /macOS Install Data /Applications/Install macOS High Sierra.app/Contents/SharedSupport
#CREATE High Sierra ISO INSTALLER
#https://www.howtogeek.com/289594/how-to-install-macos-sierra-in-virtualbox-on-windows-10/
#REF
#https://github.com/rtrouton/create_macos_vm_install_dmg
#Mojave
#https://astr0baby.wordpress.com/2018/09/25/running-macos-mojave-10-14-on-virtualbox-5-2-18-on-linux-x86_64/
MOJAVE
OpenVZ เป็นซอฟต์แวร์ที่ใช้ทำ virtualization ที่ใช้กับลินุกซ์เท่านั้น
มีข้อแตกต่างจาก xen ตรงที่ใช้เพียงเคอร์เนลเดียว
ข้อดีคือ เร็วและพร้อมใช้
ข้อเสียคือ ไม่มีการ swap หน่วยความจำ ถ้าหน่วยความจำเต็ม โปรเซสที่มาทีหลังจะตายหมด
(แต่ก็ยังมีข้อดีในข้อเสีย คือ openvz จะบริหารการสลับหน่วยความจำระหว่าง guest os อย่างมีประสิทธิภาพ และโปรเซสที่รันอยู่ก่อนที่หน่วยความจำจะเต็ม จะยังคงได้ความเร็วที่เกือบคงที่)
กำหนด
cpu: Intel E2140
mb: ECS P4M890T-M V2.0
ram: 4GB
debian: Lenny
host: server1.example.com, 192.168.1.31, 2.6.26-2-openvz-686
guest-101: test.example.com, 192.168.1.131
vz-partition: /dev/sda9
ติดตั้ง
เริ่มบน lenny
# aptitude install linux-image-2.6.26-2-openvz-686 vzctl vzquota
แก้ไขระบบตามคู่มือ
# vi /etc/sysctl.conf
... #openvz net.ipv4.conf.all.rp_filter=1 net.ipv4.icmp_echo_ignore_broadcasts=1 net.ipv4.conf.default.forwarding=1 net.ipv4.conf.default.proxy_arp = 0 net.ipv4.ip_forward=1 kernel.sysrq = 1 net.ipv4.conf.default.send_redirects = 1 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.eth0.proxy_arp=1 ...
สั่งปรับให้มีผลทันที
# sysctl -p
แก้ระบบเน็ตเวิร์คสำหรับ guest ตามคำแนะนำ
# vi /etc/vz/vz.conf
... # Controls which interfaces to send ARP requests and modify APR tables on. #NEIGHBOUR_DEVS=detect NEIGHBOUR_DEVS=all ...
บูตใหม่
# shutdown -r now
ตรวจผลหลังการบูต
# uname -r
2.6.26-2-openvz-686
สมมุติว่าจะติดตั้งระบบ openvz container ไว้ที่ /dev/sda9 ที่ฟอร์แมตเป็น ext3 ไว้เรียบร้อยแล้ว
สั่งหยุดเพิ่อปรับระบบ
# /etc/init.d/vz stop
แก้ไข fstab เพื่อให้เมานต์ที่ /var/lib/vz อัตโนมัติ
# vi /etc/fstab
... /dev/sda9 /var/lib/vz ext3 defaults 0 2 ...
ย้ายไฟล์ที่ติดตั้งแล้วมาที่ /dev/sda9 แล้วเริ่ม openvz ใหม่
# mkdir /mnt/tmp # mount /dev/sda9 /mnt/tmp # mv /var/lib/vz/* /mnt/tmp # umount /mnt/tmp # mount -a # /etc/init.d/vz start
เนื่องจากค่าไฟล์คอนฟิกของ openvz นั้น ปรับต้้งยากมาก เราเลยจะเอา util ของเขามาใช้เป็นตัวอย่าง
ไปที่ที่เก็บไฟล์คอนฟิก
# cd /etc/vz/conf
สร้างตัวอย่างไฟล์คอนฟิก โดยสมมุติว่าเราจะแบ่งให้เซิร์ฟเวอร์เครื่องนี้มี 4 guest os โดยให้ชื่อไอดี (ของอันแรก) ว่า 101
# vzsplit -n 4 > 101.conf
ปรับแต่งค่าอื่น ๆ ของ guest ตามการกำหนดข้างต้น
# vzctl set 101 --onboot yes --save # vzctl set 101 --hostname test.example.com --save # vzctl set 101 --ipadd 192.168.1.131 --save # vzctl set 101 --nameserver ns1.example.com --save
ติดตั้ง guest os โดยไปดาวน์โหลด template มาจาก debian.systs.org
# cd /var/lib/vz/template/cache/ # wget http://debian.systs.org/ostemplates/debian-5.0-i386-minimal.tar.gz
ติดตั้ง
# vzctl create 101 --ostemplate debian-5.0-i386-minimal
หากต้องการคัดลอก apt source-list ก็สามารถคัดลอกจาก host ไปใช้ได้
# cp /etc/apt/sources.list /var/lib/vz/private/101/etc/apt
เริ่มระบบ
# vzctl start 101
ตั้งรหัสผ่านของ guest ให้ root
# vzctl exec 101 passwd
ใช้งานผ่าน vzctl
# vzctl enter 102
(ออกด้วย exit)
หรือใช้งานผ่าน ssh
# ssh root@test.example.com
ติดตั้งส่วนของ guest ที่ยังเหลืออยู่
# aptitude update # aptitude install console-data locales # dpkg-reconfigure locales # aptitude upgrade
เสร็จแล้วครับ
ที่มา
WebVZ เป็นโปรแกรมจัดการ OpenVZ แบบ web based
ตอนนี้ยังทำอะไรไม่ได้มาก แต่ติดตั้งไว้ก็ดี เผื่อทำงานอะไรเล็ก ๆ น้อย ๆ
สมมุติว่าเครื่องหลักมีไอพี 192.168.1.31
# aptitude install ruby rubygems libsqlite3-ruby sqlite3 rails # gem install -v=2.1.0 rails #รอ 1 เพลิน # ln -sf /var/lib/vz / # cd /usr/local # wget http://downloads.sourceforge.net/project/webvz/webvz/webvz%202.0/webvz.2.0.tar.gz # tar xfz webvz.2.0.tar.gz # ln -sf webvz.2.0 webvz # cd webvz # ruby script/server -b 192.168.1.31
เครื่องอื่น ๆ ในวง สามารถใช้งานผ่าน url: http://192.168.1.31:3000
user: admin
pass: admin123
เสร็จแล้ว
ที่มา
บันทึกการทำ container ใช้เอง ด้วย debootstrap
# aptitude install debootstrap # cd /var/lib/vz/private # mkdir 1001 # debootstrap --arch=amd64 lenny 1001 http://server1.example.com:9999/debian # cp /etc/apt/sources.list 1001/etc/apt/ # chroot 1001 # aptitude install console-data locales ssh screen less vim # dpkg-reconfigure locales # passwd # aptitude update # aptitude upgrade # vi /etc/inittab
... ตัดทิ้ง--------8<--------------------- # Note that on most Debian systems tty7 is used by the X Window System, # so if you want to add more getty's go ahead but skip tty7 if you run X. # 1:2345:respawn:/sbin/getty 38400 tty1 2:23:respawn:/sbin/getty 38400 tty2 3:23:respawn:/sbin/getty 38400 tty3 4:23:respawn:/sbin/getty 38400 tty4 5:23:respawn:/sbin/getty 38400 tty5 6:23:respawn:/sbin/getty 38400 tty6 จบตัดทิ้ง--------->8-------------------- ...
(อาจติดตั้งแพกเกจ หรือปรับแต่งค่าอื่น ๆ ที่จำเป็นเพิ่มได้)
# exit
เก็บไว้ใช้ในโอกาสต่อไป
# cd 1001 # tar cfz ../debian.tar.gz *
เที่ยวหลังก็สามารถแตกไฟล์ออกมาใช้งานได้ เช่น
# mkdir 1002 # cd 1002 # tar xfz ../debian.tar.gz
เป็นต้น
Xen เป็นซอฟต์แวร์ที่ใช้ทำ virtualization ในทางทฤษฎีสามารถรัน guest os ใด ๆ ก็ได้ โดยมีข้อแม้คือ ซีพียู ต้องรองรับการทำ virtualization ด้วย แต่ถ้าซีพียูไม่รองรับ ต้องใช้กับ os ที่ดัดแปลงให้ใช้กับ xen เท่านั้น
(คราวก่อนติดตั้งเพื่อทดลอง windows แต่เที่ยวนี้จะทำ host)
ข้อดีคือ เร็วพอควร และสามารถ swap หน่วยความจำได้ ทำให้ใช้งานได้เหมือนในระบบลินุกส์ปกติ
ข้อเสียคือ เนื่องจากแยกเคอร์เนลและฮาร์ดแวร์กันอย่างเด็ดขาด จึงทำให้ต้องการฮาร์ดแวร์มากกว่าปกติ และหากหน่วยความจำที่แบ่งให้แต่ละ guest os ไม่พอ xen จะทำการสลับหน่วยความจำลงดิสก์ ทำให้ระบบทำงานช้ามาก (ซึ่งจะมีผลกับทุก ๆ โปรเซสที่ยังค้างอยู่ในหน่วยความจำ คือช้าทั้งระบบ)
กำหนด
cpu: Intel E2140
mb: ECS P4M890T-M V2.0
ram: 4GB
host: server1.example.com, 192.168.1.31
guest-101: test.example.com, 192.168.1.131, bridged
xen-physical-partition: /dev/sda10,xvda
apt-proxy: 192.168.1.3:9999
ติดตั้ง Xen - dom0
เริ่มติดตั้งบน lenny
# aptitude install xen-hypervisor-3.2-1-i386 xen-linux-system-2.6.26-2-xen-686 xen-utils-3.2-1 xenstore-utils xen-shell
จะใช้เน็ตเวิร์กแบบ bridge
# vi /etc/xen/xend-config.sxp
... # (network-script network-dummy) (network-script network-bridge) ...
บูตใหม่
# shutdown -r now
ตรวจผลหลังการบูต
# uname -r
2.6.26-2-xen-686
ติดตั้ง domU
สมมุติว่าจะติดตั้ง xen-domU ไว้ที่ฮาร์ดดิสก์จริง /dev/sda10 ที่แบ่งพาร์ติชั่นเป็น ext3 ไว้เรียบร้อยแล้ว โดยจะเมานต์ /dev/sda10 เป็น /dev/xvda ใน xen และแบ่งพาร์ติชั่นต่าง ๆ ของ domU ใน /dev/xvda
# xm block-attach 0 phy:/dev/sda10 xvda w
ใช้ fdisk แบ่งพาร์ติชั่นตามใจชอบ
# fdisk /dev/xvda
ในที่นี้สมมุติว่า /dev/xvda5 เมานต์เป็น /
และ /dev/xvda6 ใช้เป็น swap
ฟอร์แมต ext3 และ swap ตามลำดับ
# mkfs.ext3 /dev/xvda5 # mkswap /dev/xvda6
ใช้วิธีติดตั้งแบบ debootstrap เนื่องจากเร็วกว่าวิธีอื่น
ติดตั้ง debootstrap
# aptitude install debootstrap
ติดตั้ง lenny บน /dev/xvda5 ผ่าน apt-proxy 192.168.1.3:9999
และเนื่องจากซีพียูไม่รองรับการทำ virtualize จึงต้องติดตั้งเคอร์เนลที่แปลงมาใช้กับ xen แล้ว
# mkdir /mnt/tmp # mount /dev/xvda5 /mnt/tmp # debootstrap lenny /mnt/tmp http://192.168.1.3:9999/debian # mount -t proc none /mnt/tmp/proc # mount -o bind /dev /mnt/tmp/dev # mount -t sysfs none /mnt/tmp/sys # cp /etc/apt/sources.list /mnt/tmp/etc/ # ehco 'test.example.com' > /mnt/tmp/etc/hostname # chroot /mnt/tmp
test# vi /etc/network/interface
# The loopback network interface auto lo iface lo inet loopback # The primary network interface allow-hotplug eth0 iface eth0 inet static address 192.168.1.131 netmask 255.255.255.0 network 192.168.1.0 broadcast 192.168.1.255 gateway 192.168.1.3 # dns-* options are implemented by the resolvconf package, if installed dns-nameservers 192.168.1.3 dns-search example.com
test# vi /etc/fstab
... #proc /proc proc defaults 0 0 /dev/xvda5 / ext3 errors=remount-ro 0 1 /dev/xvda6 none swap sw 0 0
test# aptitude update test# aptitude install console-data locales ssh test# dpkg-reconfigure locales test# aptitude upgrade test# aptitude install linux-image-2.6.26-2-xen-686 test# passwd test# exit # umount /mnt/tmp/sys # umount /mnt/tmp/dev # umount /mnt/tmp/proc # umount /mnt/tmp # xm block-detach 0 xvda
สร้างไฟล์คอนฟิก
# vi /etc/xen/101.cfg
# # Kernel + memory size # kernel = '/boot/vmlinuz-2.6.26-2-xen-686' ramdisk = '/boot/initrd.img-2.6.26-2-xen-686' memory = '1024' # # Disk device(s). # root = '/dev/xvda5 ro' disk = [ 'phy:sda10,xvda,w' ] # # Hostname # name = 'test.example.com' # # Networking # vif = [ 'bridge=eth0' ] # # Behaviour # on_poweroff = 'destroy' on_reboot = 'restart' on_crash = 'restart'
เริ่ม domU - 101.cfg
# xm create 101.cfg
ตรวจสถานะ
# xm list
เข้าใช้งาน domU ด้วย ssh
# ssh root@test.example.com
เสร็จแล้วครับ
ที่มา
cpu: Intel E6300
mb: Asrock Conroe945G-DVI
ram: 1G
เที่ยวนี้ลองคอมไพล์ซอร์สเอง ไม่ผ่านซักอย่าง เลยใช้แบบไบนารีดีกว่า
ทำตาม wiki.ubuntu.com/XenOnEdgy เกือบทั้งหมด
เอาแพกเกจที่เกี่ยวข้องมาก่อน
$ sudo apt-get install xen-hypervisor-3.0-i386 xen-image-xen0-2.6.17-6-generic-xen0 xen-utils-3.0
+++ xen-hypervisor-3.0-i386* xen-image-xen0-2.6.17-6-generic-xen0*
xen-ioemu-3.0* xen-utils-3.0*
สร้างแรมดิสก์สำหรับบูตไว้ที่ /boot
$ sudo mkinitramfs -o /boot/xen0-linux-2.6.17-6-generic-xen0.initrd.img 2.6.17-6-generic-xen0
แก้ไขเมนูบูตให้ Xen อยู่อันแรก
$ sudo vi /boot/grub/menu.lst
ของเดิม /boot อยู่ที่ /dev/hda5 และ / อยู่ที่ /dev/hda7
... title XEN/2.6.17 root (hd0,4) kernel /boot/xen-3.0-i386.gz module /boot/xen0-linux-2.6.17-6-generic-xen0 root=/dev/hda7 ro module /boot/xen0-linux-2.6.17-6-generic-xen0.initrd.img ...
เน็ตเวิร์กยังไม่ได้ลอง เดี๋ยวจะกลับมาลอง
ในตัวอย่างของ wiki เขาใช้ลินุกส์เป็น DomU แล้วใช้ disk image เป็นไดร์ฟ
แต่ในที่นี้จะติดตั้ง WinXP โดยแบ่งพาร์ติชั่นจริง ๆ เป็นไดร์ฟ
สร้างไฟล์คอนฟิก ตั้งชื่อว่า winxp.cfg
$ sudo vi /etc/xen/winxp.cfg
พาร์ติชั่นที่ใช้ ผมแยกไปใช้ SATA คือ /dev/sda1
kernel = "/usr/lib/xen-ioemu-3.0/boot/hvmloader" builder='hvm' memory = 384 name = "winxp" vcpus=1 vif = [ 'type=ioemu, bridge=xenbr0' ] disk = ['phy:/dev/sda1,ioemu:hda,w','phy:/dev/hdb,hdb:cdrom,r'] device_model ='/usr/lib/xen-ioemu-3.0/bin/qemu-dm' boot='d' vnc=1 vncviewer=1 serial='pty' ne2000=0
ก่อนบูตเพื่อติดตั้ง ต้องติด xvncviewer ก่อน
$ sudo apt-get install xtightvncviewer
แล้วก็ลองบูตเพื่อติดตั้งได้เลย ด้วยคำสั่ง
$ sudo xm create winxp.cfg
รีบตามไปดูจอของ WinXP ด้วยการเรียกใช้ xvncviewer
$ xtightvncviewer localhost
ผลการทดลอง
ข้อดีคือ ความเร็วที่เกี่ยวกับฮาร์ดแวร์ดีถึงดีมาก รู้สึกหน่วงนิดเดียว สามารถใช้งานได้อย่างจริงจัง
ข้อเสีย เหมือนเดิม คือการแสดงผลผ่าน VNC มีข้อจำกัดมาก คือ
ข้อเสียอื่น ๆ ก็พอยอมรับได้ครับ เมื่อแลกกับความเร็วที่ได้มา
(ลองกับ WinMe ยังไม่ผ่านครับ)
เนื่องจากอูบุนตูเปลี่ยนการเมานต์ดิสก์ จากเดิมที่กำหนดเป็นค่าดีไวซ์ มาเป็น UUID แทน (เข้าใจว่าเปลี่ยนมาหลายรุ่นแล้ว)
และเนื่องจากผมแบ่งพาร์ติชั่นแยกไว้หลายอัน เพื่อให้ลงได้หลายดิสโตรและสามารถใช้ข้อมูลร่วมกันได้ ทำไปทำมากลัวงง ผมเลยกำหนดค่าให้ไดรฟ์ใหม่ จาก UUID กลับมาใช้เป็น /dev/hda? แบบเก่า
ลองตรวจดูว่าจะใช้ค่าอะไรบ้างด้วยคำสั่ง
$ mount
ปรากฎว่าอูบุนตูแปลงค่าเดิม /dev/hda? กลายเป็น /dev/sda? เสียหมด
ก็เลยต้องปรับแก้ค่าในไฟล์ /etc/fstab จาก UUID=... มาเป็น /dev/sda? ให้หมด
วันนี้จะกลับมาทดสอบ Xen อีกครั้ง งานที่เคยเปลี่ยนค่าพาร์ติชั่นไว้เลยกลายมาเป็นปัญหา เพราะเคอร์เนลของ Xen หาไดรฟ์ sda? ไม่พบ
ทางแก้คือต้องแก้กลับมาเป็น UUID เหมือนเดิม
คำสั่งที่ใช้คือ
$ ls /dev/disk/by-uuid/ -alh
total 0 drwxr-xr-x 2 root root 180 May 9 21:27 . drwxr-xr-x 5 root root 100 May 9 21:27 .. lrwxrwxrwx 1 root root 10 May 9 21:27 0e6d39ab-0446-46d6-a6fa-e0d37dc1d73c -> ../../sdb1 lrwxrwxrwx 1 root root 10 May 9 21:27 17905509-63dd-40e5-99fd-6522baa71c13 -> ../../sda9 lrwxrwxrwx 1 root root 10 May 9 21:27 257ff35d-8add-492c-9b76-e3adc11ff7f8 -> ../../sda7 lrwxrwxrwx 1 root root 10 May 9 21:27 2A13-19F4 -> ../../sda1 lrwxrwxrwx 1 root root 10 May 9 21:27 50f0a6d8-10d6-4a6c-b1ff-3508d66f618e -> ../../sda2 lrwxrwxrwx 1 root root 10 May 9 21:27 694d81d4-da76-430c-acb4-78491037055e -> ../../sda8 lrwxrwxrwx 1 root root 10 May 9 21:27 f64defd2-5ebd-4749-947c-b02b55ee4137 -> ../../sda6
แล้วจึงตามแก้ค่าในไฟล์ /etc/fstab และไฟล์ /boot/grub/menu.lst ให้หมด
เมื่อเปลี่ยนกลับมาเป็นรูป UUID=... เรียบร้อยแล้ว ก็จะสามารถบูต Xen ได้อย่างที่ควรจะเป็น
อีกคำสั่งนึงคือ
$ sudo vol_id -u /dev/sda8
694d81d4-da76-430c-acb4-78491037055e
เอามาจาก ubuntuforum แต่ลืมบันทึกครับ
iptables บนเดเบียน มี 2 วิธี (จริง ๆ มีหลายวิธีมาก)
# iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
# iptables -A FORWARD -s 192.168.0.0/16 -j ACCEPT
# iptables -A FORWARD -d 192.168.0.0/16 -j ACCEPT
# iptables -A FORWARD -s ! 192.168.0.0/16 -j DROP
เก็บกฎไว้ที่ไฟล์ /etc/iptables/rules
# mkdir -p /etc/iptables
# iptables-save > /etc/iptables
นำกฎมาใช้ตอนเปิดเครื่องใหม่ ผ่าน /etc/network/interfaces
# vi /etc/network/interfaces
... auto eth1 iface eth1 inet static address 192.168.5.3 netmask 255.255.255.0 network 192.168.5.0 broadcast 192.168.5.255 gateway 192.168.5.1 post-up /sbin/iptables-restore < /etc/iptables/rules pre-down /sbin/iptables-save > /etc/iptables/rules ...
# vi /usr/local/bin/d.iptables
#!/bin/sh INTERFACE=eth1 INT_NET=192.168.0.0/16 /sbin/iptables -F > /dev/null /sbin/iptables -t nat -A POSTROUTING -o $PPP_INT -j MASQUERADE /sbin/iptables -A FORWARD -s $INT_NET -j ACCEPT /sbin/iptables -A FORWARD -d $INT_NET -j ACCEPT /sbin/iptables -A FORWARD -s ! $INT_NET -j DROP
# chmod 755 /usr/local/bin/d.iptables
นำกฎมาใช้ตอนเปิดเครื่องใหม่ ผ่าน /etc/network/interfaces
# mkdir -p /etc/iptables/
# vi /etc/network/interfaces
... auto eth1 iface eth1 inet static address 192.168.5.3 netmask 255.255.255.0 network 192.168.5.0 broadcast 192.168.5.255 gateway 192.168.5.1 post-up /usr/local/bin/d.iptables pre-down /sbin/iptables-save > /etc/iptables/rules
(เวลาจะปรับปรุงสคริปต์ เอาเนื้อความจาก /etc/iptables/rules มาใช้ในการปรับปรุงได้)
อ้างอิง - http://debianclub.org/node/156
ทำแผ่นบูตฉุกเฉิน
ปัญหาคือมีเครื่องลูกข่ายที่เป็นวินโดวส์ติดไวรัส และไม่ได้ลงซอฟต์แวร์ป้องกันไวรัสไว้ (เนื่องจากทอนกำลังเครื่อง)
ทางแก้คือ ใช้แผ่นบูตเดเบียนที่ลงแพกเกจ clamav เพื่อนำไปสแกนและลบไฟล์ไวรัสทิ้ง
ติดตั้งแพกเกจในการสร้างแผ่นบูตคือ live-helper
$ sudo aptitude install live-helper
สร้างไดเรกทอรี่สำหรับงานนี้
$ mkdir ~/debian-live $ cd ~/debian-live
เราทำแผ่นบูตฉุกเฉิน ต้องใช้แพกเกจ rescue
$ lh_config -p rescue
หากต้องการเปลี่ยนแปลงค่าปริยาย สามารถเปลี่ยนได้จากไฟล์ config/bootstrap
$ vi config/bootstrap
เช่น
... # $LH_DISTRIBUTION: select distribution to use # (Default: lenny) LH_DISTRIBUTION="sid" ... # $LH_SECTIONS: select section(s) to use # (Default: main) LH_SECTIONS="main contrib non-free" ...
ปรุงไฟล์ iso
$ sudo lh_build
จะได้ไฟล์ binary.iso ซึ่งสามารถนำไปเขียนแผ่นบูตได้ตามต้องการ
ซึ่งแผ่น rescue ที่ได้นี้ จะมีแพกเกจ clamav สำหรับค้นหาไวรัสให้เรียบร้อยแล้ว
สามารถทดสอบไฟล์ iso ที่ได้ โดยใช้แพกเกจ qemu
$ sudo aptitude install qemu $ qemu -cdrom binary.iso
หมายเหตุ
/usr/share/live-helper/lists/
เช่น ถ้าจะติดตั้ง gnome ด้วย ก็ใช้พารามิเตอร์ -p gnome
เป็นต้น.stage
/usr/share/live-helper/functions/defaults.sh
โดยตรงอ้างอิง
ต้องการหาโปรแกรมที่ทำงานกับไฟล์ pdf ที่สามารถใช้งานได้ทั้งลินุกซ์และวินโดวส์
$ sudo aptitude install pdfsam
$ sudo aptitude install pdftk
แตกไฟล์ pdf
$ pdftk FILE.pdf burst
จะได้ไฟล์ pg_0001.pdf pg_0002.pdf ...
รวมไฟล์ pdf
$ pdftk pg_0001.pdf pg_0002.pdf ... cat output OUTFILE.pdf
ทั้งสองคำสั่ง จะส่งรายงานผลไปออกที่ไฟล์ doc_data.txt
เอามาจาก: zolved.com: How to combine and separate pdf files on Ubuntu
$ sudo aptitude install xournal
หมายเหตุ ในการ annotate text ที่ทำงานข้ามไปมาระหว่างลินุกซ์กับวินโดวส์ จะพบปัญหาเรื่องชื่อฟอนต์ไม่ตรงกัน หากเราใช้ฟอนต์ทดแทนกัน เราต้องแก้ไขการแทนค่าฟอนต์ด้วย
/etc/fonts/conf.d/
คือไฟล์ 90-synthetic.conf
หรือ 89-ttf-thai-tlwg-synthetic.conf
HKLM/software/Microsoft/WindowsNT/CurrentVersion/FontSubstitutes/
c:\xournal\etc\fonts\fonts.conf