# شهود سجل المفاتيح

> كيف يمنع شهود مستقلون خادم Octa Pass من أن يعرض على أشخاص مختلفين سجلات مفاتيح مختلفة، وكيف توجّه خادمك إلى شهود، وكيف تشغّل شاهدًا لغيرك.

Source: https://octap.app/ar/docs/self-hosting/key-log-witnesses/
Status: in-progress
Project: Octa Pass

:::caution[مبني ولم يُراجَع بعد]
الشهود مبنيّون ومختبَرون من البداية إلى النهاية على جهاز واحد، والصيغ مطابَقة مع تطبيقات Go المرجعية لمواصفات C2SP. ولم يراجعهم خبير التشفير من خارج المشروع بعد، شأنهم شأن بقية [سجل المفاتيح](https://octap.app/ar/docs/security/post-quantum-and-key-log/). ولم يُختر بعد من يشهد على الخدمة المستضافة، فهي بلا شهود حتى الآن.
:::

يكشف [سجل المفاتيح](https://octap.app/ar/docs/security/post-quantum-and-key-log/) المفتاح العام المستبدَل لصاحبه الحقيقي. لكن هجومًا واحدًا يفلت منه: خادم يعرض عليك سجلًا ويعرض على من تتواصل معه سجلًا آخر. يرى كل منكما سجلًا متماسكًا، فلا يلاحظ أيّ منكما شيئًا.

**الشهود** يسدّون هذه الثغرة. الشاهد شخص غير مشغّل الخادم يشغّل خدمة صغيرة توقّع ("توقيعًا مشتركًا") على حالة السجل الحالية، لكن بعد أن تتحقق أنها امتداد لآخر حالة وقّعتها. ولا يستطيع الخادم بعدها أن يشعّب سجله إلا إذا وقّع الشهود على الفرعين، والشاهد الأمين لا يفعل ذلك أبدًا.

## ما تفعله التطبيقات

عندما يكون للخادم شهود، يأتي كل رأس يرسله مع أحدث نقطة تحقق (checkpoint) وقّعوها، ومع إثبات أن الرأس امتداد لها. ويقوم جهازك بما يلي:

1. **يثبّت الشهود** في المرة الأولى، مع مفاتيح السجل نفسه، ثم يلزم الخادم بهم. يستطيع الخادم أن يضيف شهودًا أو يطلب توقيعات أكثر، لكنه لا يستطيع أن يُسقط شاهدًا أو يخفّض العدد على جهاز ثبّتهم.
2. **يحتاج إلى نصاب من التوقيعات الحديثة.** النصاب افتراضيًا أغلبية الشهود، فتعتمد أجهزة أي شخصين على شاهد مشترك واحد على الأقل. والتوقيع المشترك الأقدم من 7 أيام لا يُحسب.
3. **يرفض رأسًا ليس امتدادًا لنقطة التحقق المشهود عليها.** ويظهر ذلك تنبيهًا في **المشاركة**، مثل أي علامة أخرى على إعادة كتابة السجل.

إذا تعذّر الوصول إلى الشهود أكثر من 7 أيام، ترفض الأجهزة التي ثبّتتهم فحوص سجل المفاتيح، ومعها المشاركات الجديدة، حتى يعودوا. وهذا هو المقصود: فالخادم الذي يقطع شهوده يستطيع لولا ذلك أن يشعّب السجل من وراء ظهورهم.

تعرف أجهزة الخادم شهوده من الخادم نفسه. والجهاز الذي لم يتصل قط يمكن أن يُعطى شهودًا مزيّفين، كما يمكن أن يُعطى سجلًا مزيّفًا. ويحمي الشهود كل من ثبّت الشهود الحقيقيين.

## ما يراه الشاهد

نقاط التحقق فقط: اسم السجل وحجمه وجذر شجرته، موقّعة من الخادم. لا عناوين بريد ولا مفاتيح ولا حسابات ولا شيء عمّن يستخدم الخادم. ولا تتصل أجهزتك بأي شاهد أبدًا، فلا يعرف الشهود شيئًا عن مستخدميك أيضًا. لكن الشاهد يعرف عنوان خادمك وسرعة نمو سجله.

## استخدم شهودًا على خادمك

يتحدث الشهود بالبروتوكول القياسي [C2SP tlog-witness](https://c2sp.org/tlog-witness)، فتستطيع استخدام [شاهد Octa Pass](#شغّل-شاهدًا) أو أي شاهد آخر يقبل نقاط تحقق Ed25519.

1. **أعطِ مشغّل كل شاهد مفتاح التحقق لسجلك.** يطبعه خادمك:

   ```bash
   octapass-server admin key-log
   ```

   ```text
   origin   octapass-key-log/9oQ…
   vkey     octapass-key-log/9oQ…+1a2b3c4d+AXJ…
   ```

   الأصل (origin) مشتق من مفاتيح سجلك، فلا يمكن تغييره، ولا يتغير إلا إذا فقدت سرّ الخادم.

2. **اذكر الشهود** بعد أن يضيف مشغّلوهم سجلك:

   | المتغير | الافتراضي | الوصف |
   |---|---|---|
   | `OCTAPASS_KEY_LOG_WITNESSES` | غير مضبوط | الشهود، مفصولين بفواصل أو بأسطر جديدة. لكل شاهد عنوان URL للإرسال ومفتاح التحقق الخاص به، تفصل بينهما مسافة. 16 شاهدًا على الأكثر. |
   | `OCTAPASS_KEY_LOG_WITNESS_QUORUM` | الأغلبية | عدد من يجب أن يوقّعوا. لا تخفّضه إلا إذا قبلت أن مجموعتين من المستخدمين قد تعتمدان على شهود مختلفين. |
   | `OCTAPASS_KEY_LOG_WITNESS_INTERVAL` | `600` | الثواني بين الجولات. ترسل كل جولة نقطة التحقق الحالية إلى كل شاهد، حتى إن لم يتغير شيء، فتبقى التوقيعات حديثة. |

   ```bash
   OCTAPASS_KEY_LOG_WITNESSES="https://witness.example.org witness.example.org/octapass+5d2f…+BEk…,https://w2.example.net w2.example.net+81c0…+BFa…"
   ```

3. **تأكد أنه يعمل:**

   ```bash
   octapass-server admin key-log witness
   ```

   يرسل هذا نقطة تحقق إلى كل الشهود الآن ويذكر من وقّع منهم. وبعد أن يوقّع النصاب، تُعرض الشهود على التطبيقات مع كل رأس. وقبل ذلك لا يتغير لها شيء، فلا ضرر من ضبط المتغير قبل أن يجهز كل الشهود.

اختر شهودًا يشغّلهم أشخاص لا يتبعون لك، على بنية تحتية لا تتحكم فيها. ثلاثة شهود مع النصاب الافتراضي (اثنان) يستمرون في العمل إذا تعطّل واحد.

### استعادة نسخة احتياطية قديمة

النسخة الاحتياطية المأخوذة قبل أن تنشر حسابات أحدث مفاتيحها تحمل سجلًا أقصر. فتذهب المفاتيح الجديدة إلى حيث كانت المفاتيح الأحدث، وهذا تشعّب. يرفضه الشهود، وتُطلق الأجهزة التي رأت السجل الأحدث تنبيهًا. وهذا سجل المفاتيح يعمل كما صُمّم: لا تستطيع الاستعادة أن تعيد كتابة التاريخ بصمت. وإن اضطررت إلى استعادة نسخة قديمة، فأخبر مستخدميك قبل أن يروا التنبيه.

## شغّل شاهدًا

`octapass-witness` خادم صغير مستقل. يحتفظ بملف JSON واحد فيه أحدث نقطة تحقق وقّعها لكل سجل، وبمفتاح التوقيع الخاص به.

```bash
OCTAPASS_WITNESS_NAME=witness.example.org/octapass \
OCTAPASS_WITNESS_LOGS="octapass-key-log/9oQ…+1a2b3c4d+AXJ…" \
OCTAPASS_WITNESS_DATA_DIR=/var/lib/octapass-witness \
OCTAPASS_WITNESS_BIND=127.0.0.1:8090 \
octapass-witness
```

| المتغير | الافتراضي | الوصف |
|---|---|---|
| `OCTAPASS_WITNESS_NAME` | مطلوب | اسم شاهدك، عنوان URL بلا البروتوكول. يراه مشغّلو السجلات، ويدخل في كل توقيع مشترك. |
| `OCTAPASS_WITNESS_LOGS` | لا شيء | مفاتيح التحقق للسجلات التي تشهد عليها، مفصولة بفواصل أو بأسطر جديدة. وتُرفض نقاط التحقق من أي سجل آخر. |
| `OCTAPASS_WITNESS_DATA_DIR` | `./witness-data` | يحوي `state.json`، والمفتاح افتراضيًا. |
| `OCTAPASS_WITNESS_KEY_FILE` | `<data dir>/witness.key` | مفتاح التوقيع الخاص بك، 32 بايتًا عشوائيًا تُنشأ عند أول تشغيل ولا يقرؤها إلا مالكها. |
| `OCTAPASS_WITNESS_BIND` | `127.0.0.1:8090` | العنوان الذي يستمع عليه. ضعه خلف وكيل عكسي (reverse proxy) مع HTTPS. |

يطبع `octapass-witness vkey` مفتاح التحقق الخاص بك ليضيفه مشغّلو السجلات. ويجيب الشاهد على:

- `POST /add-checkpoint`: نقطة نهاية tlog-witness التي ترسل إليها الخوادم نقاط التحقق.
- `GET /<SHA-256 للأصل، بالست عشري>/checkpoint`: أحدث نقطة تحقق وقّعها لسجل ما، لمن يريد المقارنة.
- `GET /`: مفتاح التحقق الخاص به.

**احفظ المفتاح و`state.json` في مكان آمن، وانسخهما احتياطيًا معًا.** إن فقدت `state.json`، ستقبل تشعّبًا كنت سترفضه. وإن فقدت المفتاح، تحتاج إلى مفتاح جديد، وعلى كل مشغّل سجل أن يستبدل مفتاح التحقق الخاص بك. ولا تشغّل المفتاح نفسه في مكانين: فنسختان بحالتين منفصلتين قد توقّع كل منهما على فرع مختلف.

لا قيمة للشاهد إلا إذا كان مستقلًا. شغّل شاهدًا لخادم لا تشغّله أنت.
