Chỉ định khóa SSH cho git đẩy cho một miền nhất định


342

Tôi có trường hợp sử dụng sau: Tôi muốn có thể chuyển sang git@git.company.com:gitolite-adminsử dụng khóa riêng của người dùng gitolite-admin, trong khi tôi muốn chuyển sang git@git.company.com:some_reposử dụng khóa riêng 'của riêng tôi'. AFAIK, tôi không thể giải quyết vấn đề này bằng cách sử dụng ~/.ssh/config, vì tên người dùng và tên máy chủ giống hệt nhau trong cả hai trường hợp. Vì tôi chủ yếu sử dụng khóa riêng của mình, tôi có định nghĩa đó ~/.ssh/configcho git@git.company.com. Có ai biết một cách để ghi đè khóa được sử dụng cho một lệnh gitgọi không?

(Ngoài ra: gitolite phân biệt ai đang thực hiện việc đẩy dựa trên khóa, do đó, không có vấn đề gì, về quyền truy cập, quyền sở hữu và kiểm toán, rằng chuỗi user @ server giống hệt nhau cho những người dùng khác nhau.)


Liên quan chặt chẽ: stackoverflow.com/questions/4565700/
Ấn

Câu trả lời:


597

Ngay cả khi người dùng và máy chủ giống nhau, họ vẫn có thể được phân biệt ~/.ssh/config. Ví dụ: nếu cấu hình của bạn trông như thế này:

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

Sau đó, bạn chỉ cần sử dụng gitolite-as-alicegitolite-as-bobthay vì tên máy chủ trong URL của mình:

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

Ghi chú

Bạn muốn bao gồm tùy chọn IdentitiesOnly yesđể ngăn việc sử dụng id mặc định. Mặt khác, nếu bạn cũng có các tệp id khớp với tên mặc định, chúng sẽ được thử trước vì không giống như các tùy chọn cấu hình khác (tuân theo "lần đầu tiên thắng"), IdentityFiletùy chọn sẽ thêm vào danh sách các danh tính để thử. Xem: /server/450796/how-could-i-stop-ssh-offering-a-wrong-key/450807#450807


9
Thật sự cảm ơn. Tôi đã không hiểu rằng bạn có thể tự do chọn một 'bí danh' cho đặc tả Máy chủ trong ~ / .ssh / config
Nhầm lẫn

4
Cảm ơn vì câu trả lời này! Một điều khó hiểu đối với tôi là IdentityFile cần phải là một đường dẫn đầy đủ (tôi chỉ đặt id_rsa.rick làm đối số của mình cho IdentityFile và điều này đã thất bại). Xem trang man ssh_config (5) để biết cú pháp khác cho IdentityFile.
rickumali

1
Cảm ơn bạn rất nhiều cho câu trả lời rõ ràng và rất hữu ích. Tôi đã cố gắng để nó hoạt động được một thời gian và đã bỏ cuộc trước đó với giả định rằng cùng một người dùng phải sử dụng cùng một tệp khóa riêng id_rsa.
DrCord

7
Phần git@trong điều khiển từ xa là không cần thiết vì nó được đưa ra trong Userdòng cấu hình.
heo

2
Tôi đã vật lộn với giải pháp này cho đến khi tôi thêm một dòng khác chứa IdentitiesOnly yesngay sau dòng với IdentityFilemáy chủ. Có vẻ như nó đã được chuyển qua nhiều danh tính và một trong số đó đã bị chặn truy cập máy chủ.
Người đàn ông Fitter

57

Một cách tiếp cận khác với phương pháp được cung cấp ở trên bởi Mark Longair là sử dụng một bí danh sẽ chạy bất kỳ lệnh git nào , trên bất kỳ điều khiển từ xa nào , với khóa SSH thay thế. Ý tưởng về cơ bản là để chuyển danh tính SSH của bạn khi chạy các lệnh git.

Ưu điểm liên quan đến phương pháp bí danh máy chủ trong câu trả lời khác:

  • Sẽ hoạt động với bất kỳ lệnh git hoặc bí danh nào, ngay cả khi bạn không thể chỉ định remoterõ ràng.
  • Làm việc dễ dàng hơn với nhiều kho lưu trữ vì bạn chỉ cần thiết lập một lần cho mỗi máy khách, không phải một lần cho mỗi kho lưu trữ trên mỗi máy khách.

Tôi sử dụng một vài tập lệnh nhỏ và bí danh git admin. Bằng cách đó tôi có thể làm, ví dụ:

git admin push 

Để đẩy đến điều khiển từ xa mặc định bằng phím SSH ("admin") thay thế. Một lần nữa, bạn có thể sử dụng bất kỳ lệnh nào (không chỉ push) với bí danh này. Bạn thậm chí có thể làm git admin clone ...để sao chép một kho lưu trữ mà bạn sẽ chỉ có quyền truy cập để sử dụng khóa "quản trị" của mình.

Bước 1: Tạo các khóa SSH thay thế, tùy ý đặt cụm mật khẩu trong trường hợp bạn đang thực hiện việc này trên máy của người khác.

