debian: ติดตั้งแพกเกจ

บันทึกการติดตั้งแพกเกจต่าง ๆ

Topic: 

debian: พิมพ์ลงไฟล์ pdf

มีงานที่ต้องแปลงไฟล์ภาพ 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

งานพิมพ์จากวินโดวส์
ให้เลือกเครื่องพิมพ์เป็น Postscript แล้วพิมพ์ลงไฟล์
ต่อจากนี้อาจใช้ gs for windows ทำต่อ
หรือใช้คำสั่งบนลินุกซ์คือ gs รูปแบบคำสั่งคือ
$ gs -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile=filename.pdf -- filename.prn
-dNOPAUSE คือให้ทำรวดเดียวไม่ต้องหยุด
-sDEVICE=pdfwrite คือทำเป็น pdf
-- คือทำเสร็จแล้วให้ออกจากโปรแกรมเลย

เพิ่มเติม -sDEVICE
png = png16m
แต่คุณภาพไม่ค่อยดี สู้เป็น pdfwrite ไม่ได้ (เอามาแก้ใน gimp ได้)
ดูรายละเอียดของ DEVICE ได้จากคำสั่ง gs --help

เพิ่มเติมสำหรับวินโดวส์
หากต้องการทำต้นฉบับหนังสือเพื่อส่งโรงพิมพ์ ให้เลือกเครื่องพิมพ์เป็นพวก Image Setter เช่น Scitex เป็นต้น
จะไม่มีปัญหาเรื่องพิมพ์ตกขอบทำให้ขอบขาด

เอามาจาก Hui's BLOG: gs แปลง PDF ภาษาญี่ปุ่นเป็น PNG

กำหนดขนาดกระดาษ
$ 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 จะใช้งานง่ายกว่า

รวมไฟล์ pdf
$ gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=combined.pdf file1.pdf
file2.pdf

เอามาจาก Blog of Amorn Jiraseree-amornkun : วิธีรวมไฟล์ pdf หลายไฟล์เข้าด้วยกันในลินุกซ์

tip

debain: Terminal

บันทึกการทำงานกับเทอร์มินัล

debian: XTerm

เทอร์มินัลของ 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

debian: screen

เอามาจาก 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 ดี ๆ แบ่งบ้างนะครับ

Topic: 

screen tip: screenrc และการสั่งงานด้วยบรรทัดคำสั่ง

screen tip: screenrc และการสั่งงานด้วยบรรทัดคำสั่ง

ต้องการให้เมื่อเริ่ม screen ทุกครั้ง จะสั่งเปิด 3 หน้าต่างคือแสดง top, syslog, และ dmesg ตามลำดับ โดยตั้งชื่อ session ว่า 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 เริ่มงานแบบข้างต้น เฉพาะเมื่อเราต้องการ

จะใช้การทำงานผ่านสคริปต์ ดังนี้
สมมุติตั้งชื่อสคริปต์ว่า 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

จบแล้วครับ

Topic: 

debian: ลองติดตั้ง Hylafax

เอามาจาก 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

debian: customize hylafax

ตั้งให้พิมพ์แฟกซ์รับ อัตโนมัติ

สร้างไฟล์ที่จะดักการทำงานตอนรับแฟกซ์ ชื่อ /etc/hylafax/FaxDispatch
แล้วเริ่มการทำงานใหม่ เพื่อให้ไฟล์ใหม่นี้ถูกคัดลอกไปไว้ในไดเรคทอรี่ของ hylafax
# vi /etc/hylafax/FaxDispatch

/usr/bin/tiff2ps -a $FILE | lpr -P $PRINTER_NAME

# /etc/init.d/hylafax restart

ตั้งให้เก็บสำเนาแฟกซ์รับและแฟกซ์ส่ง

ใช้ความสามารถของ gs

แฟกซ์รับ
ใส่ที่ /etc/hylafax/FaxDispatch
แฟกซ์ส่ง
ใส่ที่ /var/spool/hylafax/bin/notify ปรับแก้สคริปต์นิดหน่อย
จริง ๆ แล้วสามารถปรับได้ที่ faxsend โดยเติมออปชั่น -A แต่ถ้าเราปรับสคริปต์ notify ก็ไม่จำเป็นต้องใส่ออปชั่นแล้ว เพราะหาที่ใส่ออปชั่นใน WHFC ไม่พบ เลยมาแก้ที่ตัวเซิร์ฟเวอร์ดีกว่า

--รอทดลอง--

เกร็ด

  • โมเด็ม Class 2 หรือ 2.0 มีปัญหาในการรับแฟกซ์ จากเครื่องแฟกซ์ที่เป็น Class 1 แต่ไม่มีปัญหาในการส่ง
Topic: 

debian: ทดลองทำ HylaFAX Client

เอามาจาก 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

แก้ปัญหาดูแฟกซ์ที่รับไม้ได้
ตั้งการอนุญาตใช้ไฟล์ ที่ไฟล์โมเด็ม (ส่วนใหญ่จะชื่อ config.ttyS0)
# vi /etc/hylafax/config.ttyS0
...
RecvFileMode:       0666
...
Topic: 

debian: ปรับปรุง HylaFax Client

ปรับปรุง 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 ให้ส่งแฟกซ์เอง

เพิ่มเติม

แก้ปัญหา 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):
    ...

debian: debootstrap

debootstrap เป็นแพกเกจที่ใช้ในการติดตั้งเดเบียนผ่านเครือข่าย
สามารถนำมาใช้ประโยชน์ได้เช่น การติดตั้งลินุกซ์ซ้อนเข้าในระบบเพื่อการทดลอง หรือการติดตั้งระบบเพิ่มเติมสำหรับงาน Virtualization

