วิธีแก้ปัญหา SSH Too many authentication failures
แก้ปัญหา SSH เชื่อมต่อไม่ได้ด้วยข้อความ Too many authentication failures โดยการตั้งค่า IdentitiesOnly เพื่อจำกัดการส่งกุญแจให้เหลือเพียงตัวที่ถูกต้องเท่านั้น
ความหมายของ "Too many authentication failures"
ข้อความ "Too many authentication failures" หมายความว่า SSH client ของคุณส่งกุญแจไปยังเซิร์ฟเวอร์จำนวนมากกว่าที่เซิร์ฟเวอร์จะยอมตรวจสอบ ทำให้เซิร์ฟเวอร์ตัดการเชื่อมต่อก่อนที่จะถึงคิวของกุญแจที่ถูกต้อง ปัญหานี้มักเกิดจากฝั่ง client เสมอ แม้ว่ากุญแจจะอยู่ในดิสก์ของคุณและเซิร์ฟเวอร์จะมีกุญแจนั้นอยู่ใน authorized_keys แล้วก็ตาม แต่ข้อมูลเหล่านี้ก็ไม่ช่วยอะไรเนื่องจากการเชื่อมต่อถูกยุติไปก่อน
ลำดับเหตุการณ์เป็นดังนี้ ssh-agent จะเก็บกุญแจส่วนตัว (private key) ทุกตัวที่คุณโหลดไว้ Client ของคุณจะทยอยส่งกุญแจเหล่านั้นให้เซิร์ฟเวอร์ทีละตัว เนื่องจาก client ไม่ทราบว่าบัญชีผู้ใช้นั้นยอมรับกุญแจตัวใด เซิร์ฟเวอร์จะปฏิเสธกุญแจที่ไม่ปรากฏใน authorized_keys และนับการปฏิเสธแต่ละครั้งเป็นความพยายามยืนยันตัวตนที่ล้มเหลว ค่า MaxAuthTries ใน sshd_config จะเป็นตัวกำหนดขีดจำกัดจำนวนครั้งที่อนุญาตให้ล้มเหลวได้ในการเชื่อมต่อหนึ่งครั้ง โดยค่าเริ่มต้นคือ 6 หาก agent ของคุณเก็บกุญแจไว้ 10 ตัวและกุญแจที่ถูกต้องอยู่ในลำดับที่ 8 เซิร์ฟเวอร์จะตัดการเชื่อมต่อก่อนที่จะตรวจสอบถึงกุญแจตัวนั้น
ดังนั้น วิธีแก้ไขคือการตั้งค่าให้ client ส่งกุญแจเพียงตัวเดียว นั่นคือตัวที่ถูกต้องเท่านั้น
สิ่งที่เซิร์ฟเวอร์นับ และบทบาทของ MaxAuthTries
การยืนยันตัวตนด้วย public key เริ่มต้นจากการเดาสุ่ม ไคลเอนต์จะส่ง public key ไปและสอบถามว่าเซิร์ฟเวอร์ยอมรับลายเซ็นที่สร้างจากคีย์นั้นหรือไม่ เซิร์ฟเวอร์จะตอบรับหรือปฏิเสธ คำว่า "ไม่" ถือเป็นความพยายามที่ล้มเหลว เช่นเดียวกับการใส่รหัสผ่านผิด
คู่มือ sshd_config(5) อธิบายขีดจำกัดไว้ว่า: "ระบุจำนวนครั้งสูงสุดที่อนุญาตให้ยืนยันตัวตนต่อการเชื่อมต่อหนึ่งครั้ง เมื่อจำนวนครั้งที่ล้มเหลวถึงครึ่งหนึ่งของค่านี้ ระบบจะบันทึกความล้มเหลวเพิ่มเติมไว้ใน log ค่าเริ่มต้นคือ 6"
จำนวน 6 ครั้งเพียงพอสำหรับบุคคลที่พิมพ์รหัสผ่าน แต่ไม่เพียงพอสำหรับ agent ที่ถือคีย์ไว้ 10 ชุด เมื่อจำนวนครั้งที่ล้มเหลวเกินขีดจำกัด sshd จะตัดการเชื่อมต่อและเขียนข้อความลงใน system log ดังนี้:
error: maximum authentication attempts exceeded for deploy from 203.0.113.10 port 51292 ssh2ไคลเอนต์ของคุณจะแสดงอีกครึ่งหนึ่งของเหตุการณ์เดียวกันนี้:
Received disconnect from 203.0.113.10 port 22:2: Too many authentication failures
Disconnected from 203.0.113.10 port 22นี่เป็นความล้มเหลวที่ต่างจาก ข้อผิดพลาด SSH permission denied (publickey) ในกรณีนั้น เซิร์ฟเวอร์ได้ตรวจสอบทุกอย่างที่คุณส่งไปแล้วแต่ไม่ยอมรับรายการใดเลย แต่ในกรณีนี้เซิร์ฟเวอร์หยุดตรวจสอบไปเสียก่อน การเข้าใจผิดว่าทั้งสองกรณีเป็นเรื่องเดียวกันคือสาเหตุที่ทำให้หลายคนเสียเวลาทั้งบ่ายไปกับการคัดลอกคีย์ใหม่ ทั้งที่คีย์นั้นถูกต้องอยู่แล้ว
เหตุใดกุญแจเดียวกันจึงใช้งานได้จากแล็ปท็อปของเพื่อนร่วมงาน
ไม่มีสิ่งใดแตกต่างกันทั้งในส่วนของกุญแจหรือตัวเซิร์ฟเวอร์ ตัวแทน (agent) ของเพื่อนร่วมงานเก็บกุญแจไว้ 2 ดอก ในขณะที่ของคุณเก็บไว้ 12 ดอก ข้อเสนอที่ส่งไปถึงก่อนสำหรับพวกเขาจะกลายเป็นลำดับที่ 9 สำหรับคุณ ซึ่งในตอนนั้นการเชื่อมต่อได้สิ้นสุดลงแล้ว
จำนวนกุญแจเพิ่มขึ้นอย่างเงียบเชียบ AddKeysToAgent yes ใน ~/.ssh/config จะเพิ่มกุญแจแต่ละดอกที่คุณใช้เข้าไปในตัวแทนและทิ้งไว้ที่นั่น ตัวแทนจัดการกุญแจบนเดสก์ท็อป เช่น GNOME Keyring บน Linux หรือ login keychain บน macOS จะโหลดกุญแจโดยอัตโนมัติเมื่อเข้าสู่ระบบโดยไม่ถาม เมื่อคุณเพิ่มกุญแจสำหรับไคลเอนต์, กุญแจสำหรับโฮสต์ git และกุญแจสำหรับเครื่องในห้องแล็บสะสมไปเรื่อยๆ ตลอดทั้งปี วันหนึ่งเซิร์ฟเวอร์ที่เคยใช้งานได้ตามปกติจะเริ่มปฏิเสธการเชื่อมต่อของคุณ ทั้งที่ไม่มีสิ่งใดเปลี่ยนแปลงบนเซิร์ฟเวอร์ แต่เป็นเพราะตัวแทนของคุณมีกุญแจมากเกินไป
วิธีตรวจสอบข้อเสนอ (offers) ด้วย ssh -v
ให้รันคำสั่งเชื่อมต่อที่ล้มเหลวด้วย -v แล้วอ่านข้อมูลการติดตาม (trace) ที่แสดงออกมา
ssh -v deploy@203.0.113.10บรรทัดสองประเภทที่มีความสำคัญคือ Will attempt key: ซึ่งจะแสดงรายการ identity ที่ไคลเอนต์รวบรวมไว้ตามลำดับที่จะนำไปใช้งานจริง และ Offering public key: ซึ่งจะปรากฏขึ้นหนึ่งครั้งสำหรับกุญแจแต่ละดอกที่ถูกส่งไปยังเซิร์ฟเวอร์
debug1: Will attempt key: /home/you/.ssh/id_ed25519 ED25519 SHA256:AAAA... agent
debug1: Will attempt key: /home/you/.ssh/id_rsa RSA SHA256:BBBB... agent
debug1: Offering public key: /home/you/.ssh/id_ed25519 ED25519 SHA256:AAAA... agent
debug1: Authentications that can continue: publickey,password
debug1: Offering public key: /home/you/.ssh/id_rsa RSA SHA256:BBBB... agentพาธ ประเภทของกุญแจ และลายนิ้วมือ (fingerprints) ของคุณจะแตกต่างจากตัวอย่าง สิ่งที่คุณต้องนับคือจำนวนบรรทัด Offering public key: ที่ปรากฏก่อนการตัดการเชื่อมต่อ หากข้อเสนอต่างๆ แสดงผ่านไปจนจบเซสชันโดยไม่มีกุญแจที่คุณต้องการปรากฏขึ้น แสดงว่าปัญหาได้รับการวินิจฉัยแล้ว คำว่า agent ที่ท้ายบรรทัดหมายความว่า identity นั้นมาจาก ssh-agent ส่วนคำว่า explicit หมายความว่า identity นั้นมาจากบรรทัด IdentityFile หรือมาจาก -i ในบรรทัดคำสั่ง
จากนั้นให้ตรวจสอบว่า agent ของคุณเก็บกุญแจอะไรไว้บ้าง:
ssh-add -lผลลัพธ์แต่ละบรรทัดคือหนึ่งกุญแจที่ถูกโหลดไว้ หากคำสั่งแสดงผลเป็น The agent has no identities. แสดงว่าปัญหาไม่ได้อยู่ที่ agent และคุณควรตรวจสอบบรรทัด IdentityFile ใน ~/.ssh/config แทน หากคำสั่งแสดงผลเป็น Could not open a connection to your authentication agent. แสดงว่าไม่มี agent ทำงานอยู่ และข้อเสนอที่ส่งไปนั้นมาจากไฟล์กุญแจเริ่มต้นของคุณ
วิธีแก้ไขที่ 1: ใช้ IdentitiesOnly ร่วมกับกุญแจหนึ่งชุดต่อหนึ่งโฮสต์
IdentitiesOnly yes สั่งให้ ssh เสนอเฉพาะกุญแจที่คุณกำหนดค่าไว้เท่านั้น และเพิกเฉยต่อกุญแจส่วนเกินที่ ssh-agent พยายามเสนอให้ เมื่อใช้คู่กับบรรทัด IdentityFile ไคลเอนต์จะส่งกุญแจเพียงชุดเดียวเท่านั้น
Host vps
HostName 203.0.113.10
User deploy
IdentityFile ~/.ssh/id_ed25519_vps
IdentitiesOnly yesบันทึกค่าดังกล่าวลงใน ~/.ssh/config จากนั้นรันคำสั่ง chmod 600 ~/.ssh/config หากไฟล์สามารถเขียนได้โดยกลุ่มหรือบุคคลทั่วไป ssh จะปฏิเสธการทำงานและแสดงข้อผิดพลาด Bad owner or permissions on /home/you/.ssh/config ตอนนี้ ssh vps จะเสนอเพียงกุญแจเดียว และ ssh -v vps ควรแสดงบรรทัด Offering public key: เพียงบรรทัดเดียวเท่านั้น
มีรายละเอียดสองประการที่มักทำให้ผู้ใช้ประหลาดใจ:
IdentitiesOnly yesเพียงอย่างเดียวไม่ได้หมายความว่า "ใช้กุญแจเดียว" ไฟล์ identity เริ่มต้นจะถูกนับเป็นกุญแจที่กำหนดค่าไว้ด้วย ดังนั้น ssh จะยังคงพยายามใช้~/.ssh/id_ed25519,~/.ssh/id_rsaและค่าเริ่มต้นอื่นๆ ที่พบ คุณจำเป็นต้องระบุบรรทัดIdentityFileด้วย- ssh-agent ยังคงเป็นผู้ทำหน้าที่ลงลายเซ็น
IdentitiesOnlyควบคุมเพียงว่ากุญแจใดจะถูกเสนอ ไม่ใช่ผู้ที่ลงลายเซ็น หากกุญแจส่วนตัวที่ระบุโดยIdentityFileถูกโหลดไว้ใน agent ตัว agent จะสร้างลายเซ็นให้โดยที่คุณไม่ต้องใส่รหัสผ่าน คุณสามารถชี้IdentityFileไปยังไฟล์.pubที่ตรงกันได้ ซึ่งเป็นวิธีที่ใช้เมื่อกุญแจส่วนตัวเก็บอยู่ใน agent หรือบน hardware token เท่านั้น
กับดักหนึ่งใน ~/.ssh/config อาจทำให้การแก้ไขนี้ล้มเหลวโดยไม่แจ้งเตือน คีย์เวิร์ดส่วนใหญ่จะใช้ค่าแรกที่พบ ซึ่งเป็นเหตุผลว่าทำไมบล็อก Host เฉพาะเจาะจงจึงต้องอยู่เหนือ Host * แต่ IdentityFile ไม่เป็นไปตามกฎนั้น คู่มือระบุว่า: "สามารถระบุไฟล์ identity หลายไฟล์ในไฟล์กำหนดค่าได้ โดยกุญแจทั้งหมดจะถูกลองใช้ตามลำดับ" ดังนั้น IdentityFile ภายใต้ Host * จะถูกเพิ่มเข้าไปรวมกับกุญแจต่อโฮสต์ของคุณ ไม่ใช่การแทนที่ ทำให้บรรทัด global ที่ลืมไว้ส่งผลให้มีการเสนอคุญแจเพิ่มเข้ามาในทุกการเชื่อมต่อ
หากคุณต้องการตาข่ายนิรภัยระดับ global ให้ตั้งค่าเฉพาะแฟล็กไว้ที่ส่วนท้ายของไฟล์:
Host *
IdentitiesOnly yesจากนั้นแต่ละโฮสต์จำเป็นต้องมี IdentityFile ของตนเอง ซึ่งเป็นผลลัพธ์ที่คุณต้องการอยู่แล้ว การระบุหนึ่งกุญแจต่อหนึ่งเซิร์ฟเวอร์ยังช่วยให้คุณสามารถเพิกถอนสิทธิ์การเข้าถึงของเครื่องใดเครื่องหนึ่งได้ในภายหลังโดยไม่ต้องออกกุญแจใหม่ทั้งหมด ซึ่งเป็นนิสัยที่ควรสร้างไว้ตั้งแต่เนิ่นๆ: ดู วิธีจัดการ SSH keys แยกตามเครื่อง
วิธีแก้ไขที่ 2: ล้างข้อมูลหรือรีสตาร์ท agent
หากคุณยังไม่สามารถแก้ไขไฟล์ config ได้ ให้ล้างข้อมูลใน agent และโหลดเฉพาะสิ่งที่จำเป็นเท่านั้น
ssh-add -l # list what is loaded
ssh-add -d ~/.ssh/id_rsa # remove one key
ssh-add -D # remove every key
ssh-add ~/.ssh/id_ed25519_vps # load the one you needหากการเชื่อมต่อทำงานได้ทันทีหลังจากใช้ ssh-add -D แสดงว่าสาเหตุมาจากตัว agent ให้ถือว่านี่เป็นการทดสอบไม่ใช่การซ่อมแซมถาวร ตัว desktop keyring agent จะโหลดกุญแจใหม่เมื่อคุณล็อกอินครั้งถัดไป ดังนั้นปัญหาจะกลับมาอีกในวันพรุ่งนี้ การเพิ่มบรรทัด IdentitiesOnly ลงใน ~/.ssh/config จะคงอยู่ถาวรแม้หลังจากรีบูตเครื่อง แต่การล้าง agent จะไม่คงอยู่ถาวร
คุณยังสามารถกำหนดอายุการใช้งานให้กับกุญแจเพื่อให้ agent ลบออกให้คุณโดยอัตโนมัติ:
ssh-add -t 1800 ~/.ssh/id_ed25519_vpsกุญแจจะถูกลบออกหลังจากเพิ่มเข้าไปแล้ว 1800 วินาที การรีสตาร์ท agent ก็เป็นอีกวิธีหนึ่ง ซึ่งวิธีการทำจะขึ้นอยู่กับว่าคุณเริ่มการทำงานของมันอย่างไร ssh-agent ที่คุณรันด้วยตัวเองจะหยุดทำงานด้วยคำสั่ง ssh-agent -k หากคุณรันผ่าน systemd user unit ที่คุณเขียนขึ้นเอง ให้รีสตาร์ท unit นั้นด้วย systemctl --user restart <unit> ส่วน keyring agent จะรีสตาร์ทพร้อมกับ session บนเดสก์ท็อปของคุณ
วิธีแก้ไขที่ 3: คำสั่งแบบครั้งเดียวสำหรับเซิร์ฟเวอร์ที่เข้าถึงเพียงครั้งเดียว
สำหรับโฮสต์ที่คุณจะไม่เพิ่มลงในไฟล์คอนฟิกูเรชัน ให้ระบุการตั้งค่าเดียวกันนี้ผ่านบรรทัดคำสั่ง:
ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_vps deploy@203.0.113.10การใช้ -i เพียงอย่างเดียวเป็นวิธีแก้ไขที่ผิดซึ่งพบบ่อยที่สุด -i จะเพิ่มคีย์เข้าไปในรายการ identity แต่มันไม่ได้ลบกุญแจที่มีอยู่ใน agent ออกจากรายการนั้น ดังนั้นคีย์อื่นๆ ทั้งหมดจะยังคงถูกส่งไปก่อนคีย์ของคุณ และการเชื่อมต่อจะยังคงถูกตัดเมื่อถึงขีดจำกัด ให้ลองรัน ssh -v -i ~/.ssh/id_ed25519_vps deploy@203.0.113.10 โดยไม่มี IdentitiesOnly แล้วคุณจะเห็นว่าคีย์จาก agent ถูกส่งไปก่อนเสมอ -i จำเป็นต้องมี -o IdentitiesOnly=yes กำกับอยู่ด้วย
หากต้องการตัดการทำงานของ agent ออกไปโดยสิ้นเชิงสำหรับการเชื่อมต่อหนึ่งครั้ง:
ssh -o IdentityAgent=none -i ~/.ssh/id_ed25519_vps deploy@203.0.113.10จากนั้น ssh จะอ่าน private key จากดิสก์โดยตรงและถามหา passphrase หากมีการตั้งค่าไว้
เครื่องมือที่สร้างขึ้นบนพื้นฐานของ ssh ก็ยอมรับตัวเลือกเดียวกันนี้เช่นกัน:
scp -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_vps report.tar.gz deploy@203.0.113.10:/tmp/
rsync -av -e "ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_vps" ./site/ deploy@203.0.113.10:/srv/site/
GIT_SSH_COMMAND="ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_vps" git clone git@example.com:team/repo.gitเหตุใดข้อผิดพลาดจึงปรากฏขึ้นที่ hop ที่สอง
ด้วย ForwardAgent yes ซ็อกเก็ตของเอเจนต์จะถูกทำให้พร้อมใช้งานบนเซิร์ฟเวอร์ที่คุณเชื่อมต่อเข้าไป คำสั่ง ssh ที่รันบนเซิร์ฟเวอร์นั้นจะใช้เอเจนต์ในเครื่องของคุณพร้อมกับกุญแจทั้งหมดที่มีผ่านซ็อกเก็ตที่ถูกส่งต่อ (forwarded socket) นี่คือสาเหตุที่ข้อผิดพลาดอาจปรากฏขึ้นใน hop จาก jump host ไปยังเซิร์ฟเวอร์ปลายทาง ในขณะที่ hop แรกทำงานได้ตามปกติ ให้รัน echo $SSH_AUTH_SOCK บนเครื่องตัวกลาง หากมี path ของซ็อกเก็ตแสดงขึ้นมา หมายความว่ามีการส่งต่อเอเจนต์ที่เข้าถึงได้ แต่หากไม่มีผลลัพธ์แสดงออกมา หมายความว่าไม่มีการส่งต่อเอเจนต์
การทำ agent forwarding มีต้นทุนแฝงอีกประการหนึ่ง ผู้ที่มีสิทธิ์ root บนเครื่องตัวกลางนั้นสามารถใช้เอเจนต์ของคุณเพื่อยืนยันตัวตนในฐานะคุณได้ตราบเท่าที่เซสชันของคุณยังเปิดอยู่ ProxyJump ช่วยหลีกเลี่ยงปัญหาทั้งสองประการนี้:
ssh -J deploy@jump.example.com deploy@10.0.0.5ProxyJump จะเปิดการเชื่อมต่อผ่าน jump host และยืนยันตัวตนกับเซิร์ฟเวอร์ปลายทางจากเครื่องของคุณโดยตรง ดังนั้น ~/.ssh/config ในเครื่องของคุณจึงมีผลในทุก hop รวมถึง IdentitiesOnly ด้วย การปิด ForwardAgent เป็นขั้นตอนมาตรฐานเมื่อ การเพิ่มความปลอดภัยให้ SSH บน VPS
คุณควรเพิ่มค่า MaxAuthTries บนเซิร์ฟเวอร์หรือไม่?
โดยปกติแล้วไม่ควรทำเช่นนั้น ให้ตรวจสอบค่าปัจจุบันก่อน:
sudo sshd -T | grep -i maxauthtriessshd -T จะแสดงการตั้งค่าที่มีผลจริงรวมถึงค่าเริ่มต้นด้วย ดังนั้นจึงรายงานค่าที่ใช้งานจริงแม้ว่าใน sshd_config จะไม่ได้ระบุไว้ก็ตาม ให้เพิ่ม -C user=deploy,host=example.com,addr=203.0.113.10 หากคุณใช้บล็อก Match เนื่องจากบล็อกดังกล่าวจะถูกประเมินแยกตามการเชื่อมต่อและจะถูกข้ามไปหากไม่ระบุ
การเพิ่มขีดจำกัดนั้นได้ผลในแง่ที่ว่าจำนวนที่มากขึ้นจะช่วยให้ไคลเอนต์ที่มีปัญหาทำงานได้มากขึ้น:
MaxAuthTries 20ตรวจสอบความถูกต้องของไฟล์และโหลด service ใหม่ โดยให้เปิด session ที่สองทิ้งไว้ในขณะที่คุณดำเนินการ:
sudo sshd -t
sudo systemctl reload ssh # Debian and Ubuntu
sudo systemctl reload sshd # RHEL familyหาก systemctl is-enabled ssh.socket รายงาน enabled บน Ubuntu 24.04 แสดงว่า sshd ถูกเปิดใช้งานด้วย socket: จะมีกระบวนการใหม่เริ่มทำงานต่อการเชื่อมต่อหนึ่งครั้งและอ่านไฟล์ sshd_config ใหม่อีกครั้ง ดังนั้นการเชื่อมต่อใหม่จะได้รับค่าที่เปลี่ยนแปลงไปโดยอัตโนมัติ
ตอนนี้ให้พิจารณาผลลัพธ์ของการเปลี่ยนแปลงนั้น ไคลเอนต์กำลังเสนอคีย์ที่เซิร์ฟเวอร์นี้จะไม่มีวันยอมรับ การเพิ่มเพดานจะทำให้เซิร์ฟเวอร์ต้องตรวจสอบข้อเสนอที่ถูกปฏิเสธถึงยี่สิบครั้งต่อการเชื่อมต่อแทนที่จะเป็นหกครั้ง สำหรับไคลเอนต์ทุกรายที่เชื่อมต่อเข้ามาและสำหรับผู้ที่พยายามเดารหัสผ่านจากอินเทอร์เน็ต ทุกข้อเสนอจะทำให้เซิร์ฟเวอร์ต้องเสียเวลาค้นหาใน authorized_keys การเข้าสู่ระบบของคุณเองจะยังคงช้าอยู่เพราะคีย์ที่ถูกต้องยังคงอยู่ท้ายแถว หากคุณเพิ่มคีย์ที่สิบสามเข้าไปใน agent ของคุณ คุณก็จะกลับไปที่จุดเดิมและต้องขอเพิ่มจำนวนอีกครั้ง
ให้เพิ่มค่านี้เฉพาะเมื่อไคลเอนต์ที่ถูกต้องจำเป็นต้องแสดงตัวตนหลายรายการจริงๆ เท่านั้น ในกรณีอื่นทั้งหมดให้แก้ไขที่ฝั่งไคลเอนต์ การลดค่านี้ลงเป็นการเพิ่มความปลอดภัยที่สมเหตุสมผลเมื่อผู้ใช้ทุกคนเข้าสู่ระบบด้วยคีย์ที่กำหนดค่าไว้แล้ว เนื่องจากจำนวนที่น้อยลงจะทำให้ผู้เดารหัสผ่านมีโอกาสลองได้น้อยลงต่อการเชื่อมต่อหนึ่งครั้ง
เหตุใด fail2ban ถึงแบนคุณจากกรณีนี้
ที่ระดับการบันทึก log เริ่มต้น sshd จะบันทึกทุกการปฏิเสธ public key:
Failed publickey for deploy from 203.0.113.10 port 51292 ssh2: ED25519 SHA256:AAAA...การเชื่อมต่อหนึ่งครั้งจาก full agent จะสร้างบรรทัดเหล่านี้หลายบรรทัดจากที่อยู่เดียวกันภายในเวลาหนึ่งหรือสองวินาที jail ของ fail2ban ใน sshd จะนับจำนวนบรรทัดความล้มเหลวของ sshd และแบนที่อยู่ต้นทางเมื่อถึงค่า maxretry ภายในเวลา findtime เนื่องจากหน้าต่างเวลาเหล่านี้มีขนาดเล็กโดยค่าเริ่มต้น การลองเชื่อมต่อใหม่เพียงสองครั้งจากจุดที่การเชื่อมต่อขัดข้องก็เพียงพอที่จะทำให้ที่อยู่ของคุณถูกแบนได้
จากนั้นอาการจะเปลี่ยนไป และนี่คือส่วนที่ทำให้ผู้คนสับสน คุณจะหยุดเห็นข้อความ "Too many authentication failures" และเริ่มไม่เห็นอะไรเลย: การเชื่อมต่อจะค้างและหมดเวลาในที่สุด เนื่องจาก firewall กำลังทิ้งแพ็กเก็ตของคุณแทนที่จะตอบกลับ อาการหมดเวลา (timeout) ในขณะที่คุณเคยได้รับข้อความแสดงข้อผิดพลาดคือสัญญาณบ่งชี้ และความแตกต่างนี้ได้อธิบายไว้ใน การเชื่อมต่อ SSH ถูกปฏิเสธเทียบกับการเชื่อมต่อหมดเวลา
จาก console ของผู้ให้บริการของคุณ หรือจากที่อยู่อื่น ให้ตรวจสอบ jail และยกเลิกการแบน:
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 203.0.113.10ใส่ที่อยู่ของคุณเองลงใน ignoreip ในไฟล์ jail.local ในระหว่างที่คุณจัดการกับฝั่ง client จากนั้นให้นำออกเมื่อดำเนินการเสร็จสิ้น ตัว jail นั้นถูกตั้งค่าไว้ใน คู่มือ fail2ban สำหรับ Ubuntu 24.04
สิ่งที่ควรทำเพียงครั้งเดียวเพื่อป้องกันไม่ให้ปัญหานี้เกิดขึ้นอีก
กำหนดให้เซิร์ฟเวอร์แต่ละเครื่องมีบล็อก Host เป็นของตัวเองในไฟล์ ~/.ssh/config โดยระบุค่า HostName, User, IdentityFile และ IdentitiesOnly yes หลังจากนั้น การใช้คำสั่ง ssh vps จะพิมพ์ได้สั้นลง โดยจะระบุคีย์เพียงคีย์เดียวเท่านั้น และจะไม่ทำให้เกิดข้อผิดพลาด MaxAuthTries ไม่ว่า ssh -v ของคุณจะมีข้อมูลมากเพียงใดก็ตาม นอกจากนี้ยังช่วยให้ผลลัพธ์ของ ssh -v สั้นพอที่จะอ่านได้ง่ายในวันที่เกิดปัญหาอื่นขึ้น
FAQ
ฉันจะแก้ไขข้อผิดพลาด "Too many authentication failures" ในขณะนี้ได้อย่างไร?
ให้ระบุเฉพาะกุญแจ (key) ที่ต้องการใช้งานเพียงรายการเดียวแทนการส่งกุญแจทั้งหมด สำหรับการเชื่อมต่อแบบเร่งด่วน ให้ใช้คำสั่ง ssh -o IdentitiesOnly=yes -i ~/.ssh/your_key user@host หากต้องการแก้ไขอย่างถาวร ให้เพิ่มบล็อกการตั้งค่าลงในไฟล์ ~/.ssh/config โดยระบุ HostName, User, IdentityFile ให้ชี้ไปยังกุญแจนั้น และตั้งค่า IdentitiesOnly yes จากนั้นใช้ chmod 600 ~/.ssh/config ตรวจสอบความถูกต้องด้วย ssh -v ซึ่งคุณควรจะเห็นบรรทัด Offering public key: เพียงบรรทัดเดียวสำหรับโฮสต์นั้น
ทำไมการใช้ ssh -i ถึงยังคงส่งกุญแจอื่นๆ ของฉันไปอีก?
เนื่องจาก -i เป็นการเพิ่ม identity เข้าไปในรายการ ไม่ใช่การจำกัดรายการ กุญแจที่โหลดอยู่ใน ssh-agent จะยังคงอยู่ในรายการและถูกส่งไปตามปกติ ซึ่งมักจะถูกส่งไปก่อนกุญแจของคุณ ทำให้เซิร์ฟเวอร์อาจพบกับ MaxAuthTries ก่อนที่จะถึงกุญแจที่ถูกต้อง -o IdentitiesOnly=yes คือออปชันที่ใช้จำกัด ssh ให้ใช้เฉพาะ identity ที่คุณระบุเท่านั้น ให้ใช้ -i ร่วมกับ -o IdentitiesOnly=yes หรือใช้ -o IdentityAgent=none เพื่อเพิกเฉยต่อ agent สำหรับการเชื่อมต่อนั้นๆ
ฉันควรเพิ่มค่า MaxAuthTries บนเซิร์ฟเวอร์เพื่อแก้ไขปัญหานี้หรือไม่?
ไม่ควรทำในเกือบทุกกรณี เพราะไคลเอนต์กำลังส่งกุญแจที่เซิร์ฟเวอร์ไม่มีวันยอมรับ การเพิ่มขีดจำกัดจะทำให้เซิร์ฟเวอร์ต้องประมวลผลกุญแจที่ถูกปฏิเสธมากขึ้นต่อการเชื่อมต่อหนึ่งครั้ง ทั้งสำหรับไคลเอนต์ปกติและสำหรับการพยายาม brute force ที่เข้ามา และปัญหานี้จะกลับมาเกิดขึ้นอีกทันทีที่คุณเพิ่มกุญแจเข้าไปใน agent อีกเพียงหนึ่งรายการ หากต้องการตรวจสอบค่าปัจจุบัน ให้ใช้ sudo sshd -T | grep -i maxauthtries จากนั้นจึงแก้ไขที่ฝั่งไคลเอนต์ด้วย IdentitiesOnly
ทำไมปัญหานี้ถึงเพิ่งเกิดขึ้นกับเซิร์ฟเวอร์ที่เคยใช้งานได้ปกติเมื่อเดือนก่อน?
เพราะ agent ของคุณมีขนาดใหญ่ขึ้น AddKeysToAgent yes ใน ~/.ssh/config จะเก็บกุญแจทุกตัวที่คุณใช้งานไว้ในหน่วยความจำ และ agent ของ keyring บนเดสก์ท็อปมักจะโหลดกุญแจโดยอัตโนมัติเมื่อล็อกอิน เมื่อจำนวนกุญแจที่โหลดไว้เกินกว่าค่า MaxAuthTries ของเซิร์ฟเวอร์ เซิร์ฟเวอร์ตัวใดก็ตามที่กุญแจของคุณอยู่ในลำดับท้ายๆ ของการส่งก็จะเริ่มเกิดข้อผิดพลาด ให้รัน ssh-add -l แล้วเปรียบเทียบจำนวนกุญแจกับขีดจำกัดบนเซิร์ฟเวอร์
ปัญหานี้จะทำให้ IP address ของฉันถูกแบนโดย fail2ban หรือไม่?
ใช่ กุญแจที่ถูกปฏิเสธแต่ละตัวจะสร้างบรรทัด Failed publickey for ... ใน log ของเซิร์ฟเวอร์ ดังนั้นการเชื่อมต่อเพียงครั้งเดียวอาจทำให้เกิดความล้มเหลวหลายรายการจาก IP ของคุณภายในเวลาไม่กี่วินาที และ jail ของ fail2ban ที่ชื่อ sshd จะแบน IP นั้นทันทีเมื่อถึงค่า maxretry ภายในระยะเวลา findtime สัญญาณบ่งชี้คือข้อผิดพลาดจะเปลี่ยนจากการปฏิเสธเป็นการค้างและตามด้วย timeout เนื่องจากแพ็กเก็ตถูกดรอปแทนที่จะได้รับการตอบกลับ ให้ปลดแบนผ่านคอนโซลด้วย sudo fail2ban-client set sshd unbanip <your address> และแก้ไขที่ฝั่งไคลเอนต์ก่อนทำการเชื่อมต่อใหม่