Planet TLWG

Syndicate content
Planet TLWG - http://linux.thai.net/planet
Updated: 1 hour 59 min ago

Neutron: rlm_raw - FreeRADIUS module

24 February, 2017 - 14:59

เรื่องนี้ เกี่ยวข้องกับ FreeRADIUS [1] ซึ่งคนที่เคยติดตั้ง และใช้งาน จะรู้ว่า FreeRADIUS จะมีฝั่ง Server และ Client โดยทั้งสองฝั่งจะถือ กุญแจ (Shared Secret) เดียวกัน โดยที่ Server จะใช้ IP Address ของ Client ในการเลือก กุญแจ ออกมาเทียบ

ปัญหาที่เกิดขึ้นคือ การใช้ FreeRADIUS เป็น Server ให้กับ Client ที่มี IP ไม่แน่นอน อย่างเช่น พวกที่มาจาก xDSL, FTTx เราจะไม่สามารถกำหนด Shared Secret ให้กับ Client นั้น ๆ ได้ นอกจากทุก Client จะถือกุญแจเดียวกัน ร่วมกันหลาย ๆ ราย

การใช้กุญแจร่วมกัน ก็อาจจะเป็นทางออก แต่ผมหาข้อมูลไปต่อ ว่าพอจะมีวิธีอื่น ๆ ที่รัดกุมกว่านี้ไหม ก็ไปเจอ [2] ที่พูดถึง rlm_raw และ dynamic_clients ซึ่งเราสามารถที่จะเอาข้อมูลจาก attribute ที่ client ส่งมา เพื่อไปใช้ประกอบกับการเลือก กุญแจ ออกมาเทียบได้ แต่ทว่า rlm_raw (original) ค่อนข้างเก่า และดึงมาใช้ตรง ๆ กับ FreeRADIUS 3.0.x ไม่ได้

ผมจึงเขียน rlm_raw [3] ขึ้นมาใหม่ โดยดู original เป็นแนวทาง และปรับมาใช้ libradius ซึ่งทำให้ code ที่เขียนใหม่ สะอาด และกระชับ กว่า code เดิมมาก

จาก ตัวอย่าง ใน README จะเห็นได้ว่า ผมสามารถ ที่จะใช้ค่า จาก attribute "NAS-Identifier" เพื่อไปเลือก secret ออกมาจาก redis server เพื่อมาตั้งค่า Client ใหม่ให้ FreeRADIUS ได้

Happy Hacking!

[1] http://freeradius.org/
[2] http://jakehe.blogspot.com/2014/07/freeradius-installation.html
[3] https://github.com/neutronth/rlm_raw

LookHin: การดักจับข้อมูลที่วิ่งเข้าออกบน HTTP/HTTPS จากแอพในมือถือ Android โดยใช้ Burp Suite

22 February, 2017 - 22:14

บทความนี้จะแสดงตัวอย่างการดักจับข้อมูลจากแอพในมือถือ Android ที่รับส่งไปยังเซิฟเวอร์ทั้งบน HTTP และ HTTPS โดยเราจะทดสอบกับแอพของไปรษณีย์ที่ใช้สำหรับตรวจสอบสถานะการส่งพัสดุ Thailand Post Track & Trace เพื่อให้เห็นว่ามีการส่งข้อมูลอะไรออกไปที่เซิฟเวอร์บ้าง โดยในการทดลองนี้จะทำกับแอพที่ใช้ certificate ของระบบเท่านั้น ส่วนแอพอย่างของ facebook หรือ instagram เขาจะมี certificate ของตัวเองที่ฝั่งมากับแอพทำให้เราไม่สามารถหลอกโปรแกรมได้ หรืออาจจะยืนยัน CA ว่าเป็น CA จริงหรือไม่ผ่านทาง DNS อีกที (ผมเข้าใจว่าอย่างนั้นนะ อันนี้ไม่แน่ใจ เดียวผมไปหาข้อมูลเพิ่มเติมมาก่อน)

ในการทดลองการดักจับข้อมูลครั้งนี้ เราจะให้ทั้งคอมฯ และมือถือต่ออยู่ใน Wi-Fi เน็ทเวิร์คเดียวกัน โดยเราจะใช้ Burp Suite Free Edition ซึ่งสามารถหาดาวน์โหลดได้จาก Burp Suite Free Edition เป็นโปรแกรมที่ทำหน้าที่เป็น proxy แต่ผมไม่ลงวิธีการติดตั้งนะครับตัวใครตัวมัน

หลังจากติดตั้งเรียบร้อยแล้ว ให้เปิดโปรแกรม Burp Suite Free Edition และเข้าไปที่แท็บ Proxy -› Options และเลือก Add เพื่อตั้ง proxy ใหม่

ทำการกำหนด Bind to port เป็น 8089 (ปกติก็คงเป็น 8080 แต่พอดีผมใช้มันไปทำอย่างอื่นแล้ว) และเลือก Bind to address เป็น All interfaces เมื่อใส่ค่าทุกอย่างเรียบร้อยก็คลิก OK

Windows Firewall จะขึ้นมาถามยืนยันการใช้งานพอร์ทให้กด Allow access

ถ้าในช่อง Running ในส่วนของ proxy ที่เราสร้างไว้ยังไม่ถูกติ๊กเป็นเครื่องหมายถูก ก็ติ๊กให้มันทำงานด้วยครับ

และในแท็บ Intercept ให้เลือก Intercept เป็น Off

จากนั้นมาที่มือถือ Android โดยให้เข้าไปที่ Setting -› Wi-Fi กดค้างที่ Wi-Fi ที่เราต่อเอาไว้แล้วเลือก Modify network

เลือก Show Advanceed options ติ๊กเลือก Show advance options และเลือก Proxy เป็น Manual และใส่ค่าต่างๆ ดังนี้

Proxy hostname = ให้ใส่ IP ของเครื่องคอมฯ ที่เราติดตั้ง Burp Suite ไว้
Proxy port = ใส่หมายเลข port ที่เรากำหนดไว้ใน Burp Suite

จากนั้นกด Connect

ขั้นตอนถัดไปคือการติดตั้ง CA Certificate ของ Burp Suite ลงในเครื่อง Android ให้เราพิมพ์ URL http://burp บนบราวเซอร์ของ Android และคลิกที่ปุ่ม CA Certificate เพื่อทำการดาวน์โหลด เมื่อทำการดาวน์โหลดมาแล้วจะได้ไฟล์ชื่อ cacert.der ให้ทำการเปลี่ยนนามสกุลของไฟล์เป็น cacert.cer

ทำการติดตั้ง CA Certificate โดยเข้าไปที่ Setting -› Advanced settings -› Security และเลือก Install from SD card

เลืกไฟล์ cacert.cer และทำการตั้งชื่อ Cartificate name

ที่หน้า Setting -› Advanced settings -› Security คลิกที่แท็บ Trusted credentials และเลือกแท็บ User จะเห็นว่ามี CA Certificate ใหม่ของเราติดตั้งไว้แล้ว เป็นอันเสร็จเรียบร้อย

ต่อไปมาเริ่มทำการทดสอบกันเลยครับ ว่ามันสามารถดักข้อมูลที่วิ่งผ่าน HTTP/HTTPS ได้จริงไหม โดยให้เปิดบราวเซอร์และพิมพ์ url ที่เป็น HTTPS ลงไป ในตัวอย่างก็เทสจากเว็บผมเองนี้หละ จะเห็นว่า HTTPS ก็ยังเป็นสีเขียวอยู่

กลับมาดูที่หน้า Burp Suite ในแท็บ HTTP history จะเห็นว่ามีข้อมูลที่วิ่งไปยังเว็บของเราแล้ว

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

กลับมาดูที่หน้า HTTP history จะเห็นว่ามีข้อมูลวิ่งที่ยังเซิฟเวอร์ของไปรษณีย์ไทยแล้วครับ (อ้าว มี username กับ password ติดมาด้วย อันนี้ไม่ได้ตั้งใจ อยู่นอกเหนือจากที่ผมคิดไว้ ฮาาา)

Kitt: Intel® Optimized LINPACK Benchmark on Debian and Ubuntu

21 February, 2017 - 04:43
Got a chance to grab 8 dedicated servers. All of them are identical configuration. Intel Xeon E5-2660 2.20 GHz – 8 Core / 16 Threads 16GB (DDR3) Memory 240GB (SSD) Storage 1 Gbps Network Port And I put Debian on 2 of them and Ubuntu 2 of them. Since I use these servers for computation, I tested … Continue reading Intel® Optimized LINPACK Benchmark on Debian and Ubuntu →

Kitt: CPU overloaded by kidle_inject ?

21 February, 2017 - 04:42
As it’s named, kidle_inject is a process to inject idleness to processors. On a good day, this will keep idle your processors, lower processor temperature, and save your battery. On a bad day, it will consume your processor somewhat like 50%+ on all cores, slow down your laptop, and drain your battery. But, you can … Continue reading CPU overloaded by kidle_inject ? →

LookHin: การดาวน์โหลดวิดีโอจาก youtube, udemy, facebook โดยใช้ youtube-dl และ ffmpeg

14 February, 2017 - 19:18

เรื่องนี้สุ่มเสี่ยงที่จะผิดกฏหมาย ถึงแม้จะนำมาใช้งานส่วนตัวผมก็ไม่แน่ใจนัก แต่อย่างน้อยเรามาตกลงกันก่อนว่าเราจะดาวน์โหลดแค่งานที่เป็นสาธารณะ และศึกษาการใช้งานทูลนี้เท่านั้น (ตัดความรับผิดชอบเรียบร้อย) บทความนี้จะแสดงตัวอย่างการดาวน์โหลดวิดีโอจากเว็บต่างๆ อย่างเช่น youtube, udemy, facebook นะครับ โดยเราจะใช้โปรแกรม youtube-dl ในการดาวน์โหลด และใช้ ffmpeg ในการแปลงฟอร์แมตของไฟล์ จริงๆ ตัว youtube-dl มันก็มีให้ใส่พารามิเตอร์ให้เลือกฟอร์แมตของไฟล์นะครับ แต่สุดท้ายมันก็ไปเรียกใช้ ffmpeg ต่ออยู่ดี ซึ้งขั้นตอนในการแปลงฟอร์แมตเนี้ยก็ใช้เวลานานพอสมควร งั้นผมเลยแยกขั้นตอนการดาวน์โหลดและการแปลงฟอร์แมตของไฟล์วิดีโอออกจากกัน โดยเริ่มจากดาวน์โหลดวิดีโอมาก่อน จากนั้นค่อยมาทำการแปลงฟอร์แมตของไฟล์อีกที

ในขั้นตอนการติดตั้งจะแนะนำเฉพาะบน Windows เท่านั้นนะครับ สำหรับผู้ที่ใช้ Linux น่าจะมีพื้นฐานมากกว่าอยู่แล้ว และขั้นตอนการติดตั้งก็ไม่ยากนักคิดว่าคงทำกันได้หมด

ติดตั้ง youtube-dl โดยให้เข้าไปดาวน์โหลดที่ https://rg3.github.io/youtube-dl/ ให้คลิกไปที่เมนู Download และเลือก youtube-dl.exe หลังจากดาวน์โหลด ให้นำไปไว้ที่ c:\youtube-dl\

ติดตั้ง FFmpeg โดยเข้าไปที่ https://ffmpeg.org/download.html และเลือก Windows Packages จะมีลิงค์ไปหน้าดาวน์โหลดสำหรับ Windows ที่ https://ffmpeg.zeranoe.com/builds/ เมื่อดาวน์โหลดมาแล้วให้ unzip และนำไปไว้ที่ c:\ffmpeg\

จากนั้นทำการคอนฟิก Enviroment Variable Path ของ windows โดยให้เข้าไปที่ Control Panel -› System and Security -› System -› Advanced system Setting และเลือกที่ Enviroment Variables

