วิธีตรวจสอบไฟล์ดาวน์โหลดด้วย checksum บน Linux
เรียนรู้วิธีใช้คำสั่ง sha256sum เพื่อตรวจสอบความถูกต้องของไฟล์ดาวน์โหลด พร้อมตัวอย่างการทดสอบความผิดพลาดเมื่อไฟล์เสียหาย เพื่อให้คุณเข้าใจหลักการทำงานของ checksum อย่างแท้จริง
ตรวจสอบไฟล์ที่ดาวน์โหลดด้วย checksum ภายในสองนาที
การตรวจสอบไฟล์ที่ดาวน์โหลดด้วย checksum ทำได้โดยการสร้าง hash ของไฟล์ที่คุณได้รับ แล้วให้เครื่องมือเปรียบเทียบค่า hash นั้นกับค่าที่ผู้เผยแพร่ระบุไว้ sha256sum สามารถทำงานทั้งสองส่วนนี้ได้ โดยตัวมันเองจะแสดงค่า digest ออกมา และเมื่อใช้ร่วมกับ -c มันจะอ่านรายการ digest แล้วรายงานว่าไฟล์ใดบ้างที่ตรงกัน คู่มือนี้จะสาธิตขั้นตอนทั้งหมดโดยใช้ไฟล์ที่คุณสร้างขึ้น จากนั้นจะทำให้ไฟล์นั้นเสียหายโดยเจตนาเพื่อให้คุณเห็นความล้มเหลวที่เกิดขึ้นจริง แทนที่จะเป็นเพียงการอ่านคำอธิบาย
โปรดจำประโยคนี้ไว้ตลอดการดำเนินการ: checksum จะบอกคุณว่าไบต์ที่คุณถืออยู่ในมือคือไบต์ชุดเดียวกับที่สร้าง digest นั้นขึ้นมาหรือไม่ แต่จะไม่บอกอะไรคุณเลยว่าใครเป็นผู้สร้างไบต์เหล่านั้น คำถามที่สองนั้นจำเป็นต้องใช้ลายเซ็นดิจิทัลและกุญแจที่คุณเชื่อถือได้ ส่วนสุดท้ายของคู่มือนี้จะแสดงให้เห็นอย่างชัดเจนว่าขอบเขตระหว่างสองสิ่งนี้อยู่ตรงไหน
สร้างไฟล์เพื่อทดลองปฏิบัติ
ให้ทำงานในไดเรกทอรีชั่วคราวเพื่อไม่ให้การกระทำใดๆ ส่งผลกระทบต่อส่วนอื่นของระบบ คำสั่งทั้งหมดด้านล่างมาจาก GNU coreutils ซึ่งเป็นชุดคำสั่งพื้นฐานที่มีอยู่บนเซิร์ฟเวอร์ Ubuntu หรือ Debian ทุกเครื่อง ดังนั้นจึงไม่จำเป็นต้องติดตั้งสิ่งใดเพิ่มเติม
mkdir -p ~/checksum-demo
cd ~/checksum-demo
printf 'the payload of a totally ordinary download\n' > payload.txt
sha256sum payload.txtคุณจะได้รับบรรทัดข้อความหนึ่งบรรทัด ประกอบด้วยอักขระเลขฐานสิบหก 64 ตัว ตามด้วยช่องว่างสองช่อง และชื่อไฟล์ อักขระ 64 ตัวนั้นคือค่า digest ของไฟล์ หากคุณรันคำสั่งเดิมอีกครั้ง บรรทัดที่ได้จะเหมือนเดิมทุกประการ เนื่องจากการทำ hashing เป็นกระบวนการที่แน่นอน (deterministic): ข้อมูลนำเข้าชุดเดิมจะให้ผลลัพธ์เดิมเสมอ หากคุณเปลี่ยนอักขระในไฟล์เพียงตัวเดียวแล้วรันคำสั่งอีกครั้ง ค่า digest จะไม่เปลี่ยนแปลงเพียงเล็กน้อย แต่มันจะดูแตกต่างไปจากเดิมอย่างสิ้นเชิง เนื่องจากเมื่อบิตข้อมูลนำเข้าเปลี่ยนไปเพียงหนึ่งบิต จะส่งผลให้บิตของผลลัพธ์เปลี่ยนไปประมาณครึ่งหนึ่ง คุณสมบัตินี้เองที่ทำให้สตริงความยาว 64 อักขระสามารถใช้เป็นตัวแทนของไฟล์อิมเมจขนาด 4 GB ได้อย่างมีประสิทธิภาพ
บันทึกไฟล์ SHA256SUMS แล้วตรวจสอบ
ค่า digest ที่แสดงบนหน้าจอไม่มีประโยชน์ในวันถัดไป ให้เขียนลงในไฟล์ด้วยรูปแบบที่ sha256sum สร้างขึ้น เพื่อให้เครื่องมือสามารถอ่านกลับมาตรวจสอบได้ในภายหลัง
sha256sum payload.txt > SHA256SUMS
cat SHA256SUMS
sha256sum -c SHA256SUMSsha256sum -c จะอ่านแต่ละบรรทัดในรายการ ทำการ hash ไฟล์ที่ระบุในบรรทัดนั้น แล้วเปรียบเทียบค่า digest ทั้งสอง หากการทำงานปกติจะแสดงผลหนึ่งบรรทัดต่อหนึ่งไฟล์:
payload.txt: OKให้ตรวจสอบสถานะการทำงาน (exit status) ด้วย เนื่องจากสคริปต์จะอ่านค่าดังกล่าวแทนการอ่านข้อความ echo $? จะแสดง 0 หลังจากทำงานเสร็จสิ้นโดยไม่มีข้อผิดพลาด ชื่อไฟล์ SHA256SUMS เป็นเพียงข้อตกลงร่วมกันไม่ใช่กฎบังคับ แต่เนื่องจากดิสทริบิวชันและหน้าดาวน์โหลดส่วนใหญ่ใช้ชื่อนี้ คุณจึงควรใช้ชื่อนี้ด้วย เพื่อให้ผู้อื่นทราบว่าไฟล์นี้เก็บข้อมูลอะไรโดยไม่ต้องเปิดอ่าน
แก้ไขหนึ่งไบต์แล้วดูการตรวจสอบล้มเหลว
ตอนนี้ให้ลองทำให้ไฟล์เสียหายโดยเจตนา คำสั่งนี้จะเขียนข้อมูลลงไปหนึ่งไบต์ที่ offset 5 โดยไม่กระทบส่วนอื่น ทำให้ไฟล์ยังคงมีความยาวและชื่อเดิมเท่าเดิม
printf 'X' | dd of=payload.txt bs=1 seek=5 conv=notrunc status=none
cat payload.txt
sha256sum -c SHA256SUMSconv=notrunc คือ flag ที่สำคัญ หากไม่มี flag นี้ dd จะตัดไฟล์ทิ้ง ณ จุดที่หยุดเขียน ซึ่งจะทำให้คุณกำลังทดสอบความเสียหายที่เห็นได้ชัดเจนกว่านี้มาก ผลการตรวจสอบตอนนี้จะแสดงข้อความว่า:
payload.txt: FAILED
sha256sum: WARNING: 1 computed checksum did NOT matchecho $? จะแสดงผลเป็น 1 โดย FAILED หมายความว่ามีการอ่านไฟล์แล้วแต่ค่า digest ไม่ตรงกับที่ระบุไว้ในรายการ ให้คืนค่าไบต์เดิมกลับไปแล้วยืนยันว่าการตรวจสอบกลับมาเป็น OK:
printf 'the payload of a totally ordinary download\n' > payload.txt
sha256sum -c SHA256SUMSนี่คือขั้นตอนทั้งหมดของนิสัยนี้ ความแตกต่างเพียงหนึ่งไบต์ไม่ว่าจะอยู่ที่ใดในไฟล์ จะทำให้เกิด FAILED ไม่ว่าจะเป็นการดาวน์โหลดที่ถูกตัดตอนจากการเชื่อมต่อที่หลุด, mirror ที่ให้บริการ build ของเมื่อวาน, proxy ที่เขียนไฟล์ใหม่ระหว่างทาง หรือดิสก์ที่ส่งคืน bad block ทั้งหมดนี้จะนำไปสู่ผลลัพธ์ในบรรทัดเดียวกันนี้ทั้งสิ้น
เมื่อรายการระบุชื่อไฟล์ที่คุณไม่ได้ดาวน์โหลดมา
ไฟล์ SHA256SUMS ที่แท้จริงจากผู้จัดจำหน่ายจะระบุรายการอิมเมจทุกไฟล์ที่โปรเจกต์นั้นปล่อยออกมา และคุณได้ดาวน์โหลดมาเพียงไฟล์เดียว ให้จำลองสถานการณ์ดังกล่าวที่นี่
printf 'a second file\n' > notes.txt
sha256sum payload.txt notes.txt > SHA256SUMS.all
rm notes.txt
sha256sum -c SHA256SUMS.allpayload.txt: OK
sha256sum: notes.txt: No such file or directory
notes.txt: FAILED open or read
sha256sum: WARNING: 1 listed file could not be readFAILED open or read เป็นความล้มเหลวที่ต่างจาก FAILED และการสับสนระหว่างสองสิ่งนี้จะทำให้เสียเวลา FAILED หมายความว่าข้อมูลไบต์ไม่ถูกต้อง ส่วน FAILED open or read หมายความว่า sha256sum ไม่ได้รับไฟล์เลย จึงไม่มีการเปรียบเทียบเกิดขึ้น ในการดาวน์โหลดจริง สาเหตุที่พบบ่อยคือไดเรกทอรีทำงาน (working directory) เนื่องจากชื่อไฟล์ในรายการเป็นแบบสัมพัทธ์กับตำแหน่งที่คุณรันคำสั่ง ให้เปลี่ยนไดเรกทอรีไปยังตำแหน่งที่เก็บไฟล์แล้วรันคำสั่งอีกครั้ง หากต้องการตรวจสอบเฉพาะไฟล์ที่คุณมีอยู่จริง ให้ระบุเจาะจงดังนี้:
sha256sum --ignore-missing -c SHA256SUMS.allคำสั่งดังกล่าวจะแสดง payload.txt: OK และจบการทำงานด้วยสถานะ 0 หากไม่มีชื่อไฟล์ใดในรายการปรากฏอยู่ --ignore-missing จะไม่ทำงานสำเร็จแบบเงียบๆ หากไม่มีไฟล์ให้ตรวจสอบ แต่จะรายงานว่า no file was verified และจบการทำงานด้วยสถานะที่ไม่ใช่ศูนย์ ซึ่งเป็นพฤติกรรมที่คุณต้องการ เพราะการตรวจสอบที่ไม่ได้ตรวจสอบอะไรเลยคือความล้มเหลวที่คุณอาจไม่ทันสังเกตเห็น
วางค่า digest ที่เผยแพร่โดยไม่ต้องตรวจสอบด้วยสายตา
การตรวจสอบอักขระเลขฐานสิบหก 64 ตัวด้วยสายตาเป็นจุดที่นิสัยนี้มักจะล้มเหลว ผู้ใช้งานมักตรวจสอบเพียง 4 ตัวแรกและ 4 ตัวสุดท้ายแล้วสรุปว่าตรงกัน ซึ่งนั่นคือจุดที่ผู้โจมตีที่มุ่งมั่นวางแผนไว้ ให้ใช้เครื่องมือในการตรวจสอบแทน กำหนดค่า EXPECTED ให้เป็น digest ที่คุณคัดลอกมาจากผู้เผยแพร่ โดยใช้ EXPECTED= ตามด้วยค่าที่วางลงไป จากนั้นสร้างบรรทัดเดียวที่ -c ต้องการ:
printf '%s %s\n' "$EXPECTED" payload.txt > payload.sha256
cat payload.sha256
sha256sum -c payload.sha256มีช่องว่างสองช่องคั่นระหว่าง digest และชื่อไฟล์ ซึ่งเป็นเหตุผลว่าทำไมรูปแบบสตริงจึงมีช่องว่างสองช่อง นั่นคือรูปแบบที่ sha256sum เขียนและรูปแบบที่ -c อ่าน ไฟล์ที่เก็บเฉพาะค่า digest โดยไม่มีข้อมูลอื่นจะไม่ถือว่าเป็นบรรทัด checksum ดังนั้นการตรวจสอบจะปฏิเสธทั้งไฟล์ด้วย no properly formatted checksum lines found แทนที่จะเดาว่าคุณหมายถึงไฟล์ใด บางโครงการเผยแพร่ในรูปแบบ BSD tagged แทน ซึ่งคือ SHA256 (payload.txt) = ตามด้วยค่า digest โดยที่ GNU coreutils จะเขียนรูปแบบนั้นด้วย sha256sum --tag payload.txt และอ่านกลับด้วย -c ดังนั้นคุณสามารถเลือกบันทึกรูปแบบใดก็ได้
เมื่อการตรวจสอบทำงานผิดปกติ ให้ดูรายการนั้นด้วย cat -A SHA256SUMS ซึ่งจะทำเครื่องหมายท้ายทุกบรรทัดด้วย $ และแสดงอักขระที่คุณไม่สามารถมองเห็นได้ตามปกติ บรรทัดที่ลงท้ายด้วย ^M$ แสดงว่าได้รับ carriage return มาจากโปรแกรมแก้ไขข้อความบน Windows โดยที่ GNU sha256sum จะเพิกเฉยต่ออักขระส่วนเกินนั้นและยังคงแสดงผล OK ดังนั้นรายการที่เป็น CRLF จึงไม่ใช่สาเหตุที่ทำให้การตรวจสอบของคุณล้มเหลว แม้ว่าเครื่องมือภายนอก coreutils อาจจะไม่ยอมรับรูปแบบดังกล่าว ให้ปรับรายการที่คุณเก็บไว้ให้เป็นมาตรฐานด้วย tr -d '\r' < SHA256SUMS > SHA256SUMS.clean
Checksum พิสูจน์อะไรได้บ้าง และพิสูจน์อะไรไม่ได้
Checksum พิสูจน์สิ่งเดียวคือ ข้อมูลไบต์บนดิสก์ของคุณเป็นชุดเดียวกับที่สร้างค่า digest ที่ประกาศไว้ ซึ่งครอบคลุมถึงความเสียหายที่เกิดขึ้นโดยอุบัติเหตุทั้งหมด รวมถึงกรณีผู้โจมตีที่ประมาทซึ่งสลับไฟล์บน download mirror แต่ไม่สามารถแก้ไขหน้าเว็บที่ประกาศค่า digest ได้
มันไม่ได้พิสูจน์อะไรเกี่ยวกับความเป็นเจ้าของ ค่า digest เป็นเพียงข้อเท็จจริงเกี่ยวกับข้อมูลไบต์ ไม่ใช่ข้อเท็จจริงเกี่ยวกับตัวบุคคล หากหน้าเว็บหนึ่งให้บริการทั้งไฟล์และค่า digest ผู้ที่สามารถแก้ไขอย่างใดอย่างหนึ่งก็สามารถแก้ไขอีกอย่างได้เช่นกัน และบรรทัด OK ของคุณจะมีความหมายเพียงว่า mirror นั้นสอดคล้องกับตัวเองเท่านั้น ดังนั้น กฎที่ทำให้การตรวจสอบ checksum มีประโยชน์คือ ให้รับค่า digest มาจากแหล่งอื่นที่ไม่ใช่แหล่งเดียวกับที่ดาวน์โหลดไฟล์ เช่น รับค่าจากโดเมนของโครงการโดยตรงผ่าน TLS (transport layer security) ในขณะที่ไฟล์ image มาจาก mirror หรือ torrent วิธีนี้จะทำให้ผู้โจมตีต้องควบคุมแหล่งข้อมูลสองแห่งแทนที่จะเป็นแห่งเดียว นอกจากนี้ มันยังไม่ได้บอกว่าข้อมูลไบต์ที่ผ่านการตรวจสอบแล้วจะทำอะไรเมื่อคุณรันมัน ซึ่งเป็นคำถามแยกต่างหากที่ควรพิจารณาสำหรับทุกสิ่งที่ทำงานในนามของคุณ ตั้งแต่สคริปต์ติดตั้งไปจนถึง dsh plugin ที่ทำงานด้วยสิทธิ์ของ agent ของคุณ
อัลกอริทึมก็มีความสำคัญเช่นกัน SHA-256 (secure hash algorithm, 256-bit output) ยังไม่มีการค้นพบการชนกัน (collision) จนถึงเดือนสิงหาคม 2026 ซึ่งเป็นเหตุผลที่ผู้เผยแพร่เลือกใช้ ส่วน MD5 (message digest 5) และ SHA-1 นั้นไม่ปลอดภัยอีกต่อไป โดยไฟล์สองไฟล์ที่ต่างกันแต่มีค่า MD5 digest เดียวกันสามารถสร้างขึ้นได้ตั้งแต่ปี 2004 และมีการเผยแพร่การโจมตีแบบ chosen-prefix SHA-1 collision ในปี 2020 ไฟล์ MD5SUMS ยังคงใช้ตรวจจับการดาวน์โหลดที่ไม่สมบูรณ์ได้ เพราะความเสียหายแบบสุ่มไม่ใช่การชนกันที่ถูกสร้างขึ้นโดยเจตนา แต่มันไม่สามารถหยุดผู้ที่พยายามหลอกลวงคุณได้ เมื่อโครงการประกาศค่าทั้งสองแบบ ให้เลือกใช้บรรทัด SHA-256
เมื่อลายเซ็นเข้ามามีบทบาท
ลายเซ็นดิจิทัลช่วยปิดช่องว่างที่ digest ทิ้งไว้ ผู้เผยแพร่จะลงนามในไฟล์ digest ด้วย private key และคุณจะตรวจสอบด้วย public key ของพวกเขา: gpg --verify SHA256SUMS.asc SHA256SUMS หากการตรวจสอบผ่าน แสดงว่ารายการ digest นั้นมาจากผู้ที่ถือครองกุญแจดังกล่าว จากนั้น sha256sum -c SHA256SUMS จะเชื่อมโยงไฟล์บนดิสก์ของคุณเข้ากับรายการนั้น ทำให้เกิดห่วงโซ่ความน่าเชื่อถือตั้งแต่กุญแจไปจนถึงระดับไบต์ของไฟล์
จุดอ่อนจะย้ายไปอยู่ที่ตัวกุญแจ การดึงกุญแจมาจากหน้าเว็บเดียวกับที่ดาวน์โหลดไฟล์จะทำให้ผู้โจมตีสามารถควบคุมทั้งสองส่วนได้ GnuPG แสดงข้อมูลนี้อย่างตรงไปตรงมา โดยการตรวจสอบครั้งแรกจะแสดง Good signature พร้อมกับ WARNING: This key is not certified with a trusted signature! ซึ่ง Good signature หมายความว่าการคำนวณทางคณิตศาสตร์นั้นถูกต้อง แต่ไม่ได้หมายความว่ากุญแจนั้นเป็นของโครงการที่คุณต้องการจริงๆ คุณควรตรวจสอบ fingerprint จากแหล่งที่สอง เช่น เอกสารของโครงการบนโดเมนอื่น หรือแพ็กเกจของ distribution ที่รวมกุญแจนั้นมาให้แล้ว และให้เปรียบเทียบ fingerprint แบบเต็มแทนที่จะดูแค่ 8 ตัวอักษรสุดท้าย นี่คือ ความระมัดระวังระดับเดียวกับที่ควรให้กับ SSH private key ด้วยเหตุผลเดียวกัน คือกุญแจคือการตัดสินใจเรื่องความเชื่อถือ และทุกสิ่งที่ตามมาจะได้รับความเชื่อถือนี้สืบทอดไป
กระบวนการ reproducible builds ยกระดับแนวคิดนี้ไปอีกขั้น digest ที่เผยแพร่อาจผูกมัดคุณไว้กับไบนารีที่สร้างจากเครื่องเดียว แต่เมื่อกระบวนการสร้างของโครงการเป็นแบบ reproducible ใครก็ตามสามารถคอมไพล์ซอร์สโค้ดเดียวกันและได้ผลลัพธ์ที่เหมือนกันทุกไบต์ ทำให้ผู้สร้างอิสระรายอื่นสามารถยืนยัน digest ที่เผยแพร่ได้ แทนที่จะต้องเชื่อถือเซิร์ฟเวอร์เพียงเครื่องเดียว สิ่งนี้มีความสำคัญมากขึ้นทุกปี เนื่องจากโค้ดจำนวนมากถูกส่งผ่านท่อส่งอัตโนมัติและแพตช์ที่เขียนโดยเครื่องจักร การตัดสินใจว่าคุณจะยอมรับสิ่งใดเข้าสู่กระบวนการ build เป็นเรื่องของนโยบาย และ นโยบายโอเพนซอร์สสำหรับโค้ดที่ช่วยโดย AI ก็ทำงานบนห่วงโซ่อุปทานเดียวกันจากอีกด้านหนึ่ง
ตัวจัดการแพ็กเกจของคุณทำสิ่งนี้ให้คุณโดยอัตโนมัติอยู่แล้ว
บน Debian และ Ubuntu นั้น apt จะรันกระบวนการตรวจสอบนี้ทุกครั้งที่มีการติดตั้งโดยที่คุณไม่ต้องร้องขอ ดัชนีแพ็กเกจจะมีค่า SHA-256 digest สำหรับไฟล์ .deb แต่ละไฟล์ ส่วนไฟล์ Release จะเก็บค่า digest ของไฟล์ดัชนีเหล่านั้น และ InRelease จะเก็บลายเซ็นดิจิทัลที่กำกับ Release ไว้ ซึ่งจะถูกตรวจสอบเทียบกับคีย์ใน /usr/share/keyrings และ /etc/apt/trusted.gpg.d เมื่อห่วงโซ่การตรวจสอบนี้ขาดช่วง apt จะแจ้งเตือนทันที เช่น The following signatures couldn't be verified because the public key is not available: NO_PUBKEY เมื่อคีย์ของ repository ภายนอกสูญหาย หรือ Hash Sum mismatch เมื่อดัชนีที่คุณดึงมาไม่ตรงกับไฟล์ Release ที่มีการลงลายเซ็นไว้ ซึ่งมักหมายความว่า caching proxy ส่งไฟล์เก่ามาให้ หรือคุณดึงข้อมูลจาก mirror ในขณะที่กำลังซิงค์ข้อมูลอยู่
นั่นคือมาตรฐานที่ควรใช้ตัดสินเมื่อหน้าเว็บของโปรเจกต์แนะนำให้คุณใช้ pipe สคริปต์จาก curl เข้าสู่ shell โดยตรง เพราะไม่มีสิ่งใดตรวจสอบความถูกต้องของข้อมูล และคุณก็ไม่เคยเห็นเนื้อหาของมันเลย ยิ่งไปกว่านั้น เซิร์ฟเวอร์สามารถส่งข้อมูลชุดหนึ่งให้สคริปต์และอีกชุดหนึ่งให้เบราว์เซอร์ได้ ทำให้คุณไม่มีสำเนาไว้ตรวจสอบภายหลัง ให้ดาวน์โหลดลงไฟล์ด้วย curl -fsSL <url> -o install.sh, ตรวจสอบค่า hash, อ่านเนื้อหาด้วย less แล้วจึงค่อยรันสคริปต์นั้น นิสัยนี้ใช้เวลาเพียงประมาณยี่สิบวินาที และเป็นนิสัยเดียวกันกับที่ควรเริ่มทำบน VPS เครื่องใหม่ในช่วงสิบนาทีแรก ก่อนที่จะติดตั้งสิ่งอื่นใดลงในเครื่อง
เก็บรายการ digest สำหรับสิ่งที่ติดตั้งด้วยตนเอง
แพ็กเกจที่ติดตั้งโดย apt จะถูกติดตามไว้ แต่ไฟล์ไบนารีที่คุณคัดลอกลงใน /usr/local/bin จะไม่ถูกติดตาม และไม่มีสิ่งใดในระบบคอยเฝ้าดูไฟล์เหล่านั้น รายการ digest จะเปลี่ยนสิ่งนี้ให้เป็นสิ่งที่ตรวจสอบได้ตามต้องการ:
printf 'a second file\n' > notes.txt
sha256sum *.txt > inventory.sha256
sha256sum -c --quiet inventory.sha256--quiet จะไม่แสดงผลลัพธ์ใดๆ เมื่อไฟล์ทุกไฟล์ตรงกัน และจะแสดงเฉพาะบรรทัดที่ตรวจสอบไม่ผ่าน ดังนั้นความเงียบคือการผ่าน และ echo $? จะยืนยันผลด้วย 0 นี่คือรูปแบบที่ควรนำไปใส่ในงานที่ตั้งเวลาไว้ --status จะทำงานละเอียดกว่าโดยไม่แสดงผลลัพธ์ใดๆ เลย และให้สถานะการทำงาน (exit status) แก่คุณเท่านั้น ให้ชี้รูปแบบเดียวกันไปยังไฟล์จริงด้วย sha256sum /usr/local/bin/* > ~/local-bin.sha256 แล้วคุณจะได้ข้อมูลพื้นฐาน (baseline) พาธจะถูกจัดเก็บในรายการตามที่คุณพิมพ์ไว้ ดังนั้นการใช้พาธแบบสัมบูรณ์ (absolute path) จะทำให้การตรวจสอบทำงานได้จากทุกไดเรกทอรี
ต้องมีความชัดเจนว่าข้อมูลพื้นฐานนี้มีค่าเพียงใด มันสามารถตรวจพบไฟล์ที่ถูกเปลี่ยนแปลงได้ แต่มันไม่สามารถตรวจพบผู้โจมตีที่มีสิทธิ์ root อยู่แล้วได้ เนื่องจากผู้โจมตีรายนั้นสามารถเขียนทับ inventory.sha256 ได้ง่ายพอๆ กับที่พวกเขาเขียนทับไฟล์ไบนารี หากคุณต้องการให้รายการนี้มีความหมาย คุณควรเก็บรายการไว้นอกเครื่อง ซึ่งเป็นส่วนหนึ่งของคำถามที่กว้างกว่าเรื่อง คุณกำลังเชื่อใจ VPS ของคุณมากน้อยเพียงใด และใครอื่นบ้างที่สามารถเข้าถึงดิสก์ภายใต้ VPS นั้นได้
FAQ
การที่ checksum ตรงกันหมายความว่าไฟล์ที่ดาวน์โหลดมาปลอดภัยหรือไม่?
ไม่ปลอดภัย หมายความเพียงว่าไบต์ที่คุณมีตรงกับค่า digest ที่คุณนำไปเปรียบเทียบ หากผู้โจมตีควบคุมหน้าเว็บที่เผยแพร่ค่า digest นั้นได้ พวกเขาก็จะเผยแพร่ค่า digest ของไฟล์ที่พวกเขาทำขึ้นเอง และการตรวจสอบของคุณก็จะแสดงผลเป็น OK การที่ค่าตรงกันเป็นเพียงการยืนยันความสอดคล้องของข้อมูลเท่านั้น การยืนยันความปลอดภัยต้องอาศัยลายเซ็นดิจิทัลที่ผ่านการตรวจสอบด้วยกุญแจ (key) ซึ่งคุณได้รับมาจากแหล่งอื่นที่เชื่อถือได้ และเมื่อนั้นค่า digest ถึงจะได้รับความน่าเชื่อถือตามไปด้วย
ทำไม sha256sum -c ถึงแสดงผลเป็น FAILED open or read?
เพราะโปรแกรมไม่ได้อ่านไฟล์นั้นเลย บรรทัดก่อนหน้าจะระบุ No such file or directory พร้อมชื่อไฟล์ที่โปรแกรมพยายามค้นหา ชื่อไฟล์ภายในไฟล์ SHA256SUMS จะอ้างอิงตามไดเรกทอรีที่คุณรันคำสั่ง ดังนั้นให้เปลี่ยนไดเรกทอรีไปยังตำแหน่งที่เก็บไฟล์ที่ดาวน์โหลดมาแล้วรันคำสั่งใหม่อีกครั้ง หากในรายการมีชื่อไฟล์ที่คุณไม่ได้ดาวน์โหลดมาด้วย ให้เพิ่มแฟล็ก --ignore-missing การแสดงผล FAILED โดยไม่มี open or read เป็นสถานการณ์ตรงกันข้าม คือโปรแกรมได้อ่านไฟล์แล้วแต่ค่า digest ไม่ตรงกัน
MD5 เพียงพอสำหรับการตรวจสอบไฟล์ที่ดาวน์โหลดหรือไม่?
หากใช้เพื่อตรวจสอบความเสียหายจากอุบัติเหตุ ถือว่าเพียงพอ การโอนถ่ายไฟล์ที่ไม่สมบูรณ์หรือบล็อกข้อมูลบนดิสก์ที่เสียหายจะไม่ทำให้ค่า MD5 ตรงกันโดยบังเอิญ แต่หากใช้ป้องกันผู้โจมตี ถือว่าไม่เพียงพอ เนื่องจากมีการสร้างไฟล์สองไฟล์ที่ให้ค่า MD5 เหมือนกันได้มาตั้งแต่ปี 2004 และ SHA-1 ก็ถูกโจมตีด้วยวิธี chosen-prefix collision ได้ในปี 2020 ให้เลือกใช้บรรทัด SHA-256 เมื่อโปรเจกต์เผยแพร่ทั้งสองค่า และให้ถือว่าโปรเจกต์ที่ใช้เฉพาะ MD5 เป็นสัญญาณของกระบวนการปล่อยซอฟต์แวร์ที่ล้าสมัย
sha256sum -c และ gpg --verify แตกต่างกันอย่างไร?
sha256sum -c ใช้พิสูจน์ว่าไฟล์ตรงกับค่า digest ที่ระบุ ส่วน gpg --verify ใช้พิสูจน์ว่าไฟล์ digest นั้นถูกลงนามโดยผู้ถือครอง private key ที่ระบุ ทั้งสองคำสั่งตอบคำถามคนละประเด็น ดังนั้นควรใช้ทั้งสองคำสั่งเมื่อโปรเจกต์มีให้เลือกใช้ทั้งคู่ ลายเซ็นดิจิทัลจะทำให้รายการ digest น่าเชื่อถือ และรายการ digest นั้นก็จะทำให้ไฟล์ที่ดาวน์โหลดมาน่าเชื่อถือตามไปด้วย
ฉันจะตรวจสอบไฟล์หนึ่งไฟล์เทียบกับค่า digest ที่แสดงบนหน้าเว็บได้อย่างไร?
อย่าใช้วิธีไล่สายตาเปรียบเทียบตัวอักษร ให้บันทึกค่า digest และชื่อไฟล์ไว้ในบรรทัดเดียวกันโดยเว้นวรรคสองช่อง จากนั้นรันคำสั่ง sha256sum -c กับไฟล์นั้นแล้วอ่านผลลัพธ์ OK หรือ FAILED ที่แสดงออกมา การสร้างบรรทัดด้วยคำสั่ง printf '%s %s\n' จะช่วยหลีกเลี่ยงความผิดพลาดในการจัดรูปแบบที่อาจทำให้ sha256sum ปฏิเสธไฟล์พร้อมแสดงข้อความ no properly formatted checksum lines found