6 قصص عملية من أيام الأسبوع SRE لدينا



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

بشكل عام ، حتى لو تم توحيد هذه التطبيقات بأفكار وحلول معمارية مشتركة ، للقضاء على المشكلات غير المعتادة فيها ، غالبًا ما يتعين عليها التنقل عبر البراري غير المألوفة التالية. ما إذا كانت هذه المشاكل تحدث ليست سوى مسألة وقت. هذه هي الأمثلة من أحدث الممارسات التي نخصصها لهذه المقالة. طاقم العمل: Golang و Sentry و RabbitMQ و nginx و PostgreSQL وغيرها.

التاريخ رقم 1. Golang و HTTP / 2


أدى تشغيل معيار يقوم بالعديد من طلبات HTTP إلى تطبيق ويب إلى نتائج غير متوقعة. ينتقل تطبيق Go البسيط في العملية المرجعية إلى تطبيق Go آخر يقع خلف الدخول / الانفتاح. عند تمكين HTTP / 2. ، نحصل على أخطاء مع الكود 400 لبعض الطلبات ، لفهم سبب هذا السلوك ، أزلنا تطبيق Go في النهاية البعيدة عن السلسلة وقمنا بإنشاء موقع بسيط في Ingress ، والذي يرجع دائمًا إلى 200. لم يتغير السلوك دائمًا!

ثم تقرر إعادة إنتاج البرنامج النصي خارج بيئة Kubernetes - على قطعة مختلفة من الأجهزة. وكانت النتيجة تكوين ملف Makefile ، بمساعدة من إطلاق حاويتين: في أحد المعايير التي تذهب إلى nginx ، في الأخرى - في Apache. كلاهما يستمع إلى HTTP / 2 مع شهادة موقعة ذاتيا. وقت التشغيل النهائي نرى في هذا المستودع .

قم بتشغيل المعايير concurrency=200 :

1.1. إنجن إكس:

 Completed 0 requests Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests ----- Bench results begin ----- Requests per second: 10336.09 Failed requests: 1623 ----- Bench results end ----- 

1.2. أباتشي:

 … ----- Bench results begin ----- Requests per second: 11427.60 Failed requests: 0 ----- Bench results end ----- 

نحن نفترض أن الهدف هنا هو تطبيق HTTP / 2 أقل صرامة في Apache.

دعنا نحاول concurrency=1000 :

2.1. إنجن إكس:

 … ----- Bench results begin ----- Requests per second: 11274.92 Failed requests: 4205 ----- Bench results end ----- 

2.2. أباتشي:

 … ----- Bench results begin ----- Requests per second: 11211.48 Failed requests: 5 ----- Bench results end ----- 

في الوقت نفسه ، نلاحظ أن النتائج لا يتم إنتاجها في كل مرة : بعض عمليات الإطلاق تمر دون مشاكل.

أدى البحث عن المشكلات في جيثب مشروع جولانج إلى # 25009 و # 32441 . من خلالهم ذهبنا إلى PR 903 : تعطيل HTTP / 2 في Go افتراضيًا!

من الصعب للغاية تفسير نتائج الاختبار دون الغوص بعمق في بنية خوادم الويب المذكورة أعلاه. في حالة معينة ، كان يكفي تعطيل HTTP / 2 للخدمة المحددة.

التاريخ رقم 2. السمفونية القديمة والحراسة


في أحد المشاريع ، لا يزال إصدار قديم جدًا من إطار عمل symfony PHP (الإصدار 2.3) يعمل. يتم إرفاق عميل Raven قديم وفصل مكتوب ذاتيًا في PHP به "في المجموعة" ، مما يعقد تصحيح الأخطاء قليلاً.

بعد نقل إحدى الخدمات في Kubernetes إلى ترقب ، وتستخدم لتعقب الأخطاء في تطبيق هذا المشروع ، توقفت الأحداث فجأة القادمة. لإعادة إنتاج هذا السلوك ، استخدمنا أمثلة من موقع الويب Sentry ، وأخذنا خيارين ونسخ DSN من إعدادات Sentry. بصريا ، كل شيء يعمل: تم إرسال رسائل الخطأ (يزعم) واحدة تلو الأخرى.

خيار التحقق من جافا سكريبت:

 <!DOCTYPE html> <html> <body> <script src="https://browser.sentry-cdn.com/5.6.3/bundle.min.js" integrity="sha384-/Cqa/8kaWn7emdqIBLk3AkFMAHBk0LObErtMhO+hr52CntkaurEnihPmqYj3uJho" crossorigin="anonymous"> </script> <h2>JavaScript in Body</h2> <p id="demo">A Paragraph.</p> <button type="button" onclick="myFunction()">Try it</button> <script> Sentry.init({ dsn: 'http://33dddd76e9f0c4ddcdb51@sentry.kube-dev.test//12' }); try { throw new Error('Caught'); } catch (err) { Sentry.captureException(err); } </script> </body> </html> 

وبالمثل في بيثون:

  from sentry_sdk import init, capture_message init("http://33dddd76e9f0c4ddcdb51@sentry.kube-dev.test//12") capture_message("Hello World") # Will create an event. raise ValueError() 

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

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

التاريخ رقم 3. RabbitMQ ووكيل الطرف الثالث


في مشروع واحد ، يتم استخدام سحابة Evotor لربط سجلات النقد. في الواقع ، إنه يعمل كوكيل: تذهب طلبات POST من Evotor مباشرة إلى RabbitMQ - من خلال البرنامج المساعد STOMP الذي تم تنفيذه عبر اتصالات WebSocket.

قدم أحد المطورين طلبات اختبار باستخدام Postman وتلقى الردود المتوقعة من 200 OK ، ومع ذلك ، أدت الطلبات من خلال مجموعة النظراء إلى 405 Method Not Allowed متوقعة 405 Method Not Allowed .

200 حسنا
 source: kubernetes namespace: kube-nginx-ingress host: kube-node-2 pod_name: nginx-2bpt7 container_name: nginx stream: stdout app: nginx controller-revision-hash: 5bdbfd564 pod-template-generation: 25 time: 2019-09-10T09:42:50+00:00 request_id: 1271dba228f0943ab2df0196ff0d7f67 user: client address: 100.200.300.400 protocol: HTTP/1.1 scheme: http method: POST host: rmq-review.kube-dev.client.domain path: /api/queues/vhost/queue.gen.eeeeffff111:1.onlinecassa:55556666/get request_query: referrer: user_agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36 content_kind: cacheable namespace: review ingress: stomp-ws service: rabbitmq service_port: stats vhost: rmq-review.kube-dev.client.domain location: / nginx_upstream_addr: 10.127.1.1:15672 nginx_upstream_bytes_received: 2538 nginx_upstream_response_time: 0.008 nginx_upstream_status: 200 bytes_received: 757 bytes_sent: 1254 request_time: 0 status: 200 upstream_response_time: 0 upstream_retries: 0 

405 الطريقة غير مسموح بها
 source: kubernetes namespace: kube-nginx-ingress host: kube-node-1 pod_name: nginx-4xx6h container_name: nginx stream: stdout app: nginx controller-revision-hash: 5bdbfd564 pod-template-generation: 25 time: 2019-09-10T09:46:26+00:00 request_id: b8dd789604864c95b4af499ed6805630 user: client address: 200.100.300.400 protocol: HTTP/1.1 scheme: http method: POST host: rmq-review.kube-dev.client.domain path: /api/queues/vhost/queue.gen.ef7fb93387ca9b544fc1ecd581cad4a9:1.onlinecassa:55556666/get request_query: referrer: user_agent: ru.evotor.proxy/37 content_kind: cache-headers-not-present namespace: review ingress: stomp-ws service: rabbitmq service_port: stats vhost: rmq-review.kube-dev.client.domain location: / nginx_upstream_addr: 10.127.1.1:15672 nginx_upstream_bytes_received: 134 nginx_upstream_response_time: 0.004 nginx_upstream_status: 405 bytes_received: 878 bytes_sent: 137 request_time: 0 status: 405 upstream_response_time: 0 upstream_retries: 0 

