
layerleak ماسح الأسرار لـ Docker Hub
راجع CONTRIBUTING.md للحصول على إرشادات المساهمة.
الموقع المنشور مبني من web/ على main بواسطة .github/workflows/pages.yml. مصدر التوثيق وعرض المتصفح المحاكي كلاهما موجود تحت هذا الدليل.
المتطلبات الأساسية:
التثبيت باستخدام Go:
go install github.com/brumbelow/layerleak@latest
layerleak --help
الهدف القياسي للتثبيت هو جذر الوحدة. لتحديد إصدار معين بشكل صريح:
go install github.com/brumbelow/[email protected]
استبدل v1.0.0 بالعلامة v1.x.y المنشورة التي تريدها.
تأكد من أن دليل GOBIN أو GOPATH/bin موجود في PATH.
مسار الوحدة هو github.com/brumbelow/layerleak، لذا فإن go install @latest يحل إلى أعلى علامة v1.x.y منشورة. يتطلب إصدار وحدة v2.x.y تغيير مسار الوحدة إلى github.com/brumbelow/layerleak/v2. الملفات الثنائية المثبتة كوحدة تُبلغ عن إصدار الوحدة المُحل عبر layerleak --version؛ البنيات من استنساخ محلي تُبلغ عن الإصدار الذي يُدمجه Go للاستنساخ، مع الرجوع إلى dev عندما لا يكون إصدار الوحدة متاحاً.
البناء من المصدر:
git clone https://github.com/brumbelow/layerleak.git
cd layerleak
go build -o layerleak .
./layerleak --help
تشغيل API باستخدام صورة حاوية:
docker pull ghcr.io/brumbelow/layerleak:latest
docker run --rm \
-p 8080:8080 \
-e LAYERLEAK_DATABASE_URL='postgres://<user>:<password>@<host>:5432/layerleak?sslmode=disable' \
ghcr.io/brumbelow/layerleak:latest
صورة الحاوية تشغل API بشكل افتراضي وتضبط LAYERLEAK_API_ADDR=0.0.0.0:8080.
تكوين البيئة الاختياري:
cp .env.example .env
تكوين النتائج وقاعدة البيانات:
export LAYERLEAK_LOG_LEVEL=info
export LAYERLEAK_FINDINGS_DIR=findings
export LAYERLEAK_API_ADDR=127.0.0.1:8080
export LAYERLEAK_PERSIST_RAW_SECRETS=0
export LAYERLEAK_TAG_PAGE_SIZE=100
export LAYERLEAK_HTTP_TIMEOUT=30s
export LAYERLEAK_MAX_FILE_BYTES=1048576
export LAYERLEAK_MAX_LAYER_BYTES=536870912
export LAYERLEAK_MAX_LAYER_ENTRIES=50000
export LAYERLEAK_MAX_MANIFEST_BYTES=0
export LAYERLEAK_MAX_CONFIG_BYTES=0
export LAYERLEAK_MAX_TAG_RESPONSE_BYTES=8388608
export LAYERLEAK_MAX_REPOSITORY_TAGS=0
export LAYERLEAK_MAX_REPOSITORY_TARGETS=0
export LAYERLEAK_REGISTRY_REQUEST_ATTEMPTS=2
# تجاوزات السجل الاختيارية؛ عادةً تترك غير مضبوطة.
export LAYERLEAK_REGISTRY_BASE_URL=
export LAYERLEAK_REGISTRY_AUTH_URL=
export LAYERLEAK_DATABASE_URL=postgres://postgres:postgres@localhost:5432/layerleak?sslmode=disable
نفس المتغيرات وقيمها الافتراضية موجودة في .env.example، وهو المصدر الموثوق للقيم الافتراضية.
عندما يتم ضبط أي من حدود MAX_* على قيمة موجبة، فإن تجاوزها يفشل المسح مع خطأ واضح بدلاً من قطع العمل بصمت.
سلوك النتائج:
findings وتدفع حالة الخروج غير الصفرية للمسح.total_findings.disposition و disposition_reason و line_number لتسهيل التصنيف ومراجعة النتائج الإيجابية الكاذبة.1 لأن المسح غير مكتمل.يأتي Layerleak مع ترحيلات SQL مُرقمة تحت migrations/.
الترحيلات يدوية عن قصد. لا يقوم الماسح بإنشاء أو ترقية المخطط تلقائياً.
يتطلب Layerleak خادم PostgreSQL >= 16.13 لـ API المدعوم بقاعدة البيانات واستمرارية الماسح.
طبق الترحيلات باستخدام psql بالترتيب:
psql "$LAYERLEAK_DATABASE_URL" -f migrations/0001_initial.up.sql
psql "$LAYERLEAK_DATABASE_URL" -f migrations/0002_finding_occurrence_metadata.up.sql
psql "$LAYERLEAK_DATABASE_URL" -f migrations/0003_scan_runs.up.sql
أو طبق الترحيلات باستخدام أمر المساعدة في الحاوية:
docker run --rm \
-e LAYERLEAK_DATABASE_URL="$LAYERLEAK_DATABASE_URL" \
ghcr.io/brumbelow/layerleak:latest \
layerleak-migrate-up
layerleak-migrate-up آمن لإعادة تشغيله عندما تكون الترحيلات مطبقة بالفعل.
إذا اكتشف حالة ترحيل جزئية، فإنه يخرج بقيمة غير صفرية ويطلب التدخل اليدوي.
المساعد يفرض أيضاً إصدار الخادم >= 16.13 ويتحقق من أن postgresql-client-16 المرفق يستخدم حزمة Ubuntu PGDG 24.04 (.pgdg24.04+) بالإصدار >= 16.13-1.pgdg24.04+1.
التراجع عن الترحيلات بالترتيب العكسي:
psql "$LAYERLEAK_DATABASE_URL" -f migrations/0003_scan_runs.down.sql
psql "$LAYERLEAK_DATABASE_URL" -f migrations/0002_finding_occurrence_metadata.down.sql
psql "$LAYERLEAK_DATABASE_URL" -f migrations/0001_initial.down.sql
الإعدادات الافتراضية التشغيلية:
first_seen_at و last_seen_at، ويخزن أيضاً تاريخ المسح الإضافي في scan_runs.(manifest_digest, fingerprint)، ويتم دمج مقتطفات السياق المتطابقة المتكررة قبل الاستمرارية.ملاحظة أمان الأسرار:
LAYERLEAK_PERSIST_RAW_SECRETS=1، فإن Postgres يخزن أيضاً قيم النتائج الخام والمقتطفات الخام.scan_runs.result_json تظل مخفية.عرض تعليمات CLI:
layerleak --help
layerleak scan --help