ในส่วนของ System variables ให้เลือกไปที่ Path และเลือก Edit

ทำการเพิ่ม path ของ youtube-dl และ ffmpeg เข้าไปดังรูป

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

1 2 youtube-dl --version ffmpeg -version

และก่อนใช้งานทุกครั้งเราควรสั่ง youtube-dl -U เพื่อทำการ update โปรแกรมให้เป็น version ใหม่สุดอยู่เสมอ

สำหรับการดาวน์โหลดวิดีโอจาก youtube เราสามารถโหลดได้ทั้งแบบเป็น playlist และที่เป็นวิดีโอเดี่ยวๆ โดยสามารถใช้คำสั่งได้ดังต่อไปนี้

แบบเป็น playlist

1 youtube-dl --no-check-certificate --ignore-errors "https://www.youtube.com/playlist?list=PL6B3937A5D230E335"

แบบแยกเป็นรายวิดีโอ

1 youtube-dl --no-check-certificate "https://www.youtube.com/watch?v=YE7VzlLtp-4"

สำหรับ facebook ก็สามารถโหลดได้เช่นกันโดยใช้คำสั่งดังต่อไปนี้

1 youtube-dl --no-check-certificate "https://www.facebook.com/DevExp/videos/1378097708883662/"

และสำหรับวิดีโอที่เราซื้อคอร์สออนไลน์ไว้บน udemy เราสามารถโหลดทั้งคอร์สมาได้ โดยใช้คำสั่งดังต่อไปนี้

1 youtube-dl -u username -p password -o "%(chapter_number)s-%(chapter)s/%(autonumber)s-%(title)s.%(ext)s" "https://www.udemy.com/java-tutorial/"

ในกรณีที่ดาวน์โหลดวิดีโอลงมาแล้ว ไฟล์ที่ได้อาจจะเป็นไฟล์ .mkv หรือนามสกุลอื่นๆ เราสามารถทำการแปลงฟอร์แมตของไฟล์ได้โดยใช้ ffmpeg โดยให้สร้างโฟลเดอร์ใหม่ขึ้นมาก่อน ในที่นี้ผมจะตั้งชื่อโฟลเดอร์ว่า new-mp4 เอาไว้เก็บไฟล์ที่ได้จากการแปลง และใช้คำสั่งสำหรับการแปลงเป็น mp4 ดังนี้

1 ffmpeg -i old-video-file.mkv -vcodec libx264 -profile:v high -acodec aac ./new-mp4/new-video-file.mp4

หรือหากว่าต้องการแปลงทั้งโฟลเดอร์ให้ใช้คำสังดังต่อไปนี้

1 FOR /F "tokens=*" %G IN ('dir /b *') DO ffmpeg -i "%G" -vcodec libx264 -profile:v high -acodec aac "./new-mp4/%~nG.mp4"

อ้างอิง: https://github.com/rg3/youtube-dl/blob/master/README.md

LookHin: การเขียนโปรแกรมเพื่อวิเคราะห์รูปภาพโดยใช้ Google Cloud Vision API

9 February, 2017 - 23:52

Google Cloud Vision สามารถวิเคราะห์ภาพได้ 6 รูปแบบคือ Label, Text, Face, Landmark, Logo, Image Properties ขั้นตอนการวิเคราะห์คือเราต้องทำการ อัพโหลดภาพขึ้นไปที่ Cloud Vision API จากนั้นเราจะได้ค่ากลับมาเป็น JSON ง่ายมากบอกเลย! เราอาจจะเอาความรู้จากบทความนี้มาทำแอพเล่นก็ได้ เช่นว่า ให้ผู้เข้าร่วมกิจกรรมทำการอัพโหลดรูปขึ้นมา และให้ระบบตรวจสอบว่าเป็นภาพอะไร แล้วเอาค่าที่ได้มาทำเป็นแคปชั่นหรือแฮชแทก แล้วอัพโหลดรูปนั้นขึ้นไปที่ Instagram (ดูวิธีการได้จากบทความที่แล้ว) อะไรประมาณนั้น แล้วแต่จะจินตนาการเช่นเคย

ในการใช้งานแบบฟรีเราสามารถอัพโหลดได้ 4MB ต่อภาพ และใช้งานได้ฟรี 1,000 หน่วยต่อเดือน (หน่วยในทีนี้ผมเข้าใจว่าหมายถึงจำนวนการร้องขอการตรวจสอบ เช่นถ้า 1 ภาพเราต้องการให้ตรวจสอบทั้ง Text และ Landmark ก็จะนับเป็น 2 หน่วย) ถ้ามากกว่านั้นก็ต้องเสียตังค์ (ก็สมเหตุสมผล ใช้มากก็ต้องใช้เงินแก้ปัญหาไป)

ขั้นตอนการสมัครเข้าใช้งาน Google Cloud Vision API ให้เข้าไปที่ Cloud Platform Console และคลิกที่ปุ่ม CREATE PROJECT

ตั้งชื่อโปรเจคและใส่ข้อมูลต่างๆ ให้เรียบร้อย

จากนั้นทำการเปิดใช้งาน Cloud Vision API โดยคลิกที่ลิงค์นี้และเลือกโปรเจคที่เราสร้างไว้เมื่อสักครู่ Enable Cloud Vision API

ขั้นตอนถัดไปให้สร้าง API Key โดยให้คลิกเข้าไปที่เมนูรูปแฮมเบอร์เกอร์ด้านซ้ายมือและเลือกไปที่ API Manager และคลิกไปที่เมนู Credentials จากนั้นให้ทำการคลิกที่ Create Credentials และเลือกเป็น API Key

หลังจากนั้นเราจะได้ API Key มาชุดหนึ่ง ให้กด RESTRICT KEY และก็กด Save ในหน้าถัดไปเลยครับ

หลังจากได้ API Key มาแล้ว เราก็มาถึงขั้นตอนการเขียนโปรแกรมหละ ให้ดาวน์โหลดตัวอย่างรูปภาพและโค้ดที่ผมเตรียมไว้ลงไปก่อนครับ google-cloud-vision-api.zip (รูปตัวอย่างผมขโมยมาจากเน็ท ฮาา) เมื่อโหลดมาแล้วจะเห็นไฟล์ google-cloud-vision.php อันนี้เป็นตัวอย่างโค้ดที่ผมเตรียมไว้ให้ ให้ทำการเปลี่ยน API_KEY เป็นของตัวเองนะครับ

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 <?php   // Google Cloud Vision API $strUrl = "https://vision.googleapis.com/v1/images:annotate?key=API_KEY";   $arrHeader = array(); $arrHeader[] = "Content-Type: application/json";     $objImgData = file_get_contents("test.jpg"); $objImgBase64 = base64_encode($objImgData);   $arrPostData = array(); $arrPostData['requests'][0]['image']['content'] = $objImgBase64;   $arrPostData['requests'][0]['features'][0]['type'] = "LABEL_DETECTION"; $arrPostData['requests'][0]['features'][0]['maxResults'] = "5";   $arrPostData['requests'][0]['features'][1]['type'] = "FACE_DETECTION"; $arrPostData['requests'][0]['features'][1]['maxResults'] = "5";   $arrPostData['requests'][0]['features'][2]['type'] = "TEXT_DETECTION"; $arrPostData['requests'][0]['features'][2]['maxResults'] = "5";   $arrPostData['requests'][0]['features'][3]['type'] = "LANDMARK_DETECTION"; $arrPostData['requests'][0]['features'][3]['maxResults'] = "5";   $arrPostData['requests'][0]['features'][4]['type'] = "LOGO_DETECTION"; $arrPostData['requests'][0]['features'][4]['maxResults'] = "5";   $arrPostData['requests'][0]['features'][5]['type'] = "IMAGE_PROPERTIES"; $arrPostData['requests'][0]['features'][5]['maxResults'] = "5";     $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,$strUrl); curl_setopt($ch, CURLOPT_HTTPHEADER, $arrHeader); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($arrPostData)); curl_setopt($ch, CURLOPT_RETURNTRANSFER,true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $result = curl_exec($ch); curl_close ($ch);   print $result;   ?>

จากนั้นสั่งรันโค้ด เราจะได้ค่าผลลัพธ์กลับมาเป็น JSON เป็นอันเรียบร้อย

อ้างอิง : https://cloud.google.com/vision/docs/

LookHin: การอัพโหลดรูปภาพและวิดีโอขึ้น Instagram โดยใช้ PHP

9 February, 2017 - 00:14

ปกติแล้ว Instagram ไม่มี API ให้เราทำการอัพโหลดรูปภาพและวิดีโอขึ้นหรอกนะครับ ตัว Official API ของทาง Instagram ทำได้แค่ดึงข้อมูลรูปภาพและรายละเอียดที่เราอัพขึ้นไปแล้วเท่านั้น หากเราต้องการจะทำการอัพโหลดรูปหรือวิดีโอขึ้นไป เราต้องทำการ reverse engineering ต้องแกะดูเองว่าข้อมูลจากแอพที่ส่งไปที่เซิฟเวอร์มันรับส่งกันยังไง ถ้าเป็นอย่างแอพทั่วๆไป ที่เขาไม่ได้เน้นเรื่องความปลอดภัยมาก เราก็อาจจะใช้วิธีดักแพคเก็จของข้อมูล และเขียนโปรแกรมจำลองวิธีการรับส่งข้อมูลขึ้นมาเอง เพื่อทำการโพสข้อมูลไปที่เซิฟเวอร์ปลายทางก็ได้

แต่สำหรับกรณีของ instagram นี้ยากหน่อย เพราะเขาทำการ encrypt ข้อมูลด้วย secret key ที่อยู่ภายในแอพก่อนแล้วค่อยทำการส่งข้อมูลนั้นออกมา การหา secret key และวิธีเข้ารหัสอะไรนี้ผมเองก็ทำไม่เป็นหรอกนะ แต่พอดีว่าผมไปเห็นโค้ดของคนอื่นใน Github ที่เขาแกะข้อมูลทุกอย่างไว้หมดแล้ว แต่โค้ดเขาเยอะมาก มากเกินความต้องการของเรา ผมเลยเอาโค้ดของเขามารีไรท์ใหม่ และตัดให้เหลือแค่ส่วนที่ตัวเองต้องการใช้งาน นั้นคืออัพโหลดรูปปละวิดีโอ การแกะโค้ดคนอื่นก็ดีครับได้ทบทวนความรู้ตัวเองไปด้วย ถ้าใครสนใจอยากดูโค้ดของเขาก็เข้าไปดูได้ครับ โค้ดเขาอยู่ที่นี้ Instagram’s private API

บทความนี้สั้นๆ นะครับ แค่จะโชว์โค้ด และเดโมการอัพโหลดรูปและวิดีโอขึ้น instagram ให้ดู ส่วนการทำงานของโค้ดว่ามันทำงานยังไงก็ไปอ่านเอาเองครับ ไม่น่ายากเกินความพยายาม โดยคลาสที่ผมเขียนขึ้นมาใหม่จะไม่มีส่วนของการ crop รูปภาพ และแปลง format ของวิดีโอนะครับ ให้ไปทำกันเอาเอง โดยวิดีโอที่ผมทดสอบจะเป็น MP4 (H264)

มาเริ่มเลย อย่างแรกเข้าไปเอาซอสโค้ดและตัวอย่างทั้งหมดมาจาก Github ที่ผมแก้ไขโค้ดและเอาขึ้นไว้ที่ https://github.com/LookHin/instagram-photo-video-upload-api

เมื่อโหลดมาหมดแล้วจะเห็นว่ามีไฟล์ทั้งหมดอยู่ 5 ไฟล์ดังนี้

