Chọn khóa riêng để sử dụng với Git


81

Tôi có 2 máy chủ Git yêu cầu 2 khóa SSH khác nhau.

git clone user1@server1:blahblahblahsử dụng ~/.ssh/id_rsa, nhưng tôi cần chỉ định khóa nào sẽ sử dụng tùy thuộc vào máy chủ tôi đang kết nối.

Tham số dòng lệnh Git nào thực hiện công việc này? (Tôi đang chạy Linux.)


2
Câu hỏi này được trả lời tại superuser.com/questions/232373/… .
Daira Hopwood


Câu trả lời:


59

Nếu bạn đang kết nối qua SSH thì khóa sẽ được điều khiển bởi tham số SSH, không phải tham số git.

SSH tìm ~/.ssh/configthông số cấu hình trong tệp. Sửa đổi tệp đó và thêm các mục nhập IdentityFile cho hai máy chủ Git như sau:

Host server1.whatever.com
  IdentityFile /path/to/key_1
Host server2.whatever.com
  IdentityFile /path/to/key_2

Bài viết này có một số chi tiết hơn.


12
Điều đó không trả lời câu hỏi. Câu hỏi là, làm cách nào để cung cấp cho git tham số này, khi ssh xử lý ủy quyền?
keks

@Keks: Bạn không thể chuyển đối số ssh qua dòng lệnh git. Câu trả lời này đưa ra một cách giải quyết. Cũng có thể có các cách giải quyết khác, ví dụ git.wiki.kernel.org/index.php/… . Lưu ý rằng cách tiếp cận đó cũng không sử dụng các đối số dòng lệnh để sửa đổi hành vi ssh.
Cameron Skinner

12
Điều đó đúng, tuy nhiên câu trả lời ban đầu của bạn không trả lời câu hỏi. Bạn cũng có thể sử dụng ssh-agentvà sử dụng ssh-addvà sau đó chỉ cần sử dụng git. Khi git kết nối qua ssh, khóa đã được bật. Bạn thấy đấy, có một số cách và câu trả lời ban đầu của bạn không thực sự hữu ích.
keks

Đây là một câu trả lời chỉ có liên kết khá nhiều. Bạn có thể tóm tắt các thông tin liên quan của bài viết trong câu trả lời của mình không?
Flimm

@Flimm: Đã thêm tóm tắt.
Cameron Skinner

92

Có một khả năng khác. Đó là để thiết lập core.sshCommand, ví dụ:

git config --local core.sshCommand "/usr/bin/ssh -i /home/me/.ssh/id_rsa_foo"

Có một trường hợp cụ thể khi chiến lược này đặc biệt hữu ích: đó là khi bạn có nhiều tài khoản trên Github, vì tất cả các tài khoản sshtrên Github git@github.comvà nó sử dụng sshkhóa để xác định bạn là người dùng Github nào. Trong trường hợp này .ssh/configcũng không và ssh-agentsẽ không làm những gì bạn muốn.

Cập nhật - Bạn không thể chạy phần trên cho đến khi bạn có kho lưu trữ cục bộ, vì vậy nếu bạn đang cố gắng sao chép kho lưu trữ từ xa, bạn sẽ cần chỉ định khóa theo cách thủ công theo câu trả lời của drawbie18:

git clone -c core.sshCommand="/usr/bin/ssh -i /home/me/.ssh/id_rsa_foo" git@github.com:me/repo.git

Khi bạn đã nhân bản kho lưu trữ, bạn có thể sử dụng git configlệnh để đặt điều này vĩnh viễn.


7
Đây sẽ là câu trả lời được chọn. Cấu hình yêu cầu được bản địa hóa độc đáo trong kho lưu trữ cần sử dụng khóa ssh khác nhau để truy cập các máy chủ git khác nhau. Không cần phải sửa đổi ~ / .ssh / config (và thậm chí / etc / hosts, trong trường hợp có nhiều tài khoản trên GitHub).
mr.b

1
Tuy nhiên, có một vấn đề: bạn không thể sao chép repo trước khi định cấu hình nó và để định cấu hình nó, trước tiên bạn cần phải nhân bản nó. HOẶC, bạn có thể git initrepo, cấu hình cục bộ để sử dụng lệnh ssh chính xác, rồi thêm điều khiển từ xa (3 bước, so với chỉ 1 với "git clone").
mr.b

3
Để sao chép repo, tôi sẽ sử dụng giải pháp của @ Guss, bên dưới, bằng cách đặt biến môi trường GIT_SSH_COMMAND. Nhưng trong sử dụng bình thường, tôi thích giải pháp của mình hơn vì nó tránh phải xuất lại biến đó mỗi khi tôi bắt đầu một trình bao mới.
Richard Smith