การใช้งาน ควรมี mirror ซึ่งอาจเป็น apt-proxy apt-cacher หรือ mirror แท้ ๆ อยู่ในเครือข่ายเราก่อน

รูปแบบใช้งานคือ

debootstrap [OPTION...] SUITE TARGET [MIRROR [SCRIPT]]

SUITE คือรุ่นของลินุกซ์ที่เราจะติดตั้ง สำหรับเดเบียนได้แก่ sarge หรือ etch เป็นต้น
TARGET คือพาร์ติชั่นที่เราเมานต์ไว้แล้วสำหรับการติดตั้ง
MIRROR คือคลังแพกเกจ เช่น apt-proxy หรือ mirror อื่น

รายละเอียดสามารถศึกษาได้เพิ่มเติมจาก man debootstrap

ตัวอย่างการใช้งาน 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 ใหม่แบบสะอาด ๆ
เมื่อจะทำการทดลองระบบใหม่ ถ้าจำเป็นต้องลงใหม่ก็ทำเหมือนเดิมครับ

ติดตั้งอูบุนตู Feisty ด้วย debootstrap จากเดเบียน 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
  • การทดลองจริง อาจไม่ราบรื่นแบบที่เขียน ถ้าผ่านขั้นตอนการติดตั้งเคอร์เนลแล้ว สามารถรีบูตเป็น Feisty แล้วมาทำต่อ อาจให้ผลที่ดีกว่า

debian: บันทึก apache2

บนเดเบียน สามารถเปิดใช้งานมอดูลด้วยคำสั่ง a2enmod MODULENAME และปิดการใช้งานด้วยคำสั่ง a2dismod MODULENAME

มอดูล

autoindex
ดูไฟล์ในไดเรกทอรี่
userdir
public_html ของผู้ใช้
rewrite
การทำ rewrite คือแปลงรูปของ url แบบต่าง ๆ
proxy
การทำ Redirect ไปยังเครื่องอื่น (mod_proxy) - ตัวอย่างการติดตั้ง
cband
จำกัดแบนด์วิดธ์ ทำได้หลายอย่าง
ยกตัวอย่างแค่อย่างเดียว คือจำกัดการใช้งานต่อไอพีให้ความเร็วไม่เกิน 1000kbps คำร้องไม่เกิน 10 ครั้งต่อวินาที และเปิดการใช้งานได้ไม่เกิน 10 ครั้งต่อวินาที
# 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

Windows 7 (นอกเรื่อง)