1 2 3 4 5 example.php //ตัวอย่างโปรแกรม instagram-photo-video-upload-api.class.php //คลาสที่เรียกใช้งาน square-image.jpg //ตัวอย่างรูปภาพ ขอให้เป็นภาพสี่เหลี่ยมจัตุรัสนะครับ square-thumb.jpg //ตัวอย่างรูปภาพ thumbnail ที่จะใช้กับวิดีโอ ขอให้เป็นภาพสี่เหลี่ยมจัตุรัสเช่นกัน test-video.mp4 //ตัวอย่างวิดีโอ เป็นไฟล์ MP4 (H264)

เปิดไฟล์ example.php ขึ้นมา จะเห็นมีอยู่แค่ไม่กี่บรรทัด คือใช้เท่านี้จริงๆ ส่วนการทำงานเบื่องหลังจะอยู่ในไฟล์ instagram-photo-video-upload-api.class.php ทั้งหมด อย่างแรกเลยให้ทำการแก้ไข YOUR_IG_USERNAME และ YOUR_IG_PASSWORD เป็น username และ password ที่เราใช้ในการ login เข้า instagram ถ้าได้แก้ไขเรียบร้อยแล้วก็สั่งรันได้เลยครับ (ผมทดสอบบน PHP 5.6 และ PHP 7)

1 2 3 4 5 6 7 8 9 10 11 include_once("instagram-photo-video-upload-api.class.php");   // Upload Photo $obj = new InstagramUpload(); $obj->Login("YOUR_IG_USERNAME", "YOUR_IG_PASSWORD"); $obj->UploadPhoto("square-image.jpg", "Test Upload Photo From PHP");   // Upload Video $obj = new InstagramUpload(); $obj->Login("YOUR_IG_USERNAME", "YOUR_IG_PASSWORD"); $obj->UploadVideo("test-video.mp4", "square-thumb.jpg", "Test Upload Video From PHP");

เมื่อสั่งรันแล้ว เราจะได้รูปภาพและวิดีโอตัวอย่างไปขึ้นที่ Instagram ของเราแล้วครับ

Thep: Dell Inspiron 5468 with Debian Power

8 February, 2017 - 15:43

TL;DR แล็ปท็อปใหม่ของผม Dell Inspiron 5468 ใช้ CPU Intel Core i5-7200U, RAM 4 GB และ SSD 256 GB ติดตั้ง Ubuntu มาพร้อม นำมาติดตั้ง Debian Sid แบบ dual boot ใช้การได้ดี ยกเว้นมีปัญหา Wi-Fi, ไม่ชินกับปุ่ม PgUp/PgDn/Home/End, และเสียงไม่ออกหูฟังโดยอัตโนมัติเมื่อเสียบ

หลังจากที่ใช้แล็ปท็อปเก่ามาได้ร่วม 6 ปี จนเริ่มออกอาการหลายอย่าง เช่น ร้อนจนดับบ่อย เล่นวิดีโอได้ไม่เกิน 5 นาที เรื่อง video call ไม่ต้องพูดถึงเลย และล่าสุดคือปุ่ม power เริ่มรวน เปิดติดบ้างไม่ติดบ้าง ต้องแก้ปัญหาด้วยวิธีแปลก ๆ เช่น ลองถอดแบตแล้วเสียบปลั๊กไปเรื่อย ๆ จนกว่าจะกดติด ก็คิดว่าคงได้เวลาซื้อแล็ปท็อปใหม่เสียที (ด้วยแรงสนับสนุนของคุณภรรยา)

Spec ที่ต้องการ
  • CPU เพื่องานคอมไพล์โปรแกรมและการเปิดหน้าต่างหลายบานทำงานพร้อมกันเยอะหน่อย ผมจึงคิดว่าผมต้องการ Core i5 หรือ i7 เพื่อประโยชน์จาก Turbo Boost (ลิงก์ที่น่าสนใจ: Best Intel Processor: Core i3, i5, i7 explained)
  • การ์ดจอ ผมไม่ต้องการการ์ดจอที่แรงนัก ได้ Intel on-board ได้ยิ่งดี เพราะไม่ต้องไปวุ่นวายหาไดรเวอร์ที่ไม่โอเพนซอร์ส แต่พบว่าเครื่องรุ่นใหม่ ๆ โดยเฉพาะ CPU Core i5, i7 มักจะมาพร้อมการ์ดจอแยก (คงเพื่อให้ประสิทธิภาพกราฟิกส์สมน้ำสมเนื้อกับความแรงของ CPU) การเจาะจง Intel on-board จะจำกัดตัวเลือกลงมากจนหาซื้อไม่ได้เลยจากร้านใกล้บ้าน ถ้าเช่นนั้น AMD ก็เป็นทางเลือกที่น่าสนใจ เพราะทำให้ราคาถูกลง โดยประสิทธิภาพก็ไม่ได้แย่เกินไปนัก (Test 1, Test 2) และยังเป็นมิตรกับโอเพนซอร์สกว่า NVIDIA อีกด้วย
  • จอภาพ ต้องการจอ 14" เพื่อความสะดวกในการพกพา (15" เทอะทะเกินไป) แต่ไม่เล็กจนเกินไป (11", 13" เนื้อที่ทำงานน้อยเกินไป) ไม่เกี่ยงชนิดของจอ ไม่จำเป็นต้อง IPS
  • OS อาจจะดูแปลกสำหรับผู้ใช้ทั่วไป แต่ผมจะให้ความสนใจกับแล็ปท็อปรุ่นที่ไม่มีไลเซนส์วินโดวส์เป็นพิเศษ เพราะผมไม่ใช้วินโดวส์อยู่แล้ว ได้ไลเซนส์มาก็เปลืองเงินเฉย ๆ ยิ่งถ้าเป็นรุ่นที่มาพร้อมลินุกซ์เลย (เช่น Ubuntu) ยิ่งน่าสนใจ เพราะเท่ากับลดความเสี่ยงที่จะใช้กับลินุกซ์ไม่ได้ลงไปเยอะ แต่รุ่นที่ลง DOS มาให้ก็สนใจเป็นอันดับรองลงไปเช่นกัน

สี่อย่างนี้ ผมใช้เป็นตัว screen เบื้องต้น แล้วค่อยไปเช็กอย่างอื่นเป็นรายตัวไป เช่น RAM, ฮาร์ดดิสก์, พอร์ตต่าง ๆ ฯลฯ

Dell Inspiron 5468

ตัดฉับมาตอนที่ผมหิ้วเครื่องออกจากร้าน มันคือ Dell Inspiron 5468 โดยมี spec ดังนี้:

  • CPU: Intel Core i5-7200U (3 MB L3 Cache, 2.50 GHz)
  • Graphic card: AMD Radeon R7 M440 (2 GB DDR3)
  • Display: 14" HD (1366x768) anti-glare
  • Memory: 4 GB DDR4
  • Hard Drive: 256 GB SATA SSD (INTEL SSDSC2KF256H6)
  • OS Bundle: Ubuntu 16.04 LTS

รายละเอียดอื่น ๆ ดูได้จาก Dell แต่ในรุ่นนี้ มี CPU ให้เลือกสองแบบ คือรุ่น Core i5 และรุ่น Core i7 ราคาต่างกันอยู่ 3,000 บาท โดยรุ่น Core i5 นั้น ได้ SSD ขนาด 256 GB ในขณะที่รุ่น Core i7 ได้ HDD ขนาด 1 TB (5400 RPM) ผมเลือกรุ่น Core i5 เพราะ SSD เลยทีเดียว

รายละเอียดอื่น ๆ

  • DVD Writer: HL-DT-ST DVD+-RW GU90N
  • Wi-Fi: Qualcomm Atheros QCA9377 802.11ac
  • Ethernet: Realtek RTL8101/2/6E PCIe Gigabit Ethernet
  • Bluetooth: Qualcomm Atheros (ID 0cf3:e009)
  • SD Card Reader: Realtek RTS5129 (ID 0bda:0129)
  • Webcam: Realtek Integrated Webcam (ID 0bda:5684)

dump ข้อมูลที่เป็นประโยชน์สำหรับผู้ที่จะซื้อมาใช้กับลินุกซ์ดังนี้ (จัดบรรทัด output เล็กน้อยเพื่อให้อ่านง่าย):

$ lscpu

Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 4 On-line CPU(s) list: 0-3 Thread(s) per core: 2 Core(s) per socket: 2 Socket(s): 1 NUMA node(s): 1 Vendor ID: GenuineIntel CPU family: 6 Model: 142 Model name: Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz Stepping: 9 CPU MHz: 797.772 CPU max MHz: 3100.0000 CPU min MHz: 400.0000 BogoMIPS: 5424.00 Virtualization: VT-x L1d cache: 32K L1i cache: 32K L2 cache: 256K L3 cache: 3072K NUMA node0 CPU(s): 0-3 Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp

$ lspci

00:00.0 Host bridge: Intel Corporation Device 5904 (rev 02) 00:02.0 VGA compatible controller: Intel Corporation Device 5916 (rev 02) 00:14.0 USB controller: Intel Corporation Sunrise Point-LP USB 3.0 xHCI Controller (rev 21) 00:14.2 Signal processing controller: Intel Corporation Sunrise Point-LP Thermal subsystem (rev 21) 00:15.0 Signal processing controller: Intel Corporation Sunrise Point-LP Serial IO I2C Controller #0 (rev 21) 00:15.1 Signal processing controller: Intel Corporation Sunrise Point-LP Serial IO I2C Controller #1 (rev 21) 00:16.0 Communication controller: Intel Corporation Sunrise Point-LP CSME HECI #1 (rev 21) 00:17.0 SATA controller: Intel Corporation Sunrise Point-LP SATA Controller [AHCI mode] (rev 21) 00:1c.0 PCI bridge: Intel Corporation Device 9d10 (rev f1) 00:1c.4 PCI bridge: Intel Corporation Sunrise Point-LP PCI Express Root Port #5 (rev f1) 00:1c.5 PCI bridge: Intel Corporation Sunrise Point-LP PCI Express Root Port #6 (rev f1) 00:1f.0 ISA bridge: Intel Corporation Device 9d58 (rev 21) 00:1f.2 Memory controller: Intel Corporation Sunrise Point-LP PMC (rev 21) 00:1f.3 Audio device: Intel Corporation Device 9d71 (rev 21) 00:1f.4 SMBus: Intel Corporation Sunrise Point-LP SMBus (rev 21) 01:00.0 Display controller: Advanced Micro Devices, Inc. [AMD/ATI] Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] (rev 83) 02:00.0 Network controller: Qualcomm Atheros QCA9377 802.11ac Wireless Network Adapter (rev 31) 03:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8101/2/6E PCI Express Fast/Gigabit Ethernet controller (rev 07)

$ lsusb

Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 007: ID 0cf3:e009 Atheros Communications, Inc. Bus 001 Device 005: ID 0bda:0129 Realtek Semiconductor Corp. RTS5129 Card Reader Controller Bus 001 Device 003: ID 0bda:5684 Realtek Semiconductor Corp. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

$ lsscsi

[0:0:0:0] disk ATA INTEL SSDSC2KF25 D07N /dev/sda [1:0:0:0] cd/dvd HL-DT-ST DVD+-RW GU90N A1C1 /dev/sr0

Ubuntu hardware certification ระบุว่า Ubuntu ที่ติดตั้งมาจากโรงงานมีปัญหา hibernate ไม่ได้ และ Bluetooth 4.0 HID ไม่ทำงาน แต่ก็รายงาน wireless adaptor เป็น Intel Wireless 3165 ในขณะที่ในเครื่องจริง ๆ เป็น Qualcomm Atheros QCA9377

เตรียมพาร์ทิชัน

เครื่องมาพร้อมกับ Ubuntu 16.04 LTS ติดตั้งไว้ โดยแบ่งพาร์ทิชันดังนี้:

$ fdisk -l /dev/sda

