การพิสูจน์ตัวตนคีย์ SSH โดยใช้ LDAP


59

ในระยะสั้น:

ต้องการวิธีการรับรองความถูกต้องของคีย์ SSH ผ่าน LDAP

ปัญหา:

เราใช้ LDAP (slapd) สำหรับบริการไดเรกทอรีและเราเพิ่งย้ายไปใช้ AMI ของเราเพื่อสร้างอินสแตนซ์ เหตุผลบิต AMI เป็นสิ่งที่สำคัญคือว่านึกคิดเราต้องการเพื่อให้สามารถเข้าสู่ระบบด้วย SSH ผ่านการตรวจสอบคีย์เร็วที่สุดเท่าที่อินสแตนซ์ที่กำลังทำงานและไม่ต้องรอให้เครื่องมือของเราค่อนข้างช้าจัดการการกำหนดค่าที่จะเขี่ยสคริปต์เพื่อเพิ่ม ปุ่มที่ถูกต้องกับอินสแตนซ์

สถานการณ์ที่เหมาะสมที่สุดคือเมื่อเพิ่มผู้ใช้ใน LDAP เราจะเพิ่มรหัสของพวกเขาเช่นกันและพวกเขาจะสามารถเข้าสู่ระบบได้ทันที

การรับรองความถูกต้องของคีย์เป็นสิ่งที่ต้องทำเนื่องจากการเข้าสู่ระบบด้วยรหัสผ่านนั้นมีความปลอดภัยน้อยกว่า

ฉันได้อ่านคำถามนี้ซึ่งแนะนำว่ามีแพทช์สำหรับ OpenSSH เรียกว่า OpenSSH-lpk เพื่อทำสิ่งนี้ แต่ไม่จำเป็นกับเซิร์ฟเวอร์ OpenSSH> = 6.2

เพิ่มตัวเลือก sshd_config (5) AuthorizedKeysCommand เพื่อสนับสนุนการดึง authorized_keys จากคำสั่งเพิ่มเติมจาก (หรือแทน) จากระบบไฟล์ คำสั่งรันภายใต้บัญชีที่ระบุโดยตัวเลือก AuthorizedKeysCommandUser sshd_config (5)

ฉันจะกำหนดค่า OpenSSH และ LDAP เพื่อใช้งานได้อย่างไร

คำตอบ:


64

อัพเดต LDAP เพื่อรวมสกีมา OpenSSH-LPK

ก่อนอื่นเราต้องอัปเดต LDAP ด้วยสคีมาเพื่อเพิ่มsshPublicKeyคุณสมบัติสำหรับผู้ใช้:

dn: cn=openssh-lpk,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: openssh-lpk
olcAttributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey'
    DESC 'MANDATORY: OpenSSH Public key'
    EQUALITY octetStringMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
olcObjectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
    DESC 'MANDATORY: OpenSSH LPK objectclass'
    MAY ( sshPublicKey $ uid )
    )

สร้างสคริปต์ที่เคียวรี LDAP สำหรับพับลิกคีย์ของผู้ใช้:

สคริปต์ควรแสดงคีย์สาธารณะสำหรับผู้ใช้ตัวอย่าง:

ldapsearch '(&(objectClass=posixAccount)(uid='"$1"'))' 'sshPublicKey' | sed -n '/^ /{H;d};/sshPublicKey:/x;$g;s/\n *//g;s/sshPublicKey: //gp'

อัปเดตsshd_configให้ชี้ไปที่สคริปต์จากขั้นตอนก่อนหน้า

  • AuthorizedKeysCommand /path/to/script
  • AuthorizedKeysCommandUser nobody

โบนัส : อัปเดตsshd_configเพื่ออนุญาตการตรวจสอบรหัสผ่านจากเครือข่าย RFC1918 ภายในตามที่เห็นในคำถามนี้

อนุญาตให้ใช้การพิสูจน์ตัวตนด้วยรหัสผ่านไปยังเซิร์ฟเวอร์ SSH จากเครือข่ายภายในเท่านั้น

ลิงค์ที่มีประโยชน์:

แก้ไข: เพิ่มผู้ใช้nobodyตามที่แนะนำ TRS-80


6
มันวิเศษมากแม้ว่าฉันจะแนะนำAuthorizedKeysCommandUser nobodyแทนที่จะเป็นรูท
TRS-80

ต้องมีบางอย่างที่แตกต่างกันเกี่ยวกับ ldapsearch หรือ sed ของฉันเพราะ piping output ไปยังคำสั่ง magic black sed ที่คุณมีให้ไม่มีเอาต์พุตถึงแม้ว่าคำสั่ง ldapsearch ธรรมดาของฉันจะส่งคืนข้อมูล ฉันจะต้องเขียนสคริปต์เพื่อทำความสะอาดผลลัพธ์แทนที่จะใช้ sed
Chris L

1
ไม่ต้องสนใจความคิดเห็นก่อนหน้าของฉัน ปัญหาของฉันเกิดจากการขึ้นบรรทัดใหม่ต่อท้ายในคุณสมบัติ sshPublicKey ซึ่งทำให้ ldapsearch ทำให้ base64 เข้ารหัสสิ่งทั้งหมด ฉันทำให้คำสั่ง sed ง่ายขึ้น:ldapsearch -u -LLL -o ldif-wrap=no '(&(objectClass=posixAccount)(uid='"$1"'))' 'sshPublicKey' | sed -n 's/^[ \t]*sshPublicKey:[ \t]*\(.*\)/\1/p'
Chris L