ติดตั้ง
How install Apache 2.4 PHP 5.4 and MySQL 5.5.21 on Windows 7
ยกเลิกพอร์ต 80 ของ Windows
Control Panel -> Program and Features -> Turn Windows features on or off
ปิด Internet Information Service
mod_wsgi
  • ไซต์ http://code.google.com/p/modwsgi/
  • คอมไพล์เองด้วยการใช้ Visual C++ รุ่นเดียวกับ Python เมื่อได้ไฟล์ mod_wsgi.so เอาไปใส่ใน c:\Apache2\modules
  • ปรับแต่ง httpd.conf ดังนี้
    ...
    LoadModule wsgi_module modules/mod_wsgi.so
    

    ที่มา: http://serverfault.com/questions/435926/cant-locate-api-module-structure-mod-wsgi

  • แก้ Firewall สำหรับพอร์ต 80
    http://superuser.com/questions/92488/apache-server-on-windows-7-opening-up-ports

    บันทึกการอัปเกรด apache2.2 และ php5 บน etch

    # 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

    apache2-ssl

    !!!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: การติดตั้งให้เรียกใช้งานเว็บเซิร์ฟเวอร์ภายในจากภายนอก

    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

    debian: ทำ Mirror ด้วย rsync แบบง่าย

    เอามาจาก ThaiLinuxCafe: ทำ mirror ด้วย rsync อย่างง่าย

    ต้องการ syncronize ไดเรคทอรี่ /var/www ของเครื่อง server1.example.com
    มายังไดเรคทอรี่ /var/www ของเครื่อง mirror.example.com
    ซึ่งมีข้อดีกว่าการคัดลอกธรรมดาด้วย cp หรือ scp ตรงที่
    ถ้าเราลบไฟล์ใน server1 ไฟล์ใน mirror จะถูกลบตามไปด้วย
    ทำให้ทั้งสองเครื่องมีความสดใหม่เหมือนกัน

    ทำที่ทั้งสองเครื่อง server1.example.com และ mirror.example.com
    ติดตั้งและปรับแต่ง rsync
    # aptitude install rsync
    # vi /etc/default/rsync
    RSYNC_ENABLE=true

    # dpkg-reconfigure rsync

    ทำที่เครื่อง server1.example.com
    เพิ่มผู้ใช้ชื่อ someuser
    server1:# useradd -m -s /bin/bash someuser
    ( -m คือให้คัดลอกรูปแบบจากไดเรคทอรี่ /etc/skel/
    -s คือให้ใช้เชลล์คือ /bin/bash )
    ทำที่เครื่อง mirror.example.com
    ทำการคัดลอก
    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 ไม่ต้องถามรหัสผ่าน

    ต่อไปเป็นการทำให้ rsync ไม่ต้องถามรหัสผ่าน โดยการใช้ public key

    ทำที่ mirror.example.com
    สร้าง 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/

    จบแล้วครับ

    rsync อัตโนมัติผ่าน cron

    ต่อไปเป็นการให้ทำงานอัตโนมัติผ่าน cron

    ทำที่เครื่อง mirror.example.com
    แก้ไข crontab
    # 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 ตอนเที่ยงคืน ทุกวัน )

    จบแล้วครับ

    debian: บันทึก imagemagick - convert

    แปลงรูปจาก jpg ธรรมดา ไปเป็น jpg แบบ interlace
    ใช้คำสั่งคือ
    # mkdir temp
    # for i in *jpg; do convert $i -interlace line temp/$i ; done

    จะได้ไฟล์ jpg ชุดใหม่เข้าไปอยู่ในไดเรกทอรี่ temp
    แปลงหลายรูป จาก tif ไปเป็น pdf
    # convert -adjoin `ls *.tif` newfile.pdf
    เอามาจาก jmetrix : Viewing multiple page tif on Linux
    แปลง tif หลายไฟล์ไปเป็น tif ไฟล์เดียวหลายภาพ
    $ convert x1.tif x2.tif x3.tif -adjoin newfile.tif
    แตก tif แบบหลายภาพ ออกมาเป็นหลายไฟล์ ไฟล์ละหนึ่งหน้า
    $ convert x.tif x%d.tif
    จะได้ออกมาเป็น x1.tif x2.tif x3.tif
    เอามาจาก [magick-users] how to split multi-page tiff into single pages
    แปลง tif แบบ 8-bit ไปเป็น 4-bit 256 สี เพื่อลดขนาด และสามารถเปิดใน Windows ได้คล่องตัวขึ้น
    เทคนิคคือแปลงเป็น gif ก่อน ไม่งั้นแปลงแล้วเปิดไม่ได้
    $ convert x.tif /tmp/x.gif
    $ convert /tmp/x.gif -depth 4 x.tif
    ไฟล์ tif จาก gimp พิมพ์บน evince ไม่ออก
    แก้ด้วยการแปลงเป็น jpg ก่อน แล้วจึงแปลงกลับเป็น tif อีกที
    $ convert x.tif /tmp/x.jpg
    $ convert /tmp/x.jpg x.tif
    อีกกรณีหนึ่ง ที่ใช้งานจริง คืองานที่เป็น tif แบบหลายหน้า เราจะกระจายออกมาก่อน แล้วแก้ไขด้วย gimp แล้วจึงรวมกลับเข้าไป โดยต้องการให้ไฟล์เล็กที่สุด คือเป็น gray 256 สี ขนาดภาพ A4 ที่ความละเอียด 200dpi
    $ convert x.tif -quality 100 /tmp/x%d.jpg
    หลังจากแก้ไขด้วย gimp เสร็จแล้ว ก็ใช้คำสั่ง
    $ convert /tmp/*jpg -geometry 1654 -density 200 -compress lzw -depth 4 -adjoin x.tif
    ที่มา : My MCP: ImageMagick convert -geometry weirdness
    สแกนหนังสือ ลดขนาดให้มากที่สุด ทำเป็น tiff g4
    $ convert infile.jpg -level 40%,85%,0.5 -type bilevel -monochrome -compress group4 outfile.tif
    ตัวเลข level black,white,gamma ปรับเอาเองตามสภาพหนังสือที่สแกน
    ถ้าเป็นหน้าสี ใช้
    $ convert infile.jpg -compress lzw -colors 8 outfile.tif
    แล้วแปลงเป็น pdf ด้วย tiff2pdf และรวมด้วย pdfjam
    ที่มา : http://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=6448

    หมายเหตุ
    ต้องลงแพกเกจ imagemagick ก่อน
    # aptitude install imagemagick

    imagemagick: การแก้ไข multiple pages tif

    ยังหาโปรแกรมที่ใช้แก้ไขภาพ 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 ครับ

    imagemagick: ทำ annotate ไฟล์ tif

    ความจำเป็นบีบบังคับให้ต้องรีบหาโปรแกรมที่สามารถทำ 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 จริง ๆ แฮะ

    debian: บันทึกการคอมไพล์ pidgin

    ลูกสาวให้ทำ msn ในลินุกซ์ให้ใช้ เคยอ่านผ่านตาที่ ubuntuclub.com
    เลยทดลองดาวน์โหลด pidgin มาคอมไพล์เอง

    คอมไพล์ครั้งแรกไม่ผ่าน ค้นเจอที่ ubuntuforum รวบรวมแพกเกจที่จำเป็นดังนี้
    $ sudo aptitude install libgtk2.0-dev libxml-perl libssl-dev libnspr4-dev libnss3-dev

    หลังจากนั้นก็คอมไพล์ตามปกติ ก็สามารถเล่นได้แล้ว

    debian: ลองติดตั้ง dns

    เอามาจาก
    ThaiLinuxCafe - debian : ติดตั้ง dns อย่างง่าย

    เรื่องของ DNS (Domain Name Server) เป็นเรื่องหลักของการใช้งานอินเตอร์เน็ต เนื้อหาซับซ้อนและทำความเข้าใจยาก
    สำหรับในที่นี้ เราเอาแค่ติดตั้งพอใช้งานได้
    โดยเราจะติดตั้งเครื่องเซิร์ฟเวอร์เพื่อทำหน้าที่เป็น DNS สำหรับใช้งานเครือข่ายภายใน
    โครงร่างคือ

    • เน็ตเวิร์กเราเป็น 192.168.1.0/24 มีโดเมนเป็น example.com
    • เครื่องที่ทำหน้าที่ name server มีชื่อว่า server1.example.com ไอพีเป็น 192.168.1.1 โดยมีชื่อเสมือนคือ ns1.example.com
    • มีเครื่องในวงเครื่องอื่น ๆ ดังนี้
      • ns2 = 192.168.1.2
      • client1 = 192.168.1.101
      • client2 = 192.168.1.102
      • client3 = 192.168.1.103

    แพกเกจที่ทำหน้าที่ DNS ในเดเบียนชื่อ bind9 และแพกเกจที่เป็นโปรแกรมช่วยชื่อ dnsutils
    งานปรับตั้งคือการสร้างไฟล์สำหรับให้ bind9 เรียกใช้ ดังนี้

    • โซนไฟล์ ไว้สำหรับค้นข้อมูลจากชื่อเป็นไอพี
    • รีเวิร์สไฟล์ ไว้สำหรับค้นข้อมูลย้อนกลับ คือจากไอพีเป็นชื่อ
    • คอนฟิกไฟล์ สำหรับบอก bind9 ว่าเราจะติดตั้ง DNS ในแบบไหน และประกอบด้วยไฟล์ข้อมูลอะไรบ้าง

    เริ่มด้วย
    ติดตั้ง 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.

    หมายเหตุ

    • เลขซีเรียลตามตัวอย่างเป็น 51 แต่ส่วนใหญ่นิยมใช้วันที่ เช่น 2006030401 เป็นต้น
    • ในเนื้อไฟล์ของโซนไฟล์และริเวิร์สไฟล์ เวลาพิมพ์ระวังอยาลืมเครื่องหมายจุด ท้ายชื่อโฮสต์
    • สำหรับเครื่อง DNS ที่ทำหน้าที่เกตเวย์ออกอินเตอร์เน็ต พบว่าเมื่อแก้ไขไฟล์ /etc/resolv.conf ให้ชี้ไปที่ DNS ของไอเอสพี เครื่องเราจะทำหน้าทีเป็น slave โดยอัตโนมัติ
    • ถ้าจะเพิ่มโดเมน และเป็นเน็ตเวิร์กคนละวง ก็ใช้วิธีเดียวกันได้ โดยสร้างโซนไฟล์ รีเวิร์สไฟล์ และคอนฟิกไฟล์สำหรับโดเมนที่เพิ่ม
    • ถ้าเพิ่มโดเมน และเป็นเน็ตเวิร์กวงเดียวกัน เช่น หนึ่งไอพี มีหลายโดเมน ให้สร้างเฉพาะโซนไฟล์ ไม่ต้องสร้างรีเวิร์สไฟล์ ซึ่งก็จะทำให้เรียกดูชื่อย้อนจากไอพีไม่ได้
    • ถ้าจะเพิ่มเน็ตเวิร์กเป็นสองวง โดยเป็นโดเมนเดียวกัน ให้ดูตัวอย่างที่ Debian Administration: Two-in-one DNS server with BIND9

    เนื้อหาไม่ค่อยถูกตามหลักการนะครับ เพราะมันยาก ถ้าจะให้รู้เรื่องจริง ๆ ต้องเข้าใจระบบอินเตอร์เน็ตพอสมควร
    ในที่นี้เอาแค่พอใช้งานได้ครับ

    อ้างอิงเพิ่มเติม

    debian: bind9 + chroot + internal/external

    *** ยังเขียนไม่เสร็จ + ยังไม่ได้ตรวจทานซ้ำ ***

    เป้า

    • ติดคุกให้ bind (chroot jail)
    • จะทำให้สามารถใช้งานได้ทั้งภายใน และภายนอก (ภายนอกไม่ค่อยจำเป็น แต่ติดตั้งไว้เผื่อจะทำอะไรเพิ่ม) คือโดเมนเดียวกัน แต่มีไอพี 2 กลุ่ม ภายในกลุ่มนึง และภายนอกอีกกลุ่มนึง
    • ติดตั้งเป็นแบบสามารถเปลี่ยนค่าไอพีได้ (allow-update)

    สมมุติว่า

    • มีโดเมนภายในเป็น example.com อย่างเดียว มีไอพีเป็น 192.168.1.0/24 โดยจะทำเรื่อง reverse ip ด้วย (คือค้นย้อนกลับจากเลขไอพีได้)
    • โดเมนภายนอกเป็น example.com และ example.org โดยที่เราจะทำให้ทุกบริการมีไอพีเดียวกัน คือเครื่องนี้เครื่องเดียวทำหลายหน้าที่ เพียงเปลี่ยนชื่อ (CNAME) ไปตามบริการนั้น ๆ ติดตั้งเป็นแบบเปลี่ยนค่าได้ เพราะไอพีเราไม่คงที่
      โดเมนภายนอก จะไม่ทำ reverse ip เพราะเรามีหลายโดเมน และถึงแม้จะมีโดเมนเดียว ค่าที่โลกภายนอกค้นได้ก็คงไม่ใช่จากเครื่องเราอยู่ดี (ค้นได้จากชื่อโดเมนอย่างเดียว ค้นย้อนกลับจากเลขไอพีไม่ได้)

    ติดตั้งแพกเกจ
    # 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

    ของ example.com
    สั่งสร้างกุญแจสำหรับลงทะเบียนโซน
    # 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

    Topic: 

    debian: bind9 แบบให้บริการเครือข่ายภายในและภายนอก

    bind9 แบบให้บริการเครือข่ายภายในและภายนอก

    การตั้งให้ name server ให้บริการเครือข่ายภายในและภายนอก โดยใช้โดเมนเดียวกัน มีข้อดีตรงที่เราไม่จำเป็นต้องแยกโดเมนให้จำยาก และเมื่อเวลาลูกข่ายภายในสั่งค้น การค้นก็ไม่ต้องเปลืองแพ็กเก็ตออกสู่ภายนอก เพียงแต่การปรับตั้งยุ่งนิดนึง
    # aptitude install bind9

    สมมุติว่า

    • เราให้บริการอยู่ 2 โดเมนคือ example.com กับ example.org
    • example.com ภายในเป็น 192.168.1.0/24 ส่วนภายนอกเป็น 111.112.113.114 (ไอพีสมมุติ)
    • example.org ภายในเป็น 10.0.0.0/24 ภายนอกเป็น 211.212.213.214 (ไอพีสมมุติ)
    • เครื่องที่เรากำลังตั้งอยู่ ให้ชื่อว่า ns1 (ซึ่งเราทำเป็น all-in-one ก็อาจมีชื่อเป็น www และ mail ด้วย)
      โดยมีไอพีของ ns1.example.com เป็น 192.168.1.1 และ ไอพีของ ns1.example.org เป็น 10.0.0.1

    จะต้องมีไฟล์คอนฟิกคือ 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

    Topic: 

    ลองติดตั้ง dns แบบเปลี่ยนค่าได้

    จะทดลองทำ 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

    เรียบร้อยแล้วครับ

    หมายเหตุ

    • ในระหว่างการทำงานอัปเตด โปรแกรมจะสร้างโซนไฟล์สำรองขึ้นมาในชื่อว่า example.com.zone.jnl
    • เมื่อสั่งเริ่ม bind9 ใหม่ จะพบว่าเนื้อหาของโซนไฟล์ถูกเปลี่ยนแปลงไปตามการอัปเดต
    • ส่วนการอัปเดตรีเวิร์สไฟล์ด้วย ยังทำไม่เป็นครับ :)
    • ใจจริง อยากปรับเปลี่ยนเนื้อโซนไฟล์กับรีเวิร์สไฟล์ ให้เอาเรื่อง ลูกเล่นของ BIND9 DNS Server! มารวมเสียทีเดียว แต่กลัวตัวเองงง เลยปล่อยไว้อย่างเดิม :)

    หมายเหตุ 2
    ข้อเขียนนี้เป็นเพียงการทดลองเท่านั้น แต่ใจสู้เขียน ด้วยค้นหาวิธีการแบบง่าย ๆ ไม่พบ (step by step) เลยต้องทดลองเอง และต้องการบันทึกผลการทดลองที่สามารถใช้งานได้แล้ว ดังนั้นจึงยังไม่ทราบผลข้างเคียงเรื่องความปลอดภัย และความถูกต้องตามระเบียบแบบแผนที่ควรเป็น
    จึงต้องการขอคอมเมนต์และคำแนะนำเพื่อให้ได้รู้เรื่องกันในวงกว้างครับ
    (ก่อนหน้านี้ เวลาต้องการอัปเดตเลขไอพี ผมใช้สคริปต์ในการสร้างโซนไฟล์ และรีเวิร์สไฟล์ขึ้นมาใหม่ แลัวจึงสั่งเริ่ม bind9 ใหม่ จึงไม่มีปัญหาเรื่องความปลอดภัยมาเกี่ยว)

    อ้างอิง

    บันทึกติดตั้ง postfix/SASL/TLS

    Postfix เป็นแพกเกจ Mail Server ที่ได้รับความนิยมมากกว่าแพกเกจของเดเบียนเอง (Exim)
    ดูจาก debian-administration: Mail Server Poll

    ผมแทบไม่รู้อะไรเกี่ยวกับ Postfix SASL และ TLS เลย
    แต่ขออนุญาตบันทึกไว้รอศึกษาครับ

    เอามาจาก tribulaciones: Postfix/SASL/TLS HowTo for Debian Sid and Sarge

    งาน Server
    ติดตั้งแพกเกจ
    # 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

      แก้คอนฟิกของ 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

      แก้ไขไฟล์ /etc/postfix/main.cf
    ## 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
    ต้องไม่มีรายงานข้อผิดพลาด

    งาน Client
    ติดตั้งแพกเกจ
    # 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

    การติดตั้ง 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
    Topic: 

    debian: ลองติดตั้ง drupal5 แบบเดเบียน

    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 ได้เลย

    หมายเหตุ

    หากต้องการเปลี่ยนเฉพาะซับไดเรคทอรี่เป็นชื่ออื่น เช่นเปลี่ยนเป็น http://www.example.com/content
    1. ให้เปลี่ยนที่ไฟล์ /etc/drupal/5/apache.conf
      # vi /etc/drupal/5/apache.conf
      Alias /content /usr/share/drupal5
    2. สร้างไฟล์ทดแทนไฟล์ settings.php ของ drupal ชื่อไฟล์ baseurl.php
      # 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

    3. เริ่ม apache2 ใหม่
      # /etc/init.d/apache2 restart

    (แต่หากต้องการใช้ใน root คือ http://www.example.com เฉย ๆ ควรดาวน์โหลดและติดตั้ง drupal เองที่ /var/www
    หรือแก้ไข /etc/apache2/site-enabled/default ให้ชี้มาที่ /usr/share/drupal5 อย่างใดอย่างหนึ่ง)

    หากต้องการ clean url
    1. เปิดใช้งานมอดูล rewrite
      # a2enmod rewrite
    2. แก้ htaccess
      # vi /etc/drupal/5/htaccess
      ...
      RewriteBase /content
      ...
    3. เริ่ม apache2 ใหม่
      # /etc/init.d/apache2 restart
    ถ้าทดลองหลายครั้ง คือมีการ install และ remove หลายครั้ง อาจทำให้หามอดูลใน apache2 ไม่พบ
    แก้ไขดังนี้
    # 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 สะดวกกว่า
    เที่ยวนี้บันทึกเอาไว้ดู ว่าติดตั้งจากเดเบียนทำยังไง

    Topic: 

    debian: Virtualization

    ทดลองเกี่ยวกับ Virtualization

    Topic: 

    ubuntu: feisty - qemu

    เดี๋ยวนี้ 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 น่าใช้ที่สุด เนื่องจากการทำงานราบเรียบกว่า Xen, VirtualBox, kvm, VMWare แพ้แต่ Parallel เท่านั้น ถึงแม้จะรันช้ากว่า แต่มีข้อดีตรงที่เราสามารถปรับเปลี่ยนได้ตามที่เราต้องการ
    • ในขั้นตอนติดตั้งโปรแกรม ควรปิดการทำงานของ kqemu โดยถ้าเป็น Windows Xp ให้เอาออปชั่น -kernel-kqemu ออก และถ้าเป็น Windows 98-ME ให้เติมออปชั่น -no-kqemu
    • ถ้าเป็นซีพียูตระกูลอินเทล - VT จะได้ความเร็วที่ราบรื่น แม้ไม่ได้ใส่ออปชั่น -kernel-kqemu ก็ตาม
    • เวลาติดตั้งโปรแกรม ควรใช้ประโยชน์จากการที่ qemu สามารถทำ overlay ได้มีเทคนิกดังนี้
      1. สร้างอิมเมจหลักก่อน สมมุติว่าชื่อ winxp.qcow
        $ qemu-img create -f qcow winxp.qcow 5G
      2. ติดตั้งวินโดวส์ โดยใช้ hda เป็น winxp.qcow จนเสร็จเรียบร้อย
      3. สร้าง Overlay image เพื่อเก็บอิมเมจเก่าไว้
        $ qemu-img create -b winxp.qcow -f qcow winxp.ovl
      4. ติดตั้งโปรแกรม หรือทำการทดลองใด ๆ บน Overlay image ที่สร้างขึ้น
      5. ถ้าติดตั้งไม่ผ่าน หรือทดลองจนงานเละ ก็ให้ลบอิมเมจ winxp.ovl ทิ้งไป แล้วเริ่มขั้นตอนก่อนหน้านี้ใหม่
      6. ถ้าติดตั้งหรือทดลองจนเสร็จเรียบร้อยแล้ว และต้องการบันทึกงานเข้าไปรวมกับอิมเมจเก่า ให้ใช้คำสั่ง
        $qemu-img commit winxp.ovl
        ผลคือข้อมูลใน winxp.ovl จะถูกบันทึกลงใน winxp.qcow และ winxp.ovl จะถูกลดขนาดลงมา พร้อมที่จะรับงานใหม่ต่อไป
    • ทดสอบล่าสุดบนเดเบียน qemu รุ่น 0.8.2 ซีพียู Pentium E6300 พบว่า
      • บน WindowsXP สั่งด้วย qemu เฉย ๆ เร็วกว่าใช้พารามิเตอร์ -kernel-kqemu
      • บน WindowsMe สั่งด้วย qemu -no-kqemu เร็วและเสถียรกว่า qemu เฉย ๆ (การสั่งด้วย qemu เฉย ๆ จะเปิดใช้งาน kqemu ในโหมด user โดยอัตโนมัติ)
      • บน WindowsMe สั่งด้วย qemu-system-x86_64 เฉย ๆ เสถียรเท่ากับสั่งด้วย qemu -no-kqemu แต่ช้ากว่า

      สรุปว่าสำหรับ qemu ตั้งแต่รุ่น 0.8.2 เป็นต้นไป ต้องทดลองดูหลาย ๆ แบบ ดูว่าแบบไหนดีที่สุด ไม่จำเป็นต้องเป็นตามคู่มือเสมอไป

    หมายเหตุ

    • ผมอัปเกรดจาก dapper ด้วยคำสั่ง aptitude dist-upgrade จึงอาจมีสคริปต์เก่าหลงเหลืออยู่ ไม่แน่ใจว่าถ้าติดตั้งอูบุนตูจากแผ่นติดตั้งของ Feisty ล้วน ๆ ขั้นตอนการติดตั้ง qemu จะต่างออกไปจากนี้หรือไม่

    อ้างอิง

    debian: qemu เก็บตก

    ทดลองใช้ 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

    Topic: 

    debian: บันทึกการปรุง qemu รุ่นปรับแก้ NumLock/CapsLock เพื่อแจกจ่าย

    รุ่นนี้เป็นรุ่นปรับแก้บั๊กเรื่อง 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
    หากคร้านที่จะคอมไพล์เอง ดาวน์โหลดได้ที่นี่ครับ ฝากทดสอบบั๊กให้ด้วย

    อ้างอิง
    Murray's Blog: Building modified debian packages

    บันทึกการแก้ปัญหา Num Lock - Caps Lock ของ qemu

    เมื่อได้ลองใช้งาน 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 ทั้งคู่

    debian: ทดลอง XenOnLenny

    จะเอามาลองทดสอบ 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

    ... ติดตั้งตามปกติ ...
    หมายเหตุ

    • ถ้ามีการเปลี่ยนความละเอียดของหน้าจอบน Windows XP อาจต้องปิดหน้าต่างของ xtightvncviewer แล้วก็ใช้คำสั่ง $ xtightvncviewer localhost ใหม่
    • ถ้าติดตั้งเรียบร้อยแล้ว อย่าลืมเปลี่ยนพารามิเตอร์ boot ในไฟล์ winxp.cfg เป็น boot = 'c' ด้วย

    ผลการทดลอง

    • หลังจากใช้ qemu มานาน เลยมีความรู้สึกว่าเร็วจี๋ทีเดียว โดยเฉพาะเรื่องเน็ตเวิร์ก เร็วมาก ๆ
    • แป้นพิมพ์ตัวเลข ยังมีอาการพิมพ์ไม่ติดเป็นบางครั้ง
    • ตำแหน่งเมาส์ไม่ตรงกัน ระหว่าง Dom0 กับ DomU แก้โดยต้องลองปรับตำแหน่งเมาส์ด้วยการเคลื่อนเมาส์ให้พ้นกรอบของหน้าต่าง Viewer แล้วย้ายมาเริ่มใหม่ในด้านตรงข้าม (ต้องลองไปลองมา แล้วจะเริ่มขยับตรงเอง)
    • ความเร่งของเมาส์ไม่เท่ากัน ระหว่าง Dom0 กับ DomU แก้โดยปรับที่ Windows XP ให้ปิดการทำงานของการเร่งเมาส์
      Control Panel -> Mouse -> TAB-Pointer options -> ปิด Enhance pointer position
    • ยังมีปัญหา(ติดตั้งยังไม่เป็น)เรื่องเน็ตเวิร์กคือ ping จาก DomU ไป Dom0 ได้ แต่ในทางกลับกัน ping ไม่ได้ ยังไม่ทราบว่าต้องตั้งที่ไหน
      จะติดตั้งแบบ NAT เหมือน qemu ก็กลัวเสียความเร็ว เดี๋ยวมีโอกาสค่อยลองอีกทีนึง (แก้ที่ไฟล์ winxp.cfg ตำแหน่ง vif และไฟล์ /etc/xen/scripts/qemu-ifup)

    สรุป
    ถึงแม้จะยังไม่สมบูรณ์แบบ แต่ก็น่าใช้มาก โดยเฉพาะถ้าต้องการความเร็วในการใช้งาน การติดตั้งก็ไม่ยากเหมือนแต่ก่อน
    เสียดายที่ต้องใช้กับซีพียูที่มีโหมด Vitualize เท่านั้น (Intel-VT, AMD-Pacifica) และโอเอสก็ต้องเป็น 32bit ขึ้นไปแบบ Windows XP
    ถ้าใช้กับ Win98 ได้นี่จะประหยัดไลเซ่นซ์วินโดวส์เก่า ๆ ได้เยอะเลย

    อ้างอิง

    debian: บันทึก VirtualBox

    หลังจากทดลอง Xen แล้ว พบว่ายังมีปัญหาเกี่ยวกับคีย์บอร์ดที่ค่อนข้างเอาแน่เอานอนไม่ได้ และปัญหาความไม่คุ้นเคยในการใช้เมาส์ผ่าน VNC
    จึงได้มาทดลองใช้ VirtualBox
    ซีพียูอินเทล E6300 หน่วยความจำ 1G
    พบว่า

    • ถ้าใช้กับวินโดวส์ 9x ติดตั้งยาก มีปัญหากับ VGA และถ้าสามารถติดตั้งผ่านแล้ว ความเร็วสู้ qemu -no-kqemu ไม่ได้
    • ถ้าใช้กับวินโดวส์ Xp ความเร็วดีมาก สงสัยว่าจะเร็วกว่า Xen เสียอีก และเสถียรดีมาก ดีกว่า qemu สรุปว่าถ้าเป็น Windows Xp น่าใช้ VirtualBox มาก ๆ

    จึงบันทึกการปรับตั้งค่าไว้ดังนี้

    มีปัญหาว่าบางครั้ง แม้จะแก้ไขให้เราอยู่ในกลุ่ม 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 -&gt Host Interface
    Interface name : tap0
    Setup application : ~/ifup-tap0

    สำหรับ Windows XP เขาให้หน่วยความจำปริยายมาเป็น 128M แต่เรากำหนดเป็น 384M

    ใน Windows XP ตั้งค่าให้ไอพีเป็น 192.168.1.4 และเกตเวย์เป็น 192.168.4.254

    การเมานต์ไฟล์ vdi

    ntfs
    $ 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
    vfat
    $ sudo mount -o loop,offset=0x$(hd -h 100000 IMAGE.vdi | grep "eb 3C 90" | cut -c 1-8) IMAGE.vdi /MOUNT/POINT

    ที่มา: forums.virtualbox.org: Mounting .vdi file on host

    debian: ติดตั้ง OS X Guest ใน VirtualBox

    มีงานที่ต้องการทดสอบการแสดงผล ของ 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

    ขั้นตอน

    • 1.ติดตั้ง Snow Leopard (10.6) เพื่อจะสามารถดาวน์โหลด Mavericks (10.9) ได้ และนำมาสร้างเป็นไฟล์ iso เพื่อติดตั้งต่อไป
    • 2.ติดตั้ง Mavericks

    ต้องเตรียม

    • ซื้อแผ่น Snow Leopard (10.6) ราคา 620 บาท บวกค่าส่งอีก 300 บาท (ต้องสมัคร/ใช้บัญชี Apple ID)
    • iBoot Ivy Bridge 1.1.0 สำหรับบูตเข้า Snow Leopard (ต้องลงทะเบียน) แตกไฟล์แล้วเก็บไฟล์ iBoot-Ivy-Bridge.iso ไว้ (ถ้าบูตไม่ผ่าน ลองดาวน์โหลด iBoot ตัวอื่นดู)
    • เนื้อที่ว่างของฮาร์ดดิสก์ ประมาณ 30-60 GB

    1.ติดตั้ง Snow Leopard

    เอา 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" นี้ไว้ได้ แต่หากไม่ต้องการใช้แล้วก็ลบทิ้งได้เลย

    ที่มา

    2.ติดตั้ง Mavericks

    เอา 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)

    จบแล้ว

    ที่มา

    รายงานผล

    • Snow Leopard: เปิด About this Mac ไม่ได้
    • Mavericks: การรันไม่ค่อยลื่นเท่าไหร่ แต่ก็พอใช้งาน test/debug Safari/iBooks ตามจุดประสงค์หลักได้
    • ใช้ปุ่ม Alt ขวามือ แทนปุ่ม Command ใน Mac
    • Mouse wheel หมุนกลับทางกับของลินุกซ์/วินโดวส์

    debian: macOS guest on VirtualBox - create installation media short note.

    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

    debian: ทดลองติดตั้ง OpenVZ บน lenny

    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

    เสร็จแล้วครับ

    ที่มา

    debian: บันทึกติดตั้ง WebVZ บน lenny

    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

    เสร็จแล้ว

    ที่มา

    webvz: ทำ container ใช้เอง

    บันทึกการทำ 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

    เป็นต้น

    debian: ทดลองติดตั้ง Xen บน lenny

    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

    เสร็จแล้วครับ

    ที่มา

    ubuntu: ลอง XenOnEdgy

    cpu: Intel E6300
    mb: Asrock Conroe945G-DVI
    ram: 1G

    เที่ยวนี้ลองคอมไพล์ซอร์สเอง ไม่ผ่านซักอย่าง เลยใช้แบบไบนารีดีกว่า
    ทำตาม wiki.ubuntu.com/XenOnEdgy เกือบทั้งหมด

    ติดตั้ง Dom0

    เอาแพกเกจที่เกี่ยวข้องมาก่อน
    $ 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
    ...

    เน็ตเวิร์กยังไม่ได้ลอง เดี๋ยวจะกลับมาลอง

    ติดตั้ง WinXP เป็น DomU

    ในตัวอย่างของ 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 มีข้อจำกัดมาก คือ

    • พอยเตอร์ของเมาส์ไม่ตรง ทำให้ขัดความรู้สึก ต้องไปยกเลิกฟังก์ชั่น Enhance pointer precesion ของเมาส์ ถึงจะพอใช้งานได้
    • เวลาเปลี่ยนความละเอียดของ Desktop อาจต้องเริ่ม xtightvncviewer ใหม่

    ข้อเสียอื่น ๆ ก็พอยอมรับได้ครับ เมื่อแลกกับความเร็วที่ได้มา

    (ลองกับ WinMe ยังไม่ผ่านครับ)

    ubuntu: แก้ปัญหาเรื่อง UUID

    เนื่องจากอูบุนตูเปลี่ยนการเมานต์ดิสก์ จากเดิมที่กำหนดเป็นค่าดีไวซ์ มาเป็น 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 แต่ลืมบันทึกครับ

    Topic: 

    debian: iptables

    iptables บนเดเบียน มี 2 วิธี (จริง ๆ มีหลายวิธีมาก)

    1. แบบใช้ iptables-save + iptables-restore
      รันคำสั่งเพื่อสร้างกฎต่าง ๆ
      # 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
      ...
      
    2. แบบใช้สคริปต์
      สร้างสคริปต์เก็บไว้คือ /usr/local/bin/d.iptables
      # 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

    debian: ทำแผ่นบูตฉุกเฉิน

    ทำแผ่นบูตฉุกเฉิน

    ปัญหาคือมีเครื่องลูกข่ายที่เป็นวินโดวส์ติดไวรัส และไม่ได้ลงซอฟต์แวร์ป้องกันไวรัสไว้ (เนื่องจากทอนกำลังเครื่อง)
    ทางแก้คือ ใช้แผ่นบูตเดเบียนที่ลงแพกเกจ 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
    • หากต้องการปรับค่าปริยายของระบบ เช่นต้องเปลี่ยน mirror โดยทดสอบหลายครั้ง ให้ปรับแก้สคริปต์ /usr/share/live-helper/functions/defaults.sh โดยตรง

    อ้างอิง

    Topic: 

    debian: โปรแกรมจัดการ pdf

    ต้องการหาโปรแกรมที่ทำงานกับไฟล์ pdf ที่สามารถใช้งานได้ทั้งลินุกซ์และวินโดวส์

    รวมหรือแตกไฟล์ แบบ GUI เลือกใช้ Pdfsam
    เป็น java แต่ใช้งานไม่ยาก ถ้าบริจาคตั้งแต่ 1 เหรียญขึ้นไปจะมีสิทธิ์ใช้งานรุ่นพิเศษที่มีความสามารถมากขึ้น
    $ sudo aptitude install pdfsam
    รวมหรือแตกไฟล์แบบบรรทัดคำสั่ง เลือกใช้ pdftk (the pdf toolkit)
    $ 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

    ทำ annotation เลือกใช้ Xournal
    $ 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/
      แต่กับ xournal เราต้องแก้ที่ c:\xournal\etc\fonts\fonts.conf
    Topic: