วันพุธที่ 19 พฤษภาคม พ.ศ. 2553

DNS Postfix กับ SPF

ช่วงนี้งานพวกการติดตั้งระบบหรือปรับปรุงระบบเพื่อทำให้การใช้งานมีประสิทธิภาพดูเหมือนว่าจะทยอยมาให้ทำเรื่อย ๆ เช่นคราวนี้ เป็นคราวของ EMAIL

ในการติดตั้ง email server นั้นปกติแล้วหากเราไม่ได้กำหนดอะไรไว้มากนักเราก็จะเจอว่ามีผู้ประสงค์ดีคอยส่ง email พวกโฆษณาให้เราเยอะมาก เอาเป็นว่าวันละหลาย ๆ รอบ

วันนี้เลยต้องพึ่ง SPF (Sender Policy Framework) หลักการของ spf นั้นง่ายมาก มันเริ่มด้วยเครื่องที่รับ email เวลาที่ได้รับการติดต่อมานั้นก็ทำการถามไปยัง dns ที่ควบคุม domain ที่ส่งมา ถามว่า "email ที่กำลังรับอยู่นี้ ได้ถูกส่งมาจากเครื่องที่กำหนดไว้หรือไม่"

มาดูรูปแบบที่กำหนดไว้ DNS กัน

mydomain.com TXT "v=spf1 a mx a:mydomain.com mx:mydomain.com mx:mail.mydomain.com ip4:xxx.xxx.xxx.0/24 ip4:xxx.xxx.xxx.xxx ~all"

อธิบายได้ดังนี้
  • v=spf1 แสดงว่า TXT นี้เป็นการกำหนด SPF
  • a แสดงว่า เครื่องนี้เป็นเครื่อง ส่ง email ของ mydomain.com ด้วย
  • mx แสดงว่า MX server นี้ ส่ง email ของ mydomain.com ด้วย
  • ip4:xxx.xxx.xxx.0/24 แสดงว่า ทุกเครื่องที่มีช่วงของ ip นี้ เป็นเครื่องที่ใช้ส่ง email ของ mydomain.com (อันนี้มีประโยชน์มากสำหรับคนที่ใช้ smtp ของ ISP เป็นคนส่ง)
  • ip4:xxx.xxx.xxx.xxx แสดงว่า เครื่องที่มี ip นี้ เป็นเครื่องที่อนุญาติให้ส่ง email ได้
  • ~all แสดงว่า SPF ที่ได้รับมาหากตรวจสอบแล้วไม่ตรงก็จะทำการบอก mail server ว่า ให้กำหนดเป็น softfail
หากเราทำการกำหนดดังกล่าวแล้ว เวลาเปิด email ดู เช่นใน gmail เราก็จะได้ header ว่า
Received-SPF: pass (google.com: domain of user@mydomain.com designates xxx.xxx.xxx.xxx as permitted sender) client-ip=xxx.xxx.xxx.xxx;

อ้างอิง: http://old.openspf.org/wizard.html?mydomain= เอาไว้สร้าง spf
อ้าวอิง: http://www.debianhelp.co.uk/dnsrecords.htm เอาไว้อ่านความหมายของ DNS record

แถมในส่วนของ postfix อีกหน่อย ...

ปกติแล้ว postfix นั้นไม่ได้มีการตรวจสอบ spf ไว้ก่อน เราต้องทำเอง ด้วยวิธีดังนี

  1. อันแรกเอาเป็นว่าก็ต้องติดตั้ง postfix ก่อน (อันนี้ไปทำเอง)
  2. จากนั้นก็ติดตั้ง tumgreyspf ด้วย $ aptitude install tumgreyspf
  3. แล้วก็แวะไปอ่าน /usr/share/doc/tumgreyspf/README.Debian เพื่อมากำหนดค่าต่าง ๆ
  4. แล้วก็ reload postfix
เท่านี้เอง

อ้างอิง: http://workaround.org/ispmail/lenny/spf

วันจันทร์ที่ 10 พฤษภาคม พ.ศ. 2553

TTS กับเพชรพระอุมา

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

หลังจากที่ได้ฟังการอ่านบางตอนแล้วก็พบว่า คิดถึง "นกน้อย" หรือคณะพากษ์ละคร ที่มีในสมัยก่อนมาก

แต่ในฐานะนักพัฒนาระบบแล้ว ผมกลับอยากพัฒนาระบบ Text to Speech เพื่ออ่านหนังสืออื่น ๆ ด้วย เพราะจะพึ่งการอ่านจากคนต้องใช้เวลาและความร่วมมือค่อนข้างสูง