طلب Tcpdump من Evotor
 200.100.300.400.21519 > 100.200.400.300: Flags [P.], cksum 0x8e29 (correct), seq 1:879, ack 1, win 221, options [nop,nop,TS val 2313007107 ecr 79097074], length 878: HTTP, length: 878 POST /api/queues//vhost/queue.gen.ef7fb93387ca9b544fc1ecd581cad4a9:1.onlinecassa:55556666/get HTTP/1.1 device-model: ST-5 device-os: android Accept-Encoding: gzip content-type: application/json; charset=utf-8 connection: close accept: application/json x-original-forwarded-for: 10.11.12.13 originhost: rmq-review.kube-dev.client.domain x-original-uri: /api/v2/apps/e114-aaef-bbbb-beee-abadada44ae/requests x-scheme: https accept-encoding: gzip user-agent: ru.evotor.proxy/37 Authorization: Basic X-Evotor-Store-Uuid: 20180417-73DC-40C9-80B7-00E990B77D2D X-Evotor-Device-Uuid: 20190909-A47B-40EA-806A-F7BC33833270 X-Evotor-User-Id: 01-000000000147888 Content-Length: 58 Host: rmq-review.kube-dev.client.domain {"count":1,"encoding":"auto","ackmode":"ack_requeue_true"}[!http] 12:53:30.095385 IP (tos 0x0, ttl 64, id 5512, offset 0, flags [DF], proto TCP (6), length 52) 100.200.400.300:80 > 200.100.300.400.21519: Flags [.], cksum 0xfa81 (incorrect -> 0x3c87), seq 1, ack 879, win 60, options [nop,nop,TS val 79097122 ecr 2313007107], length 0 12:53:30.096876 IP (tos 0x0, ttl 64, id 5513, offset 0, flags [DF], proto TCP (6), length 189) 100.200.400.300:80 > 200.100.300.400.21519: Flags [P.], cksum 0xfb0a (incorrect -> 0x03b9), seq 1:138, ack 879, win 60, options [nop,nop,TS val 79097123 ecr 2313007107], length 137: HTTP, length: 137 HTTP/1.1 405 Method Not Allowed Date: Tue, 10 Sep 2019 10:53:30 GMT Content-Length: 0 Connection: close allow: HEAD, GET, OPTIONS 

طلب Tcpdump بواسطة حليقة
 777.10.74.11.61211 > 100.200.400.300:80: Flags [P.], cksum 0x32a8 (correct), seq 1:397, ack 1, win 2052, options [nop,nop,TS val 734012594 ecr 4012360530], length 396: HTTP, length: 396 POST /api/queues/%2Fvhost/queue.gen.ef7fb93387ca9b544fc1ecd581cad4a9:1.onlinecassa:55556666/get HTTP/1.1 Host: rmq-review.kube-dev.client.domain User-Agent: curl/7.54.0 Authorization: Basic = Content-Type: application/json Accept: application/json Content-Length: 58 {"count":1,"ackmode":"ack_requeue_true","encoding":"auto"}[!http] 12:40:11.001442 IP (tos 0x0, ttl 64, id 50844, offset 0, flags [DF], proto TCP (6), length 52) 100.200.400.300:80 > 777.10.74.11.61211: Flags [.], cksum 0x2d01 (incorrect -> 0xfa25), seq 1, ack 397, win 59, options [nop,nop,TS val 4012360590 ecr 734012594], length 0 12:40:11.017065 IP (tos 0x0, ttl 64, id 50845, offset 0, flags [DF], proto TCP (6), length 2621) 100.200.400.300:80 > 777.10.74.11.61211: Flags [P.], cksum 0x370a (incorrect -> 0x6872), seq 1:2570, ack 397, win 59, options [nop,nop,TS val 4012360605 ecr 734012594], length 2569: HTTP, length: 2569 HTTP/1.1 200 OK Date: Tue, 10 Sep 2019 10:40:11 GMT Content-Type: application/json Content-Length: 2348 Connection: keep-alive Vary: Accept-Encoding cache-control: no-cache vary: accept, accept-encoding, origin 

