TgWitness / เอกสาร

อ้างอิง / หลักฐาน

พยานอิสระ

เรียกใช้ witness ด้วยกุญแจและบอทของตัวเอง เผยแพร่จุดตรวจสอบที่ลงนามแล้วไปยังช่อง และตรวจสอบการส่งออกข้อมูลกับจุดตรวจสอบดังกล่าว

การตั้งค่าบอทและพร็อกซีในภาษารัสเซีย

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

แผนผังกระบวนการCollector → Witness (จุดตรวจสอบที่ลงนาม: จำนวนบันทึก + ค่าแฮชส่วนหัว); Witness → สมุดบันทึกพยาน, กุญแจส่วนตัว; Witness → ช่อง Telegram (โพสต์ที่ลงนามผ่านบอทของระบบเอง); ไฟล์ ZIP ของหลักฐาน → verify.py; สมุดบันทึกพยาน, กุญแจส่วนตัว → verify.py; ช่อง Telegram → verify.py (หน้าส่งออก Telegram Desktop หรือ t.me/s)CollectorWitnessสมุดบันทึกพยาน,กุญแจส่วนตัวช่อง Telegramไฟล์ ZIP ของหลักฐานverify.pyจุดตรวจสอบที่ลงนาม:จำนวนบันทึก + ค่าแฮชส่วนหัวโพสต์ที่ลงนามผ่านบอทของระบบเองหน้าส่งออก Telegram Desktopหรือ t.me/s
แผนภาพในรูปแบบข้อความ
  1. Collector → Witness (จุดตรวจสอบที่ลงนาม: จำนวนบันทึก + ค่าแฮชส่วนหัว)
  2. Witness → สมุดบันทึกพยาน, กุญแจส่วนตัว
  3. Witness → ช่อง Telegram (โพสต์ที่ลงนามผ่านบอทของระบบเอง)
  4. ไฟล์ ZIP ของหลักฐาน → verify.py
  5. สมุดบันทึกพยาน, กุญแจส่วนตัว → verify.py
  6. ช่อง 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 จะ:

  1. ดึงส่วนหัวมาเอง (ผู้รวบรวมข้อมูลไม่สามารถส่งหรือข้ามส่วนหัวนี้ได้);
  2. ตรวจสอบลายเซ็นของผู้เก็บข้อมูล, กุญแจผู้เก็บข้อมูลที่ถูกตรึง (--collector-fingerprint, หรือกุญแจแรกที่พบ), จำนวนที่ไม่ลดลง และส่วนหัวที่ไม่เปลี่ยนแปลงที่จำนวนที่ไม่เปลี่ยนแปลง;
  3. เพิ่มบันทึกที่ลงนามแล้วลงในบันทึกของตนเอง: witness.anchor ด้วยสถานะ ok, key_changed, rollback (จำนวนบันทึกน้อยกว่าเดิม), fork (ความยาวเท่ากัน แต่ส่วนหัวต่างกัน ) หรือ invalid (คำตอบไม่ผ่านการตรวจสอบ), หรือ witness.no_response เมื่อ ผู้รวบรวมข้อมูลไม่ตอบกลับ;
  4. ส่งผลลัพธ์ไปยังช่อง (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) และเซิร์ฟเวอร์ ที่ควบคุมโดยผู้ดำเนินการเดียวกัน ล้วนไม่ใช่คลังข้อมูลของบุคคลที่สามที่ไม่สามารถเปลี่ยนแปลงได้