Bước 2: Tạo một tập lệnh có tên là ssh-as.sh, chạy các công cụ sử dụng SSH, nhưng sử dụng một khóa SSH cụ thể thay vì mặc định:

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

Bước 3: Tạo một tập lệnh có tên là git-as.sh. Nó chạy các lệnh git bằng khóa SSH đã cho.

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

Bước 4: Thêm một bí danh (sử dụng một cái gì đó phù hợp cho Đá PATH_TO_SCRIPTS_DIR kèm bên dưới):

# 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"

Thêm chi tiết tại: http://noamlewis.wordpress.com/2013/01/24/git-admin-an-alias-for-rucky-git-commands-as-a-privileged-ssh-identity/


4
Câu trả lời rất hay. Đừng quên thêm dấu ngoặc kép xung quanh $@-> "$@"để an toàn.
kevinarpe

@sinelaw Cái này có còn hoạt động không? Tôi nhận được quyền từ chối lỗi mọi lúc
Alok Kumar

55

Bạn có thể sử dụng biến môi trường git GIT_SSH_COMMAND. Chạy cái này trong terminal của bạn dưới kho git của bạn:

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

Thay thế ~/.ssh/your_private_keybằng đường dẫn của khóa riêng ssh bạn muốn sử dụng. Và bạn có thể thay đổi lệnh git tiếp theo (trong ví dụ là git submodule update --init) cho người khác thích git pull, git fetchvv


1
Tài liệu đầy đủ có tại git-scm.com/docs/git#git-codeGITSSHcode ; nó cần một recentish Git (> = 2.3. *) mặc dù.
Christian Ulbrich

2
Cảm ơn bạn về một giải pháp đơn giản không yêu cầu bất cứ điều gì ngoại trừ việc đặt một biến môi trường.

4
Lưu ý rằng ~ / .ssh / id_rsa (hoặc bất cứ khóa mặc định nào của bạn) sẽ được ưu tiên so với khóa bạn truyền qua -i. Vì vậy, bạn thực sự muốn sử dụng GIT_SSH_COMMAND = 'ssh -i ~ / .ssh / your_private_key -o IdentityOnly = yes' để làm cho nó bỏ qua các khóa khác
staktrace

Làm thế nào bạn có thể cập nhật git đẩy? Tôi không thể tìm thấy nó trong tài liệu
lebed2045

Sẽ rất tuyệt nếu tạo bí danh bash hoặc git - tương tự như câu trả lời của sinelaw nhưng sử dụng phương pháp này thay vì phải tạo tập lệnh ở đâu đó.
Inigo

14

Một hệ thống dựa trên Unix (Linux, BSD, Mac OS X), danh tính mặc định được lưu trong thư mục $ HOME / .ssh , trong 2 tệp: private key: $HOME/.ssh/id_rsa public key: $HOME/.ssh/id_rsa.pub Khi bạn sử dụng sshmà không có tùy chọn -i, nó sử dụng khóa riêng mặc định để xác thực với hệ thống từ xa.

Nếu bạn có một khóa riêng khác mà bạn muốn sử dụng, ví dụ $ HOME / .ssh / triển khai_key , bạn phải sử dụngssh -i ~/.ssh/deploy_key ...

Điều đó thật phiền phức. Bạn có thể thêm các dòng sau vào $ HOME / .bash_profile : ssh-add ~/.ssh/deploy_key ssh-add ~/.ssh/id_rsa

Vì vậy, mỗi lần bạn sử dụng sshhoặc githoặc scp(về cơ bản sshquá), bạn không cần phải sử dụng tùy chọn -inữa.

Bạn có thể thêm bao nhiêu khóa tùy thích trong tệp $ HOME / .bash_profile .


10

Một cách khác là sử dụng ssh-nhận dạng, để quản lý danh tính ssh của bạn .

Nó tự động tải và sử dụng các khóa khác nhau dựa trên thư mục làm việc hiện tại của bạn, các tùy chọn ssh, v.v ... có nghĩa là bạn có thể dễ dàng có một thư mục công việc / riêng tư và thư mục / cuối cùng sử dụng các khóa và định danh khác nhau với ssh.


9

Tôi đang sử dụng Git Bash trên Win7. Sau đây làm việc cho tôi.

Tạo một tệp cấu hình tại ~ / .ssh / config hoặc c: / users / [your_user_name] /. Ssh / config. Trong tệp nhập:

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

Tôi đoán máy chủ phải là một URL chứ không chỉ là "tên" hoặc ref cho máy chủ của bạn. Ví dụ,

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

Đường dẫn cũng có thể được viết ở định dạng / c / users / [user_name] / ....

Giải pháp được cung cấp bởi Giordano Scalzo cũng rất tuyệt. https://stackoverflow.com/a/9149518/1738546


9

Từ git 2.10 trở lên cũng có thể sử dụng cài đặt gshconfig sshCommand. Trạng thái tài liệu :

Nếu biến này được đặt, git fetch và git push sẽ sử dụng lệnh được chỉ định thay vì ssh khi chúng cần kết nối với hệ thống từ xa. Lệnh có cùng dạng với biến môi trường GIT_SSH_COMMAND và bị ghi đè khi biến môi trường được đặt.