phao cứu sinh! có rất nhiều người hướng dẫn cách sử dụng ./ssh/config để thiết lập điều này và sử dụng ssh-agent / ssh-add -K cho mac. Đã sử dụng nó được một năm, nhưng nó đột ngột ngừng hoạt động ở High Sierra với các bản vá mới nhất. core.sshCommand hoạt động khi mọi thứ khác không thành công. cảm ơn!
Steve

2
Cảm ơn bạn cho giải pháp thanh lịch này. Tuy nhiên tôi chỉ muốn chính xác rằng core.sshCommand chỉ có sẵn cho git> = 2.10.0
slonepi

32

Nói chung, bạn muốn sử dụng ~/.ssh/configcho việc này. Chỉ cần ghép nối địa chỉ máy chủ với các khóa bạn muốn sử dụng cho chúng như sau:

Host github.com
  IdentityFile ~/.ssh/id_rsa.github
Host heroku.com
  IdentityFile ~/.ssh/id_rsa.heroku
Host *
  IdentityFile ~/.ssh/id_rsa

Host *biểu thị bất kỳ máy chủ nào, vì vậy tôi sử dụng nó để đặt ~/.ssh/id_rsalàm khóa mặc định để sử dụng.


9
Ý tưởng này không hoạt động nếu bạn có nhiều tài khoản trên một máy chủ như GitHub và bạn muốn có một khóa riêng tư khác nhau cho từng tài khoản.
Flimm

Đối với nhiều tài khoản trên một máy chủ, hãy xem câu trả lời này stackoverflow.com/questions/3225862/…
lexicalscope,

22

Trong kịch bản của tôi, tương tự như kịch bản @Richard Smith (có giải pháp, BTW, không phù hợp với tôi), tôi cần sử dụng các khóa khác nhau cho cùng một máy chủ trong các kho lưu trữ khác nhau.

Giải pháp cho tôi là thiết lập phiên chính xác với biến môi trường GIT_SSH_COMMAND, như sau:

export GIT_SSH_COMMAND="ssh -o IdentitiesOnly=yes -i ~/.ssh/my-secret-identitiy"

Cập nhật :

Một điều khác cần lưu ý ở đây là việc đặt biến môi trường một cách chính xác có thể là một việc hối hả, vì vậy tôi đang sử dụng các phương tiện sửa đổi dấu nhắc lệnh được cung cấp bởi những thứ như Liquid Prompt hoặc Fish Shell để gắn vào shell và tiếp tục cập nhật các biến môi trường theo thư mục hiện tại và một số quy tắc. Ví dụ: tất cả các dự án cá nhân của tôi cần đến khóa SSH cá nhân của tôi với Gitlab, ~/Documents/Projects/personalvì vậy khi shell hook chạy pwdvà nhận thấy rằng thư mục hiện tại nằm trong đường dẫn đó, nó sẽ tự động đặt các GIT_SSH_COMMANDbiến khi cần thiết.


15

Sử dụng ssh-add path-to-private-keynó hoạt động ra khỏi hộp.


5
Không nếu bạn có hai khóa triển khai và chúng chỉ hoạt động với một kho lưu trữ nhất định. Trong trường hợp đó, nó có thể sử dụng sai khóa và nói rằng bạn không có quyền truy cập.
cdmckay

Tôi đã nhận được vấn đề cdmckay nói
Suge

7

Bạn có thể đặt cấu hình --global hoặc --local, global sẽ cập nhật ~/.gitconfigtệp, local sẽ cập nhật cấu hình trong kho .git/configvà ghi đè cấu hình global (~ / .gitconfig)

git config --local --add core.sshCommand 'ssh -i ~ / .ssh / my_key'


2
hoạt động như một sự quyến rũ, đây chính xác là những gì tôi cần, một giải pháp cho một repo cụ thể.
Quaestor Lucem

5

Người dùng Windows ở đây, tôi vừa gặp sự cố này và có một giải pháp hơi khác, sau đó tôi đã đọc ở đây cho đến nay. Vấn đề tôi gặp phải là tôi chỉ muốn sao chép một repo bằng khóa ssh riêng tư cụ thể và không phải định cấu hình toàn cục cấu hình git của tôi hoặc thêm cài đặt git bash cụ thể, khi tôi thực hiện công việc của mình trong PowerShell. Về cơ bản, tôi chỉ muốn có một số khóa riêng tư trong thư mục .ssh của mình và tôi tham chiếu chúng trong các kho lưu trữ cụ thể theo yêu cầu.