1
@Chris เวทมนตร์สีดำน้อยลงอย่างแน่นอน แต่ sed ยังคงเป็นฟังก์ชั่นการเขียนหนึ่งครั้ง 1 ทาง;)
249 Froyke Froyke

1
ในรุ่นของฉัน OpenSSH (5.3p1-122.el6) มีAuthorizedKeysCommandRunAsและไม่AuthorizedKeysCommandUser
mveroone

5

สำหรับทุกคนที่ได้รับข้อผิดพลาดเมื่อรัน ldapsearch:

sed: 1: "/^ /{H;d};": extra characters at the end of d command

อย่างที่ฉันเคยเป็น (บน FreeBSD) การแก้ไขคือการเปลี่ยนคำสั่ง sed แรกเป็น:

/^ /{H;d;};

(เพิ่มเซมิโคลอนหลัง 'd')


4

แค่ต้องการแบ่งปัน "วิธีการ" ของฉันฝั่งไคลเอ็นต์ของฉันคือ Debian / Ubuntu เฉพาะ แต่ฝั่งเซิร์ฟเวอร์ของฉันนั้นโดยทั่วไปเหมือนกับข้างต้น แต่มีอีกเล็กน้อย "HowTo:"

เซิร์ฟเวอร์:

เปิดใช้งานแอตทริบิวต์กุญแจสาธารณะ:

เครดิต:

https://blog.shichao.io/2015/04/17/setup_openldap_server_with_openssh_lpk_on_ubuntu.html

cat << EOL >~/openssh-lpk.ldif
dn: cn=openssh-lpk,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: openssh-lpk
olcAttributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey'
  DESC 'MANDATORY: OpenSSH Public key'
  EQUALITY octetStringMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
olcObjectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
  DESC 'MANDATORY: OpenSSH LPK objectclass'
  MAY ( sshPublicKey $ uid )
  )
EOL

ตอนนี้ใช้สิ่งนี้เพื่อเพิ่ม ldif:

ldapadd -Y EXTERNAL -H ldapi:/// -f ~/openssh-lpk.ldif

การเพิ่มผู้ใช้ด้วยกุญแจสาธารณะ SSH ใน phpLDAPadmin

ก่อนอื่นให้สร้างผู้ใช้ด้วยเทมเพลต“ Generic: บัญชีผู้ใช้” จากนั้นไปที่ส่วน "แอตทริบิวต์ ObjectClass" คลิก "เพิ่มมูลค่า" และเลือกแอตทริบิวต์ "ldapPublicKey" หลังจากที่คุณส่งแล้วให้กลับไปที่หน้าแก้ไขผู้ใช้คลิก“ เพิ่มแอททริบิวใหม่” ที่ส่วนบนสุดแล้วเลือก“ sshPublicKey” วางกุญแจสาธารณะในพื้นที่ข้อความจากนั้นคลิก“ อัปเดตออบเจ็กต์”

sshPublicKey คุณสมบัติไม่แสดง - OpenLDAP PHPLDAP SSH Key Auth

ลูกค้า Ubuntu:

apt-get -y install python-pip python-ldap
pip install ssh-ldap-pubkey
sh -c 'echo "AuthorizedKeysCommand /usr/local/bin/ssh-ldap-pubkey-wrapper\nAuthorizedKeysCommandUser nobody" >> /etc/ssh/sshd_config' && service ssh restart

สร้างคีย์ทดสอบ:

ssh-keygen -t rsa

3

นี้ไม่ได้เป็นคำตอบที่เต็มรูปแบบเพียงนอกจากคำตอบของ c4urself ฉันจะเพิ่มนี่เป็นความคิดเห็น แต่ฉันไม่มีชื่อเสียงเพียงพอที่จะแสดงความคิดเห็นดังนั้นโปรดอย่า downvote!

นี่คือสคริปต์ที่ฉันใช้สำหรับAuthorizedKeysCommand(ตามเวอร์ชันของ c4urself) มันทำงานโดยไม่คำนึงว่าค่าจะถูกส่งกลับในการเข้ารหัส base64 หรือไม่ สิ่งนี้มีประโยชน์อย่างยิ่งหากคุณต้องการจัดเก็บคีย์ที่ได้รับอนุญาตหลายรายการใน LDAP - แยกคีย์ด้วยอักขระขึ้นบรรทัดใหม่คล้ายกับไฟล์ authorized_keys

#!/bin/bash
set -eou pipefail
IFS=$'\n\t'

result=$(ldapsearch '(&(objectClass=posixAccount)(uid='"$1"'))' 'sshPublicKey')
attrLine=$(echo "$result" | sed -n '/^ /{H;d};/sshPublicKey:/x;$g;s/\n *//g;/sshPublicKey:/p')

if [[ "$attrLine" == sshPublicKey::* ]]; then
  echo "$attrLine" | sed 's/sshPublicKey:: //' | base64 -d
elif [[ "$attrLine" == sshPublicKey:* ]]; then
  echo "$attrLine" | sed 's/sshPublicKey: //'
else
  exit 1
fi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.