Một ví dụ sử dụng sẽ là: git config core.sshCommand "ssh -i ~/.ssh/[insert_your_keyname]

Trong một số trường hợp, điều này không hoạt động vì ssh_config ghi đè lệnh, trong trường hợp này cố gắng ssh -i ~/.ssh/[insert_your_keyname] -F /dev/nullkhông sử dụng ssh_config.


8

Tôi đã kết hợp với nhau và thử nghiệm với github theo cách tiếp cận sau, dựa trên việc đọc các câu trả lời khác, kết hợp một vài kỹ thuật:

  • cấu hình SSH chính xác
  • viết lại URL git

Ưu điểm của phương pháp này là, sau khi được thiết lập, nó không yêu cầu bất kỳ công việc bổ sung nào để làm cho đúng - ví dụ: bạn không cần thay đổi URL từ xa hoặc nhớ sao chép mọi thứ khác nhau - việc viết lại URL khiến tất cả đều hoạt động .

~/.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

Miễn là bạn giữ tất cả các repos công việc của mình dưới ~ / dev / công việc và các vật dụng cá nhân ở nơi khác, git sẽ sử dụng khóa SSH chính xác khi thực hiện thao tác kéo / sao chép / đẩy vào máy chủ và nó cũng sẽ đính kèm địa chỉ email chính xác vào tất cả cam kết của bạn.

Người giới thiệu:


Làm thế nào điều này làm việc với nhân bản? includeIfTôi chỉ nên làm việc nếu có một .gitthư mục hiện tại tôi nghĩ?
gièm pha

Đợi tôi hiểu, đó là URL viết lại quan tâm đến điều đó. Câu trả lời này là vô cùng hữu ích!
gièm pha

4

Nếu sử dụng phiên bản ssh của Git trên windows, dòng tệp nhận dạng trong cấu hình ssh trông giống như

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

nơi /cdành choc:

Để kiểm tra, trong git của bash làm

cd ~/.ssh
pwd 

3

Bạn có thể cần xóa (hoặc nhận xét) cấu hình Máy chủ mặc định .ssh / cấu hình


1

bạn được chỉ định nhiều nhất trong khóa cấu hình tệp ssh:

# 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

Như một người khác đã đề cập, core.sshCommandcấu hình có thể được sử dụng để ghi đè khóa SSH và các tham số khác.

Đây là một exmaple nơi bạn có một khóa thay thế được đặt tên ~/.ssh/workrsavà muốn sử dụng nó cho tất cả các kho lưu trữ được nhân bản theo ~/work.

  1. Tạo một .gitconfigtệp mới trong ~/work:
[core]
  sshCommand = "ssh -i ~/.ssh/workrsa"
  1. Trong cấu hình git toàn cầu của bạn ~/.gitconfig, thêm:
[includeIf "gitdir:~/work/"]
  path = ~/work/.gitconfig

0

Một khả năng để sử dụng ~/.ssh/configlà sử dụng Matchhạn chế thay vì Hosthạn chế. Cụ thể Match Execgọi một lệnh shell để quyết định có áp dụng khai báo hay không. Trong bash bạn có thể sử dụng lệnh sau:

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

Điều này sử dụng [lệnh bash để xác minh nếu hai chuỗi bằng nhau. Trong trường hợp này, nó đang kiểm tra nếu chuỗi git@git.company.com:gitolite-adminkhớp với đầu ra thu được từ $(git config --get remote.origin.url)''lệnh.

Bạn có thể sử dụng bất kỳ lệnh nào khác xác định kho lưu trữ mà shell đang bật. Để làm việc này, điều quan trọng là phải có $SHELLbiến được xác định cho shell của bạn, trong trường hợp của tôi /bin/bash. Ví dụ đầy đủ sau đó sẽ là như sau ~/.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

Trong ví dụ này tôi giả sử ~/.ssh/yourOwnPrivateKeycó chứa khóa riêng của bạn và khóa đó ~/.ssh/gitolite-adminchứa khóa riêng của người dùng gitolite-admin. Tôi đã bao gồm IdentitiesOnly yeskhai báo để đảm bảo rằng chỉ có một khóa được cung cấp cho máy chủ git, được đề cập bởi Mark Longair . Các khai báo khác chỉ là các tùy chọn ssh tiêu chuẩn cho git.

Bạn có thể thêm cấu hình này nếu bạn có một vài some_repophím mà bạn muốn sử dụng với các phím khác nhau. Nếu bạn có một số kho lưu trữ tại git@git.company.comvà hầu hết trong số chúng sử dụng thì ~/.ssh/yourOwnPrivateKeysẽ có ý nghĩa hơn khi đưa khóa này làm mặc định cho máy chủ lưu trữ. Trong trường hợp này, ~/.ssh/configsẽ là:

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

Lưu ý rằng thứ tự quan trọng và Host git.company.comhạn chế sẽ xuất hiện sau Match Execmột hoặc một.


0

Cấu hình kho lưu trữ của bạn bằng cách sử dụng git config. Ví dụ:

git config --add --local core.sshCommand 'ssh -i ~/.ssh/<<<PATH_TO_SSH_KEY>>>'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.