Disk /dev/sda: 238.5 GiB, 256060514304 bytes, 500118192 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: gpt Device Start End Sectors Size Type /dev/sda1 2048 1026047 1024000 500M EFI System /dev/sda2 1026048 7317503 6291456 3G Microsoft basic data /dev/sda3 7317504 483756031 476438528 227.2G Linux filesystem /dev/sda4 483756032 500117503 16361472 7.8G Linux swap

สองพาร์ทิชันแรก (sda1, sda2) ใช้สำหรับ UEFI boot พาร์ทิชันที่สาม (sda3) เป็น Ubuntu 16.04 LTS โดยเมานท์กับ / เพียงจุดเดียว และที่ท้ายดิสก์เป็นพาร์ทิชัน swap 7.8 GB (ประมาณสองเท่าของ RAM 4 GB)

หากจะติดตั้ง Debian โดยลบ sda3 ทิ้งไปเลยก็ย่อมได้ แต่เห็นว่า Ubuntu image ที่ติดตั้งมาจากโรงงานอาจพอมีประโยชน์สำหรับอ้างอิงอาการต่าง ๆ ที่อาจพบในอนาคต ระหว่าง config จากโรงงานกับที่เราติดตั้งเอง และอาจใช้ลอกการบ้านในกรณีที่มีปัญหากับฮาร์ดแวร์ได้ จึงตัดสินใจว่าจะหดพาร์ทิชัน Ubuntu แล้วสร้างพาร์ทิชันใหม่สำหรับ Debian และ /home

วิธีการที่ใช้คือ:

  1. ดาวน์โหลด Debian Installer จากหน้าโครงการ Debian-installer โดยผมเลือก Current daily snapshot สำหรับ amd64
  2. เขียน installer image โดยเสียบ USB flash drive เปล่า แล้วตรวจหา device file ของมันด้วยคำสั่ง dmesg แล้วไล่หาดูอุปกรณ์ล่าสุดใน log ซึ่งในกรณีของผมมันคือ /dev/sdb จากนั้นก็สั่งเขียน: # dd if=debian-testing-amd64-netinst.iso of=/dev/sdb
  3. เตรียม firmware โดยดาวน์โหลด firmware tarball จาก Debian cdimage มารอไว้เพื่อเขียนลง flash drive โดยจากขั้นตอนที่แล้ว ISO image ที่เขียนลงไปจะทำให้ใน flash drive จะมี 2 partition เกิดขึ้น พาร์ทิชันแรกใช้สำหรับบูต Debian installer และเราจะเขียน firmware ลงในพาร์ทิชันที่สอง โดยอาจจะแตก tarball ทั้งหมดลงไปเลย: # mount /dev/sdb2 /mnt # tar xzf firmware.tar.gz -C /mnt # umount /mnt หรือเลือกเฉพาะที่ต้องใช้สำหรับเครื่องนี้ คือ firmware-atheros และ firmware-realtek: $ tar xzf firmware.tar.gz # su Password: # mount /dev/sdb2 /mnt # cp firmware-atheros*.deb firmware-realtek*.deb /mnt # umount /mnt
  4. บูต Installer โดย disable secure boot เสียก่อน (ผมไม่แน่ใจว่า Debian installer สามารถบูตใน secure mode ได้หรือเปล่า แต่เนื่องจากผมมีเวลาไม่มาก จึงรวบรัดตัดตอน และเครื่อง Dell นี้ก็สามารถปิด secure boot ได้ โดยกด F12 ขณะเปิดเครื่องแล้วเซ็ต boot mode เป็น legacy mode คือ UEFI with secure boot OFF จากนั้นก็เซ็ต boot order ให้บูตจาก USB drive ก่อน internal HDD) เมื่อบูตเข้า Debian installer แล้ว ก็ตอบคำถามไปเรื่อย ๆ จนเสร็จขั้น load installer components แล้วหยุดอยู่แค่นั้น
  5. resize พาร์ทิชัน Ubuntu โดยกด Alt-F2 เพื่อไปที่ console ที่ 2 แล้วกด Enter เพื่อเข้า Busybox shell แล้วเริ่ม resize partition sda3 ตามขั้นตอนที่แนะนำใน หน้านี้ คือ:
    1. check file system # fsck /dev/sda3
    2. ปิด journal เพื่อเปลี่ยนพาร์ทิชัน ext4 ให้เป็น ext2 # tune2fs -o ^has_journal /dev/sda3
    3. check file system อีกครั้งเพื่อจัดระเบียบบล็อคต่าง ๆ # e2fsck -f /dev/sda3
    4. resize file system ใน sda3 # resize2fs /dev/sda3 15G
    5. resize ตัวพาร์ทิชัน sda3 ด้วย fdisk # fdisk /dev/sda โดยขั้นตอนที่ต้องทำคือ:
      1. ลบพาร์ทิชัน sda3 ด้วยคำสั่ง d
      2. เพิ่มพาร์ทิชัน sda3 กลับคืนด้วยขนาดใหม่ ด้วยคำสั่ง n
      3. เขียนตารางพาร์ทิชันลงดิสก์ ด้วยคำสั่ง w
      4. ออกจาก fdisk ด้วยคำสั่ง q

จากนี้ ระบบก็พร้อมแล้วสำหรับติดตั้ง Debian GNU/Linux สามารถกด Alt-F5 เพื่อกลับไป console ติดตั้งเพื่อทำงานต่อได้ หรือจะรีบูตเข้า installer อีกรอบเพื่อความแน่ใจก็ตามแต่

Debian GNU/Linux

เพื่อไม่ให้บล็อกนี้ยาวเกินไป ผมขอข้ามรายละเอียดการติดตั้ง Debian เอาเป็นว่า ผมเลือกติดตั้ง Xfce desktop เครื่องนี้จึงเป็นเครื่องที่ปลอด GNOME ยิ่งกว่าเครื่องก่อนที่อาจจะยังมีแพกเกจของ GNOME ตกค้างอยู่บ้างระหว่างย้ายมา Xfce

การใช้งานนับว่ารวดเร็วปรู๊ดปร๊าดกว่าเครื่องก่อนอย่างมโหฬาร SSD ทำให้อ่าน-เขียนดิสก์ได้เร็วแบบลื่นหัวแตก ความรู้สึกเหมือนสมัยใช้ RAM disk บน DOS ยังไงยังงั้น ใช้ aptitude upgrade/install/remove โปรแกรมได้สนุกสนาน ไม่ต้องรอนาน โหลด Firefox พร้อมประวัติและ bookmark ต่าง ๆ ที่ import มาจากเครื่องเก่าเสร็จภายใน 3 วินาที บ้าไปแล้ว! และเครื่องก็แทบไม่ร้อนเลยแม้จะเล่นวิดีโอยาว ๆ ทำให้พัดลมระบายความร้อนแทบไม่ได้ทำงานเลย นาน ๆ จะได้ยินสักครั้ง เป็นการใช้คอมพิวเตอร์ที่เงียบสนิทจนน่าตกใจ เมื่อเทียบกับเครื่องเก่า

ปัญหาที่พบ

ก่อนที่จะลงรายละเอียดที่เป็นความชอบส่วนตัว ผมขอบันทึกปัญหาที่พบเสียก่อน:

  • Wi-Fi หลุดบ่อยเมื่อใช้กับ access point ที่มีการเปลี่ยน bandwidth เป็นระยะ อ่าน syslog แล้ว พบว่ามีข้อความ firmware crash ซึ่งตรงกับรายงานใน Debian #839662 และ LP #1627474 คงต้องติดตามที่ upstream ว่ามีการแก้ไขอะไรอย่างไรบ้าง
  • แป้นพิมพ์วางปุ่ม PgUp/PgDn/Home/End ไว้ในปุ่มเดียวกับปุ่มลูกศร โดยให้กดปุ่ม Fn เพื่อเลือก ซึ่งการกดปุ่มประกอบเพิ่มอีกปุ่มทำให้ไม่สะดวกอย่างมาก
  • เสียงไม่ออกหูฟังโดยอัตโนมัติเมื่อเสียบ เสียงยังคงออกลำโพงของเครื่องตามปกติ ต้องไปเลือกอุปกรณ์เอาต์พุตใน audio mixer แบบ manual เอา (อาการใน Ubuntu หนักกว่า คือนอกจากเสียงจะไม่ออกหูฟังแล้ว ใน sound config ยังไม่มีรายการของหูฟังให้เลือกเลยด้วย)

ส่วนอื่น ๆ เช่น webcam, bluetooth ยังไม่ได้ทดสอบครับ ไว้ถ้ามีโอกาสค่อยว่ากันอีกที

การปรับแต่งซอฟต์แวร์

หัวข้อนี้เป็นการปรับแต่งซอฟต์แวร์สำหรับให้ตัวผมเองในอนาคตอ่าน ในกรณีที่ต้องเซ็ตเครื่องทำงานเครื่องใหม่

นอกจาก Xfce ปกติแล้ว ผมติดตั้งแพกเกจต่อไปนี้ของ GNOME เพิ่มเติม:

  • gucharmap เพื่อใช้ดู/ป้อนอักขระยูนิโค้ด
  • evince สำหรับเปิดเอกสาร PDF แม้ผมจะใช้ MuPDF เป็นหลัก แต่บางครั้งก็ต้องมี Evince ไว้สำรองเผื่อเหลือเผื่อขาด
  • eog แม้จะซ้ำซ้อนกับ ristretto ของ Xfce เพราะ ristretto ยังไม่สามารถสั่งหมุนภาพ 90 องศาได้ ซึ่งจำเป็นเวลานำเข้ารูปจากกล้องดิจิทัล

