อ้างอิง / หลักฐาน
พยานอิสระ
เรียกใช้ witness ด้วยกุญแจและบอทของตัวเอง เผยแพร่จุดตรวจสอบที่ลงนามแล้วไปยังช่อง และตรวจสอบการส่งออกข้อมูลกับจุดตรวจสอบดังกล่าว
การตั้งค่าบอทและพร็อกซีในภาษารัสเซีย
ผู้เก็บข้อมูลจะลงนามในบันทึกของตนเอง ดังนั้นผู้ใดก็ตามที่ควบคุมผู้เก็บข้อมูลและกุญแจของมัน ก็สามารถ ในหลักการ เขียนใหม่หรือตัดทอนบันทึกและลงนามใหม่ได้ Witness ทำให้สิ่งนั้น สามารถตรวจพบได้ นี่เป็นกระบวนการแยกต่างหาก — คอนเทนเนอร์อีกตัว หรือดีกว่าคือเซิร์ฟเวอร์ที่บุคคลอื่น ดำเนินการ — ซึ่งจะดึงส่วนหัวของบันทึกที่ลงนามจากเครื่องมือเก็บข้อมูลทุกไม่กี่นาที ลงนามสิ่งที่ มันเห็นด้วยกุญแจของตัวเอง เก็บไว้ในบันทึกของตัวเอง และโพสต์ไปยังช่อง Telegram
แผนภาพในรูปแบบข้อความ
- Collector → Witness (จุดตรวจสอบที่ลงนาม: จำนวนบันทึก + ค่าแฮชส่วนหัว)
- Witness → สมุดบันทึกพยาน, กุญแจส่วนตัว
- Witness → ช่อง Telegram (โพสต์ที่ลงนามผ่านบอทของระบบเอง)
- ไฟล์ ZIP ของหลักฐาน → verify.py
- สมุดบันทึกพยาน, กุญแจส่วนตัว → verify.py
- ช่อง Telegram → verify.py (หน้าส่งออก Telegram Desktop หรือ t.me/s)
สิ่งที่ TgWitness สามารถทำได้ และสิ่งที่มันทำไม่ได้#
| TgWitness มี | พยานไม่เคย |
|---|---|
| โทเค็นพยานแบบอ่านอย่างเดียวสำหรับพื้นที่ทำงานหนึ่งแห่ง | เซสชัน Telegram หรือข้อมูลรับรอง API ของผู้เก็บข้อมูล |
| กุญแจ Ed25519 และบันทึกของตัวเอง | ห้องเก็บรักษาข้อมูลของระบบเก็บรวบรวม, กุญแจลงนาม หรือ โทเค็นแผงควบคุม |
| โทเค็นบอท Telegram ของตัวเอง | เนื้อหาข้อความ: ส่วนหัวประกอบด้วยจำนวนบันทึกและค่าแฮช |
โทเค็นถูกสร้างขึ้นบนหน้า Witness ของแผงควบคุม แสดงขึ้นเพียงครั้งเดียว และถูกเก็บไว้เพียงในรูปแบบ
SHA-256 เท่านั้น มันเปิดจุดปลายทาง (endpoint) เพียงหนึ่งจุดเท่านั้น คือ GET /api/witness/head ซึ่งส่งคืน
จุดตรวจสอบ (checkpoint) ที่เพิ่งลงนาม พร้อมตัวนับการเก็บข้อมูลที่ไม่มีเนื้อหา (content-free) ที่ลงนามแล้ว และสถานะการทำงาน
มันไม่สามารถเปิดแผงควบคุม อ่านเนื้อหาข้อความ หรือเปลี่ยนการตั้งค่าได้ และ
โทเค็นของแผงควบคุมไม่ได้รับการยอมรับที่นั่น สามารถเพิกถอนโทเค็นได้บนหน้าเดียวกัน เครื่องมือเก็บข้อมูลจะบันทึก
เมื่อกุญแจพยานใหม่เริ่มตรวจสอบ (witness.seen) และแสดงการตรวจสอบครั้งสุดท้ายต่อโทเค็น;
พยานที่ยังไม่ตรวจสอบภายใน 2.5 ช่วงเวลากำหนดจะถูกทำเครื่องหมายว่าเกินกำหนด
พยานใหม่จะส่งคำท้าแบบสุ่มใน การโหวตแต่ละครั้ง; คำสั่งบันทึกจะสะท้อนคำท้าดังกล่าวภายใต้ลายเซ็นของผู้รวบรวม ตัวนับ ถูกผูกกับจุดตรวจสอบที่แม่นยำและถูกรวมไว้ในโพสต์ของพยานที่ลงนามแล้ว พยานรุ่นเก่า ยังคงได้รับการยอมรับจากพยานแบบสแตนด์อโลน การเพิ่มขนาดของบันทึกเพียงอย่างเดียวจะไม่ถูกนับเป็นข้อความใหม่
สิ่งที่ระบบตรวจสอบและบันทึก#
ทุกช่วงเวลา (ค่าเริ่มต้นคือ 10 นาที) TgWitness จะ:
- ดึงส่วนหัวมาเอง (ผู้รวบรวมข้อมูลไม่สามารถส่งหรือข้ามส่วนหัวนี้ได้);
- ตรวจสอบลายเซ็นของผู้เก็บข้อมูล, กุญแจผู้เก็บข้อมูลที่ถูกตรึง (
--collector-fingerprint, หรือกุญแจแรกที่พบ), จำนวนที่ไม่ลดลง และส่วนหัวที่ไม่เปลี่ยนแปลงที่จำนวนที่ไม่เปลี่ยนแปลง; - เพิ่มบันทึกที่ลงนามแล้วลงในบันทึกของตนเอง:
witness.anchorด้วยสถานะok,key_changed,rollback(จำนวนบันทึกน้อยกว่าเดิม),fork(ความยาวเท่ากัน แต่ส่วนหัวต่างกัน ) หรือinvalid(คำตอบไม่ผ่านการตรวจสอบ), หรือwitness.no_responseเมื่อ ผู้รวบรวมข้อมูลไม่ตอบกลับ; - ส่งผลลัพธ์ไปยังช่อง (channel) พร้อมลายเซ็น รวมถึงข้อความ "no answer" ในขณะที่ TgWitness
กำลังทำงานและสามารถเข้าถึง Bot API ได้ ID ของการโพสต์ถูกบันทึกไว้ (
witness.posted), รวมถึงการโพสต์ที่ล้มเหลวด้วย (witness.post_failed).
โพสต์มีลักษณะดังนี้; บรรทัดสุดท้ายมีข้อความที่ลงนาม:
TgWitness witness #42 · journal head
Collector 3fa9c2d1e0b4a7f6: 18234 records
Head 9b1f…c07e
2026-10-28T19:40:00.123+00:00
TGW1.eyJhdCI6…<statement>.<signature>
Run a witness#
คุณจำเป็นต้องมีบอต Telegram (สร้างบอตด้วย @BotFather), ช่องที่บอตดังกล่าวเป็น ผู้ดูแลระบบ และที่อยู่ของผู้เก็บข้อมูลที่สามารถเข้าถึงได้จากผู้ให้คำพยาน — ผ่าน HTTPS นอก เครือข่ายส่วนตัว (ดูโปรไฟล์ HTTPS ในส่วนการติดตั้ง)
เปิด Extras → บอทในช่องของคุณ → ตั้งค่าบอท
ในแผงควบคุม สามขั้นตอน ได้แก่
สิทธิ์การเข้าถึงแบบอ่านอย่างเดียว, ช่องของคุณ และช่วงเวลา จากนั้นจึงเริ่มใช้งาน witness นโยบายการเผยแพร่
พร็อกซี HTTP/SOCKS5 (เลือกได้) และที่อยู่ API บอทที่กำหนดเอง อยู่ในส่วนการตั้งค่าขั้นสูง
แบบฟอร์ม
จะดาวน์โหลด witness.json
พร้อมกุญแจผู้เก็บข้อมูล (collector key) ของพื้นที่ทำงานนี้ที่ถูกตรึงไว้ ดาวน์โหลด
โทเค็นอ่านอย่างเดียวที่สร้างขึ้นใหม่โดยใช้ตัวเลือก “บันทึกไฟล์การเข้าถึง
เป็น witness-token.txt
” และวางมันพร้อมกับ bot-token.txt
ที่สร้างขึ้นบนโฮสต์ของ witness ข้างๆ ไฟล์ JSON นั้น ผู้เก็บข้อมูลจะไม่ได้รับโทเค็นของบอทเลย
การดาวน์โหลดไม่เริ่มบริการหรือเผยแพร่ข้อความ ไม่มีพยานโครงการที่โฮสต์
ถูกลงทะเบียนโดยอัตโนมัติ
python -m tgwitness.witness run --config witness.json --check-config
python -m tgwitness.witness run --config witness.json
python -m tgwitness.witness fingerprint --config witness.json
คำสั่งแรกตรวจสอบไฟล์การตั้งค่าและไฟล์ลับโดยไม่มีการส่งคำขอผ่านเครือข่ายหรือการสร้าง กุญแจ เส้นทางใน JSON เป็นเส้นทางสัมพัทธ์กับไฟล์นั้น ส่วนเส้นทาง CLI/สภาพแวดล้อมเป็นเส้นทางสัมพัทธ์กับ ไดเรกทอรีทำงาน เก็บลายนิ้วมือของพยานไว้ภายนอกโฮสต์ของมัน ตัวบ่งชี้ การสำรวจครั้งสุดท้ายของตัวเก็บข้อมูลยืนยันเพียงการร้องขอเท่านั้น; การเผยแพร่จะถูกรายงานโดย Proof หรือตรวจสอบ ในบันทึกพยานและช่องสื่อสาร
หากแผงควบคุมอยู่เบื้องหลังอุโมงค์ SSH ให้เปิดเผยเฉพาะจุดสิ้นสุดของ witness ที่กำหนดขอบเขตไว้บน
ชื่อโฮสต์ HTTPS แยกต่างหาก โดยใช้ตัวอย่าง Caddy นี้
พื้นที่ทำงานเริ่มต้นจะใช้ https://witness.example.org ส่วนพื้นที่ทำงานอื่น ๆ จะใช้
https://witness.example.org/profiles/ID โทเค็นยังคงจำเป็น; แผงควบคุมและ
เส้นทาง API อื่น ๆ ของมันจะไม่ถูกส่งต่อโดยโฮสต์เสมือนนั้น
เลือก all สำหรับจุดตรวจสอบที่เผยแพร่เป็นประจำ ช่วงเวลา 5 นาที หมายถึงประมาณ 288
โพสต์ต่อพื้นที่ทำงานต่อวัน changes/problems ปล่อยให้จุดตรวจสอบบางส่วนไม่เผยแพร่โดยเจตนา
MTProxy ใช้สำหรับไคลเอนต์ Telegram ของผู้รวบรวมข้อมูล การตรวจสอบ HTTP ของ Witness และ HTTPS
Bot API ของ Telegram ใช้เส้นทางตรง/HTTP/SOCKS5 ของตนเอง (Bot API)
ข้างๆ ตัวเก็บข้อมูล (collector) โดยใช้ Docker (บนโฮสต์เดียวกัน — กระบวนการและกุญแจอิสระ แต่
ผู้ดำเนินการเดียวกัน): ใส่ค่าลงใน .env และเริ่มโปรไฟล์
TGWITNESS_WITNESS_TOKEN=tgww_...
TGWITNESS_WITNESS_BOT_TOKEN=123456:ABC...
TGWITNESS_WITNESS_CHANNEL=@your_witness_channel
# another workspace: TGWITNESS_WITNESS_COLLECTOR=http://tgwitness:8787/profiles/<workspace ID>
docker compose --profile witness up -d
docker compose logs witness # prints the witness key fingerprint
หากใช้ภาพที่เผยแพร่แล้ว ให้ใช้docker compose --project-directory . -f deploy/compose/compose.image.yaml --profile witness up -d
บนเซิร์ฟเวอร์ของผู้อื่น (พยานอิสระที่แท้จริง): คัดลอกรีโพสิตอรีไปยังที่นั่น ตั้งค่า
TGWITNESS_WITNESS_COLLECTOR=https://your-collector.example.org พร้อมทั้งค่าสามค่าข้างต้น
ใน .env แล้ว
docker compose --project-directory . -f deploy/compose/compose.witness.yaml up -d
หรือโดยไม่ต้องใช้ Docker:
python -m tgwitness.witness run --collector https://your-collector.example.org \
--token-file witness-token.txt --bot-token-file bot-token.txt --channel @your_witness_channel
ตัวเลือก#
| ตัวเลือก | สภาพแวดล้อม | ค่าเริ่มต้น | ความหมาย |
|---|---|---|---|
--interval |
TGWITNESS_WITNESS_INTERVAL |
10 | ระยะเวลาระหว่างการตรวจสอบ: 1–1440 นาที |
--timeout |
_TIMEOUT |
30 | เวลาที่ต้องรอตัวเก็บข้อมูลและ API ของ Bot: 5–600 วินาที |
--post |
_POST |
all |
all: ทุกการตรวจสอบ; changes: ปัญหาใหม่หรือหัวข้อใหม่; problems: มีแต่ปัญหาและคำตอบที่ขาดหายไป |
--title |
_TITLE |
TgWitness witness |
คำแรกๆ ของทุกโพสต์ในช่อง |
--collector-fingerprint |
_COLLECTOR_FINGERPRINT |
– | ให้ปักคีย์ผู้เก็บข้อมูลไว้แทนที่จะเชื่อถือคำตอบแรก |
--proxy |
_PROXY |
direct | socks5://host:port หรือ http://host:port |
--bot-api |
_BOT_API |
https://api.telegram.org |
ที่อยู่ API ของบอท เช่น เซิร์ฟเวอร์ API ของบอทในท้องถิ่น |
--data-dir |
_DATA |
witness-data |
กุญแจ Witness และบันทึก |
--config |
_CONFIG |
– | ไฟล์ JSON พร้อมตัวเลือกใดก็ตามข้างต้น |
ที่อยู่ผู้รวบรวม โทเค็น และช่องมาจาก --collector, --token หรือ
--token-file, --bot-token หรือ --bot-token-file และ --channel, หรือ _COLLECTOR, _TOKEN,
_TOKEN_FILE, _BOT_TOKEN, _BOT_TOKEN_FILE และ _CHANNEL ซึ่งช่วยรักษาความลับไม่ให้ปรากฏใน
รายการกระบวนการ
ไฟล์การตั้งค่าใช้ชื่อตัวเลือกที่มีขีดล่าง (underscore) พร้อมด้วย texts ซึ่งใช้แทนคำ
ในโพสต์ของช่อง:
{"collector": "https://your-collector.example.org", "token_file": "witness-token.txt",
"bot_token_file": "bot-token.txt", "channel": "@your_witness_channel",
"interval": 5, "timeout": 30, "post": "changes", "title": "Partner witness",
"texts": {"ok": "journal head", "no_response": "no answer from the collector", "records": "records"}}
กุญแจ texts: ok, key_changed, rollback, fork, invalid, no_response, collector,
records, head. บรรทัดคำสั่งมีลำดับความสำคัญเหนือสภาพแวดล้อม และสภาพแวดล้อมมีลำดับความสำคัญเหนือไฟล์
ตัวเลือกหรือกุญแจข้อความที่ไม่รู้จักจะหยุดการทำงานของ witness พร้อมแสดงข้อความแจ้งเตือน แทนที่จะถูกละเลย
คำที่ใช้ไม่เคยส่งผลต่อการตรวจสอบ: verify.py จะตรวจสอบโทเค็นที่ลงนามไว้ที่ท้ายทุก
โพสต์ กับ --post changes หรือ problems การตรวจสอบที่ยังไม่ถูกโพสต์ยังคงอยู่ใน
สมุดบันทึกพยาน และ verify.py จะแสดงรายการเหล่านั้นว่ายังไม่เคยถูกโพสต์; บันทึกเริ่มต้นจะระบุชื่อ
นโยบาย การตรวจสอบทุกครั้งยังคงปรากฏในสมุดบันทึก ดังนั้นการโพสต์น้อยลงหมายถึงเวลา Telegram
อิสระน้อยลง ไม่ใช่การตรวจสอบน้อยลง
แม้ไม่มีช่อง (channel) TgWitness ก็ยังคงเก็บบันทึกไว้ได้ เก็บลายนิ้วมือของกุญแจ TgWitness
(python -m tgwitness.witness fingerprint) ไว้ที่อื่น
ตรวจสอบ#
สำหรับผู้ใช้ TgWitness สามารถส่งออกบันทึกได้ดังนี้:
python -m tgwitness.witness export --out witness.zip
# Docker (add -f deploy/compose/compose.witness.yaml on a witness server):
docker compose exec witness python -m tgwitness.witness export --out /witness/witness.zip
docker compose cp witness:/witness/witness.zip .
จากนั้น สามารถทำได้ทุกที่ โดยใช้ไฟล์ ZIP ที่ลงนามจากเครื่องมือเก็บข้อมูล และช่องสนทนาที่ส่งออกจาก Telegram
Desktop (ส่งออกประวัติการสนทนา
→ JSON จะได้ result.json
) หรือหน้าสาธารณะ https://t.me/s/…
ของมัน:
python verify.py tgwitness-evidence.zip --fingerprint COLLECTOR_SHA256 \
--witness witness.zip --witness-fingerprint WITNESS_SHA256 --channel result.json
verify.py ตรวจสอบบันทึกของ Witness (ห่วงโซ่และลายเซ็น) จากนั้นตรวจสอบว่าทุกหัวข้อความที่
Witness ได้เห็นเป็นส่วนหนึ่งของบันทึกที่ส่งออก: บันทึกที่ตำแหน่งนั้นต้องมี
แฮชที่ตรงกันพอดี หัวข้อความที่ไม่ตรงกันจะผ่านการตรวจสอบไม่สำเร็จ — บันทึกถูกเปลี่ยนแปลงหลังจาก
Witness ได้เห็นมัน นอกจากนี้ยังรายงานหัวข้อความที่เห็นหลังการส่งออก ความผิดปกติที่พยาน
บันทึกไว้ คำตอบที่ล้มเหลว ช่วงเวลามีจุดตรวจสอบที่ตรงกันอยู่ใน
การส่งออกนี้ ("ได้รับการยืนยันจาก X ถึง Y") และช่องว่าง จุดตรวจสอบที่ตามมาไม่ขยายช่วงเวลานั้น
ผลลัพธ์รวมถึงหมายเลขบันทึกที่ตรงกันล่าสุดและจำนวนบันทึกที่ตามมา
ที่ไม่มีจุดตรวจสอบที่ตรงกัน เฉพาะคำตอบที่ลงนามด้วยกุญแจของไฟล์ส่งออกเองเท่านั้นที่นับ: ไฟล์ส่งออกที่ลงนาม
ด้วยกุญแจที่ผู้เป็นพยานไม่เคยเห็นจะถูกรายงานว่าไม่ได้รับการเป็นพยาน และหากไม่มี--fingerprint ผู้
ลงนามจะยังคงไม่ถูกตรึง ด้วย--channel ทุกโพสต์ที่ลงนามต้องตรงกับบันทึกในสมุดบันทึกของผู้เป็นพยาน
บันทึกต่อบันทึก: โพสต์ที่เปลี่ยนแปลงจะล้มเหลวในการตรวจสอบ ส่วนโพสต์ที่ขาดหายไปจะถูกรายการไว้ วันที่ใน
ไฟล์ส่งออก JSON ของ Telegram ที่ให้มา เป็นข้อมูลเมตาที่แก้ไขได้ ซึ่งอยู่นอกโทเค็นผู้เป็นพยานที่ลงนาม
การตรงกับโทเค็นไม่ยืนยันวันที่เผยแพร่; ผลลัพธ์จะรายงานอย่างชัดเจน
ว่าการตรวจสอบเวลาเผยแพร่ไม่ได้ดำเนินการ
จำเป็นต้องมีขอบเขตการส่งออกที่มีผู้เป็นพยาน#
สำหรับการส่งต่อข้อมูลที่ต้องรวมถึงบันทึกสุดท้ายที่มีพยานรับรอง ให้เพิ่ม --require-witness:
python verify.py tgwitness-evidence.zip --fingerprint COLLECTOR_SHA256 \
--witness witness.zip --witness-fingerprint WITNESS_SHA256 --require-witness
สิ่งนี้ต้องการลายนิ้วมือของพยานที่เก็บรักษาไว้อย่างอิสระและจุดตรวจสอบที่ตรงกัน
ที่จุดสิ้นสุดที่แม่นยำของการส่งออกนี้ จุดตรวจสอบที่ครอบคลุมเพียงส่วนนำหน้าก่อนหน้านี้
ไม่เพียงพอ ให้หยุดการเก็บข้อมูลชั่วคราว ให้พยานสังเกตสถานะสุดท้าย และส่งออก
ก่อนที่จะมีการเขียนบันทึกเพิ่มเติม; หากบันทึกมีการเปลี่ยนแปลง ให้เก็บจุดตรวจสอบอีกจุดและ
ส่งออกสถานะนั้น จุดตรวจสอบที่สร้างขึ้นภายหลังเพียงอย่างเดียวไม่สามารถตรวจสอบค่าแฮชสุดท้ายของการส่งออกที่สั้นกว่าได้
เมื่อมีการระบุ --channel ด้วย การขาดโพสต์ที่อ้างว่ามีอยู่หรือชุดการจับคู่ที่ว่างเปล่าจะทำให้การตรวจสอบ
ที่เข้มงวดนี้ล้มเหลว หากไม่มีตัวบ่งชี้นี้ การตรวจสอบความสมบูรณ์แบบปกติจะยังคงรายงาน
บันทึกที่ไม่มีพยานยืนยัน โดยไม่ปฏิเสธอาร์ไคฟ์ที่สมบูรณ์ในส่วนอื่น
ธงนี้ช่วยรักษาความสอดคล้องกับบันทึกพยานที่ได้รับการจัดเตรียมและตรึงไว้แล้ว ผู้ดำเนินการ ยังคงต้องยืนยันความเป็นอิสระของพยานและเก็บรักษาบันทึกของพยานไว้อย่างแยกต่างหาก ธงนี้ไม่ยืนยันความจริงของข้อความ การเก็บรวบรวมที่ครบถ้วน หรือระยะเวลาการทำงานที่วัดได้อย่างอิสระ
Witness แสดงให้เห็นว่าผู้เก็บข้อมูลได้รายงานอะไรในช่วงเวลาดังกล่าว และว่าการส่งออกข้อมูลในภายหลังสอดคล้อง กับข้อมูลนั้น มันไม่แสดงว่าผู้เก็บข้อมูลได้บันทึกทุกสิ่งที่ Telegram ส่งมา หรือ ว่าเนื้อหาของข้อความนั้นเป็นความจริง Witness ที่ถูกดำเนินการโดยผู้ดำเนินการเดียวกันบนเครื่องเดียวกันนั้น มีความน่าเชื่อถือต่ำกว่าเมื่อถูกดำเนินการโดยบุคคลอื่น
การเพิ่มจำนวนเพียงอย่างเดียวไม่สามารถยืนยันความต่อเนื่องแบบเพิ่มข้อมูลเท่านั้น (append-only) บนออนไลน์ได้: การเปรียบเทียบแบบออฟไลน์ ต้องตรวจสอบให้ตรงกันระหว่างแฮชของส่วนนำ (prefix hash) ที่เก็บไว้กับข้อมูลส่งออกทั้งหมดจากตัวเก็บรวบรวม ช่วงเวลาที่ Witness หยุดทำงานหรือการเผยแพร่ล้มเหลวจะทิ้งช่วงว่างที่ไม่มีจุดอ้างอิงจากภายนอก โพสต์ที่หายไป สามารถรายงานได้โดยเปรียบเทียบกับบันทึกของ Witness ที่เก็บรักษาไว้; ทั้งช่อง (channel) และเซิร์ฟเวอร์ ที่ควบคุมโดยผู้ดำเนินการเดียวกัน ล้วนไม่ใช่คลังข้อมูลของบุคคลที่สามที่ไม่สามารถเปลี่ยนแปลงได้