ترى العين المدربة للمهندس الفرق على الفور:

  • حليقة: POST /api/queues/%2Fclient…
  • Evotor: POST /api/queues//client…

كان الشيء أنه في إحدى الحالات //vhost غير مفهوم (بالنسبة إلى RabbitMQ) //vhost ، وفي الحالة الأخرى - %2Fvhost ، وهو السلوك المتوقع عندما:

 # rabbitmqctl list_vhosts Listing vhosts ... /vhost 

في قضية مشروع RabbitMQ حول هذا الموضوع ، يشرح المطور:

لن نستبدل الترميز٪. إنها طريقة قياسية لترميز مسار عنوان URL وكانت منذ زمن طويل. على افتراض أن٪-encoding في الأدوات التي تستند إلى HTTP ستزول نظرًا لوجود حتى الإطار الأكثر شيوعًا على افتراض أن مسارات عناوين URL هذه "ضارة" هي قصيرة النظر وساذجة. يمكن تغيير اسم المضيف الافتراضي الافتراضي إلى أي قيمة (مثل تلك التي لا تستخدم خطوط مائلة أو أي أحرف أخرى تتطلب٪-encoding) وعلى الأقل مع إصدار Pivotal BOSH من RabbitMQ ، يتم حذف المضيف الظاهري الافتراضي في وقت النشر على أي حال .

تم حل المشكلة دون مزيد من مشاركة مهندسينا (على الجانب Evotor بعد الاتصال بهم).

التاريخ رقم 4. الجين في بوستجرس


يحتوي PostgreSQL على فهرس مفيد للغاية ، وغالبًا ما يتم نسيانه. بدأت هذه القصة مع شكاوى حول الفرامل في التطبيق. في مقالة حديثة ، قدمنا ​​بالفعل مثالًا لسير العمل التقريبي عند تحليل مثل هذه الحالات. وهنا لدينا APM - Atatus - أظهرت الصورة التالية:



في الساعة 10 صباحًا ، هناك زيادة في الوقت الذي يقضيه التطبيق في العمل مع قاعدة البيانات. كما هو متوقع ، يكمن السبب في الاستجابات البطيئة لنظام إدارة قواعد البيانات. بالنسبة لنا ، يعد تحليل الاستعلامات وتحديد مجالات المشكلات وفهارس "التعليق" روتينًا مفهومًا. يساعد okmeter الذي نستخدمه فيه كثيرًا : هناك كل من اللوحات القياسية لمراقبة حالة الخوادم ، والقدرة على بناء لوحاتنا بسرعة - من خلال إخراج مقاييس إشكالية:



تشير الرسوم البيانية لتحميل وحدة المعالجة المركزية إلى أن إحدى قواعد البيانات يتم تحميلها بنسبة 100٪. لماذا؟ ستطالب لوحات PostgreSQL الجديدة بما يلي:



سبب المشكلات واضح على الفور - المستهلك الرئيسي لوحدة المعالجة المركزية:

 SELECT u.* FROM users u WHERE u.id = ? & u.field_1 = ? AND u.field_2 LIKE '%somestring%' ORDER BY u.id DESC LIMIT ? 

بالنظر إلى خطة العمل الخاصة باستعلام المشكلة ، وجدنا أن التصفية حسب الحقول المفهرسة في الجدول توفر field_1 كبيرًا للغاية: تتلقى قاعدة البيانات أكثر من 70 ألف صف حسب id و field_1 ، ثم تبحث عن سلسلة فرعية فيما بينها. اتضح أن LIKE على سلسلة فرعية يتكرر على كمية كبيرة من البيانات النصية ، مما يؤدي إلى تباطؤ خطير في تنفيذ الاستعلام وزيادة في تحميل وحدة المعالجة المركزية.

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