รายการปรับแต่งซอฟต์แวร์

  • Console:
    • ตั้งค่าใน /etc/default/keyboard: XKBLAYOUT="us,th" XKBVARIANT=",tis" XKBOPTIONS="grp:alt_shift_toggle,lv3:ralt_switch,terminate:ctrl_alt_bksp,\ grp_led:scroll,ctrl:nocaps" ใช้ผังแป้นพิมพ์ มอก. 820-2538 พร้อม level 3 shift และเปลี่ยนปุ่ม CapsLock ให้เป็น Ctrl (ผมเคยอธิบายเหตุผลไว้ใน blog เก่า)
  • Xfce:
    • โปรแกรม > ตั้งค่า > ปรับละเอียดโปรแกรมจัดการหน้าต่าง:
      • สิ่งอำนวยความสะดวก > ปิดตัวเลือก เรียงหน้าต่างต่อชนโดยอัตโนมัติเมื่อย้ายไปชนขอบหน้าจอ
        ป้องกัน accidental maximization
      • พื้นที่ทำงาน > ปิดตัวเลือก ใช้การกลิ้งลูกกลิ้งเมาส์บนพื้นโต๊ะในการสลับพื้นที่ทำงาน
        ป้องกันความรำคาญจากการกลิ้งลูกกลิ้งเมาส์นอกหน้าต่างโดยบังเอิญ
    • โปรแกรม > ตั้งค่า > โปรแกรมจัดการหน้าต่าง:
      • โฟกัส > ยกเมื่อคลิก > ปิดตัวเลือก ยกหน้าต่างขึ้นเมื่อคลิกภายในหน้าต่างโปรแกรม
        เป็นความสะดวกส่วนตัว ที่บ่อยครั้งอยากดูเนื้อหาหน้าต่างหนึ่งเต็ม ๆ เพื่อใช้ประกอบการป้อนคำสั่งในอีกหน้าต่างหนึ่งที่เผยเฉพาะบริเวณที่ป้อนก็พอแล้ว ถ้าอยากดูเนื้อหาหน้าต่างที่ป้อนข้อความอยู่แบบเต็ม ๆ เมื่อไร ก็ค่อยไปคลิกที่กรอบหน้าต่างเอา
    • แอพเพล็ต สลับพื้นที่ทำงาน:
      • คุณสมบัติ > รูปปรากฏ > จำนวนแถว = 2
        เพื่อจัดวางพื้นที่ทำงานแบบ 2×2
    • โปรแกรม > ตั้งค่า > รูปลักษณ์:
      • สไตล์ = Greybird (จากแพกเกจ greybird-gtk-theme)
        เป็น theme ที่ทำให้วิดเจ็ตของ GTK+ 3 ไม่ใหญ่เทอะทะเหมือน theme มาตรฐาน
  • Vim:
    • install vim เพื่อใช้แทน vim-tiny
    • remove nano (ไม่เคยได้ใช้เลย ในเครื่องก่อน ๆ นั้น ยังประนีประนอมด้วยการเซ็ต vim ให้เป็น default editor แต่ nano ที่เหลือไว้ก็กินเนื้อที่ในระบบเฉย ๆ โดยไม่เคยถูกเรียกใช้เลย)
    • ตั้งค่าใน /etc/vim/vimrc.local: " Disable mouse clicks set mouse-=a vim 8 มาพร้อมกับการรองรับ mouse แม้จะทำงานใน text mode ซึ่งทำให้ตำแหน่งเคอร์เซอร์เปลี่ยนเมื่อมีการ copy/paste ข้ามหน้าต่างด้วยเมาส์ หรือแม้แต่การคลิกในหน้าต่างเพื่อโฟกัส และยิ่งสร้างความสับสนยิ่งขึ้นถ้ายังอยู่ใน insert mode ดังนั้น ปิดมันซะ! " Force syntax highlight syntax on vim มี default config เปลี่ยนไปมาเรื่อง syntax highlight บางรุ่นก็เปิด บางรุ่นก็ปิด ดังนั้น ตัดปัญหาด้วยการระบุสิ่งที่เราต้องการให้ชัดเสีย
    • ตั้งค่าใน ~/.vimrc: set modeline ด้วยเหตุผลด้านความปลอดภัย vim จึงปิดการใช้ modeline ไว้ และไม่แนะนำให้เปิดใช้เมื่อเป็น root แต่ผมใช้ในซอร์สโค้ดเพื่อความสะดวกในการควบคุมสไตล์การร่นย่อหน้า จึงเปิดใช้ในขอบเขตของ user ปกติเท่านั้น ถ้าต้องเปิด text file ที่ไม่น่าเชื่อถือ ควรใช้ less เปิดดูก่อน
สรุป

โดยรวมแล้ว ผมพอใจกับเครื่องใหม่นี้มาก มันทำให้งานผมเสร็จได้เร็วขึ้น โดยปัจจัยหลักคือ SSD ที่ทำให้ไม่ต้องรอ I/O นาน นอกจากนี้ยังพอใจกับความร้อนที่น้อย การรองรับของลินุกซ์ที่เพียงพอต่อความต้องการ มียกเว้นแค่สองเรื่องที่ค่อนข้างร้ายแรง คือ Wi-Fi ที่หลุดบ่อยเมื่อใช้กับ access point ที่มีการเปลี่ยนแบนด์วิดท์เป็นระยะ (กับ access point บางตัวไม่มีปัญหานี้) และปุ่ม Home/End/PgUp/PgDn ที่ต้องกด Fn ร่วมด้วย (external keyboard ช่วยได้ แต่ก็ต้องฝึกใช้ปุ่มแล็ปท็อปให้เคยชินเพื่อความคล่องตัวในการใช้งานนอกสถานที่ด้วย)

LookHin: การเขียนโปรแกรมลงบน Sonoff WiFi Smart Switch (ESP8266)

6 February, 2017 - 07:11

ภายในของ Sonoff WiFi Smart Switch ก็เป็น ESP8266 ที่ต่อกับรีเลย์เพื่อใช้ควบคุมการเปิดปิดของวงจรไฟฟ้า โดยสามารถใช้งานกับไฟบ้านที่แรงดัน 90-250v AC(50/60Hz) รับกระแสได้สูงสุด 10A เพียงพอสำหรับการเอามาใช้สำหรับเปิดปิดหลอดไฟทั่วๆ ไป ราคาประมาณ 280-300 บาท ซึ่งทางผู้ผลิตเขาก็มีแอพชื่อ eWeLink เอาไว้ให้เราโหลดมาใช้ควบคุมตัวสวิตซ์ตัวนี้ได้อยู่แล้วแหละ แต่ว่ามันก็ใช้แค่เปิดปิดกับตั้งเวลาได้เท่านั้น ซึ่งไม่ได้ตรงกับความต้องการของเรา ความต้องการของเราคือต้องการทำให้หลอดไฟจุดทุกในบ้านสามารถควบคุมได้ผ่านระบบควบคุมกลางคือ Raspberry Pi 3 (แต่ในบทความนี้จะพูดถึงแค่การเขียนโปรแกรมลงบน ESP8266 ของ Sonoff WiFi Smart Switch เท่านั้นนะครับ)

หลังจากไปหาซื้อมาแล้วก็แกะกล่อง ใช้ไขขวงดันๆ เดียวมันก็หลุดออกมาครับ (หลุดพร้อมประกัน)

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

1 2 3 4 5 GPIO14 GND TX RX VCC 3.3V

เมื่อบัดกรีขาต่างๆ เรียบร้อยแล้ว ให้ทำการต่อ Sonoff กับ USB To UART เพื่อทำการเขียนโปรแรกมลงไป โดยให้ต่อขาต่างๆ ดังนี้

1 2 3 4 5 [Sonoff] --> [USB To UART] VCC --> VCC (3.3V) RX --> TX TX --> RX GND -->GND

หลังจากต่อวงจรเสร็จเรียบร้อยให้ทำการกดสวิตซ์สีดำค้างเอาไว้ และเสียบสาย USB เข้ากับคอมพิวเตอร์เพื่อทำการโปรแกรม (ต้องกดค้างก่อนเสียบสายด้วยนะครับ สำคัญมากๆ) โดยให้เขียนโค้ดต่างๆ ดังนี้

โดยให้ใส่ SSID และ Password ของ WI-FI ของเราลงไป และเราจะเขียนโปรแรกมให้ฟิกค่า IP ของอุปกรณ์เอาไว้เพื่อความสะดวกในการเรียกใช้งาน (คงไม่สะดวกแน่ๆ ถ้าจะให้มันรับ DHCP เข้ามา) ดาวน์โหลดโค้ดตัวอย่าง

1 2 3 4 5 6 const char* ssid = "WIFI_SSID"; const char* password = "WIFI_PASSWORD";   const IPAddress ip(192, 168, 1, 100); // IP ของอุปกรณ์ตัวนี้ 192.168.1.100 const IPAddress subnet(255, 255, 255, 0); const IPAddress gt(192, 168, 1, 1); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 #include <ESP8266WiFi.h> #include <ESP8266WebServer.h>   const char* ssid = "WIFI_SSID"; const char* password = "WIFI_PASSWORD";   const IPAddress ip(192, 168, 1, 100); const IPAddress subnet(255, 255, 255, 0); const IPAddress gt(192, 168, 1, 1);   const int SwitchPin = 12; // GPIO12 int SwitchValue = HIGH;   ESP8266WebServer server(80);   void handleNotFound(){ //server.send(404, "text/plain", "404 Not Found");   if(SwitchValue == HIGH) { server.send(200, "text/plain", "ON"); }else{ server.send(200, "text/plain", "OFF"); }   delay(1000); }   void setup(void){   // Set Output PIN pinMode(SwitchPin, OUTPUT); digitalWrite(SwitchPin, SwitchValue);   // Connect WiFi WiFi.mode(WIFI_STA); WiFi.config(ip, gt, subnet); WiFi.begin(ssid, password);   // Wait for connection while(WiFi.status() != WL_CONNECTED){ delay(1000); }   server.on("/", [](){ if(SwitchValue == HIGH) { server.send(200, "text/plain", "ON"); }else{ server.send(200, "text/plain", "OFF"); }   delay(1000); });   server.on("/ON", [](){ SwitchValue = HIGH;   server.send(200, "text/plain", "ON"); digitalWrite(SwitchPin, SwitchValue); delay(1000); });   server.on("/OFF", [](){ SwitchValue = LOW;   server.send(200, "text/plain", "OFF"); digitalWrite(SwitchPin, SwitchValue); delay(1000); });   server.onNotFound(handleNotFound);   server.begin(); }   void loop(void){ server.handleClient(); }

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

หลังจากอัพโหลดโปรแกรมเรียบร้อยแล้ว ให้ทำการประกอบทุกอย่างลงกล่องให้เหมือนเดิมและนำไปใช้งานได้ (ที่สำคัญให้ต่อสาย L กับ N ให้ถูกทั้งขาเข้าและขาออกด้วยนะครับ)

ทดสอบสั่งเปิดปิดไฟ โดยเปิดบราวเซอร์และพิมพ์ IP ของ Sonoff WiFi Smart Switch ที่เราคอนฟิกไว้ตอนเขียนโปรแกรม ดังนี้

http://192.168.1.100/ON
http://192.168.1.100/OFF

ก่อนจบ: ข้อเสียอย่างหนึ่งของ Sonoff Smart Switch คือว่ามันใช้ Relay ธรรมดา ทำให้เวลาเปิดปิดวงจรจะมีเสียงนิดหน่อย ถ้าเป็นไปได้ผมว่าจะหา Solid State Relay มาเปลี่ยนอยู่ //แต่ก็แพง

bact: เอกสาร ม.409 สัมมนาทางมานุษยวิทยา 2/2559

5 February, 2017 - 19:39

ทำเอกสารประกอบวิชาสัมมนาเทอมนี้ จะอัปโหลดรายการบรรณานุกรมที่ WordPress.com มันไม่ให้ (.rdf .xml .zip .txt ไม่ได้สักกะอัน) เลยต้องมาฝากไว้ในบล็อกตัวเอง

TU AN409 2/2559 Bibliography

LookHin: การสร้าง Telegram Bot สำหรับส่งข้อมูลแจ้งเตือนจาก ESP8266

30 January, 2017 - 07:12

บทความนี้จะแสดงตัวอย่างการสร้าง Telegram Bot สำหรับส่งข้อมูลแจ้งเตือนจากอุปกรณ์ไฟฟ้าที่ควบคุมด้วย ESP8266 อาจจะนำไปประยุกต์ใช้สำหรับทำวงจรแจ้งเตือนเมื่อมีผู้บุกรุกด้วยการนำ ESP8266 ไปต่อกับเซ็นเซอร์วัดระยะทางด้วยคลื่นอัลตราโซนิค (Ultrasonic Distance Sensor) หรือเซ็นเซอร์อินฟราเรด (PIR Sensor) ซึ้งถ้ามีผู้บุกรุกก็จะให้ส่งข้อความแจ้งเตือนมายัง Telegram หรือจะนำไปต่อกับเซ็นเซอร์ตรวจจับควันก็แล้วแต่จินตนาการ

ขั้นตอนการทำก็แบ่งออกเป็น 2 ขั้นตอนใหญ่ๆ คือ
1. สร้าง Telegram Bot
2. เขียนโปรแกรมบน ESP8266 เพื่อส่งข้อความมายัง Telegram ของเรา (ในบทความนี้จะใช้ ESP-01 และใช้สวิตซ์เป็นอินพุต ในการใช้งานจริงให้เปลี่ยนจากสวิตซ์ไปเป็น PIR Sensor หรือหากว่าต้องการรับอินพุตที่เป็น Analog ให้เปลี่ยนไปใช้ ESP-07 หรือ ESP-12 ที่มีขา ADC มาให้นะครับ)

สำหรับการสร้าง Telegram Bot ให้เราทำการเพิ่ม @BotFather เป็นเพื่อนกับเราก่อน ซึ่งเราจะต้องสั่งให้ @BotFather สร้างบอทให้เรา (ไม่เข้าใจเหมือนกันว่าทำไมเขาไม่ให้ทำผ่านหน้าเว็บ แต่เขาให้ทำในนี้ก็ทำไปครับ)