ที่ดูไว้ก็มี pyTTS, pyTTSx นั่นแหละ

วันอังคารที่ 4 พฤษภาคม พ.ศ. 2553

vi ไวเป็นลิง

แต่ก่อนมี เพื่อนเคยพูดไว้ว่า "vi ไวเป็นลิง" ภายหลังได้ลองเล่นเองแล้ว ก็เห็นด้วยเป็นอย่างยิ่ง โดยเฉพาะเมื่อต้องทำงานกับ ไฟล์ที่มีขนาดใหญ่ (เคยเป็น 100 MB มาแล้ว) แต่ว่าพอไม่ได้ใช้นาน ๆ ไหง ลืมซะอย่างนั้น ก็เลยขอบันทึกไว้กันลืม ดังนี้

การเลื่อนตำแหน่ง
  • ^f = เลื่อนลง 1 หน้า
  • ^b = เลื่อนขึ้น 1 หน้า
  • ^d = เลื่อนลงครึ่งหน้า
  • ^u = เลื่อนขึ้นครึ่งหน้า
การลบ
  • x = ลบ 1 อักขระ
  • dw = ลบตั้งแต่เคอร์เซอร์จนถึงต้นคำหน้า
  • d$, D = ลบตั้งแต่เคอร์เซอร์จนถึงท้ายบรรทัด
  • dL = ลบตั้งแต่บรรทัดปัจจุบันจนถึงท้ายจอภาพ
  • dh = ลบ 1 อักขระก่อนถึงเคอร์เซอร์
  • dd = ลบบรรทัดปัจจุบัน
  • dG = ลบจากบรรทัดปัจจุบันจนถึงท้ายไฟล์
  • d1G = ลบจากบรรทัดปัจจุบันจนถึงต้นไฟล์
  • ใช้ร่วมกับตัวเลข

    • d3w, 3dw = ลบ 3 คำ
    • 5dd, 4dj = ลบ 5 บรรทัด จากบรรทัดปัจจุบัน ( 4dj=ลบบรรทัดปัจจุบัน และอีก 4 บรรทัดถัดไป )
    • 4dk = ลบบรรทัดปัจจุบัน และอีก 4 บรรทัดก่อนหน้า
    • 5Gdd = ลบบรรทัดที่ 5

When you need to ssh to server without entering password.

Loggin into server without password is stupid way. But sometime we need to do that e.g. Cron

So

# CREATE DSA AT CLIENT
user1@client:~$ ssh-keygen -t dsa

