ระบุคีย์ SSH สำหรับ git push สำหรับโดเมนที่กำหนด


342

ฉันมีกรณีการใช้งานดังต่อไปนี้: ฉันต้องการที่จะผลักดันให้git@git.company.com:gitolite-adminใช้คีย์ส่วนตัวของผู้ใช้gitolite-adminในขณะที่ฉันต้องการที่จะผลักดันให้git@git.company.com:some_repoใช้คีย์ส่วนตัว 'ของตัวเอง' AFAIK ฉันไม่สามารถแก้ปัญหานี้ได้~/.ssh/configเนื่องจากชื่อผู้ใช้และชื่อเซิร์ฟเวอร์เหมือนกันในทั้งสองกรณี ขณะที่ผมส่วนใหญ่ใช้คีย์ส่วนตัวของฉันเองฉันได้ที่กำหนดไว้ในสำหรับ~/.ssh/config git@git.company.comไม่มีใครรู้วิธีการแทนที่คีย์ที่ใช้สำหรับการgitเรียกใช้ครั้งเดียวหรือไม่?

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


เกี่ยวข้องอย่างใกล้ชิด: stackoverflow.com/questions/4565700/ …
Ciro Santilli 郝海东冠状病病六四事件法轮功

คำตอบ:


597

แม้ว่าผู้ใช้และโฮสต์จะเหมือนกันพวกเขายังสามารถแยกแยะความแตกต่าง~/.ssh/configได้ ตัวอย่างเช่นหากการกำหนดค่าของคุณมีลักษณะเช่นนี้:

Host gitolite-as-alice
  HostName git.company.com
  User git
  IdentityFile /home/whoever/.ssh/id_rsa.alice
  IdentitiesOnly yes

Host gitolite-as-bob
  HostName git.company.com
  User git
  IdentityFile /home/whoever/.ssh/id_dsa.bob
  IdentitiesOnly yes

จากนั้นคุณเพียงใช้gitolite-as-aliceและgitolite-as-bobแทนชื่อโฮสต์ใน URL ของคุณ:

git remote add alice git@gitolite-as-alice:whatever.git
git remote add bob git@gitolite-as-bob:whatever.git

บันทึก

คุณต้องการรวมตัวเลือกIdentitiesOnly yesเพื่อป้องกันการใช้รหัสเริ่มต้น มิฉะนั้นหากคุณมีไฟล์รหัสที่ตรงกับชื่อเริ่มต้นพวกเขาจะได้รับการลองก่อนเพราะต่างจากตัวเลือกการกำหนดค่าอื่น ๆ (ซึ่งปฏิบัติตาม "ชนะครั้งแรก") IdentityFileตัวเลือกจะต่อท้ายรายการตัวตนที่จะลอง ดู: /server/450796/how-could-i-stop-ssh-offering-a-wrong-key/450807#450807


9
เยี่ยมมากขอบคุณ ฉันไม่เข้าใจว่าคุณสามารถเลือก 'นามแฝง' สำหรับข้อมูลจำเพาะโฮสต์ได้อย่างอิสระใน ~ / .ssh / config
Confusion

4
ขอบคุณมากสำหรับคำตอบนี้! หนึ่ง gotcha สำหรับฉันคือ IdentityFile นั้นต้องเป็นเส้นทางที่เต็ม (ฉันใส่ id_rsa.rick เป็นอาร์กิวเมนต์ของฉันกับ IdentityFile เท่านั้นและสิ่งนี้ล้มเหลว) ดู ssh_config (5) หน้าคนสำหรับไวยากรณ์อื่น ๆ สำหรับ IdentityFile
rickumali

1
ขอบคุณมากสำหรับคำตอบที่ชัดเจนและเป็นประโยชน์มาก ฉันพยายามทำให้มันใช้งานได้สักพักแล้วก็ล้มเลิกไปก่อนโดยมีข้อสันนิษฐานว่าผู้ใช้รายเดิมต้องใช้ไฟล์คีย์ส่วนตัว id_rsa เดียวกัน
DrCord

7
git@ไม่จำเป็นต้องใช้ชิ้นส่วนในรีโมทดังที่ระบุไว้ในUserบรรทัดการกำหนดค่า
dolmen

2
ฉันกำลังดิ้นรนกับวิธีแก้ปัญหานี้จนกว่าฉันจะเพิ่มอีกบรรทัดที่มีIdentitiesOnly yesทันทีหลังจากที่สายIdentityFileสำหรับโฮสต์ ดูเหมือนว่าจะผ่านไปหลายตัวและหนึ่งในนั้นถูกปิดกั้นจากการเข้าถึงโฮสต์
ผู้ชายช่างฟิต