الحل النهائي الحالي هو إضافة فهرس GIN لـ field_2 . هذا هو بطل اليوم - نفس "الجني". باختصار ، GIN هو نوع من الفهرس يعمل بشكل جيد جدًا في البحث عن النص الكامل ، مما يسرعه نوعيًا. يمكنك قراءة المزيد عنها ، على سبيل المثال ، في هذه المادة الرائعة .



كما ترون ، سمحت هذه العملية البسيطة بإزالة الحمل الإضافي ومعها - وتوفير المال للعميل.

التاريخ رقم 5. التخزين المؤقت S3 في إنجن إكس


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

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

يبدو أنه أسهل من أخذ nginx وإعداد الوكلاء مع التخزين المؤقت ، إعادة التحقق ، تحديث الخلفية وغيرها من لعبة ورق؟ ومع ذلك ، كما هو الحال في أي مكان آخر ، هناك بعض الفروق الدقيقة ...

بدا التكوين التقريبي لمثل هذا الوكيل مع التخزين المؤقت كما يلي:

 proxy_cache_key $uri; proxy_cache_methods GET HEAD; proxy_cache_lock on; proxy_cache_revalidate on; proxy_cache_background_update on; proxy_cache_use_stale updating error timeout invalid_header http_500 http_502 http_503 http_504; proxy_cache_valid 200 1h; location ~ ^/(?<bucket>avatars|images)/(?<filename>.+)$ { set $upstream $bucket.s3.amazonaws.com; proxy_pass http://$upstream/$filename; proxy_set_header Host $upstream; proxy_cache aws; proxy_cache_valid 200 1h; proxy_cache_valid 404 60s; } 

وبشكل عام ، نجحت: تم عرض الصور ، كل شيء كان جيدًا مع ذاكرة التخزين المؤقت ... ومع ذلك ، ظهرت مشاكل مع عملاء AWS S3. على وجه الخصوص ، توقف العميل من aws-sdk-php عن العمل. أظهر تحليل سجلات nginx أن المنبع أعاد رمز 403 لطلبات HEAD ، وأن الاستجابة تحتوي على خطأ محدد: SignatureDoesNotMatch . عندما رأينا أن nginx يقدم طلبًا للحصول على المنبع ، فقد أصبح كل شيء في مكانه.

والحقيقة هي أن العميل S3 يوقع كل طلب ، والخادم يتحقق هذا التوقيع. في حالة البروكسي البسيط ، كل شيء يعمل بشكل جيد: يصل الطلب إلى الخادم دون تغيير. ومع ذلك ، عند تمكين التخزين المؤقت ، يبدأ nginx في تحسين العمل مع الواجهة الخلفية واستبدال طلبات HEAD بـ GET. المنطق بسيط: من الأفضل استرداد وحفظ الكائن بالكامل ، ومن ثم جميع طلبات HEAD من ذاكرة التخزين المؤقت أيضًا. ومع ذلك ، في حالتنا ، لا يمكن تعديل الطلب ، لأنه تم توقيعه.

هناك حلان أساسيان:

  1. لا تدفع عملاء S3 عبر الوكلاء ؛
  2. إذا كان "ضروريًا" ، فأوقف تشغيل proxy_cache_convert_head $request_method إلى مفتاح التخزين المؤقت. في هذه الحالة ، يقوم nginx بإرسال طلبات HEAD "كما هي" وتخزين الردود عليها بشكل منفصل.

التاريخ رقم 6. DDoS ومحتوى مستخدم Google


لم مساء الأحد لا تنذر المشاكل حتى - فجأة! - قائمة انتظار إبطال ذاكرة التخزين المؤقت على خوادم الحافة لم تنمو ، مما يعطي حركة مرور للمستخدمين الحقيقيين. هذا عرض غريب للغاية: بعد كل شيء ، يتم تنفيذ ذاكرة التخزين المؤقت في الذاكرة ولا ترتبط بمحركات الأقراص الثابتة. تعد عملية مسح ذاكرة التخزين المؤقت في البنية المستخدمة عملية رخيصة ، لذلك لا يمكن أن يظهر هذا الخطأ إلا في حالة الحمل العالي حقًا. تم تأكيد ذلك من خلال حقيقة أن نفس الخوادم بدأت في الإبلاغ عن ظهور 500 خطأ (ارتفاع الخط الأحمر في الرسم البياني أدناه) .



أدت هذه الزيادة الحادة إلى تجاوزات وحدة المعالجة المركزية:



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

بعد جمع البيانات من سجلات nginx ، كشفنا أننا نتعامل مع شبكة روبوت معينة:

 35.222.30.127 US [15/Sep/2019:21:40:00 +0300] GET "http://example.ru/?ITPDH=XHJI" HTTP/1.1 301 178 "http://example.ru/ORQHYGJES" "Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)" "-" "upcache=-" "upaddr=-" "upstatus=-" "uplen=-" "uptime=-" spdy="" "loc=wide-closed.example.ru.undef" "rewrited=/?ITPDH=XHJI" "redirect=http://www.example.ru/?ITPDH=XHJI" ancient=1 cipher=- "LM=-;EXP=-;CC=-" 107.178.215.0 US [15/Sep/2019:21:40:00 +0300] GET "http://example.ru/?REVQSD=VQPYFLAJZ" HTTP/1.1 301 178 "http://www.usatoday.com/search/results?q=MLAJSBZAK" "Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)" "-" "upcache=-" "upaddr=-" "upstatus=-" "uplen=-" "uptime=-" spdy="" "loc=wide-closed.example.ru.undef" "rewrited=/?REVQSD=VQPYFLAJZ" "redirect=http://www.example.ru/?REVQSD=VQPYFLAJZ" ancient=1 cipher=- "LM=-;EXP=-;CC=-" 107.178.215.0 US [15/Sep/2019:21:40:00 +0300] GET "http://example.ru/?MPYGEXB=OMJ" HTTP/1.1 301 178 "http://engadget.search.aol.com/search?q=MIWTYEDX" "Mozilla/5.0 (Windows; U; Windows NT 6.1; en; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)" "-" "upcache=-" "upaddr=-" "upstatus=-" "uplen=-" "uptime=-" spdy="" "loc=wide-closed.example.ru.undef" "rewrited=/?MPYGEXB=OMJ" "redirect=http://www.example.ru/?MPYGEXB=OMJ" ancient=1 cipher=- "LM=-;EXP=-;CC=-" 

يتم تتبع نمط مفهوم في السجلات:

  • وكيل المستخدم الحقيقي ؛
  • طلب إلى عنوان URL الجذر مع وسيطة GET عشوائية لتجنب الوقوع في ذاكرة التخزين المؤقت ؛
  • يشير المرجع إلى أن الطلب جاء من محرك بحث.

نقوم بجمع العناوين والتحقق من انتمائها - جميعها تنتمي إلى googleusercontent.com ، مع شبكتين فرعيتين (107.178.192.0/18 و 34.64.0.0/10). تحتوي هذه الشبكات الفرعية على أجهزة GCE افتراضية وخدمات متنوعة ، مثل ترجمة الصفحة.

لحسن الحظ ، فإن الهجوم لم يدم طويلاً (حوالي ساعة) وانخفض تدريجياً. يبدو أن الخوارزميات الوقائية داخل Google قد نجحت ، لذا تم حل المشكلة "بنفسها".

لم يكن هذا الهجوم مدمراً ، لكنه أثار أسئلة مفيدة للمستقبل:

  • لماذا لا تعمل مكافحة ddos؟ يتم استخدام خدمة خارجية ، والتي أرسلنا إليها طلبًا مطابقًا. ومع ذلك ، كان هناك الكثير من العناوين ...
  • كيف تحمي نفسك من هذا في المستقبل؟ في حالتنا ، حتى خيارات إغلاق الوصول على أساس جغرافي ممكنة.

PS


اقرأ أيضًا في مدونتنا:

Source: https://habr.com/ru/post/ar471892/


All Articles