Generating public/private dsa key pair.
Enter file in which to save the key (/Users/user1/.ssh/id_dsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/user1/.ssh/id_dsa.
Your public key has been saved in /Users/user1/.ssh/id_dsa.pub.
The key fingerprint is:
9a:30:11:3c:3c:cf:89:01:3a:e1:5d:bd:49:c9:50:f4 user1@client
The key's randomart image is:
+--[ DSA 1024]----+
|. .+.o*o. |
|.o. B. =. |
|o. ..B..oE |
| . ..+o |
| o S |
| o o |
| o |
| |
| |
+-----------------+

# COPY PUBLIC DSA TO SERVER

user1@client:~$ scp ~/.ssh/id_dsa.pub user1@some.server.com:/home/user1/.ssh

user1@some.server.com's password:
id_dsa.pub 100% 642 0.6KB/s 00:00


# SETUP AUTHORIZED_KEY FROM CLIENT TO SERVER
user1@some.server.com:~$ cd ~/.ssh
user1@some.server.com:~$ touch authorized_keys
user1@some.server.com:~$ chmod 600 authorized_keys
user1@some.server.com:~$ cat id_dsa.pub >> authorized_keys


DONE!

Secure TCP/IP Connections with SSH Tunnels กับ PostgreSQL

ผมชอบ SSH ตรงที่มันสามารถทำ SSH Tunnels ได้นี่แหละ และก็อีกครั้งที่ผมได้ประสบการณ์ดี ๆ เกี่ยวกับการใช้งาน Database ระยะไกลอีกครั้ง

|---------------------|
| 222.222.22.222 |
| Postgres:5432 |
|----------|----------|
|
|
|---------------------|
| 10.0.0.01 |
| Firewall |
|----------|----------|
|
|
|---------------------|
| 10.0.0.20 |
| local web server |
|----------|----------|


ดูจากรูป เครื่อง Server ของผมฝากไว้ที่ ISP โดยได้ทำการ ติดตั้ง PostgreSQL และ run ไว้ที่พอร์ต 127.0.0.1:5432 เพราะว่าไม่อยากให้ใครมาต่อ นอกจากที่ตัวมันเอง

คราว นี้ก็เป็นประเด็นว่า แล้วถ้าอยากต่อ Database ไปยังเครื่อง Server จากที่อยู่หลัง FireWall หละ จะทำอย่างไร อย่างแรกที่นึกออกก็คือ VPN

หลัง จากติดตั้ง OpenVPN แล้ว ปัญหาก็ตามมา คือ มันช้า แล้วก็หลุดบ่อยด้วย หาทางแก้อยู่ตั้งนาน สุดท้ายก็มาจบที่ SSH Tunnel อีกตามเคย


เอกสาร ที่ผมนำมาเล่าให้ฟังนั้นสามารถอ่านแบบภาษาอังกฤษได้ที่ http://developer.postgresql.org/pgdocs/postgres/ssh-tunnels.html


ขั้น แรกก็ SSh เข้าไปที่เครื่อง local ก่อน
$ ssh username@10.0.0.20

ต่อ มาก็ต้องลุยด้วยการสร้าง Tunnel
$ ssh -L 63333:localhost:5432 username@222.222.222.222
# อธิบายได้ดังนี้
# จะทำการสร้าง Tunnel ที่ 10.0.0.20:63333 (เค้าเรียกว่า End of Tunnel) ไปยัง 222.222.222.222:5432 (เรียกว่า End of Remote Tunnel) และก็เป็นพอร์ตที่เปิดให้บริการ Database อยู่ด้วย
# โดยใช้ผู้ใช้งาน username ต่อไปยัง 222.222.222.222

ที่เครื่อง local web server ตรวจดูความเรียบร้อยหน่อยว่า มีการเปิดพอร์ต 63333 ไว้จริงหรือไม่ด้วย
$ netstat -an |grep 63333

จากนั้นก็ลองดูว่าสามารถใช้งาน postgres ได้จากเครื่อง local หรือไม่
$ psql -h localhost -p 63333 -U postgresuser -l

Postfix กับการส่ง email ด้วยหลาย ๆ Relay





Normally when you need to send massive emails via shared gateway. The possibility way is to set your gateway to relay to ISP's smtp. But what happen if a huge destination emails is in local network. You have to send every local email by local relay?

Please try this

# Create a hash transport map
# touch /etc/postfix/transport
# Add this lines to /etc/postfix/transport
mydomain.com relay:10.0.0.25:25
# Create Map
#postmap /etc/postfix/transport
# Add your transportation to /etc/postfix/main.cf
# postconf -e "transport_maps = hash:/etc/postfix/transport"
# Then reload your postfix
#/etc/init.d/postfix reload

การใช้งาาน PostgreSQL ในส่วนงานต่าง ๆ OLTP, DW, WEB

คราวก่อนนำเนื้อหามาแปะไว้ (PostgreSQL กับการกำหนดค่าที่น่าสนใจของ WEB, OLPT, DW ) กะว่าจะอธิบายต่อที่ตรงนี้ แต่เท่าที่ดูแล้วคิดว่านำออกมาอธิบายต่างหากดีกว่า

การติดตั้ง PostgreSQL โดย Package ที่สำเร็จรูปนั้น แน่นอนว่าการทำ Package ออกมาจะมีการกำหนดค่ามาเพื่อรองรับ Application ทั่ว ๆ ไป แต่เนื่องจากความเป็นจริง เมื่อมีการนำมาใช้งานแล้ว เราต้องทำการปรับค่าต่าง ๆ เพื่อให้เหมาะสมกับงานที่ต่างกันออกไป

งานที่ต่าง ๆ กันก็ขอแบ่งออกเป็น 3 อย่างดังนี้ก่อน
  1. WEB - Web Transactional
  2. OLTP - Online Transactional Processing
  3. DW - Data Warehouse
งานทั้ง 3 ประเภทนี้ต่างกัน ทำให้การกำหนดค่าต่าง ๆ ของ Database แตกต่างกันด้วย ลองนึกถึงว่าถ้าหากเราต้องการขับรถ ไปยังที่แตกต่างกัน เราจะเลือกรถอย่างไรดี

ในด้าน Database ก็เหมือนกัน ทุกวันนี้หลายคนใช้ Database Configurature เดียว เพื่องานทุกอย่าง อาจเนื่องจากเหตุผลทางด้านการเงิน แต่เมื่อทำงานไปซักพักก็จะเข้าใจว่าทำไม

ก่อนอื่นเราต้องทำความเข้าใจกับ ประเภทของงานทั้ง 3 กันก่อน
"WEB" การเรียกใช้งานส่วนใหญ่เป็นการแสดงผล มีการเรียกการใช้งาน Database บ้าง แต่ส่วนใหญ่จะถูกออกแบบมาเพื่อบริการข้อมูล ไม่ค่อยมีการทำ Transaction
"OLTP" มีการเรียกใช้งานข้อมูลเพื่อประกอบการใช้งาน และมีการบันทึกข้อมูล Transaction กลับไปยัง ฐานข้อมูล มีรายงานที่เกี่ยวกับทางด้าน Tranaction ในแต่ละวัน
"DW" Datawarehouse มีลักษณะเฉพาะ โดยมีจุดประสงค์เพื่อนำข้อมูลที่เก็บไว้มาทำเป็นการวิเคราะห์ และตัดสินใจ และบางครั้งส่งผลที่ได้กลับไปยัง OLTP เพื่อกำหนดวิธีการทำงานต่าง ๆ รายงานส่วนใหญ่ถูกออกแบบมาเพื่อ ทำเป็นข้อมูลเพื่อการตัดสินใจ

เมื่อทราบลักษณะงานต่าง ๆ แล้ว เราก็เริ่มดำเนินการกำหนดค่ากันเลย ซึ่งในส่วนนี้จะมุ่งไปยัง Database เท่านั้น ส่วน Application นั้น ก็ขึ้นอยู่กับประเภทของงาน


CPU
ปัจจุบันเท่าที่ประสบมา จำนวน CPU 4-8 cores ก็เพียงพอกับงานที่เกี่ยวกับ Database แล้ว และแต่ละ CPU ก็มีความเร็วที่ค่อนข้างมากแล้วด้วย

MEMORY
หลักง่าย ๆ คือ ถ้าอยากให้เร็วก็ใส่ เยอะ ๆ ปัจจุบันเท่าที่เห็นคือ 16GB

HARDDISK
"many spindles are better" หมายความว่า ถ้าทำ RAID ให้ใช้ HD หลาย ๆ ตัวทำ RAID ใน 1 Volume ในส่วนนี้มีผลต่อ การทำงานของ Database เป็นอย่างมาก เพราะว่า งานส่วนใหญ่ให้ Load Data แล้วประมวลผลใน MEMORY ไม่พอหรอก

NETWORK
หลาย ๆ คนซื้อ Server ที่มี Networks Interface เยอะ ๆ แต่ว่าใช้อันเดียวเอง (เป็นเพราะว่า ไม่เคยเจอ Traffice เยอะ ๆ อย่างผม)


คราวนี้มาดูการปรับแต่งของ Database กัน

max_connections หมายถึงจำนวน connection ที่สามารถเข้ามาใช้งานได้เมื่อขนาดที่มีการใช้งานมากที่สุด โดยแต่ละ connection นั้นจะใช้ ทรัพยากร shared_buffer ที่กำหนดไว้ แน่นอนว่า ถ้ากำหนดไม่ดีจะมีอาการที่บอกว่า "out of memory" นะ

max_connections = 200  # small server   max_connections = 700  # web application database   max_connections = 40   # data warehousing database
shared_buffer หมายถึงปริมาณของหน่วยความจำที่ต้องใช้งานเพื่อการประมวลผล process ก่อนที่จะมีการใช้ disk เพื่อทำ operation ประมาณว่ามี active operations ได้มากเท่าไหร่

# shared_buffers = ( Available RAM / 4 ) # shared_buffers = 512MB   # basic 2GB web server # shared_buffers = 8GB     # 64-bit server with 32GB RAM

work_mem หมายถึงปริมาณของหน่วยความจำที่สามารถใช้ในแต่ละ query ได้ ถ้า Query อะไรที่ซับซ้อนก็ต้องเพิ่มค่านี้เลยครับ
# Most web applications should use the formula below, because their  # queries often require no work_mem.  # work_mem = ( AvRAM / max_connections ) ROUND DOWN to 2^x # work_mem = 2MB  # for 2GB server with 700 connections    # Formula for most BI/DW applications, or others running many complex # queries: # work_mem = ( AvRAM / ( 2 * max_connections ) ) ROUND DOWN to 2^x # work_mem = 128MB   # DW server with 32GB RAM and 40 connections 
ในส่วนตัวแล้ว กว่าจะปรับค่านี้ลงตัวก็ต้องลองหลาย ๆ รอบเหมือนกัน บางทีดูรูปแล้วน่าจะเข้าใจมากขึ้น ref: http://momjian.us/main/presentations.html