57

วิธีทางเลือกที่หนึ่งนำเสนอข้างต้นโดย Mark Longairคือการใช้นามแฝงที่จะเรียกใช้ใด ๆคำสั่งคอมไพล์บนใด ๆจากระยะไกลด้วยคีย์ SSH ทางเลือก โดยทั่วไปแนวคิดจะเปลี่ยนข้อมูลประจำตัว SSH ของคุณเมื่อรันคำสั่ง git

ข้อดีที่สัมพันธ์กับวิธีนามแฝงของโฮสต์ในคำตอบอื่น ๆ :

  • จะทำงานกับคำสั่ง git หรือนามแฝงใด ๆแม้ว่าคุณจะไม่สามารถระบุได้remoteอย่างชัดเจน
  • ทำงานกับที่เก็บได้ง่ายขึ้นเนื่องจากคุณต้องตั้งค่าครั้งเดียวต่อเครื่องไคลเอนต์ไม่ใช่หนึ่งครั้งต่อที่เก็บข้อมูลบนเครื่องไคลเอนต์แต่ละเครื่อง

ผมใช้สคริปเล็ก ๆ น้อย ๆ adminและนามแฝงคอมไพล์ อย่างนั้นฉันทำได้เช่น:

git admin push 

เพื่อผลักดันรีโมตเริ่มต้นโดยใช้คีย์ SSH ทางเลือก ("ผู้ดูแลระบบ") อีกครั้งคุณสามารถใช้คำสั่งใด ๆ (ไม่ใช่แค่push) กับนามแฝงนี้ คุณสามารถทำได้ด้วยgit admin clone ...การโคลนที่เก็บที่คุณจะสามารถเข้าถึงได้โดยใช้คีย์ "admin" ของคุณ

ขั้นตอนที่ 1:สร้างคีย์ SSH ทางเลือกโดยตั้งค่าข้อความรหัสผ่านในกรณีที่คุณทำสิ่งนี้กับเครื่องของผู้อื่น

ขั้นตอนที่ 2:สร้างสคริปต์ชื่อ“ ssh-as.sh” ที่เรียกใช้เนื้อหาที่ใช้ SSH แต่ใช้คีย์ SSH ที่กำหนดแทนค่าเริ่มต้น:

#!/bin/bash
exec ssh ${SSH_KEYFILE+-i "$SSH_KEYFILE"} "$@"

ขั้นตอนที่ 3:สร้างสคริปต์ชื่อ“ git-as.sh” ที่เรียกใช้คำสั่ง git โดยใช้คีย์ SSH ที่กำหนด

