
مصيدة SSH/Telnet متوسطة التفاعل مبنية باستخدام Cowrie, Loki, Promtail, Grafana - مزودة على DigitalOcean عبر Terraform مع خط أنابيب تحقق GitLab CI.
مجموعة مصائد SSH/Telnet منشورة على droplet من DigitalOcean باستخدام Terraform. يتم التقاط الهجمات بواسطة Cowrie، وتخزينها في Loki، وتصوّرها في Grafana مع خريطة عالمية حية لأصول الهجمات.
---```
honeypot/
├── cowrie/
│ └── etc/
│ ├── cowrie.cfg # Cowrie honeypot configuration
│ └── userdb.txt # Accepted and rejected fake credentials
├── geoip/
│ └── .gitkeep # Placeholder - MMDB files are gitignored
├── grafana/
│ ├── provisioning/
│ │ ├── dashboards/
│ │ │ ├── dashboards.yml # Provisioning: dashboard provider
│ │ │ └── honeypot-dashboard.json # Pre-built Attack Monitor dashboard
│ │ └── datasources/
│ │ └── loki.yml # Auto-provisioned Loki datasource
│ └── grafana.ini # Grafana server settings
├── loki/
│ └── config.yml # Loki single-binary config and retention
├── promtail/
│ └── config.yml # Promtail scrape and GeoIP pipeline
├── scripts/
│ ├── geoip-update.sh # Download or refresh GeoIP database
│ └── setup-firewall.sh # Host UFW rules for honeypot ports
├── terraform/
│ ├── templates/
│ │ ├── cloud-init.yaml.tftpl # Droplet first-boot script (Terraform-templated)
│ │ └── env.tftpl # .env lines embedded via Terraform
│ ├── backend.tf # Terraform backend config
│ ├── main.tf # Droplet, SSH key, firewall, cloud-init
│ ├── outputs.tf # IPs and helpful post-apply values
│ ├── terraform.tfvars.example # Example variable values (copy to terraform.tfvars)
│ ├── variables.tf # Terraform input variables
│ └── versions.tf # Terraform and provider version constraints
├── .env.example # Example environment file for manual setup
├── .gitignore # Ignored paths and files
├── .gitlab-ci.yml # CI/CD pipeline: fmt, validate, Checkov
├── docker-compose.yml # Docker Compose file for the honeypot stack
├── LICENSE # GPLv2 license
├── manual-deployment.sh # Legacy VM bootstrap without Terraform
└── README.md # Project documentation
## متطلبات الأجهزة
> ملاحظة: تستند هذه المتطلبات إلى خطة DigitalOcean Basic Droplet اعتبارًا من مايو 2026 وهي الحد الأدنى من المتطلبات لتشغيل المشروع.
- المزود: DigitalOcean
- الخطة: Basic Droplet - 1 Intel vCPU
- الذاكرة العشوائية: 1 جيجابايت (+2 جيجابايت مبادلة)
- التخزين: 35 جيجابايت NVMe SSD
- نظام التشغيل: Ubuntu 24.04 LTS
## التثبيت والإعداد
>ملاحظة: بعد التثبيت، يُوصى بفتح محطة طرفية جديدة والتأكد من قدرتك على SSH عبر `ADMIN_SSH_PORT` (الافتراضي: 2022) قبل إغلاق جلستك الأصلية.
### نشر Terraform (موصى به)
1. قم بإنشاء رمز API لـ DigitalOcean بأذونات قراءة/كتابة:
- سجل الدخول إلى DigitalOcean وانتقل إلى Account > API > Tokens > Generate New Token.
- قم بتسمية الرمز الخاص بك (مثل "Cowrie Honeypot") وحدد أذونات "Full Access".
- انقر على "Generate Token" وانسخ قيمة الرمز إلى مكان آمن (لن تتمكن من رؤيته مرة أخرى).
2. قم بإنشاء زوج مفاتيح SSH على جهازك المحلي وانسخ مسار المفتاح العام.
3. انتقل إلى دليل `terraform` ثم انسخ وعدّل ملف المتغيرات:
> ملاحظة: يجب تكوين `do_token` و `ssh_public_key_path` و `grafana_admin_password` كحد أدنى في `terraform.tfvars` قبل التطبيق.```bash
cd terraform
cp terraform.tfvars.example terraform.tfvars
ملاحظة: يجب تثبيت Terraform على جهازك المحلي. راجع دليل تثبيت Terraform للحصول على التعليمات.```bash terraform init # Initialize Terraform and download providers terraform apply
5. إذا كان الاختبار - إعادة النشر مع الاستبدال:```bash
terraform apply -replace="digitalocean_droplet.honeypot"
### النشر اليدوي (إصدار قديم)
1. أنشئ Droplet على DigitalOcean بمتطلبات الأجهزة المذكورة أعلاه ومفتاح SSH الخاص بك.
2. اتصل عبر SSH بـ Droplet أو استخدم لوحة التحكم على الويب من DigitalOcean وقم بتشغيل الأوامر التالية:```bash
ssh root@<your-droplet-ip> # If using DigitalOcean web console, skip this command
git clone https://gitlab.com/Oseguera12/cowrie-honeypot-digitalocean.git /opt/honeypot
cd /opt/honeypot
cp .env.example .env
nano .env
bash manual-deployment.sh
ملاحظة: بشكل افتراضي، يكتب Terraform الحالة في
terraform/terraform.tfstateعلى جهازك المحلي. يحتوي هذا الملف على قيم إخراج حساسة (عنوان IP الخاص بالدروبلت، كلمة مرور Grafana، بصمة مفتاح SSH) ويجب ألا يتم تضمينه أبدًا في الالتزامات (commits). يغطي.gitignoreكلًا من*.tfstateو*.tfstate.*.
مخاطر الحالة المحلية:
apply متزامنين أن يفسدا الملفلأي شيء يتجاوز المختبر الشخصي، قم بالتبديل إلى خلفية (backend) عن بُعد. يحتوي terraform/backend.tf على تكوين DigitalOcean Spaces معلق (متوافق مع S3).
لتفعيل الخلفية البعيدة:
terraform.tfvars): ```bash
export AWS_ACCESS_KEY_ID=
export AWS_SECRET_ACCESS_KEY=
backend "s3" في terraform/backend.tf واملأ اسم الحاوية ونقطة نهاية المنطقة.terraform init -migrate-state لنقل الحالة المحلية الحالية إلى Spaces.يقوم ملف .gitlab-ci.yml بتشغيل ثلاث وظائف في كل دفعة في مرحلة validate واحدة:
ملاحظة: يمنع
terraform:fmtوterraform:validateخط الأنابيب عند الفشل. تم ضبطcheckov:scanعلىallow_failure: trueلأن بعض النتائج هي مقايضات مقصودة. قم بكبت النتائج المقبولة المحددة باستخدام تعليقات# checkov:skip=CKXXXالمضمنة بدلاً من تعطيل الوظيفة بالكامل.
يطلق CKV_DIO_4 ("تأكد من أن مدخل جدار الحماية ليس مفتوحاً على مصراعيه") مرة واحدة ضد مورد digitalocean_firewall بالكامل. يتم كبته بتعليق واحد # checkov:skip=CKV_DIO_4: داخل كتلة المورد في terraform/main.tf. يوثق الجدول أدناه سبب تعمد كل منفذ مفتوح.
flowchart TB internet((Internet))
subgraph tf["Terraform"] fw[DigitalOcean Cloud Firewall] droplet[Ubuntu 24.04 droplet] fw --> droplet end
subgraph compose["Docker Compose on droplet"] cowrie["Cowrie honeypot — SSH on port 22, Telnet on port 23"] promtail[Promtail with GeoIP labels] loki[Loki log store] grafana["Grafana — host :3000"] cowrie -->|JSON logs from ./data/cowrie-logs| promtail --> loki --> grafana end
internet -->|22/23 honeypot| fw internet -->|Admin SSH :2022| fw internet -->|Grafana :3000| fw droplet --> compose
## الملاحظات
بيانات تم جمعها على مدى 5 أيام من النشر المباشر (2026-05-05 إلى 2026-05-09):
| المقياس | القيمة |
|------------------------|--------|
| إجمالي الاتصالات | 41,700 |
| محاولات تسجيل الدخول | 15,400 |
| عمليات تسجيل الدخول الناجحة | 868 |
| الأوامر المنفذة | 836 |
| الملفات التي تم تنزيلها | 6 |
| عدد البلدان المصدرة الفريدة | 106 |
### أهم البلدان المهاجمة
| البلد | عدد الاتصالات |
|-------------------|---------------|
| ألمانيا | 9,768 |
| هولندا | 9,110 |
| الولايات المتحدة | 7,706 |
| المملكة المتحدة | 3,858 |
| سنغافورة | 1,770 |
| بلجيكا | 1,422 |
### أنماط بيانات الاعتماد
اسم المستخدم الأكثر شيوعًا كان `root` بـ 3,866 محاولة، يليه `admin` (728) و`user` (494)، مما يعكس الماسحات الآلية التي تستهدف بيانات الاعتماد الافتراضية وحسابات الخدمات المعروفة. كلمة المرور الأكثر شيوعًا كانت `123456` (1,480 محاولة) تليها `123` و`12345`، وهو ما يتوافق مع أدوات القوة الغاشمة القائمة على القواميس.
### سلوك المهاجم داخل الصدفة المزيفة
نجحت 868 محاولة تسجيل دخول ضد مجموعة بيانات الاعتماد المزيفة. من تلك الجلسات، تم تنفيذ 836 أمرًا. الأمر الأكثر شيوعًا كان `uname -s -v -n -r -m` (360 عملية تنفيذ) — وهو أمر قياسي لتحديد بصمة النظام يتم تشغيله بواسطة البرامج النصية الآلية لمرحلة ما بعد الاستغلال لتحديد نظام التشغيل ومعمارية الهدف قبل نشر حمولة. تضمنت الأوامر الأخرى المرصودة `export HISTFILE=/dev/null` لتعطيل تسجيل سجل الصدفة، و`export HISTSAVE=/dev/null`، مما يشير إلى أن المهاجمين يحاولون بنشاط إخفاء آثارهم حتى داخل ما يعتقدون أنه نظام تم اختراقه.
### الخلاصة الأساسية
حجم حركة المسح الآلي — 41,700 اتصال في 5 أيام من 106 دولة — يؤكد أن أي خدمة SSH متاحة للعموم تواجه محاولات قوة غاشمة مستمرة في غضون ساعات من التعرض. النمط السلوكي المتمثل في تشغيل `uname` فورًا متبوعًا بأوامر قمع السجل يتوافق مع أطر عمل ما بعد الاستغلال الآلية التي تعمل بأقل قدر من التدخل البشري.
## الاستخدام
### استخدام لوحة Grafana
> ملاحظة: يتم تعيين بيانات اعتماد لوحة التحكم في ملف terraform.tfvars أو .env (للنشر اليدوي)
يمكن الوصول إلى لوحة التحكم على:```
http://<your-droplet-ip>:3000
تسجيل الدخول باستخدام admin / <GRAFANA_ADMIN_PASSWORD>.
cowrie/etc/userdb.txt - يحتوي على بيانات الاعتماد المقبولة لـ honeypot.
قم بتحرير هذا الملف لضبط بيانات اعتماد honeypot
تسجيلات الدخول المقبولة تنقل المهاجم إلى shell وهمي حيث يتم تسجيل جميع الأوامر
الإدخالات المرفوضة يتم تسجيلها كمحاولات فاشلة
يشرح هذا القسم القرارات المتخذة والمشكلات التي تمت مواجهتها أثناء تطوير هذا المشروع. إنه بمثابة انعكاس لعملية تطوير المشروع والدروس المستفادة. انتقل إلى الاعتبارات الأمنية إذا كنت تريد فقط معرفة كيفية استخدام المشروع.
لماذا الاستضافة السحابية؟
لماذا DigitalOcean؟
لماذا Terraform؟
manual-deployment.sh، مخصص للمستخدمين الذين ليس لديهم خبرة مع Terraform أو يفضلون عدم استخدامه. يتطلب هذا المسار توفير Droplet والاتصال به واستنساخ المستودع وتشغيل البرنامج النصي. يسمح Terraform بالتكرار بشكل أسرع: تعديل قاعدة التعليمات البرمجية وإعادة النشر دون تكرار كل خطوة يدوية من جهازك المحلي. كما يسهل هدم البنية التحتية والبدء من جديد. إذا نما المشروع من honeypot واحد إلى honeynet، فإن Terraform يتوسع بشكل أكثر نظافة من التوفير اليدوي أو البرنامج النصي القديم وحده.لماذا Cowrie؟
لماذا Loki؟
لماذا Grafana؟
لماذا Promtail؟
لماذا GeoIP؟
scripts/geoip-update.sh: لا يتطلب حسابًا أو مفتاح API، مما يحافظ على سهولة النشر لأي شخص يستنسخ المستودع. تقوم مرحلة GeoIP المضمنة في Promtail بقراءة ملف MMDB المحلي وإضافة تصنيفات للوحة Geomap في Grafana.نظرة عامة خطوة بخطوة لما يحدث عند إعداد honeypot باستخدام Terraform أو برنامج النشر اليدوي.
على جهازك:
terraform/terraform.tfvars: رمز API، مسار مفتاح SSH العام، كلمة مرور Grafana، عنوان URL/فرع المستودع، manage_do_firewall اختياريterraform init: يقوم بتثبيت موفر DigitalOcean محليًاterraform apply: يقوم Terraform ببناء خطة، ثم يقوم بإنشاء أو تحديث المواردفي DigitalOcean:
droplet_image و droplet_size و region إلخ.user_data إلى cloud-init المقدم: عند التمهيد الأول، يحصل الجهاز الافتراضي على منفذ SSH الإداري، و repo_url / repo_branch من git، ونسخة مشفرة بـ base64 من .env المُنشأ (كلمة مرور Grafana و ADMIN_SSH_PORT من env.tftpl)manage_do_firewall صحيحًا):
terraform/main.tf)على الـ Droplet، يتم تشغيل cloud-init تلقائيًا:
package_update / package_upgrade، ثم تثبيت الحزم المدرجة (curl، git، ufw، …). في وقت مبكر من التمهيد، يقوم write_files بإنشاء /root/honeypot.env (ملف env.tftpl المقدم من Terraform كـ base64: كلمة مرور Grafana، ADMIN_SSH_PORT، إلخ.)runcmd (الترتيب في terraform/templates/cloud-init.yaml.tftpl): تعيين iptables / ip6tables إلى الخلفيات القديمة/swapfile، fstab، swappiness)داخل Docker Compose:
/ready على المنفذ 3100 داخل الحاوية؛ على المضيف فقط 127.0.0.1:3100)depends_on في docker-compose.yml)، ثم يبدأانdata/cowrie-logs لـ Promtailيقوم المستخدم بإنشاء الجهاز الافتراضي، ويتصل عبر SSH، ويشغل البرنامج النصي من المستودع المستنسخ.
يقوم manual-deployment.sh بما يلي:
.envapt update & apt upgradeufw و iptablessshd على ADMIN_SSH_PORT وتعطيل ssh.socketscripts/setup-firewall.shscripts/geoip-update.sh و cron شهريdocker compose pull / up -d، ثم ينتظر البرنامج النصي لفحوصات صحة Loki و Grafana ويطبع ملخصًاالحلول التي تم النظر فيها:
القرار:
المقايضات:
الدروس المستفادة:
docker compose up لأن المنفذ 22 كان قيد الاستخدام بالفعل ولا يمكن ربطه بواسطة Cowrie.الحلول التي تم النظر فيها:
sshd قد تم تكوينه بشكل خاطئ أو يستمع على المنفذ الخطأالقرار:
sshd إلى ADMIN_SSH_PORT (الافتراضي 2022) وإعادة تشغيله أولاً، ثم يتم إيقاف وتعطيل ssh.socket لتحرير المنفذ 22 ليقوم Docker بربطه لـ Cowrie. يتم تطبيق قواعد UFW بعد كلتا الخطوتين للسماح بمنفذ الإدارة الجديد.المقايضات:
الدروس المستفادة:
ssh.socket هو وحدة مقبس systemd تحتفظ بالمنفذ 22 للتنشيط عند الطلب عبر SSH. يجب إيقافه وتعطيله قبل أن يتمكن Docker من ربط المنفذ 22 للمضيف لـ Cowrie. إذا كان لا يزال نشطًا، يفشل docker compose up مع "address already in use".وظيفة GeoIP
Grafana HTTPS
وظيفة الخادم الوكيل
رخصة جنو العمومية العامة الإصدار 2.0 (GPLv2) راجع نص الترخيص الكامل في ملف LICENSE.
| الوظيفة | الأداة | الغرض |
|---|
terraform:fmt | hashicorp/terraform:1.8 | التنسيق: يفشل إذا كان أي ملف يحتاج إلى terraform fmt |
terraform:validate | hashicorp/terraform:1.8 | التحقق من صحة التكوين دون الاتصال بـ DigitalOcean |
checkov:scan | bridgecrew/checkov:latest | أخطاء تكوين IaC في كود Terraform |
| Check ID | المورد | النتيجة | القرار |
|---|
CKV_DIO_4 | digitalocean_firewall.honeypot — SSH إداري وارد | منفذ SSH الإداري مفتوح لـ 0.0.0.0/0 | مقبول — تقييده بعنوان IP ثابت غير عملي لمختبر محمول؛ موصى به في الإنتاج |
CKV_DIO_4 | digitalocean_firewall.honeypot — المنفذ 22 وارد | المنفذ 22 مفتوح لـ 0.0.0.0/0 | متعمد — هذا هو سطح مصيدة SSH؛ تقييد المصدر يهزم الغرض |
CKV_DIO_4 | digitalocean_firewall.honeypot — المنفذ 23 وارد | المنفذ 23 مفتوح لـ 0.0.0.0/0 | متعمد — سطح مصيدة Telnet؛ نفس المنطق كالمنفذ 22 |
CKV_DIO_4 | digitalocean_firewall.honeypot — المنفذ 3000 وارد | Grafana HTTP مكشوف لـ 0.0.0.0/0 | مقبول لأغراض إمكانية الوصول في المختبر — قيد معروف موثق في اعتبارات الأمان; يجب على النشرات الإنتاجية تقييده بعنوان IP معروف أو بروكسي عبر HTTPS على المنفذ 443 |
| اللوحة | الوصف |
|---|
| خريطة الهجمات العالمية | خريطة جغرافية تحتوي على طبقات خريطة حرارية + علامات توضح مصدر كل اتصال |
| إجمالي الاتصالات | عدد جلسات honeypot الواردة في النطاق الزمني المحدد |
| محاولات تسجيل الدخول | إجمالي محاولات تخمين بيانات الاعتماد (Brute-force) |
| عمليات تسجيل الدخول الناجحة | المهاجمون الذين طابقوا بيانات اعتماد userdb.txt |
| الأوامر المنفذة | أوامر shell منفذة داخل shell الوهمي |
| الملفات التي تم تنزيلها | البرامج الضارة/البرامج النصية التي تم التقاطها عبر wget/curl |
| معدل الاتصال | سلسلة زمنية: اتصالات/ثانية، محاولات دخول فاشلة/ثانية، نجاحات/ثانية |
| أسماء المستخدمين الأكثر استخدامًا | أسماء مستخدمي SSH الأكثر تجربة |
| كلمات المرور الأكثر استخدامًا | كلمات المرور الأكثر تجربة |
| الأوامر الأكثر استخدامًا | أوامر shell الأكثر تنفيذًا |
| الهجمات حسب الدولة | جدول اتصالات على مستوى الدولة |
| الأحداث الأخيرة | تدفق مباشر لأحدث الأحداث |
| تنزيلات الملفات | جدول بكل ملف حاول المهاجم سحبه |
systemctl enable --now dockersshd على ADMIN_SSH_PORT؛ تعطيل ssh.socket بحيث يكون المنفذ 22 للمضيف مجانيًا لـ Cowriegit clone من repo_url / repo_branch إلى /opt/honeypot (يجب أن يتضمن docker-compose.yml وملفات التكوين).env على القرص: نقل /root/honeypot.env إلى /opt/honeypot/.env (الوضع 600)scripts/setup-firewall.sh (UFW لـ SSH الإداري، 22، 23، 3000)scripts/geoip-update.sh (DB-IP City Lite إلى geoip/)؛ إضافة سطر cron شهري لنفس البرنامج النصيdata/cowrie-logs و data/cowrie-dl مع الأذونات التي يتوقعها Compose/opt/honeypot، docker compose pull ثم docker compose up -d