تشغيل مسح ضد صورة OCI عامة على أي سجل مدعوم:
./layerleak scan ubuntu
./layerleak scan library/nginx:latest --format json
./layerleak scan alpine:latest --platform linux/amd64
./layerleak scan mongo
./layerleak scan ghcr.io/homebrew/core/hello:latest
./layerleak scan quay.io/prometheus/busybox:latest
./layerleak scan gcr.io/distroless/static:nonroot
./layerleak scan public.ecr.aws/docker/library/alpine:3.20
./layerleak scan mcr.microsoft.com/hello-world:latest

كل مسح يكتب ملف نتائج JSON إلى دليل مخرجات النتائج.
إذا لم يتم ضبط LAYERLEAK_FINDINGS_DIR، فإن دليل المخرجات الافتراضي هو findings/ تحت أقرب دليل أبوي يحتوي على go.mod (عادة جذر المستودع)، مع الرجوع إلى دليل العمل الحالي عندما لا يتم العثور على جذر مستودع.
تحتوي ملفات النتائج المحفوظة هذه على سجلات نتائج مع redacted_value، و context_snippet مخفي، وموقع مصدر دقيق، وبيانات التصنيف، ورقم السطر لكل نتيجة.
إذا كان LAYERLEAK_PERSIST_RAW_SECRETS=1، فإن ملفات النتائج المحفوظة تتضمن أيضاً value الخام و raw_context_snippet.
إذا تم تمكين التخزين الدائم Postgres، فإن findings.value الخام و finding_occurrences.raw_snippet يظلان فارغين ما لم يكن LAYERLEAK_PERSIST_RAW_SECRETS=1.
بالنسبة للصور متعددة البنى، يتجاوز layerleak مانيفستات الإثبات والمصدر مثل application/vnd.in-toto+json بدلاً من عدّها كمسوحات منصة فاشلة.
مسوحات المستودع العارية:
mongo يقوم بتعداد كل علامة عامة في ذلك المستودع، يحل كل علامة إلى digest، يجمع الـ digests المكررة، ويمسح الأهداف المميزة.mongo:latest أو mongo@sha256:....صيغة الأمر:
layerleak [command]
layerleak scan <image-ref> [flags]
أعلام النطاق لمسوحات المستودع (كل منها يتجاوز متغير البيئة المطابق لأمر واحد):
يأتي Layerleak أيضاً مع API JSON بسيط تحت cmd/api.
API مدعوم بـ Postgres ويتطلب LAYERLEAK_DATABASE_URL؛ لا يخدم من ملفات النتائج على القرص.
ابدأه بـ:
go run ./cmd/api
أو قم بتشغيل حاوية API:
docker run --rm \
-p 8080:8080 \
-e LAYERLEAK_DATABASE_URL='postgres://<user>:<password>@<host>:5432/layerleak?sslmode=disable' \
ghcr.io/brumbelow/layerleak:latest
نقاط النهاية الحالية:
GET /healthPOST /api/v1/scansGET /api/v1/scans/{id}GET /api/v1/repositoriesGET /api/v1/repositories/{repository}/scansGET /api/v1/repositories/{repository}/findingsGET /api/v1/findings/{id}GET /health يُرجع {"status":"ok"} ولا يتطلب مخزناً أو ماسحاً مهيأً.
مناسب لفحوصات جاهزية Kubernetes وأهداف healthcheck في Docker Compose.
POST /api/v1/scans يبقى متزامناً. يقبل جسم JSON مع reference و platform اختياري، ويُرجِع scan_run_id عندما يكون التخزين الدائم Postgres ممكناً.
استجابات مسح API تعيد استخدام نفس مخطط النتيجة المخفية مثل مخرجات CLI JSON.
GET /api/v1/scans/{id} يُرجِع بيانات التعريف للتشغيل المخزن بالإضافة إلى لقطة النتيجة المخفية المخزنة.
نقاط نهاية المستودع والنتائج تبقى أيضاً مخفية: تُرجِع redacted_value و context_snippet مخفي، أبداً قيم سرية خام أو مقتطفات خام من Postgres.
GET /api/v1/repositories/{repository}/scans و GET /api/v1/repositories/{repository}/findings يقبلان معلمة استعلام registry اختيارية (مثل ?registry=ghcr.io). عند حذفها، يكون السجل الافتراضي docker.io للتوافق مع الإصدارات السابقة. استخدم هذا لجلب مسوحات للمستودعات على GHCR، Quay، GCR، MCR، Amazon ECR Public، أو أي سجل مستضاف ذاتياً.
نقاط النهاية القائمة (/repositories, /repositories/{repository}/scans, /repositories/{repository}/findings) تقبل ?limit= و ?offset= للترقيم. limit الافتراضي هو 50 والحد الأقصى 200. /repositories/{repository}/findings يقبل أيضاً ?disposition=actionable|suppressed|all؛ عند حذفها، تتضمن الاستجابة فقط النتائج القابلة للتنفيذ.
لا يتضمن API مصادقة. لنشر المؤسسات، احتفظ به على شبكة خاصة وضعه أمام بوابة المصادقة/التفويض الخاصة بك أو سياسة الوكيل العكسي.
يأتي هذا المستودع مع مجموعة Compose في docker-compose.yml مع خدمات db و migrate و api.
الخط الأساسي لخدمة db هو postgres:16.13-alpine.
إذا كنت تستخدم صورة Postgres مختلفة، حافظ على إصدار الخادم 16.13 أو أحدث.
اضبط متغيرات النشر (قم بتصديرها في الشل أو ضعها في ملف .env بجانب docker-compose.yml):
export LAYERLEAK_IMAGE=ghcr.io/brumbelow/layerleak:latest
export LAYERLEAK_DB_NAME=layerleak
export LAYERLEAK_DB_USER=layerleak
export LAYERLEAK_DB_PASSWORD=replace-me
export LAYERLEAK_API_PORT=8080
تحقق من تكوين Compose المعروض قبل النشر:
docker compose config
قم بتشغيل الترحيلات مرة واحدة قبل بدء API:
docker compose --profile manual run --rm migrate
ابدأ خدمة API:
docker compose up -d api
في Dockge أو Komodo، استورد نفس ملف Compose وقم بتشغيل خدمة migrate مرة واحدة قبل تمكين خدمة api طويلة الأمد.
صدر تحت رخصة MIT — انظر LICENSE.
إذا كان هذا المستودع قد وفر لك وقتاً أو ساعدك، يمكنك دعم التحديثات المستقبلية هنا:
شكراً لك :) هذا يساعد حقاً في الحفاظ على استمرارية المشروع.
| المتغير | القيمة الافتراضية | الغرض |
|---|
LAYERLEAK_LOG_LEVEL | info | مستوى التسجيل: debug، info، warn، أو error. |
LAYERLEAK_FINDINGS_DIR | غير مضبوط | أين يتم كتابة ملفات نتائج JSON. إذا كان غير مضبوط، الافتراضي هو findings/ تحت أقرب دليل أبوي يحتوي على go.mod، مع الرجوع إلى دليل العمل الحالي. |
LAYERLEAK_API_ADDR | 127.0.0.1:8080 | عنوان الربط لخادم API. صورة الحاوية تتجاوز هذا إلى 0.0.0.0:8080. |
LAYERLEAK_PERSIST_RAW_SECRETS | 0 | اضبط على 1 لكتابة قيم الأسرار الخام ومقتطفات السياق الخام إلى القرص وPostgres. النتائج تظل مخفية بشكل افتراضي. |
LAYERLEAK_HTTP_TIMEOUT | 30s | المهلة لكل طلب لكل استدعاء سجل (مانيفستات، بلوكات، صفحات علامات، رموز مصادقة). يقبل أي مدة Go (30s، 2m، 1h). |
LAYERLEAK_MAX_FILE_BYTES | 1048576 (1 MiB) | الحد الأقصى للبايتات المُفكوك ضغطها لكل ملف داخل طبقة. يتم تخطي الملفات الأكبر من ذلك باعتبارها كبيرة جداً. يجب أن يكون أكبر من الصفر. |
LAYERLEAK_MAX_LAYER_BYTES | 536870912 (512 MiB) | الحد الأقصى للبايتات في تيار الطبقة المُفكوك ضغطها لكل طبقة. 0 يعطل الحد. |
LAYERLEAK_MAX_LAYER_ENTRIES | 50000 | الحد الأقصى لإدخالات tar لكل طبقة. 0 يعطل الحد. |
LAYERLEAK_MAX_MANIFEST_BYTES | 0 | الحد الأقصى لبايتات جسم المانيفست. 0 يعطل الحد. |
LAYERLEAK_MAX_CONFIG_BYTES | 0 | الحد الأقصى لبايتات جسم تكوين الصورة. 0 يعطل الحد. |
LAYERLEAK_MAX_TAG_RESPONSE_BYTES | 8388608 (8 MiB) | الحد الأقصى للبايتات لكل صفحة استجابة قائمة علامات السجل. 0 يعطل الحد. |
LAYERLEAK_TAG_PAGE_SIZE | 100 | حجم صفحة قائمة علامات السجل للمسح على مستوى المستودع. |
LAYERLEAK_MAX_REPOSITORY_TAGS | 0 | الحد الأقصى للعلامات التي يتم تعدادها لكل مسح مستودع. 0 يعطل الحد. |
LAYERLEAK_MAX_REPOSITORY_TARGETS | 0 | الحد الأقصى للأهداف المميزة التي يتم حلها لكل مسح مستودع. 0 يعطل الحد. |
LAYERLEAK_REGISTRY_REQUEST_ATTEMPTS | 2 | عدد المحاولات (بما في ذلك الأولى) لكل طلب سجل. |
LAYERLEAK_REGISTRY_BASE_URL | غير مضبوط | تجاوز اختياري. عادةً يستنتج layerleak هذا من كل مرجع صورة؛ اضبط فقط لإجبار المسح عبر وكيل أو نقطة نهاية بديلة. |
LAYERLEAK_REGISTRY_AUTH_URL | غير مضبوط | تجاوز اختياري. عادةً يتم اكتشافه من تحدي WWW-Authenticate الخاص بالسجل. |
LAYERLEAK_DATABASE_URL | غير مضبوط | إذا تم ضبطه، يكتب layerleak المسوحات إلى Postgres ويفشل الأمر إذا لم ينجح التخزين الدائم. |
| العلم | الغرض |
|---|
--tag-page-size | حجم صفحة قائمة علامات السجل لمسوحات المستودع. يجب أن يكون أكبر من الصفر. يتجاوز LAYERLEAK_TAG_PAGE_SIZE. |
--max-repository-tags | الحد الأقصى للعلامات التي يتم تعدادها لكل مسح مستودع. 0 يعطل الحد. يتجاوز LAYERLEAK_MAX_REPOSITORY_TAGS. |
--max-repository-targets | الحد الأقصى للأهداف المميزة التي يتم حلها لكل مسح مستودع. 0 يعطل الحد. يتجاوز LAYERLEAK_MAX_REPOSITORY_TARGETS. |