เมื่อเพิ่ม @BotFather เป็นเพื่อนแล้ว เราจะเห็นคำสั่งต่างๆ ขึ้นมาให้เราใช้งาน ลองพิมพ์ /help ระบบจะแสดงคำสั่งต่างๆ ขึ้นมาให้

ทีนี้ให้เราสร้าง Bot โดยใช้คำสั่ง /newbot ซึ่งระบบจะให้เราใส่ชื่อที่จะใช้เรียกบอทของเรา และให้ใส่ username ของบอท ซึ่งตรง username นี้จะต้องไม่ซ้ำกับคนอื่นและจะต้องลงท้ายด้วย bot เท่านั้น (ตัวอย่างผมจะใช้ชื่อบอทว่า SmartHomeABC123 และใช้ username ว่า SmartHomeABC123Bot) เมื่อสร้างเสร็จแล้วระบบจะแสดง Access Token ขึ้นมาให้เรา Token ตัวนี้จะใช้สำหรับการส่งข้อความนะครับ จดไว้ๆ

จากนั้นให้เราทำการเพิ่มบอท @SmartHomeABC123Bot เป็นเพื่อนของเราก่อน และลองทักมันไปสัก 1 ครั้ง จะเห็นว่าไม่มีอะไรขึ้นมา ไม่ต้องตกใจ อ่านข้อต่อไปครับ สิ่งที่เราต้องการไม่ได้ให้มันตอบกลับ แต่เราต้องการ ID ของเราเอง เพื่อใช้ในการส่งข้อความกลับ

จากนั้นให้พิมพ์คำสั่งนี้ที่ browser หรือหากใครใช้ CURL เป็นก็ตามสะดวก ออ อย่าลืมเปลี่ยนตรงคำว่า <ACCESS_TOKEN> เป็น Access Token ของบอทตัวเองด้วยนะครับ

https://api.telegram.org/bot<ACCESS_TOKEN>/getUpdates

สำหรับฟอร์แมตของคำสั่งจะเป็น https://api.telegram.org/bot<ACCESS_TOKEN>/API_COMMAND นะครับ สามารถอ่านข้อมูลเพิ่มเติมได้ว่าเราสามารถสั่งอะไรได้บ้างจาก Link นี้ครับ https://core.telegram.org/bots/api

หลังจากสั่ง /getUpdates เราจะได้ข้อมูลของข้อความและ id ของผู้ส่ง ซึ่งเดียวเราจะใช้ id ตรงนี้ในการนำไปใช้ในการส่งข้อความจาก ESP8266 ต่อไป (ถ้าสั่ง /getUpdates แล้วไม่มีข้อมูลอะไรขึ้น ให้ลองพิมพ์ข้อความทักบอทของเราไปอีกรอบ บาททีเราอาจจะเว้นช่วงนานไปจนข้อความนั้นหมดอายุไปก่อน)

หลังจากนั้นลองทำการส่งข้อความจากบอทของเรากลับมาหาเราหน่อยโดยใช้คำสั่ง CURL ถ้าใครใช้ CURL ไม่เป็นหรือไม่ได้ลงไว้ก็ข้ามไปเลยครับ อันนี้ผมทำให้ดูเฉยๆ โดยเราจะส่งเป็นพารามิเตอร์ text และ chat_id เป็น method post เข้าไป

1 curl -X POST https://api.telegram.org/bot<ACCESS_TOKEN>/sendMessage -d text="test test" -d chat_id="<YOUR_CHAT_ID>" -k

เย้ๆ ส่งข้อความได้แล้ว

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

อย่ากแรกต่อวงจรตามนี้ก่อน โดยให้ต่อ ESP-01 เข้ากับ USB To UART เพื่อทำการเขียนโปรแกรมลงไป และต่อสวิตซ์แบบ pull-up เข้ากับขา GPIO-2 ส่วนรายละเอียดอื่นๆ ตามนี้ครับ

1 2 3 4 5 6 7 8 [ESP-01] --> [USB To UART] RX --> TX TX --> RX VCC --> VCC (3.3v) CH_PD --> VCC (3.3v) GNC --> GND GPIO-0 --> GND GPIO-2 --> ต่อ pull-up กับสวิตซ์

เขียนโค้ดบน Arduino และทำการ upload sketch เข้าไปที่ ESP-01 ที่เราต่อวงจรเตรียมเอาไว้ เมื่อเรียบร้อยแล้วก็ทดสอบกดสวิตซ์ ระบบจะทำการส่งข้อความมาหาเราที่ Telegram ของเราแล้วครับ (Download Source Code)

โดยจากโค้ดให้แก้บรรทัดดังต่อไปนี้ โดยให้ใส่ค่าต่างๆ ตามที่เราได้มาจากขั้นตอนก่อนหน้านี้นะครับ

1 2 3 4 const char* ssid = "WIFI_SSID"; const char* password = "PASSWORD123"; const String AccessToken = "<YOUR_ACCESS_TOKEN>"; String PostData = "text=แจ้งเตือน: สวิตซ์บน ESP8266 ถูกกด&chat_id=<YOUR_CHAT_ID>"; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 #include <ESP8266WiFi.h> #include <WiFiClientSecure.h>   // WIFI SSID & Password const char* ssid = "WIFI_SSID"; const char* password = "PASSWORD123";   // Telegram Server API const int httpsPort = 443; const char* host = "api.telegram.org"; const String AccessToken = "<YOUR_ACCESS_TOKEN>";   const int SwitchPin = 2; // GPIO2 int SwitchOldStatus = HIGH; int SwitchNewStatus = HIGH;   void setup(void){ Serial.begin(9600);   pinMode(SwitchPin, INPUT);   WiFi.mode(WIFI_STA); WiFi.begin(ssid, password);   // Wait for connection while(WiFi.status() != WL_CONNECTED){ delay(500); } }   void loop(void){   // Read Data From Switch SwitchNewStatus = digitalRead(SwitchPin);   if(SwitchNewStatus == LOW && SwitchNewStatus != SwitchOldStatus){   String PostData = "text=แจ้งเตือน: สวิตซ์บน ESP8266 ถูกกด&chat_id=<YOUR_CHAT_ID>";   WiFiClientSecure client; Serial.print("connecting to "); Serial.println(host);   if (!client.connect(host, httpsPort)) { Serial.println("connection failed"); return; }   // POST client.print(String("POST ") + "/bot" + AccessToken + "/sendMessage HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "User-Agent: ESP8266-Notification\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n" + "Cache-Control: no-cache\r\n" + "Content-Length: " + String(PostData.length()) + "\r\n" + "\r\n" + PostData);   // Header Serial.println("-------Response Header-------"); while (client.connected()) { String line = client.readStringUntil('\n'); if (line == "\r") { break; }   Serial.println(line); }   // Body Serial.println("-------Response Body-------"); String body = client.readStringUntil('\n'); Serial.println(body);   }   SwitchOldStatus = SwitchNewStatus; delay(500); }

หลังจากทำการ upload sketch ให้ลองเปิด Serial Monitor ขึ้นมาดู Log และทดสอบกดสวิตซ์ดูได้เลยครับ จะเห็นว่ามีข้อมูลถูกส่งออกไปยัง API ของ Telegram แล้ว

ขั้นต่อไปก็เอาไปใช้งานจริง ให้ถอดตัว USB To UART ที่เราใช้ upload sketch ออกและต่อวงจรดังรูป

1 2 3 4 5 [ESP-01] --> [Battery] VCC --> VCC (3.3v) CH_PD --> VCC (3.3v) GNC --> GND GPIO-2 --> ต่อ pull-up กับสวิตซ์

หมายเหตุ: ปกติผมจะส่งข้อมูลจากเซ็นเซอร์ไปยัง Raspberry Pi ที่ทำหน้าที่ควบคุมทั้งระบบก่อน แล้วค่อยส่งจาก Raspberry Pi ออกไปยัง service อื่นๆ ข้างนอกอีกทีนะครับ เพราะถ้าต้องมาแก้ไขข้อความหรือเปลียน Access Token ผมคงแก้ไขจากฝั่งของ Raspberry Pi น่าจะง่ายกว่ามานั้ง upload sketch ใหม่

Thep: Long Time No Thanks

11 January, 2017 - 12:47

ผมร้างจากการเขียน blog ขอบคุณผู้สนับสนุนงานพัฒนาของผมไปเกือบหนึ่งปีเต็ม (นับจาก entry ล่าสุด อีกหนึ่งเดือนก็จะครบปี) รู้สึกผิดอยู่เหมือนกัน ถึงแม้จะได้อัปเดตหน้า ขอบคุณ มาเป็นระยะ แต่เวลาไม่เอื้ออำนวยให้เขียน blog สักเท่าไร และความพยายามเพิ่มเนื้อหาสาระใน blog ด้วยประเด็นที่น่าสนใจ ก็ทำให้ผัดวันเขียน blog ขอบคุณมาเรื่อย ๆ

อย่างไรก็ดี ผมก็ขอถือโอกาสนี้ ขอบคุณย้อนหลัง 11 เดือน สำหรับผู้ที่ได้ หย่อนสตางค์ลงหมวก เพื่อสนับสนุนงานพัฒนาซอฟต์แวร์เสรีของผม ดังนี้:

  • เดือนกุมภาพันธ์ 2559
    • คุณธนาธิป ศรีวิรุฬห์ชัย
    • ผู้ไม่แสดงตน 1 ท่าน
  • เดือนมีนาคม 2559
    • คุณธนาธิป ศรีวิรุฬห์ชัย
  • เดือนเมษายน 2559
    • คุณวิทยา ไตรสารวัฒนะ
    • คุณธนาธิป ศรีวิรุฬห์ชัย
  • เดือนพฤษภาคม 2559
    • คุณธนาธิป ศรีวิรุฬห์ชัย
  • เดือนมิถุนายน 2559
    • คุณวิทยา ไตรสารวัฒนะ
  • เดือนกรกฎาคม 2559
    • คุณธนาธิป ศรีวิรุฬห์ชัย
  • เดือนสิงหาคม 2559
    • คุณวิทยา ไตรสารวัฒนะ
  • เดือนกันยายน 2559
    • ผู้ไม่ประสงค์จะออกนาม
  • เดือนธันวาคม 2559
    • คุณวิทยา ไตรสารวัฒนะ

ขอขอบคุณสำหรับการสนับสนุนที่ผ่านมาของทุกท่านครับ ขอให้ทุกท่านมีความสุขความเจริญในหน้าที่การงาน มีสุขภาพแข็งแรง คิดสิ่งใดก็ขอให้สมความปรารถนานะครับ

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

ช่วงที่ผ่านมา งานซอฟต์แวร์เสรีของผมก็ยังอยู่ใน maintenance mode เช่นเคย โดยเป็นการดูแลโครงการต่าง ๆ ของ TLWG ซึ่งขณะนี้ได้ ย้าย ไปที่ GitHub แล้ว และ release รุ่นปรับปรุงออกมาเรื่อย ๆ ตามโอกาส ดังข่าวประกาศต่าง ๆ ที่เว็บ LTN ดังกล่าว พร้อมทั้งอัปโหลด แพกเกจ เข้า Debian ตามปกติ

ส่วนงานแปล ก็ยังคงอัปเดตคำแปลของ Xfce ใน development snapshot และตรวจทานคำแปลของ GNOME ตามที่โอกาสจะอำนวย ซึ่งก็เรียกได้ว่าไม่ได้ active เท่าเมื่อก่อน แต่ก็ยังไม่เลิกทำนะครับ