#!/bin/bash
SSH_KEYFILE=$1 GIT_SSH=${BASH_SOURCE%/*}/ssh-as.sh exec git "${@:2}"

ขั้นตอนที่ 4:เพิ่มนามแฝง (ใช้สิ่งที่เหมาะสมสำหรับ“ PATH_TO_SCRIPTS_DIR” ด้านล่าง):

# Run git commands as the SSH identity provided by the keyfile ~/.ssh/admin
git config --global alias.admin \!"PATH_TO_SCRIPTS_DIR/git-as.sh ~/.ssh/admin"

รายละเอียดเพิ่มเติมได้ที่: http://noamlewis.wordpress.com/2013/01/24/git-admin-an-alias-for-running-git-commands-as-a-privileged-ssh-identity/th


4
คำตอบที่ดีมาก อย่าลืมเพิ่มเครื่องหมายคำพูดล้อมรอบ$@-> "$@"เพื่อความปลอดภัย
kevinarpe

@sinelaw สิ่งนี้ยังใช้งานได้หรือไม่ ฉันได้รับอนุญาตปฏิเสธข้อผิดพลาดตลอดเวลา
Alok Kumar

56

GIT_SSH_COMMANDคุณสามารถใช้ตัวแปรสภาพแวดล้อมของคอมไพล์ รันสิ่งนี้ในเทอร์มินัลของคุณภายใต้ที่เก็บ git ของคุณ:

GIT_SSH_COMMAND='ssh -i ~/.ssh/your_private_key' git submodule update --init

แทนที่~/.ssh/your_private_keyด้วยพา ธ ของคีย์ส่วนตัว ssh ที่คุณต้องการใช้ และคุณสามารถเปลี่ยนคำสั่งคอมไพล์ที่ตามมา (ในตัวอย่างเป็นgit submodule update --init) กับคนอื่น ๆ ชอบgit pull, git fetchฯลฯ


1
เอกสารฉบับเต็มอยู่ที่git-scm.com/docs/git#git-codeGITSSHcode ; มันต้องการrecentish Git (> = 2.3. *) แม้ว่า
Christian Ulbrich

2
ขอบคุณสำหรับคำตอบง่ายๆที่ไม่ต้องการอะไรนอกจากตั้งค่าตัวแปรสภาพแวดล้อมเดียว
โนอาห์ Sussman

4
โปรดทราบว่า ~ / .ssh / id_rsa ของคุณ (หรือคีย์เริ่มต้นของคุณคืออะไร) จะมีความสำคัญมากกว่าคีย์ที่คุณส่งผ่านทาง -i ดังนั้นคุณต้องการใช้ GIT_SSH_COMMAND = 'ssh -i ~ / .ssh / your_private_key -o IdentitiesOnly = ใช่' เพื่อทำให้มันไม่สนใจปุ่มอื่น ๆ
staktrace

คุณจะอัพเดท git push ได้อย่างไร? ฉันหามันไม่พบในเอกสารประกอบ
lebed2045

จะเป็นการดีที่จะสร้างนามแฝง bash หรือ git - คล้ายกับคำตอบของ sinelaw แต่ใช้วิธีนี้แทนที่จะต้องสร้างสคริปต์ที่ไหนสักแห่ง
Inigo

14

หนึ่งระบบที่ใช้ Unix (Linux, BSD, Mac OS X) ข้อมูลประจำตัวเริ่มต้นจะถูกเก็บไว้ในไดเรกทอรี$ HOME / .sshใน 2 ไฟล์: private key: $HOME/.ssh/id_rsa public key: $HOME/.ssh/id_rsa.pub เมื่อคุณใช้sshโดยไม่มีตัวเลือก-iมันจะใช้ไพรเวตคีย์เริ่มต้นเพื่อรับรองความถูกต้องกับระบบระยะไกล

หากคุณมีคีย์ส่วนตัวอื่นที่คุณต้องการใช้เช่น$ HOME / .ssh / deploy_keyคุณต้องใช้ssh -i ~/.ssh/deploy_key ...

มันน่ารำคาญ. คุณสามารถเพิ่มบรรทัดต่อไปนี้ใน$ HOME / .bash_profile ของคุณ : ssh-add ~/.ssh/deploy_key ssh-add ~/.ssh/id_rsa

ดังนั้นทุกครั้งที่คุณใช้sshหรือgitหรือscp(พื้นsshเกินไป) คุณจะได้ไม่ต้องใช้ตัวเลือก-iอีกต่อไป

คุณสามารถเพิ่มคีย์ได้มากเท่าที่คุณต้องการในไฟล์$ HOME / .bash_profile $


10

อีกทางเลือกหนึ่งคือการใช้SSH-ident เพื่อจัดการ identities

มันจะโหลดและใช้คีย์ที่แตกต่างกันโดยอัตโนมัติตามไดเรกทอรีการทำงานปัจจุบันของคุณตัวเลือก ssh และอื่น ๆ ... ซึ่งหมายความว่าคุณสามารถมีงาน / ไดเรกทอรีและส่วนตัว / ไดเรกทอรีที่จบลงอย่างโปร่งใสโดยใช้คีย์และตัวตนที่แตกต่างกันด้วย ssh


9

ฉันใช้ Git Bash กับ Win7 ต่อไปนี้ใช้งานได้สำหรับฉัน

สร้างไฟล์ปรับแต่งที่ ~ / .ssh / config หรือ c: / users / [your_user_name] /. ssh / config ในไฟล์ให้ป้อน:

Host your_host.com
     IdentityFile [absolute_path_to_your_.ssh]\id_rsa

ฉันเดาว่าโฮสต์ต้องเป็น URL ไม่ใช่ "ชื่อ" หรือการอ้างอิงสำหรับโฮสต์ของคุณ ตัวอย่างเช่น,

Host github.com
     IdentityFile c:/users/[user_name]/.ssh/id_rsa

เส้นทางสามารถเขียนในรูปแบบ / c / users / [user_name] / ....

โซลูชันของ Giordano Scalzo นั้นยอดเยี่ยม https://stackoverflow.com/a/9149518/1738546


9

จาก git 2.10 ขึ้นไปเป็นไปได้ที่จะใช้การตั้งค่า gitconfig sshCommand สถานะเอกสาร :

หากตั้งค่าตัวแปรนี้ git fetch และ git push จะใช้คำสั่งที่ระบุแทน ssh เมื่อต้องการเชื่อมต่อกับระบบระยะไกล คำสั่งอยู่ในรูปแบบเดียวกับตัวแปรสภาพแวดล้อม GIT_SSH_COMMAND และจะถูกเขียนทับเมื่อตั้งค่าตัวแปรสภาพแวดล้อม

ตัวอย่างการใช้งานจะเป็น: git config core.sshCommand "ssh -i ~/.ssh/[insert_your_keyname]

ในบางกรณีสิ่งนี้ไม่ทำงานเนื่องจาก ssh_config แทนที่คำสั่งในกรณีนี้พยายามssh -i ~/.ssh/[insert_your_keyname] -F /dev/nullไม่ใช้ ssh_config


8

ฉันได้เปลื้องผ้าด้วยกันและทดสอบด้วย gitub วิธีการต่อไปนี้ขึ้นอยู่กับการอ่านคำตอบอื่น ๆ ซึ่งรวมเทคนิคไม่กี่:

  • กำหนดค่า SSH ที่ถูกต้อง
  • git URL เขียนใหม่

ข้อดีของวิธีนี้คือเมื่อตั้งค่าแล้วมันไม่จำเป็นต้องมีงานเพิ่มเติมใด ๆ เพื่อทำให้ถูกต้องตัวอย่างเช่นคุณไม่จำเป็นต้องเปลี่ยน URL ระยะไกลหรืออย่าลืมโคลนสิ่งต่าง ๆ - การเขียน URL ใหม่ทำให้ใช้งานได้ทั้งหมด .

~/.ssh/config

# Personal GitHub
Host github.com
  HostName github.com
  User git
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/github_id_rsa

# Work GitHub
Host github-work
  HostName github.com
  User git
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/work_github_id_rsa

Host *
  IdentitiesOnly yes

~/.gitconfig

[user]
    name = My Name
    email = personal@personal.email

[includeIf "gitdir:~/dev/work/"]
    path = ~/dev/work/.gitconfig

[url "github-work:work-github-org/"]
    insteadOf = git@github.com:work-github-org/

~/dev/work/.gitconfig

[user]
    email = work@work.email

ตราบใดที่คุณเก็บ repos งานทั้งหมดของคุณไว้ที่ ~ / dev / work และของส่วนตัวที่อื่น git จะใช้คีย์ SSH ที่ถูกต้องเมื่อทำการดึง / โคลนนิ่ง / pushes ไปยังเซิร์ฟเวอร์และมันจะแนบที่อยู่อีเมลที่ถูกต้องกับทุกคน ความมุ่งมั่นของคุณ

อ้างอิง:


มันทำงานอย่างไรกับการโคลนนิ่ง? includeIfควรทำงานถ้ามี.gitไดเรกทอรีฉันคิดว่า?
detly

เดี๋ยวก่อนฉันเข้าใจแล้วมันคือการเขียน URL ใหม่ คำตอบนี้มีประโยชน์อย่างไม่น่าเชื่อ!
detly

4

หากใช้เวอร์ชัน ssh ของ Git บน windows บรรทัดไฟล์ข้อมูลประจำตัวในการกำหนดค่า ssh จะมีลักษณะดังนี้

IdentityFile /c/Users/Whoever/.ssh/id_rsa.alice

ที่/cมีไว้สำหรับc:

เพื่อตรวจสอบในทุบตีคอมไพล์ทำ

cd ~/.ssh
pwd 

3

คุณอาจต้องลบการกำหนดค่าโฮสต์เริ่มต้น (หรือแสดงความคิดเห็น) .ssh / config


1

คุณระบุมากที่สุดในไฟล์ config ssh key:

# Default GitHub user
Host one
 HostName gitlab.com
 User git
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/key-one
 IdentitiesOnly yes

#two user
Host two
 HostName gitlab.com
 User git
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/key-two
 IdentitiesOnly yes

0

ตามที่คนอื่นพูดถึงการกำหนดค่าcore.sshCommandสามารถใช้เพื่อแทนที่คีย์ SSH และพารามิเตอร์อื่น ๆ

นี่คือ exmaple ที่คุณมีกุญแจสำรองชื่อและต้องการที่จะใช้สำหรับเก็บทั้งหมดภายใต้โคลน~/.ssh/workrsa~/work

  1. สร้าง.gitconfigไฟล์ใหม่ภายใต้~/work:
[core]
  sshCommand = "ssh -i ~/.ssh/workrsa"
  1. ในการกำหนดค่า git ทั่วโลกของคุณ~/.gitconfigเพิ่ม:
[includeIf "gitdir:~/work/"]
  path = ~/work/.gitconfig

0

ความเป็นไปได้ทางหนึ่งที่จะใช้~/.ssh/configคือใช้Matchข้อ จำกัด แทนHostข้อ จำกัด โดยเฉพาะMatch Execเรียกคำสั่งเชลล์เพื่อตัดสินใจว่าจะใช้การประกาศหรือไม่ ใน bash คุณสามารถใช้คำสั่งต่อไปนี้:

[ git@git.company.com:gitolite-admin = $(git config --get remote.origin.url)'' ]

สิ่งนี้ใช้[คำสั่งbash เพื่อตรวจสอบว่ามีสองสตริงเท่ากัน ในกรณีนี้เป็นการทดสอบว่าสตริงgit@git.company.com:gitolite-adminตรงกับเอาต์พุตที่ได้รับจาก$(git config --get remote.origin.url)''คำสั่ง

คุณสามารถใช้คำสั่งอื่นใดที่ระบุที่เก็บที่เชลล์เปิดอยู่ สำหรับการทำงานมันเป็นสิ่งสำคัญที่จะมีตัวแปรที่กำหนดให้เปลือกของคุณในกรณีของฉัน$SHELL /bin/bashตัวอย่างแบบเต็มจะเป็นดังต่อไปนี้~/.ssh/config:

Match Exec "[ git@git.company.com:gitolite-admin = $(git config --get remote.origin.url)'' ]"
  IdentityFile ~/.ssh/gitolite-admin
  IdentitiesOnly yes
  ForwardAgent no
  ForwardX11 no
  ForwardX11Trusted no

Match Exec "[ git@git.company.com:some_repo = $(git config --get remote.origin.url)'' ]"
  IdentityFile ~/.ssh/yourOwnPrivateKey
  IdentitiesOnly yes
  ForwardAgent no
  ForwardX11 no
  ForwardX11Trusted no

ในตัวอย่างนี้ผมสันนิษฐานว่า~/.ssh/yourOwnPrivateKeyมีคีย์ส่วนตัวของคุณเองและที่มีคีย์ส่วนตัวของผู้ใช้~/.ssh/gitolite-admin gitolite-adminฉันรวมการIdentitiesOnly yesประกาศเพื่อให้แน่ใจว่ามีเพียงคีย์เดียวเท่านั้นที่เสนอให้กับเซิร์ฟเวอร์ git ที่ระบุโดยMark LongairLongair การประกาศอื่น ๆ เป็นเพียงตัวเลือก ssh มาตรฐานสำหรับ git

คุณสามารถเพิ่มการกำหนดค่านี้หากคุณมีหลายอย่างsome_repoที่คุณต้องการใช้กับปุ่มที่แตกต่างกัน หากคุณมีที่เก็บข้อมูลหลายแห่งgit@git.company.comและส่วนใหญ่ใช้ที่เก็บที่~/.ssh/yourOwnPrivateKeyเหมาะสมเพื่อรวมคีย์นี้เป็นค่าเริ่มต้นสำหรับโฮสต์ ในกรณีนี้~/.ssh/configจะเป็น:

Match Exec "[ git@git.company.com:gitolite-admin = $(git config --get remote.origin.url)'' ]"
  IdentityFile ~/.ssh/gitolite-admin
  IdentitiesOnly yes

Host git.company.com
  IdentityFile ~/.ssh/yourOwnPrivateKey
  IdentitiesOnly yes
  ForwardAgent no
  ForwardX11 no
  ForwardX11Trusted no

โปรดทราบว่าคำสั่งซื้อมีความสำคัญและHost git.company.comข้อ จำกัด ควรปรากฏหลังจากรายการMatch Execหนึ่งรายการ


0

git configกำหนดค่าพื้นที่เก็บข้อมูลของคุณโดยใช้ ตัวอย่างเช่น:

git config --add --local core.sshCommand 'ssh -i ~/.ssh/<<<PATH_TO_SSH_KEY>>>'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.