الساعة الأولى ليست اختيارية
مساحة عناوين IPv4 على الإنترنت صغيرة بما يكفي لأن يستغرق مسحها بالكامل من شخص غريب ذي تمويل جيد بضع دقائق، ومن حاسوب محمول عادي بضع ساعات. نطاقات الاستضافة منشورة ومُفهرَسة ويُعاد مسحها باستمرار، فالعنوان الجديد ليس غامضًا — بل هو إدخال جديد في قائمة موجودة بالفعل. عمليًا، تصل أول محاولة تسجيل دخول SSH آلية إلى جهاز حديث الإقلاع قبل أن تنتهي حتى من قراءة رسالة الترحيب، وستتبعها آلاف المحاولات الأخرى من مصادر لا صلة بينها، تجرّب جميعها المئات القليلة نفسها من كلمات المرور على الأسماء القليلة نفسها من المستخدمين. لا شيء من هذا موجَّه إليك تحديدًا. إنها آلة تصنّف الإنترنت إلى يستجيب ولا يستجيب، والشيء الوحيد الذي يقرر في أي الكومتين ستقع هو ما فعلته في الساعة الأولى.
والخبر الجيد أن هذا العمل مملّ ومحدود. أربعة ضوابط تُنجز معظمه: المصادقة بالمفاتيح بدلاً من كلمات المرور، ورفض كل منفذ وارد لا تُقدّم عليه خدمة عن قصد، وتطبيق التحديثات الأمنية دون أن يُطلب منك ذلك، والتوقف عن العمل بصلاحيات root. كل واحد منها يستغرق دقائق قليلة ولا شيء فيه غريب. ما يجعل من المفيد تدوين هذا تحديدًا لخادم خارجي بلا KYC هو اللاتماثل في الطرف الآخر — مسار الاسترداد. لدى مزوّد تقليدي، ينتهي ملف sshd_config السيئ بتذكرة دعم، وتحقق من الهوية، وجلسة طرفية (console). أما هنا فلا توجد هوية مسجَّلة للتحقق منها، وهذا هو صُلب فكرة المنتج بالكامل، وهو أيضًا السبب في أن ضغطة مفتاح غير حذرة تكلّفك الجهاز نفسه لا عشرين دقيقة فحسب. كل خطوة أدناه مكتوبة وهذا في الحسبان.
ما الذي يهاجم الخادم الصغير فعليًا
يظهر في السجلات نوعان مختلفان تمام الاختلاف، ويستحق الأمر الفصل بينهما لأن ما يهزم كلًا منهما مختلف عن الآخر. الغالبية الساحقة هي مسح جماعي عشوائي: روبوتات تعمل عبر مساحة العناوين بحثًا عن SSH يقبل كلمات المرور، وقواعد بيانات مربوطة بـ 0.0.0.0، ولوحات تحكم بيانات اعتماد افتراضية، ونسخ اختبار منسية، وتطبيقات ويب غير مُحدَّثة لها ثغرة استغلال (exploit) معروفة للعموم. هذا النوع لا يهمّه إطلاقًا الغرض من خادمك. لا يمكن مجادلته، ولا يتوقف أبدًا، وتهزمه قائمة التحقق في هذا الدليل هزيمة كاملة — ليس لأن القائمة ذكية، بل لأن الروبوتات تبحث عن أجهزة تخطّت هذه الخطوات، وهناك الكثير منها.
أما النوع الثاني فهو هجوم موجَّه — شخص يريد جهازك أنت تحديدًا — وهو نادر ومكلف ولا يدخل عبر SSH إلا نادرًا جدًا. يصل عبر التطبيق الذي نشرته، أو تبعية (dependency) لم تراجعها، أو بيانات اعتماد أعدت استخدامها، أو حاسوب محمول اختُرق قبل أن يلمس الخادم أصلاً. لهذا لا ينتهي التحصين عند جدار الحماية: تصبح الأسئلة الحقيقية هي بأي صلاحية تعمل خدمتك، وإلى أين يمكنها الوصول في الاتجاه الصادر، وبأي سرعة تُحدّثها. يستحق معرفته أثناء التخطيط: خطط VPS لدينا تعتمد على افتراضية كاملة بتقنية KVM، فأنت تُشغّل نواتك (kernel) الخاصة، ومجموعة الأدوات كلها — nftables، وufw، والـ namespaces، والـ seccomp، وإعدادات sysctl المخصصة — تعمل فعليًا، وهو ما لا يصحّ في منتجات "VPS" القائمة على الحاويات (containers) حيث تعود النواة إلى جهة أخرى.
SSH: المفاتيح، وباب واحد فقط
المصادقة بكلمة المرور على منفذ SSH عام هي أكبر خطر تفرضه على نفسك بنفسك على خادم مستأجَر، وإزالتها هي الدقائق الخمس الأعلى قيمة في هذا الدليل. وَلِّد زوج مفاتيح Ed25519 على جهازك الخاص — أبدًا على الخادم، حيث سيُولَد النصف الخاص على المضيف عينه الذي تحاول حمايته — واحمِه بعبارة مرور (passphrase)، وحمّله في وكيل (agent) بحيث تُطلَب منك عبارة المرور مرة واحدة لكل جلسة لا مرة عند كل تسجيل دخول. انسخ النصف العام إلى الخادم، وتأكد أنه يعمل، وعندها فقط أوقف كلمات المرور. مع وجود PasswordAuthentication no وKbdInteractiveAuthentication no، تتوقف آلاف المحاولات اليومية عن كونها خطرًا وتصبح مجرد ضجيج: لا توجد كلمة مرور لتخمينها، فتفشل المحاولة قبل أن تصبح مثيرة للاهتمام أصلاً.
يستحق root قرارًا خاصًا به. يُبقي PermitRootLogin prohibit-password وصول root بالمفاتيح متاحًا لحالات الطوارئ؛ أما PermitRootLogin no فأكثر صرامة ويُجبر كل جلسة على المرور عبر حساب مُسمّى يملك sudo، وهذا ما تريده بمجرد أن يلمس الجهاز أكثر من شخص واحد. أضِف AllowUsers حتى لا يصبح حساب طارئ أنشأته إحدى الحزم مسارًا لتسجيل الدخول أبدًا. نقل الخدمة (daemon) بعيدًا عن المنفذ 22 يستحق أن تفعله، لكن كن صريحًا مع نفسك بشأن السبب: فهو ليس ضابط أمان — أي شخص يفحص عنوانك سيجد المنفذ الجديد خلال ثوانٍ — بل هو نظافة سجلات، يزيل الغالبية العظمى من الضجيج الآلي بحيث تصبح الإدخالات المتبقية في auth.log إدخالات تستحق أن تقرأها فعلاً. أيًا كان ما تغيّره، تحقق منه بـ sshd -t قبل إعادة التحميل، وأبقِ جلستك الحالية مفتوحة إلى أن تتصل طرفية ثانية بنجاح. هذه العادة هي الفرق بين خطأ إملائي وخادم مفقود.
الرفض الافتراضي، والنصف من جدار الحماية الذي لا يضبطه أحد
لجدار الحماية على الخادم مهمة واحدة: جعل الإجابة عن سؤال "ما الذي يستمع هنا؟" مطابقة تمامًا لقائمة الأشياء التي نشرتها عن قصد. ارفض كل ما هو وارد افتراضيًا، واسمح بالصادر، ثم افتح المنافذ واحدًا تلو الآخر مع سبب واضح لكل منها. قبل أن تكتب قاعدة واحدة، شغّل ss -tulpen واقرأ ما هو مربوط بالفعل — التثبيت الافتراضي يستمع على منافذ أكثر مما يتوقعه معظم الناس، وقاعدة بيانات أو ذاكرة تخزين مؤقت (cache) مربوطة بـ 0.0.0.0 بدلاً من 127.0.0.1 هي الطريقة الكلاسيكية التي ينتهي بها خادم صغير داخل مجموعة بيانات شخص ما. اربط الخدمات المحلية بواجهة loopback أولاً؛ فجدار الحماية خط دفاعك الثاني، لا خط دفاعك الوحيد.
ثم هناك النصف الذي يُتجاهَل عادةً. كل خطة هنا تأتي مع /64 من عناوين IPv6 إلى جانب IPv4 الخاص بها، ومعظم الخدمات (daemons) الحديثة تربط العائلتين معًا دون مشكلة. إن كانت قواعدك تغطي IPv4 فقط، فإن خدمة تظنها محمية بجدار الحماية تصبح قابلة للوصول عبر IPv6 من قِبل أي شخص يحلّ العنوان — ومسح IPv6 لبادئة استضافة معروفة أمر روتيني تمامًا. يتعامل ufw مع كلا العائلتين، لكن فقط عندما يكون IPV6=yes مضبوطًا في /etc/default/ufw؛ تحقق من ذلك بـ ufw status verbose بدلاً من افتراضه. Docker يستحق الشك نفسه: نشر منفذ حاوية (container) بـ -p يُدرج قواعد في سلسلة iptables الخاصة به تُقيَّم قبل قواعد ufw، لذا فإن حاوية ظننتها محمية كثيرًا ما تكون مفتوحة على مصراعيها. اربطها صراحةً بـ 127.0.0.1:port وضع وسيطًا عكسيًا (reverse proxy) أمامها. أيًا كان ما تضبطه، اختبره من مكان آخر على الإنترنت — فالقاعدة التي لم تُقرأ إلا في الملف قاعدة لم تُختبر قط.
تحديثات لا تحتاج إلى تذكّرها
البرمجيات غير المُحدَّثة هي السبب الفعلي في خسارة معظم الخوادم الصغيرة، والسبب بشري لا تقني: التحديث عمل مُمل يتنافس مع كل شيء آخر عليك فعله. أتمِت قناة التحديثات الأمنية وتختفي المشكلة. تطبّق unattended-upgrades على Debian وUbuntu التحديثات الأمنية وفق مؤقّت زمني دون أن تعترض طريقك؛ اقصرها على قناة الأمان بدلاً من كل تحديث متاح، حتى لا يُعيد إصدار ميزات روتيني تشغيل تطبيقك في الساعة الثالثة فجرًا. يهمّ هذا أكثر على جهاز خارجي تديره بنفسك مما يهمّ على منصة مُدارة، لأنه لا أحد يُحدّثه نيابة عنك، ولا مدير حساب سيراسلك بشأن ثغرة CVE حرجة — إذ لا يوجد عنوان بريد إلكتروني مسجَّل للوصول إليك.
تحتاج تحديثات النواة (kernel) إلى إعادة تشغيل كي تسري، لذا احسم سياسة إعادة التشغيل لديك بتعمّد بدلاً من اكتشافها لاحقًا. يخبرك needrestart بالخدمات التي لا تزال تعمل مقابل مكتبات محذوفة، ونافذة Unattended-Upgrade::Automatic-Reboot في ساعات الفجر مناسبة لخدمة عديمة الحالة (stateless). تفاعل واحد مهم: إن كنت اتبعت دليل تشفير القرص الكامل لدينا وكان نظام ملفات الجذر لديك مشفّرًا، فإن إعادة التشغيل التلقائية تتوقف عند طلب عبارة مرور وتبقى هناك إلى أن تفتحها عبر الشبكة. إما أن تُبقي إعادة التشغيل التلقائية معطَّلة على تلك الأجهزة، أو تتأكد أن الفتح عن بُعد مُختبَر وأنك مستيقظ خلال تلك النافذة الزمنية. أيًا كان اختيارك، دوِّنه — فالسياسة التي تعيش في رأسك فقط تتوقف عن الوجود لحظة أن تكون في إجازة.
تحديد معدل الاتصالات، وfail2ban، وأرضية الضجيج
بمجرد إيقاف المصادقة بكلمة المرور، لا يمكن لهجوم القوة الغاشمة (brute force) ضد SSH أن ينجح. يستحق الأمر التوضيح بدقة: ما الذي تمنحه أدوات مثل fail2ban بعد تلك النقطة؟ ليس دفاعًا ضد التخمين — فهذا مستحيل أصلاً — بل سجل أهدأ، ومعالج (CPU) أقل استهلاكًا في مصافحات محكوم عليها بالفشل، وضابط حقيقي على الطبقات التي لا تزال فيها الأسرار قابلة للتخمين. وجّهه إلى الأماكن المهمة: نموذج تسجيل دخول تطبيق ويب، أو SMTP AUTH في خادم بريد، أو مسار إداري يحاول أحدهم سبر أغواره (enumerating). يمنحك ufw limit سقفًا رخيصًا لمعدل الاتصالات دون أي برمجية إضافية على الإطلاق. حفنة من إعدادات النواة تستحق الدقائق الخمس نفسها — تفعيل SYN cookies، وتفعيل تصفية المسار العكسي (reverse-path filtering)، وإيقاف ردود ICMP على البث (broadcast)، وتجاهل إعلانات موجّه IPv6 (router advertisements) على خادم له عنوان ثابت.
لكن اعرف أين تتوقف حدود المضيف. لا شيء من هذا ينجو من هجوم حجمي (volumetric)، لأن الفيضان (flood) يملأ أنبوب الشبكة قبل أن يُزعج المعالج بوقت طويل: فبحلول اللحظة التي تصل فيها الحزم إلى قواعد nftables الخاصة بك، تكون قد استهلكت بالفعل عرض النطاق الذي كنت تحاول حمايته. لهذا السبب تقف تنقية L3/L4 التي تصل إلى 1.5 Tbps في مقدّمة الأسطول وتُدرَج ضمن كل خطة بدلاً من أن تُباع كإضافة، مع درع L7 اختياري لفيضانات طبقة التطبيق التي تبدو كطلبات مشروعة. جدار حماية مضيفك يتولى الدقة؛ والشبكة تتولى الحجم. معاملة أحدهما كبديل عن الآخر هي ما يجعل الناس يُفاجَؤون.
إغلاق الباب على نفسك هو الخطر الحقيقي هنا
من بين كل ما يمكن أن يسوء في هذه الساعة الأولى، فإن النتيجة الأرجح بفارق كبير ليست اختراقًا. إنها أنت، في نهاية جلسة طويلة، تعيد تحميل sshd_config معطوب أو تُفعّل جدار حماية تحتوي قاعدة السماح فيه على خطأ إملائي، لتكتشف أن الباب قد أُغلق خلفك. لدى مزوّد تقليدي هذا مجرد إزعاج. أما هنا فهو يستحق احترامًا حقيقيًا، لأن التسجيل ليس أكثر من اسم مستخدم وكلمة مرور مع ثمانية رموز استرداد، دون أي بريد إلكتروني في الحلقة، وذلك تحديدًا حتى لا توجد هوية يمكن أن تتسرّب — ومزوّد لا يستطيع التعرّف عليك لا يستطيع أيضًا التعرّف عليك لإعادتك إلى خادمك. لا أحد يستطيع أن يكفلك. هذه الخاصية هي المنتج يعمل كما صُمم، وهي السبب في أن الاحتياطات أدناه عادات لا مجرد اقتراحات.
أربعة منها لا تكلّف شيئًا. خذ لقطة (snapshot) قبل أن تلمس SSH أو جدار الحماية، حتى تكون إعادة التحميل السيئة تراجعًا (rollback) لا إعادة بناء. سجِّل مفتاحًا عامًا ثانيًا من جهاز مختلف — هاتف، أو حاسوب عمل محمول، أو نسخة غير متصلة — لأن مفتاحًا واحدًا على قرص واحد يفصله فنجان قهوة مسكوب واحد عن ألا يكون هناك مفتاح على الإطلاق. أبقِ طرفية ثانية متصلة أثناء تغيير أي شيء قد يقطع الأولى، واختبر دائمًا الإعداد الجديد من اتصال جديد تمامًا قبل أن تترك القديم. وتقبّل أين ينتهي سلّم الاسترداد: اللقطات تعيش على المضيف نفسه وهي وسيلة راحة للتراجع لا نسخة احتياطية، لذا فإن أي شيء ستفتقده حقًا مكانه تخزين خارج الخادم (off-host) — إضافة النسخ الاحتياطية المشفّرة اليومية، أو نسخك الخاصة المشفّرة من جهة العميل (client-side) والمرفوعة إلى مكان آخر. يجب أن يكون أسوأ سيناريو لديك هو إعادة النشر والاستعادة، تُقاس بالدقائق، لا الضياع الكامل.
SP·08ما تضيفه بعد ذلك، تبعًا لوظيفة الجهاز
قائمة التحقق أعلاه هي الأرضية، وهي نفسها لكل جهاز. أما ما يُضاف فوقها فيعتمد كليًا على وظيفته. خادم ويب عام يحتاج إلى TLS، ووسيط عكسي (reverse proxy) يُنهيه، والتطبيق يعمل بمستخدم بلا امتيازات، وقاعدة البيانات على loopback أو على جهاز آخر كليًا. نقطة نهاية VPN شكل مختلف تمامًا — منفذ UDP واحد، لا حزمة ويب، ولا خدمات عامة على الإطلاق — وهي مشروحة من البداية إلى النهاية في إنشاء VPN خاص بك عبر WireGuard. خادم البريد هو الأكثر تطلبًا بين الثلاثة ويحتاج إلى التحكم في rDNS على العنوان، وهو ما تشمله كل خطة؛ ويغطي استضافة البريد ذاتيًا على VPS خارجي نصف الموضوع المتعلق بقابلية التسليم (deliverability). مرحّل Tor هو عمدًا نقيض المجهولية — فهو خدمة منشورة يمكن التواصل معها — والمفاضلات موضّحة في تشغيل مرحّل على VPS بلا اشتراط KYC. وأي شيء يحمل حالة خاصة في حالة السكون ينبغي أن يُشفَّر أيضًا، وهذا ضابط منفصل له أنماط فشله الخاصة، مشروح في LUKS والفتح عن بُعد.
يستحق الأمر أن يُختتم بموضع التحصين ضمن الصورة الأكبر، لأنه ليس سوى طبقة واحدة من ثلاث طبقات تفشل كل منها بشكل مستقل. ما يعرفه المضيف عنك هو الأول، وهو هنا أقرب إلى لا شيء: اسم مستخدم يموَّل برصيد مسبق الدفع بالعملات الرقمية ابتداءً من $30.00، دون بطاقة ودون مستند في السلسلة — وهذا موضوع الدفع مقابل الاستضافة بشكل مجهول. قانون مَن ينطبق هو الثاني، ويُحدَّد بموقع العتاد عبر 6 منطقة من مناطقنا لا بموقعك أنت، ويُبحث منطقة بمنطقة في أي موقع استضافة خارجي عليك اختياره؟. أما ما تسمح به الآلة نفسها فهو الثالث، وهذا وحده يخصّك أنت — لا يستطيع أي مزوّد ضبطه نيابة عنك. VPS ابتداءً من $8.00/شهريًا يعمل خلال نحو 15 min، ما يعني أن الساعة التي تليه هي التي تُحسَم فيها السلامة الفعلية لهذا الجهاز. أنفقها بتعمّد.
SP·09خطوة بخطوة
-
01
انشر، ثم ادخل قبل أي شيء آخر
انشر من لوحة التحكم واختر توزيعة ستُبقيها فعليًا محدَّثة — Debian حالية أو Ubuntu LTS هي الإجابة المملة والصحيحة. يعمل VPS خلال نحو 15 min وتصلك بيانات اعتماد root في لوحتك. اتصل على الفور، وحدِّث النظام بالكامل، واضبط اسم مضيف (hostname) حتى تكون السجلات لاحقًا قابلة للقراءة. لا يحدث شيء آخر على هذا الجهاز إلى أن تنتهي من بقية هذه الخطوات.
ssh root@203.0.113.10 apt update && apt full-upgrade -y hostnamectl set-hostname edge-01 apt install -y ufw unattended-upgrades needrestart
-
02
الانتقال بعيدًا عن root: مستخدم مُسمّى، ومفتاح، وsudo
وَلِّد زوج المفاتيح على حاسوبك المحمول، أبدًا على الخادم. ثم أنشئ حسابًا مُسمّى على الجهاز، وضع النصف العام في
authorized_keysالخاص به، وامنحهsudo. افتح طرفية ثانية وسجّل الدخول بذلك المستخدم الآن — قبل أن تغيّر أي شيء آخر، بينما لا يزال دخول root عبر SSH يعمل كخيار احتياطي.# on your own machine ssh-keygen -t ed25519 -C "laptop" ssh-copy-id -i ~/.ssh/id_ed25519.pub root@203.0.113.10 # on the server adduser --disabled-password --gecos "" ops usermod -aG sudo ops install -d -m 700 -o ops -g ops /home/ops/.ssh cp /root/.ssh/authorized_keys /home/ops/.ssh/ chown ops:ops /home/ops/.ssh/authorized_keys chmod 600 /home/ops/.ssh/authorized_keys
-
03
أحكِم إغلاق خدمة SSH (daemon) — مع إبقاء طرفية ثانية مفتوحة
اكتب التغييرات في ملف إضافي (drop-in) بدلاً من تعديل الإعداد الأصلي المُرفَق، حتى لا تُرجعها ترقية التوزيعة بصمت أبدًا. تحقق من الصياغة بـ
sshd -tقبل إعادة التحميل، أعد التحميل، ثم أثبِت نجاحه من اتصال جديد تمامًا بينما يبقى الاتصال الحالي حيًا. إن فشل الاتصال الجديد، تظل لديك جلسة تعمل يمكنك التراجع من خلالها. فخّ توزيعة واحد يستحق الذكر: على Ubuntu 24.04 تُفعَّل الخدمة (daemon) عبر socket، لذا يُتجاهَلPortفيsshd_config— اضبط المنفذ بـsystemctl edit ssh.socketبدلاً من ذلك، أو عطّل وحدة الـ socket.cat > /etc/ssh/sshd_config.d/10-hardening.conf <<'EOF' Port 2222 PermitRootLogin prohibit-password PasswordAuthentication no KbdInteractiveAuthentication no AllowUsers ops X11Forwarding no MaxAuthTries 3 LoginGraceTime 20 EOF sshd -t && systemctl reload ssh # new terminal, do not close the old one: ssh -p 2222 ops@203.0.113.10
-
04
اضبط جدار الحماية على الرفض الافتراضي، على عائلتي IP كلتيهما
تأكد أن IPv6 مفعَّل في ufw، ثم ارفض كل ما هو وارد وافتح فقط المنافذ التي تُقدّم عليها خدمة عن قصد — بما في ذلك منفذ SSH الجديد، الذي يجب السماح به قبل تفعيل جدار الحماية. تحقق مما يستمع فعليًا وأنت هنا، وانقل أي شيء ينبغي أن يبقى محليًا إلى loopback.
grep IPV6 /etc/default/ufw # must read IPV6=yes ufw default deny incoming ufw default allow outgoing ufw limit 2222/tcp ufw allow 80,443/tcp ufw enable ufw status verbose ss -tulpen # anything on 0.0.0.0 or :: ?
-
05
فعِّل التحديثات الأمنية التلقائية دون إشراف
فعِّل قناة الأمان فقط، حتى تصل الرقع (patches) دون أن يُعيد إصدار ميزات تشغيل تطبيقك دون سابق إنذار. احسم سياسة إعادة التشغيل صراحةً — وأبقِ إعادة التشغيل التلقائية معطَّلة إن كان نظام ملفات الجذر مشفّرًا ويحتاج إلى فتح يدوي.
dpkg-reconfigure -plow unattended-upgrades cat > /etc/apt/apt.conf.d/51-local <<'EOF' Unattended-Upgrade::Automatic-Reboot "false"; Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; EOF unattended-upgrade --dry-run --debug | tail -20
-
06
قلِّل الضجيج وشدِّد إعدادات النواة
أضف
fail2banللطبقات التي لا يزال يمكن فيها تخمين سرّ ما، واضبط الحفنة من قيم sysctl الصحيحة ببساطة على خادم عام بعنوان ثابت. هذا رخيص، ويجعل السجلات تستحق القراءة.apt install -y fail2ban cat > /etc/sysctl.d/99-harden.conf <<'EOF' net.ipv4.tcp_syncookies = 1 net.ipv4.conf.all.rp_filter = 1 net.ipv4.icmp_echo_ignore_broadcasts = 1 net.ipv4.conf.all.accept_redirects = 0 net.ipv6.conf.all.accept_ra = 0 kernel.kptr_restrict = 2 EOF sysctl --system
-
07
تحقق من الخارج، ثم دوِّن دليل التشغيل (runbook)
ثِق بالمنظور القادم من الإنترنت، لا بالمنظور من داخل الجهاز. تأكد أن منفذ SSH القديم اختفى، وأنه لا شيء غير متوقَّع يستجيب، وأن تسجيل الدخول بالمفتاح فقط مفروض فعليًا. ثم دوِّن الحقائق الثلاث التي ستحتاجها في أسوأ أيامك: أين يعيش مفتاحك الثاني، وأي لقطة (snapshot) أخذتها، وأين توجد النسخة الاحتياطية خارج الخادم (off-host).
# from another machine ssh -p 22 ops@203.0.113.10 # must time out or be refused ssh -p 2222 -o PreferredAuthentications=password ops@203.0.113.10 # expected: Permission denied (publickey) ssh -p 2222 ops@203.0.113.10 'sudo ufw status verbose; uptime'


