# स्वतंत्र गवाह

Canonical page: https://phishdestroy.github.io/TgWitness/hi/docs/reference/witness/

अपनी कुंजी और बॉट के साथ एक विटनेस चलाएँ, एक चैनल पर हस्ताक्षरित चेकपॉइंट प्रकाशित करें और उनके विरुद्ध एक्सपोर्ट्स की जाँच करें।

[रूसी में बॉट और प्रॉक्सी की सेटिंग](https://github.com/phishdestroy/TgWitness/blob/main/docs/ru/WITNESS.md)।

एक कलेक्टर अपने स्वयं के जर्नल पर हस्ताक्षर करता है, इसलिए जो कोई भी कलेक्टर और उसकी कुंजी को नियंत्रित करता है, वह सिद्धांत रूप में जर्नल को फिर से लिख या संक्षिप्त कर सकता है और फिर से हस्ताक्षर कर सकता है। एक गवाह इसे पता लगाने योग्य बनाता है। यह एक अलग प्रक्रिया है — एक और कंटेनर, या बेहतर कहें तो कोई और चलाया हुआ सर्वर — जो हर कुछ मिनटों में कलेक्टर के हस्ताक्षरित जर्नल हेड को प्राप्त करता है, जो उसने देखा उसे अपनी कुंजी से हस्ताक्षरित करता है, उसे अपने स्वयं के जर्नल में रखता है और एक टेलीग्राम चैनल पर पोस्ट करता है।

प्रवाह आरेख · संग्रहकर्ता → गवाह (हस्ताक्षरित चेकपॉइंट: रिकॉर्ड की संख्या + हेड हैश); गवाह → विटनेस जर्नल, अपनी कुंजी; गवाह → टेलीग्राम चैनल (अपने स्वयं के बॉट के माध्यम से हस्ताक्षरित पोस्ट); साक्ष्य ज़िप → verify.py; विटनेस जर्नल, अपनी कुंजी → verify.py; टेलीग्राम चैनल → verify.py (टेलीग्राम डेस्कटॉप एक्सपोर्ट या t.me/s पृष्ठ) · संग्रहकर्ता · गवाह · विटनेस जर्नल, अपनी कुंजी · टेलीग्राम चैनल · साक्ष्य ज़िप · verify.py · हस्ताक्षरित चेकपॉइंट: · रिकॉर्ड की संख्या + हेड हैश · अपने स्वयं के बॉट के माध्यम · से हस्ताक्षरित पोस्ट · टेलीग्राम डेस्कटॉप एक्सपोर्ट · या t.me/s पृष्ठ

**चित्र को पाठ के रूप में**

1. संग्रहकर्ता → गवाह (हस्ताक्षरित चेकपॉइंट: रिकॉर्ड की संख्या + हेड हैश)
2. गवाह → विटनेस जर्नल, अपनी कुंजी
3. गवाह → टेलीग्राम चैनल (अपने स्वयं के बॉट के माध्यम से हस्ताक्षरित पोस्ट)
4. साक्ष्य ज़िप → verify.py
5. विटनेस जर्नल, अपनी कुंजी → verify.py
6. टेलीग्राम चैनल → verify.py (टेलीग्राम डेस्कटॉप एक्सपोर्ट या t.me/s पृष्ठ)

## गवाह को क्या मिलता है, और क्या नहीं मिलता

| गवाह के पास है | गवाह ने कभी नहीं |
| --- | --- |
| एक कार्यक्षेत्र के लिए केवल-पठन **विटनेस टोकन** | संग्रहकर्ता का टेलीग्राम सत्र या एपीआई क्रेडेंशियल्स |
| अपनी Ed25519 कुंजी और जर्नल | संग्रहकर्ता का तिजोरी, हस्ताक्षर कुंजी या पैनल टोकन |
| इसका अपना टेलीग्राम बॉट टोकन | संदेश सामग्री: हेडर में रिकॉर्ड की संख्या और एक हैश होता है |

टोकन पैनल के **विटनेस** पेज पर बनाया जाता है, एक बार दिखाया जाता है और केवल एक SHA-256 के रूप में संग्रहीत किया जाता है। यह ठीक एक एंडपॉइंट, `GET /api/witness/head`, खोलता है, जो एक ताज़ा हस्ताक्षरित चेकपॉइंट के साथ-साथ हस्ताक्षरित सामग्री-मुक्त संग्रह काउंटर और परिचालन स्वास्थ्य लौटाता है। यह पैनल नहीं खोल सकता, संदेश की सामग्री नहीं पढ़ सकता या सेटिंग्स नहीं बदल सकता, और पैनल टोकन वहां स्वीकार नहीं किया जाता है। उसी पेज पर टोकन को रद्द करें। कलेक्टर यह रिकॉर्ड करता है कि एक नई विटनेस कुंजी (`witness.seen`) कब जांच शुरू करती है और प्रति टोकन अंतिम जांच दिखाता है; एक विटनेस जो 2.5 अंतरालों के भीतर जांच नहीं करता है, उसे समय-सीमा समाप्त (overdue) के रूप में चिह्नित किया जाता है।

नए गवाह प्रत्येक पोल पर एक यादृच्छिक चुनौती भेजते हैं; कैप्चर स्टेटमेंट इसे कलेक्टर के हस्ताक्षर के नीचे दोहराता है। काउंटर सटीक चेकपॉइंट से बंधे होते हैं और हस्ताक्षरित गवाह पोस्ट में शामिल किए जाते हैं। लेगसी हेड्स स्टैंडअलोन गवाह द्वारा स्वीकारे जाते रहते हैं। केवल जर्नल की वृद्धि को कभी भी नए संदेश के रूप में नहीं गिना जाता है।

## यह क्या जाँचता और रिकॉर्ड करता है

प्रत्येक अंतराल (डिफ़ॉल्ट रूप से 10 मिनट) पर गवाह:

1. स्वयं हेड को प्राप्त करता है (कलेक्टर इसे धकेल या छोड़ नहीं सकता);
2. संग्रहकर्ता के हस्ताक्षर, पिन किए गए संग्रहकर्ता कुंजी (`--collector-fingerprint`, या पहली देखी गई कुंजी), एक गैर-घटती गिनती और एक अपरिवर्तित गिनती पर अपरिवर्तित हेड का सत्यापन करता है;
3. अपने स्वयं के जर्नल में एक हस्ताक्षरित रिकॉर्ड जोड़ता है: `witness.anchor` स्थिति `ok`, `key_changed`, `rollback` (पहले से कम रिकॉर्ड), `fork` (लंबाई समान, अलग हेडर) या `invalid` (उत्तर सत्यापन में विफल रहा), या `witness.no_response` जब संग्रहकर्ता ने उत्तर नहीं दिया;
4. परिणाम को चैनल पर पोस्ट करता है, हस्ताक्षरित, जिसमें "कोई उत्तर नहीं" भी शामिल है, जब तक कि गवाह चल रहा हो और बॉट एपीआई तक पहुँच सकता हो। पोस्ट आईडी रिकॉर्ड की जाती है (`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>
```

## एक विटनेस चलाएँ

आपको एक टेलीग्राम बॉट (@BotFather से एक बनाएँ), एक चैनल जहाँ वह बॉट एक प्रशासक हो, और गवाह से पहुँच योग्य कलेक्टर का पता — निजी नेटवर्क के बाहर HTTPS के माध्यम से ([परिनियोजन](https://phishdestroy.github.io/TgWitness/hi/docs/reference/deployment/) में HTTPS प्रोफ़ाइल देखें)।

**एक्स्ट्रा** खोलें **→ अपने चैनल में एक बॉट →** पैनल में **एक बॉट सेट करें** । तीन चरणों में केवल-पढ़ने की पहुँच, आपके चैनल और अंतराल को कवर किया जाता है, फिर विटनेस लॉन्च किया जाता है। प्रकाशन नीति, वैकल्पिक HTTP/SOCKS5 प्रॉक्सी और कस्टम बॉट API पता **उन्नत सेटिंग्स** के अंतर्गत हैं। यह फ़ॉर्म इस वर्कस्पेस की कलेक्टर कुंजी को पिन करके `witness.json` डाउनलोड करता है। **'Save access file** as' को `witness-token.txt` के साथ नए बनाए गए केवल-पठनीय टोकन को डाउनलोड करें; उसे और विटनेस होस्ट पर बनाए गए `bot-token.txt` को उस 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/वातावरण पथ वर्किंग डायरेक्टरी के सापेक्ष होते हैं। गवाह फिंगरप्रिंट को उसके होस्ट के बाहर बनाए रखें। कलेक्टर का अंतिम-पोल संकेतक केवल अनुरोध की पुष्टि करता है; प्रकाशन की सूचना प्रूफ द्वारा दी जाती है या गवाह जर्नल और चैनल में जाँची जाती है।

यदि पैनल एक SSH टनल के पीछे रहता है, तो [इस कैडी उदाहरण](https://github.com/phishdestroy/TgWitness/blob/main/deploy/Caddyfile.witness.example) के साथ एक अलग HTTPS होस्टनेम पर केवल स्कोप्ड विटनेस एंडपॉइंट को एक्सपोज़ करें। डिफ़ॉल्ट वर्कस्पेस फिर `https://witness.example.org` का उपयोग करता है, अन्य वर्कस्पेस `https://witness.example.org/profiles/ID` का उपयोग करते हैं। टोकन अभी भी आवश्यक हैं; उस वर्चुअल होस्ट द्वारा पैनल और इसके अन्य API रूट फॉरवर्ड नहीं किए जाते हैं।

नियमित रूप से प्रकाशित चेकपॉइंट्स के लिए `all` चुनें। पांच मिनट के अंतराल का मतलब है प्रति कार्यक्षेत्र प्रति दिन लगभग 288 पोस्ट। `changes`/`problems` जानबूझकर कुछ जांचें अप्रकाशित छोड़ देते हैं। MTProxy कलेक्टर के टेलीग्राम क्लाइंट के लिए है। विटनेस HTTP पोलिंग और टेलीग्राम का HTTPS बॉट API अपने स्वयं के डायरेक्ट/HTTP/SOCKS5 रूट ([बॉट API](https://core.telegram.org/bots/api)) का उपयोग करते हैं।

**कलेक्टर के बगल में, 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
```

या डॉकर के बिना:

```
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 | कलेक्टर और बॉट एपीआई के लिए प्रतीक्षा समय, 5–600 सेकंड |
| `--post` | `_POST` | `all` | `all`: हर जाँच; `changes`: एक नया सिर या एक समस्या; `problems`: केवल समस्याएँ और अनुत्तरित प्रश्न |
| `--title` | `_TITLE` | `TgWitness witness` | हर चैनल पोस्ट के पहले शब्द |
| `--collector-fingerprint` | `_COLLECTOR_FINGERPRINT` | – | पहले उत्तर पर भरोसा करने के बजाय कलेक्टर कुंजी को पिन करें |
| `--proxy` | `_PROXY` | सीधा | `socks5://host:port` या `http://host:port` |
| `--bot-api` | `_BOT_API` | `https://api.telegram.org` | बॉट एपीआई पता, उदाहरण के लिए एक स्थानीय बॉट एपीआई सर्वर |
| `--data-dir` | `_DATA` | `witness-data` | विटनेस कुंजी और जर्नल |
| `--config` | `_CONFIG` | – | उपरोक्त किसी भी विकल्प के साथ JSON फ़ाइल |

कलेक्टर एड्रेस, टोकन और चैनल `--collector`, `--token` या `--token-file`, `--bot-token` या `--bot-token-file` और `--channel`, या `_COLLECTOR`, `_TOKEN`, `_TOKEN_FILE`, `_BOT_TOKEN`, `_BOT_TOKEN_FILE` और `_CHANNEL` से आते हैं, जो प्रक्रिया सूची से रहस्यों को बाहर रखता है।

एक कॉन्फ़िग फ़ाइल अंडरस्कोर वाले विकल्प नामों का उपयोग करती है, साथ ही `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`. कमांड लाइन का प्रभाव वातावरण पर, और वातावरण का प्रभाव फ़ाइल पर होता है। अज्ञात विकल्प या टेक्स्ट कुंजियाँ अनदेखा किए जाने के बजाय एक संदेश के साथ विटनेस को रोक देती हैं। शब्दावली सत्यापन को कभी प्रभावित नहीं करती: verify.py हर पोस्ट के अंत में हस्ताक्षरित टोकन की जाँच करता है। `--post changes` या `problems` के साथ, जो जाँचें पोस्ट नहीं की गई थीं वे अभी भी विटनेस जर्नल में होती हैं और `verify.py` उन्हें कभी पोस्ट न किए गए के रूप में सूचीबद्ध करता है; स्टार्ट रिकॉर्ड नीति का नाम बताता है। हर जाँच अभी भी जर्नल में दिखाई देती है, इसलिए कम पोस्ट का मतलब कम स्वतंत्र टेलीग्राम समय होता है, न कि कम जाँचें।

चैनल के बिना भी विटनेस अपना जर्नल रखता है। विटनेस की कीफिंगरप्रिंट (`python -m tgwitness.witness fingerprint`) को कहीं और रखें।

## सत्यापित करें

गवाह पक्ष से, इसका जर्नल निर्यात करें:

```
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 और टेलीग्राम डेस्कटॉप से एक्सपोर्ट किए गए चैनल (*चैट इतिहास एक्सपोर्ट करें* → 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` गवाह जर्नल (चेन और हस्ताक्षर) की जाँच करता है, फिर यह कि **गवाह द्वारा देखा गया हर हेड निर्यात किए गए जर्नल का हिस्सा है**: उस गिनती पर रिकॉर्ड में ठीक वही हैश होना चाहिए। जो हेड मेल नहीं खाता, वह सत्यापन में विफल हो जाता है — गवाह द्वारा देखने के बाद जर्नल को बदला गया था। यह निर्यात के बाद देखे गए हेड्स, गवाह द्वारा दर्ज की गई विसंगतियों, असफल हुए उत्तरों, उन अवधियों जिनके मिलते-जुलते चेकपॉइंट इस निर्यात में मौजूद हैं ("X से Y तक गवाह द्वारा सत्यापित") और अंतरालों की भी रिपोर्ट करता है। बाद के चेकपॉइंट उन अवधियों का विस्तार नहीं करते हैं। परिणाम में अंतिम मेल खाने वाले रिकॉर्ड नंबर और बिना मेल खाने वाले चेकपॉइंट वाले पिछड़े रिकॉर्डों की संख्या शामिल होती है। केवल उसी उत्तरों की गिनती की जाती है जिन पर एक्सपोर्ट की अपनी कुंजी से हस्ताक्षर किए गए हैं: एक एक्सपोर्ट जिसे किसी ऐसी कुंजी से हस्ताक्षरित किया गया हो जिसे गवाह ने कभी नहीं देखा, उसे गवाह द्वारा देखे नहीं गए के रूप में रिपोर्ट किया जाता है, और `--fingerprint` के बिना उसका हस्ताक्षरकर्ता अनपिन रहता है। `--channel` के साथ हर हस्ताक्षरित पोस्ट को विटनेस जर्नल से रिकॉर्ड-दर-रिकॉर्ड मिलाना चाहिए: बदले गए पोस्ट सत्यापन में विफल हो जाते हैं, और गायब पोस्ट की सूची दी जाती है। एक प्रदान किए गए टेलीग्राम JSON एक्सपोर्ट में एक तारीख संपादन योग्य मेटाडेटा है, जो हस्ताक्षरित विटनेस टोकन के बाहर होती है। टोकन से मेल खाने का मतलब प्रकाशन की तारीख का प्रमाणीकरण नहीं है; परिणाम स्पष्ट रूप से रिपोर्ट करता है कि प्रकाशन-समय सत्यापन नहीं किया गया था।

### साक्ष्ययुक्त निर्यात सीमा की आवश्यकता

हस्तांतरण के लिए जिसमें गवाह द्वारा प्रमाणित अंतिम रिकॉर्ड शामिल होना चाहिए, `--require-witness` जोड़ें:

```
python verify.py tgwitness-evidence.zip --fingerprint COLLECTOR_SHA256 \
    --witness witness.zip --witness-fingerprint WITNESS_SHA256 --require-witness
```

इसके लिए स्वतंत्र रूप से रखे गए गवाह के फिंगरप्रिंट और इस एक्सपोर्ट के बिल्कुल अंत में एक मिलान करने वाले चेकपॉइंट की आवश्यकता होती है। केवल पहले के प्रीफ़िक्स को कवर करने वाला एक चेकपॉइंट अपर्याप्त है। संग्रह को रोकें, गवाह को अंतिम स्थिति देखने दें, और आगे के जर्नल राइट्स से पहले एक्सपोर्ट करें; यदि जर्नल बदलता है, तो एक और चेकपॉइंट रखें और उस स्थिति को एक्सपोर्ट करें। केवल एक बाद का चेकपॉइंट एक छोटे एक्सपोर्ट के अंतिम हैश को सत्यापित नहीं कर सकता है। जब `--channel` भी प्रदान किया जाता है, तो दावे वाले गायब पोस्ट या एक खाली मैच सेट इस सख्त जांच में विफल हो जाते हैं। फ्लैग के बिना, सामान्य अखंडता जांचें अन्यथा सही संग्रह को अस्वीकार किए बिना, बिना गवाह वाले रिकॉर्ड की रिपोर्ट करती हैं।

यह फ़्लैग प्रदान किए गए, पिन किए गए विटनेस रिकॉर्ड के साथ सुसंगति लागू करता है। ऑपरेटर को अभी भी विटनेस की स्वतंत्रता स्थापित करनी होगी और इसके रिकॉर्ड को अलग से संरक्षित रखना होगा। यह संदेश की सत्यता, संपूर्ण संग्रह या स्वतंत्र रूप से मापे गए रनटाइम को स्थापित नहीं करता है।

एक विटनेस यह दिखाता है कि कलेक्टर ने उन समयों पर क्या रिपोर्ट किया था और बाद के एक्सपोर्ट्स उससे मेल खाते हैं। यह नहीं दिखाता कि कलेक्टर ने टेलीग्राम द्वारा दी गई हर चीज़ को रिकॉर्ड किया, या कि संदेश की सामग्री सच है। एक ही ऑपरेटर द्वारा एक ही मशीन पर चलाया गया विटनेस, किसी और द्वारा चलाए गए विटनेस से कमजोर होता है।

केवल बढ़ी हुई संख्या ऑनलाइन केवल-संलग्न निरंतरता स्थापित नहीं कर सकती: ऑफ़लाइन तुलना में प्रत्येक संरक्षित प्रीफ़िक्स हैश का मिलान पूर्ण कलेक्टर एक्सपोर्ट से होना चाहिए। विटनेस के डाउनटाइम और विफल प्रकाशन से बाहरी एंकर के बिना अंतराल रह जाते हैं। रखे गए विटनेस जर्नल के खिलाफ गायब पोस्टों की रिपोर्ट की जा सकती है; न तो एक चैनल और न ही उसी ऑपरेटर द्वारा नियंत्रित कोई सर्वर एक अपरिवर्तनीय तृतीय-पक्ष आर्काइव है।