ส่วนชีวิตทั่วไป ตอนนี้ผมต้องศึกษางานสาขาอื่น เพื่อให้สามารถรับงานที่ generate income ได้มากกว่างานรองรับภาษาไทย เพื่อความอยู่รอดของครอบครัวครับ เรื่องที่ไม่เคยทำก็หัดเสียให้เป็น ก็พร้อมรับคำชี้แนะจากผู้รู้ และเปิดรับงานนอกสาขาเดิม ส่วนจะทำได้มากน้อยแค่ไหนก็ต้องพิจารณาศักยภาพของตัวเองเป็นกรณีไปครับ

Kitt: Yet another leap second added

1 January, 2017 - 08:23
235960 – 23:59:60 – the leap second added. UTC (based on solar mean)  – TAI (based on atomic clock) = -37 seconds Happy New Year 2017 UTC

bact: Hacking Team RCS กับการดู “ข้อมูลเข้ารหัส” โดยไม่ต้องถอดรหัส

27 December, 2016 - 09:42

(ต่อเนื่องจากโพสต์นี้และโพสต์นี้ในเฟซบุ๊ก)

แม้จะยังไม่แน่ชัดว่าอุปกรณ์ชื่อ “SSLX-GEO” และ “SSLX-T200” ที่ทางกลุ่ม “พลเมืองต่อต้าน Single Gateway” พบในระบบที่อ้างว่าเป็นของกองทัพบกนั้นคืออะไร และทางกองทัพบกก็ได้ปฏิเสธข้อมูลดังกล่าวแล้ว

แต่เมื่อปีที่แล้ว มีเอกสารอีกชุดใน Wikileaks เป็นอีเมลและเอกสารส่งสินค้าของบริษัท Hacking Team ที่ระบุว่ามีการส่งสินค้า ติดตั้ง และทดสอบระบบส่งโปรแกรมฝังตัวเพื่อเข้าควบคุมเครื่องปลายทางที่ชื่อ Remote Control System (RCS) Galileo ในประเทศไทย เมื่อเดือนพฤษภาคม 2558

—-

RCS ไม่ใช่อุปกรณ์หรือระบบถอดรหัสการสื่อสาร แต่ทำงานโดยไปฝังตัวที่เครื่องปลายทางเพื่อเข้าควบคุมเครื่อง จากนั้นก็สามารถอ่านข้อมูลที่เครื่องเป้าหมาย ก่อนข้อมูลจะถูกเข้ารหัสและส่งออกไป และหลังข้อมูลถูกส่งเข้ามาและได้รับการถอดรหัส (แอปสื่อสารเป็นผู้ถอดรหัสเอง แล้ว RCS ค่อยไปอ่าน)

พูดอีกอย่าง แม้ RCS จะไม่ได้ถอดรหัส แต่มันทำให้การเข้ารหัสหมดความหมาย

เมื่อ RCS เข้าควบคุมเครื่องได้แล้ว ก็แน่นอนว่าจะสามารถดูข้อมูลอื่นๆ ในเครื่องได้ด้วย ไม่เฉพาะข้อมูลการสื่อสาร

Citizen Lab พบหลักฐานว่าระบบนี้ถูกใช้ในหลายประเทศ เช่น อาเซอร์ไบจาน อียิปต์ เอธิโอเปีย ฮังการี อิตาลี คาซัคสถาน เกาหลี มาเลเซีย เม็กซิโก โอมาน ปานามา ซาอุดิอาระเบีย ซูดานอาหรับเอมิเรสต์ ตุรกี และประเทศไทย

—-

ข้อมูลคอมพิวเตอร์ในระบบเครือข่ายนั้น จำแนกได้เป็น 2 ประเภทใหญ่คือ

1) ข้อมูลที่อยู่นิ่งๆ ในเครื่อง หรือ ข้อมูล ณ จุดพัก (data at rest)

2) ข้อมูลที่วิ่งไปมาระหว่างเครื่อง 2 เครื่อง หรือ ข้อมูลระหว่างเดินทาง (data in transit)

—-

การเข้ารหัสการสื่อสารด้วย SSL (Secure Sockets Layer) หรือ TLS (Transport Layer Security) นั้นเป็นการเข้ารหัสข้อมูลประเภทที่ 2 (ข้อมูลระหว่างเดินทาง) เพื่อให้ข้อมูลที่ส่งจากปลายทางหนึ่งไปยังอีกปลายทางหนึ่งมีความปลอดภัย ไม่สามารถถูกดูได้โดยเครื่องที่ต้องผ่านระหว่างทาง (ระบบอินเทอร์เน็ตทำงานคล้ายระบบไปรษณีย์ในแง่ที่ว่ากว่าข้อมูลจะถึงจุดหมาย ต้องฝากส่งกันหลายต่อหลายทอด)

การถอดรหัสข้อมูลที่ส่งด้วย SSL/TLS นั้นเป็นเรื่องยากหากไม่มีกุญแจที่ใช้ส่งข้อมูลแต่ละครั้ง (และระบบทำงานปกติไม่มีรูรั่ว)

เมื่อการดักและถอดรหัสข้อมูลประเภทที่ 2 (ข้อมูลระหว่างเดินทาง) ทำได้ยาก อีกวิธีที่จะดูข้อมูลได้ก็คือ พุ่งเป้าไปยังข้อมูลประเภทที่ 1 (ข้อมูล ณ จุดพำนัก) แทน

—-

หาก “จุดพำนัก” ดังกล่าวสามารถระบุที่ตั้งได้ชัดเจน เป็นเครื่องในความครอบครองของบุคคลหรือหน่วยงานที่ติดต่อได้ การ “ขอ” ข้อมูลตรงๆ จากบุคคลหรือหน่วยงานดังกล่าว ก็เป็นเรื่องที่ทำได้ (ไม่ว่าจะถูกต้องตามกฎหมายหรือไม่ก็ตาม)

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

—-

อ่านความสามารถส่วนหนึ่งของ RCS และรายละเอียดเกี่ยวกับอีเมลสอบถามและการติดตั้งทดสอบในประเทศไทยเมื่อพฤษภาคม 2558 — ระบบนี้อาจจะเกี่ยวหรือไม่เกี่ยวกับคำสั่งกระทรวงไอซีทีที่ 163/2557 ตั้งคณะทำงานทดสอบระบบเฝ้าติดตามออนไลน์ เมื่อ 15 ธ.ค. 2557

—-

ในแง่นี้ แม้ระบบ Remote Control System จะไม่ใช่ระบบที่ถอดรหัสข้อมูลการสื่อสาร แต่ก็เป็นระบบที่ทำให้การเข้ารหัสข้อมูลการสื่อสารระหว่างเครื่องไม่มีความหมายอีกต่อไป

และในกรณีข้อมูลการสื่อสารที่เป็นการสื่อสาร 2 ฝั่งนั้น แม้ปลายทางอีกฝั่งจะไม่ติดเชื้อ RCS แต่เนื่องจากข้อมูลการสื่อสาร (เช่นการแชต) นั้นมีการแลกเปลี่ยนรู้เท่ากันทั้ง 2 ฝั่ง ก็แปลว่าตัว RCS ก็จะรู้ข้อมูลการสื่อสารของอีกฝั่งได้ด้วย (เฉพาะที่มีการแลกเปลี่ยนกับเครื่องที่ติดเชื้อ)

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

—-

สิ่งที่พอจะสบายใจได้บ้าง (หรืออาจจะไม่ก็ได้นะ) ก็คือ

1) RCS นั้นจะต้องทำอย่างเจาะจงเป้าหมาย (ส่วนเป้าหมายจะมีได้กี่เป้าหมายนั้น ก็แล้วแต่ทรัพยากร)

2) RCS ฝังตัวที่เครื่องเป้าหมายโดยอาศัยรูรั่วของแอปและระบบปฏิบัติการ (exploits) ถ้าเราหมั่นอัปเดตระบบปฏิบัติการและแอปเสียหน่อย (ใครใช้ระบบรุ่นเก่าๆ ที่โดนผู้ผลิตลอยแพแล้วก็เสียใจด้วย) ไม่ติดตั้งแอปน่าสงสัย และใช้เน็ตอย่างระมัดระวัง ไม่คลิกลิงก์มั่ว ไม่เปิดไฟล์แนบแปลกๆ (RCS Agent สามารถติดมากับไฟล์เช่น PDF, PowerPoint, Word) ก็พอจะปลอดภัยระดับหนึ่ง

ภาพหน้าจอจากเอกสาร RCS Certificates Case Study (หน้า 1-5) ของ Hacking Team

<figure class="wp-caption aligncenter" id="attachment_3493" style="width: 1288px"><figcaption class="wp-caption-text">RCS Exploit Portal</figcaption></figure> คำถาม-ข้อกังวลที่ต้องตอบ

คำถามเร็วๆ ตอนนี้คือ 

1) ใครเป็นคนควบคุมระบบนี้? ใช้อำนาจตามกฎหมายใด?

2) กลไกอะไรจะตรวจสอบการใช้อำนาจจากระบบนี้ เป็นกลไกที่ทำงานได้จริงไหม?

3) ความสามารถของ RCS นี่มีมากกว่าดักข้อมูล มันควบคุมเครื่องเป้าหมายได้ เปิดปิดกล้องได้ จะดาวน์โหลดข้อมูลอะไรมาใส่เครื่องเป้าหมายก็ได้ ถ้ามีการขอหมายหรือคำสั่งศาล คำสั่งจะอนุญาตให้ทำอะไรได้บ้าง?

4) ในซอร์สโค้ดที่หลุดออกมา มีการตั้งชื่อไฟล์ปลอมๆ ที่บ่งถึงรูปโป๊เด็ก เช่น “childporn.avi” และ “pedoporno.mpg” ซึ่งแม้อาจจะเป็นเรื่องตลกในกลุ่มโปรแกรมเมอร์ของ Hacking Team แต่ก็ทำให้เราเห็นถึงความเป็นไปได้ในการ “สร้างพยานหลักฐาน” – เรื่องนี้น่าห่วงมากๆ

วิดีโอโฆษณาของ Hacking Team

<iframe allowfullscreen="true" class="youtube-player" height="402" src="https://www.youtube.com/embed/8oilhYYj8_g?version=3&amp;rel=1&amp;fs=1&amp;autohide=2&amp;showsearch=0&amp;showinfo=1&amp;iv_load_policy=1&amp;wmode=transparent" style="border:0;" type="text/html" width="660"></iframe>

วิดีโอสาธิต RCS Galileo บน Windows

<iframe allowfullscreen="true" class="youtube-player" height="402" src="https://www.youtube.com/embed/a1_6bVAUjRQ?version=3&amp;rel=1&amp;fs=1&amp;autohide=2&amp;showsearch=0&amp;showinfo=1&amp;iv_load_policy=1&amp;wmode=transparent" style="border:0;" type="text/html" width="660"></iframe>

Kitt: Ubuntu 16.10 Kernel 4.8.0 boot time

26 December, 2016 - 00:11
I don’t really know when, I suspect around 4.8.0-30 or a bit earlier that kernel boot time has noticeably increased. There is a bug/regression report on launchpad Quick fix ? Try 4.9 mainline ppa. Results from my systemd-analyze: 4.8.0-32 = 12.331s 4.9 = 5.041s

LookHin: การติดตั้งและใช้งาน Tor แบบ Expert Bundle และทำเป็น Service ของ Windows พร้อมทั้งเปลี่ยนเส้นทางทุก 1 นาที

25 December, 2016 - 11:07