Lệnh sau hoạt động cho việc này:

git clone -c core.sshCommand="ssh -i ~/.ssh/<PRIVATE KEY NAME>" <CLONE URL>

Về cơ bản những gì điều này làm được là khi khởi tạo git repo, nó đặt tùy chọn core.sshCommand trước khi chạy bản sao. Vì vậy, khóa ssh cụ thể mà bạn muốn sử dụng cho repo này được đặt CHỈ cho repo này. Đây có thể không phải là một giải pháp lý tưởng cho mọi trường hợp nhưng đối với những gì tôi muốn thì nó là như vậy.


Cảm ơn bạn. Tôi không biết về -ctùy chọn git clone. Điều này tốt hơn là thiết lập môi trường như tôi đề xuất khi nhân bản.
Richard Smith

1

Các câu trả lời khác đã truyền cảm hứng cho tôi viết một đoạn script nhỏ chọn khóa ssh tùy thuộc vào các tùy chọn dòng lệnh hoặc (nếu có) các giá trị của git remote -v. Hy vọng nó giúp!

Để thực sự trả lời câu hỏi: Sử dụng gat.

Xem thêm https://bitbucket.org/eikerobert/gat/src/master/

#!/bin/bash

usegat=false

for VAR in "$@"
do
    if [ "$VAR" != "${VAR/git@bitbucket.org:myaccount/}" ]; then
        usegat=true
    fi
done

if [ $usegat=false ]; then
   /usr/bin/git rev-parse --is-inside-work-tree >/dev/null 2>&1
   isinsidegitrepo=$?
    #echo $isinsidegitrepo
   if [ $isinsidegitrepo = 0 ]; then
       remote=`/usr/bin/git remote -v`
       if [ "$remote" != "${remote/git@bitbucket.org:myaccount/}" ]; then
           usegat=true
       fi
   fi
fi


if [ $usegat = true ]; then
    # echo "TRUE"
    /usr/bin/git -c core.sshCommand="/usr/bin/ssh -i /home/myaccount/.ssh/mykey" "$@"
else
     #echo "FALSE"
    /usr/bin/git "$@"
fi

0

Một tùy chọn khác là viết một tập lệnh nhỏ để làm cho core.sshCommandthông minh hơn một chút - kiểm tra xem thư mục làm việc hiện tại có định cấu hình khóa SSH cụ thể hay không và nếu có thì hãy sử dụng nó, nếu không - hãy dựa vào độ phân giải khóa SSH tiêu chuẩn.

Đây là phiên bản đầu tiên của tôi:

#!/bin/bash
key="$(git config ssh.key)"
if [ -n "$key" ]; then
        ssh -o IdentitiesOnly=yes -i "$key" "$@"
else
        ssh "$@"
fi

Sau đó, thiết lập nó thành lệnh git SSH toàn cục :

chmod 755 ~/.local/bin/git-ssh-command
git config --global core.sshCommand ~/.local/bin/git-ssh-command

( ~/.local/binlà tiêu chuẩn hiện tại để "đặt tập lệnh người dùng tại đây" trên hệ điều hành SystemD )

Sau khi thiết lập điều này, bạn có thể định cấu hình bất kỳ kho lưu trữ nào để sử dụng khóa SSH cụ thể bằng cách đặt tùy chọn cấu hình ssh.key:

git config --local ssh.key ~/.ssh/my-non-default-private-key

Thủ thuật tùy chọn bổ sung

  • Đặt toàn cầu ssh.key có "khóa dự phòng mặc định thành khóa SSH không mặc định" hoặc một cái gì đó.
  • Khi git thực thi core.sshCommandtrong thư mục gốc của kho lưu trữ, tùy chỉnh của bạn git-ssh-commandcó thể xem xét điều đó và có một số kinh nghiệm về tên thư mục. Điều này có thể được thực hiện trong elsephần vì vậy heuristics chỉ bắt đầu nếu không có khóa cụ thể ssh.key.
  • Bạn có thể thêm git remote -vséc để thêm phỏng đoán dựa trên điều khiển từ xa, như trong tập lệnh của Eike
  • Nếu bạn muốn xem điều khiển từ xa của kho lưu trữ nhưng có nhiều điều khiển từ xa cần các khóa khác nhau, bạn có thể thêm remote="$1:$(sed "s,.* ,,;s,',,g"<<<"$2")"vào đầu tập lệnh để giải quyết điều khiển từ xa đang được vận hành - và kiểm tra lại điều đó ( $remotesẽ giống như cột giữa trong git remote -vđầu ra).
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.