จริงๆ ผมเคยเขียนเรื่องการใช้งาน Tor ไปแล้ว 2 ครั้ง มาดูอีกทีเป็นช่วงเดือนเดียกันนี้ด้วย คือเดือนธันวาคมปี 2013 “ติดตั้งและใช้งาน Tor + Provoxy เพื่ออำพรางตัว” และธันวาคมปี 2014 “ติดตั้งและใช้งาน Tor + Vidalia บน Linux Mint เมื่อ ธันวาคม 2014” ที่ผ่านมาผมติดตั้งและใช้งานผ่าน Vidalia มาตลอดเพราะใช้งานง่ายดี แต่ตอนนี้ทางโครงการเขาเอา Vidalia ออกแล้ว และเหลือให้เฉพาะ Tor Browser ซึ่งก็เป็น Tor รวม Firefox Browser มาด้วยนั้นหละ แต่แบบนี้มีคนสอนใช้งานเยอะแล้ว เดี๋ยวเราข้ามไปติดตั้งกันแบบ Expert Bundle และทำมันเป็น Service ของ Windows และปรับเปลี่ยนคอนฟิกนิดหน่อยเพื่อให้มันเปลี่ยนเส้นทางทุกๆ 1 นาที

อย่างแรกก็เข้าไปดาวน์โหลดโปรแกรมกันก่อน ให้เลือกโหลดตัว Expert Bundle นะครับ

https://www.torproject.org/download/download.html.en

เมื่อโหลดมาแล้วให้ทำการ unzip และเอาไฟล์ที่ได้ไปวางไว้ที่ c:\Tor\ (จริงๆ วางที่ไหนก็ได้นะตามสะดวก)

จากนั้นทำการสร้างคอนฟิกไฟล์ ชื่อ torrc ไว้ที่โฟลเดอร์ C:\Tor\Data\Tor\

โดยใส่คอนฟิกไป 1 ตัวคือ MaxCircuitDirtiness 60 ค่านี้คือสั่งให้เปลี่ยนเส้นทางใหม่ทุกๆ 60 วินาที ค่าปกติจะเป็น 10 นาที แต่อันนี้เราต้องการให้เปลี่ยนเร็วขึ้นหน่อย (หน่วยวินาที) (แต่ค่าปกติที่ผมใช้คือ 5 นาที)

1 MaxCircuitDirtiness 60

จากนั้นทำการรัน tor ให้เป็น Service ของ Windows โดยใช้คำสั่ง tor –service install –options -f “C:\Tor\Data\Tor\torrc” โดยให้เปิด Command Prompt และเลือกรันเป็น Administrator

จากนั้นสั่งเพิ่ม Service Tor เข้าไปในระบบ

1 2 cd c:\Tor\Tor tor --service install --options -f "C:\Tor\Data\Tor\torrc"

จากนั้นเข้าไปดูใน Service ของ Windows หน่อยหนึ่งว่ามี Tor Win32 Service ขึ้นมาแล้วหรือยัง เราสามารถสั่ง Stop และ Start service จากหน้านี้ก็ได้

หรือหากต้องการสั่ง Start และ Stop service ก็สามารถสั่งผ่านทาง command line ได้โดยใช้คำสั่งดังนี้ครับ

1 2 tor --service stop tor --service start

และหากต้องการลบ Service ของ Tor ออกจากระบบก็ให้ใช้คำสั่ง

1 tor --service remove

เท่านี้หละครับ เราติดตั้ง Tor แบบ Beginner Expert เรียบร้อยแล้ว ต่อไปถ้าจะให้โปรแกรมอื่นๆ เข้ามาใช้งาน Tor เราก็แค่ไปกำหนดให้โปรแกรมนั้นวิ่งมาใช้งาน Tor ผ่าน SOCKS5 ที่พอร์ต 9050 หรือหากโปรแกรมของคุณไม่สามารถใช้งาน proxy ผ่าน SOCKS5 ได้ ก็ให้ติดตั้ง Privoxy ให้ฟอร์เวิร์ดพอร์ตมาที่ HTTP อีกทีก็ได้ครับ ผมเคยเขียนวิธีไว้แล้วเมื่อปลายปี 2013 “ติดตั้งและใช้งาน Tor + Provoxy เพื่ออำพรางตัว

ขั้นต่อไปเรามาติดตั้ง Google Chrome plugin เพื่อเอาไว้สลับเส้นทางว่าเราจะใช้ Tor หรือว่าไม่ใช้ โดยผมเลือกใช้ plugin ตัวนี้นะครับ “Proxy SwitchyOmega” โดยเมื่อติดตั้งเสร็จแล้วจะมีไอคอนกลมๆ ขึ้นทางขวามือ ให้คลิกแล้วเลือกไปที่ Options

ให้คลิกเลือกไปที่ Profile :: proxy แล้วตั้งค่าตามนี้ และกดปุ่ม Apply changes ด้านซ้ายมือเป็นอันเรียบร้อย

1 2 3 Protocal = SOCKS5 Server = 127.0.0.1 Port = 9050

เวลาที่เราจะใช้งาน Tor ก็ให้คลิกไปที่รูปวงกลมทางขวาแล้วเลือกไปที่ proxy หรือถ้าหากต้องการกลับมาใช้แบบไม่ผ่าน Tor ก็คลิกเลือกไปที่ Direct

ทีนี้ก่อนจบ เราก็มาทดสอบดู IP ที่เราได้กันหน่อยว่ามันเปลี่ยนทุกๆ 1 นาทีจริงไหม โดยเปิดเข้าไปที่ https://check.torproject.org/ แล้วลองจับเวลาดูเองนะครับ ว่าทุกๆ 1 นาที เราได้ IP ใหม่มาหรือยัง ถ้าต้องการเปลี่ยนระยะเวลาก็เข้าไปแก้ไขที่ไฟล์ torrc แล้วเปลี่ยนเป็นค่าที่ต้องการแล้วสั่ง restart service ก็เรียบร้อย

ขอให้ทุกคนปลอดภัย

ข้อมูลอ้างอิง : https://www.torproject.org/docs/tor-manual.html.en

Sothorn: CentOS 7-1611

20 December, 2016 - 21:00

CentOS 7-1611 ออกมาเมื่อวันที่ 12 ธันวาคม 2559 ที่ผ่านมา พัฒนามาจาก Red Hat Enterprise Linux 7.3 ที่ออกมาเมื่อ เดือน พฤศจิกายน 2559  ซึ่งกลายเป็นเลขเวอร์ชันของ CentOS 7-1611

มีอะไรอัพเดทบ้าง

 

  • Since release 1503 (abrt>= 2.1.11-19.el7.centos.0.1) CentOS-7 can report bugs directly to bugs.centos.org. You can find information about that feature at this page.

  • Various new packages include among others: python-gssapi, python-netifaces, mod_auth_openidc, pidgin and Qt5.
  • Support for the 7th-generation Core i3, i5, and i7 Intel processors and I2C on 6th-generation Core Processors has been added.
  • Various packages have been rebased. Some of those are samba, squid, systemd, krb5, gcc-libraries, binutils, gfs-utils, libreoffice, GIMP,SELinux, firewalld, libreswan, tomcat and open-vm-tools.
  • SHA2 is now supported by OpenLDAP.
  • ECC-support has been added to OPenJDK-8, PerlNet:SSLeay and PerlIO::Socket::SSL.

  • Bluetooth LE is now supported.
  • virt-p2v is now fully supported. virt-v2v and virt-p2v add support for the latest windows releases.
  • Lots of updated storage, network and graphics drivers.
  • Technology Preview: Among others support of Btrfs, OverlayFS, CephFS, DNSSEC, kpatch, the Cisco VIC and usNIC kernel driver, nested virtualization with KVM and multi-threaded xz compression with rpm-builds.

รายการอัพเดททั้งหมด https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/7.3_Release_Notes/index.html

ความต้องการ RAM

  • 1024 MB สำหรับ การติดตั้ง CentOS 7-1611
  • 1280 MB สำหรับการติดตั้งแบบ LiveCD
  • 1344 MB สำหรับการติดตั้งแบบ LiveGNOME หรือ LiveKDE

หน้าตาตอนติดตั้ง

สำหรับขั้นตอนการติดตั้งโดยรวมก็ยังเหมือนกับเวอรชัน 1511

สำหรับการแบ่งพาร์ติชันให้ระวังหารแบ่งพาร์ติดชันแบบ Auto เพราะมันจะแบ่ง /home ไว้มากที่สุด

ส่วนการยอมรับ License ได้พัฒนาดีขึ้นกว่า 1511 เพราะ 1511 ต้องยอมรับ License แบบ Text

1611 ได้แก้ไขให้ยอมรับ License แบบกราฟิกแล้ว ง่ายขึ้นเยอะ

 

<script>window.twttr=(function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);t._e=[];t.ready=function(f){t._e.push(f);};return t;}(document,"script","twitter-wjs"));</script>

Kitt: เรามาเป็นแอดมินได้ไง

9 December, 2016 - 09:17
tl;dr ไม่รู้เหมือนกัน 55+ ปี 3 วิชา Computer Networks สอน TCP/IP (อ.ยืน อ.เขมทัต อ.ปรีดา ม.เกษตร) ประกอบกับที่ภาคคอมคณะไรสักอย่างได้รับเครื่อง SUN SPARCStation 5 มาจากมูลนิธิ Hitachi เครื่องนี้ต่ออินเทอร์เน็ตผ่าน MODEM + leased line ไปที่ศูนย์คอมพิวเตอร์ ผมกับเพื่อนไม่กี่คนมี account บนเครื่องนี้ telnet จาก PC ไปหัดใช้คำสั่ง UNIX ใช้อินเทอร์เน็ตได้ (pine, talk, gopher, inn, irc (#thai #siam …)) .. ตอนนั้นเป็นของใหม่ ของแพง(มาก) มีโอกาสได้ใช้ก็ตื่นตาตื่นใจ ปี 4 เพื่อนคนนึงทำโปรเจคเกี่ยวกับอินเทอร์เน็ต ขอเครื่อง 486 มาลง BSD ได้แผ่นติดตั้ง … Continue reading เรามาเป็นแอดมินได้ไง →

Kitt: เรามาเขียนโค้ดได้ไง

8 December, 2016 - 03:10
ปี 2529 อยู่ ม.2 ไม่เคยเล่นเกม ไม่เคยใช้โปรแกรมสำเร็จรูป แตะคอมพิวเตอร์ครั้งแรกก็หัดโค้ดเลย มันคือเครื่อง VTech Laser 200 (https://en.wikipedia.org/wiki/VTech_Laser_200) ROM เป็น BASIC interpreter สมัยนั้นเรียกของพวกนี้ว่า home computer ก็ไม่แน่ใจว่าเครื่องนี้เป็นของใคร แต่มันวางอยู่ที่บ้านที่ไปอาศัยอยู่ช่วงนั้น หัดจากคู่มือของเครื่อง (ภาษาอังกฤษ) หนังสือตัวอย่างโปรแกรมที่แถมมา จนเขียน BASIC เป็น ม.ปลาย ที่โรงเรียนสอนภาษา Logo .. ช่วงนั้นมีเครื่อง PC ที่บ้านแล้ว รับจ้างเขียนโปรแกรม พิมพ์รายงาน ป.ตรี รับจ้างเขียน inventory ให้ รพ.ศรีนครินทร์ (Clipper/Netware) โปรเจคจบเขียน C/C++ เป็นโปรแกรมบน Windows ป.โท ระหว่างเรียนเขียน C, C++, CLIPS, LISP, Prolog, OCaml, Smalltalk, … Continue reading เรามาเขียนโค้ดได้ไง →

Kitt: €2.99/mo. Scaleway VC1S

6 December, 2016 - 16:22
Same tools, same OS as $5/month: DigitalOcean vs Vultr dd write bs=4k count=10k 100k 1M 403 398 184 MB/s dd read bs=4k 2.0 GB/s sysbench --test=cpu --cpu-max-prime=10000 run 17.9875 sec. stress-ng --cpu 1 --cpu-method all -t 30 94.22 ops/sec The disk performance is comparable to those of DO/Vultr. But, even equipped with 2 x 64-bit x86 processor, … Continue reading €2.99/mo. Scaleway VC1S →