Làm cách nào tôi có thể chuyển tiếp khóa gpg qua ssh-agent?


29

Tôi có thể sử dụng tệp cấu hình ssh để cho phép chuyển tiếp các khóa ssh được thêm vào ssh-agent. Làm thế nào tôi có thể làm tương tự với các phím gpg?


3
Cả hai câu trả lời đều đề nghị chạy socat để lộ ổ cắm unix tác nhân GPG trên cổng tcp. Tuy nhiên, không giống như các ổ cắm unix, các cổng TCP không có cùng cấp độ kiểm soát truy cập. Đặc biệt, mọi người dùng trên cùng một máy chủ hiện có thể kết nối với đại lý GPG của bạn. Điều này có thể ổn nếu bạn có máy tính xách tay một người dùng, nhưng nếu bất kỳ người dùng nào khác cũng có thể đăng nhập vào cùng một hệ thống (hệ thống nơi đại lý GPG đang chạy), họ cũng có thể truy cập vào đại lý GPG của bạn, gây ra vấn đề bảo mật nghiêm trọng. Để socat trực tiếp bắt đầu SSH bằng cách sử dụng loại địa chỉ EXEC có lẽ là cách tốt nhất để khắc phục điều này.
Matthijs Kooijman

Đối với một bài thuyết trình của giải pháp openssh 6.7+, xem 2015.rmll.info/IMG/pdf/an-advanced-introduction-to-gnupg.pdf
PHS

Điều này rất hữu ích với tôi.
phs

Câu trả lời:


16

EDIT: Câu trả lời này đã lỗi thời khi hỗ trợ phù hợp đã được triển khai trong OpenSSH, xem câu trả lời của Brian Minton.

SSH chỉ có khả năng chuyển tiếp các kết nối tcp trong đường hầm.

Tuy nhiên, bạn có thể sử dụng một chương trình như socatđể chuyển tiếp ổ cắm unix qua TCP, với một cái gì đó tương tự (bạn sẽ cần giao tiếp cả trên máy khách và máy chủ lưu trữ):

# Get the path of gpg-agent socket:
GPG_SOCK=$(echo "$GPG_AGENT_INFO" | cut -d: -f1)

# Forward some local tcp socket to the agent
(while true; do
    socat TCP-LISTEN:12345,bind=127.0.0.1 UNIX-CONNECT:$GPG_SOCK;
done) &

# Connect to the remote host via ssh, forwarding the TCP port
ssh -R12345:localhost:12345 host.example.com

# (On the remote host)
(while true; do
    socat UNIX-LISTEN:$HOME/.gnupg/S.gpg-agent,unlink-close,unlink-early TCP4:localhost:12345;
done) &

Kiểm tra nếu nó hoạt động với gpg-connect-agent. Đảm bảo rằng GPG_AGENT_INFO không được xác định trên máy chủ từ xa, để nó rơi trở lại $HOME/.gnupg/S.gpg-agentổ cắm.

Bây giờ hy vọng tất cả những gì bạn cần là một cách để chạy tất cả điều này một cách tự động!


Vâng, các khóa tác nhân ssh được chuyển tiếp tự động khi chuyển tiếp được đặt trong tệp cấu hình. Tôi sẽ thử nó.
txwikinger

Bạn nói đúng, ssh-agent cũng sử dụng ổ cắm unix, nhưng có hỗ trợ đặc biệt cho nó (hơi mệt ở đây :) Tuy nhiên, giải pháp vẫn hoạt động.
b0fh

1
Đối với giải pháp này, tác nhân gpg của tôi sẽ có thể truy cập công khai qua cổng 12345 nếu tôi không đứng sau tường lửa / NAT. Điều này nên được đề cập trong câu trả lời xin vui lòng.
Jonas Schäfer

Tôi đoán lần chỉnh sửa cuối cùng của bạn đã khắc phục vấn đề đó, Jonas? localhostbây giờ nó chỉ ràng buộc thôi.
jmtd

Điều này không thành công với tôi với các đối số sau từ máy chủ từ xa gpg-connect-agent: can't connect to server: ec=31.16383 gpg-connect-agent: error sending RESET command: Invalid value passed to IPC. Điều khiển từ xa socatchết. Các địa phương socatchết và thốt lên socat[24692] E connect(3, AF=1 "", 2): Invalid argument. Trang này khiến tôi tin rằng điều này sẽ không bao giờ hoạt động, vì đại lý không lưu trữ khóa (chỉ là cụm mật khẩu). Điều này đã được xác nhận để làm việc bởi bất cứ ai?
jmtd

17

Chuyển tiếp ổ cắm tên miền Unix mới của OpenSSH có thể thực hiện việc này trực tiếp bắt đầu với phiên bản 6.7.

Bạn sẽ có thể một cái gì đó như:

ssh -R /home/bminton/.gnupg/S.gpg-agent:/home/bminton/.gnupg/S-gpg-agent -o "StreamLocalBindUnlink=yes" -l bminton 192.168.1.9

@DrewR. Vui mừng khi nghe điều đó.
Brian Minton

2
Tôi tìm thấy một chi tiết quan trọng cần thiết: trên máy từ xa (không có khóa riêng), phải có khóa công khai của danh tính ký. Phiên bản gpg cục bộ 2.1.15 OS X, linux 2.1.11 từ xa.
phs

4

Trong các phiên bản mới của GnuPG hoặc Linux, các đường dẫn của ổ cắm có thể thay đổi. Đây có thể được tìm thấy thông qua

$ gpgconf --list-dirs agent-extra-socket

$ gpgconf --list-dirs agent-socket

Sau đó thêm các đường dẫn này vào cấu hình SSH của bạn:

Host remote
  RemoteForward <remote socket> <local socket>

Giải pháp nhanh để sao chép các khóa công khai:

scp .gnupg/pubring.kbx remote:~/.gnupg/

Trên máy từ xa, kích hoạt tác nhân GPG:

echo use-agent >> ~/.gnupg/gpg.conf

Trên máy từ xa, cũng sửa đổi cấu hình máy chủ SSH và thêm tham số này (/ etc / ssh / sshd_config):

StreamLocalBindUnlink yes

Khởi động lại máy chủ SSH, kết nối lại với máy từ xa - sau đó nó sẽ hoạt động.


Hướng dẫn chi tiết hơn bao gồm một số khắc phục sự cố có thể được tìm thấy ở đây: mlohr.com/gpg-agent-forwarding
MaLo

1
Trong trường hợp máy chủ từ xa chạy phiên bản Debian hiện tại, có vẻ như việc chạy systemctl --global mask --now gpg-agent.service gpg-agent.socket gpg-agent-ssh.socket gpg-agent-extra.socket gpg-agent-browser.socketlà cần thiết để ngăn systemd khởi chạy một ổ cắm ăn cắp tác nhân gpg từ xa. Theo bug.debian.org/850982 đây là hành vi dự định.
sampi

3

Tôi đã phải làm như vậy, và dựa trên kịch bản của mình dựa trên giải pháp của b0fh, với một vài sửa đổi nhỏ: Nó bẫy thoát và giết chết các quy trình nền, và nó sử dụng các tùy chọn "fork" và "reuseaddr" để socat, giúp bạn tiết kiệm vòng lặp (và làm cho nền xã hội sạch sẽ có khả năng tiêu diệt).

Toàn bộ thiết lập tất cả chuyển tiếp trong một lần, vì vậy nó có thể đến gần hơn với một thiết lập tự động.

Lưu ý rằng trên máy chủ từ xa, bạn sẽ cần:

  1. Dây móc khóa bạn định sử dụng để đăng nhập / en / giải mã công cụ.
  2. Tùy thuộc vào phiên bản gpg trên điều khiển từ xa, một GPG_AGENT_INFObiến giả . Tôi điền trước với ~/.gnupg/S.gpg-agent:1:1- 1 đầu tiên là một PID cho tác nhân gpg (Tôi giả mạo nó là "init", luôn luôn chạy), thứ hai là số phiên bản giao thức đại lý. Điều này sẽ phù hợp với một chạy trên máy cục bộ của bạn.

#!/bin/bash -e

FORWARD_PORT=${1:-12345}

trap '[ -z "$LOCAL_SOCAT" ] || kill -TERM $LOCAL_SOCAT' EXIT

GPG_SOCK=$(echo "$GPG_AGENT_INFO" | cut -d: -f1)
if [ -z "$GPG_SOCK" ] ; then
    echo "No GPG agent configured - this won't work out." >&2
    exit 1
fi

socat TCP-LISTEN:$FORWARD_PORT,bind=127.0.0.1,reuseaddr,fork UNIX-CONNECT:$GPG_SOCK &
LOCAL_SOCAT=$!

ssh -R $FORWARD_PORT:127.0.0.1:$FORWARD_PORT socat 'UNIX-LISTEN:$HOME/.gnupg/S.gpg-agent,unlink-close,unlink-early,fork,reuseaddr TCP4:localhost:$FORWARD_PORT'

Tôi tin rằng cũng có một giải pháp chỉ liên quan đến một lệnh gọi SSH (kết nối lại từ máy chủ từ xa đến máy chủ cục bộ) bằng cách sử dụng -o LocalCommand, nhưng tôi không thể tìm ra cách tiêu diệt thuận tiện khi thoát ra.


Bạn không thiếu một số đối số 'user @ host' trước socat, trong lệnh cuối cùng phải không? Dù sao đi nữa, ngay cả sau khi sửa nó, điều này đã thất bại với tôi với "socat [6788] E connect (3, AF = 2 127.0.0.1 0, 16): Kết nối đã từ chối" bật lên cục bộ, khi thử tác nhân gpg-connect-agent từ xa.
David Faure

1

Theo GnuPG Wiki , bạn phải chuyển tiếp ổ cắm từ xa S.gpg-agent.extrađến ổ cắm cục bộ S.gpg-agent. Hơn nữa, bạn cần phải kích hoạt StreamLocalBindUnlinktrên máy chủ.
Hãy nhớ rằng bạn cũng cần phần công khai của khóa có sẵn trên GnuPG từ xa .

Sử dụng gpgconf --list-dir agent-sockettương ứng gpgconf --list-dir agent-extra-sockettrên điều khiển từ xa để có được các đường dẫn thực tế.


Tóm lược

  1. Cấu hình bổ sung trên remote /etc/sshd_config:

    StreamLocalBindUnlink yes
    
  2. Nhập khóa công khai của bạn trên điều khiển từ xa:

    gpg --export <your-key> >/tmp/public
    scp /tmp/public <remote-host>:/tmp/public
    ssh <remote-host> gpg --import /tmp/public
    
  3. Lệnh kết nối thông qua SSH với tính năng chuyển tiếp tác nhân gpg: (đường dẫn cho Debian của tôi)

    ssh -R /run/user/1000/gnupg/S.gpg-agent:/run/user/1000/gnupg/S.gpg-agent.extra <remote-host>
    

@brian minton: Nó không hoạt động với tôi nếu không chuyển tiếp đến ổ cắm thêm.
doak

0

Thay thế cho việc sửa đổi /etc/ssh/sshd_configbằng StreamLocalBindUnlink yes, thay vào đó, bạn có thể ngăn việc tạo các tệp ổ cắm cần thay thế:

systemctl --global mask --now \
  gpg-agent.service \
  gpg-agent.socket \
  gpg-agent-ssh.socket \
  gpg-agent-extra.socket \
  gpg-agent-browser.socket

Lưu ý rằng điều này ảnh hưởng đến tất cả người dùng trên máy chủ.

Phần thưởng: Cách kiểm tra chuyển tiếp đại lý GPG đang hoạt động:

  • Địa phương: ssh -v -o RemoteForward=${remote_sock}:${local_sock} ${REMOTE}
  • Kiểm tra xem ${remote_sock} được hiển thị trong đầu ra dài dòng từ ssh
  • Xa: ls -l ${remote_sock}
  • Xa: gpg --list-secret-keys
    • Bạn sẽ thấy rất nhiều debug1tin nhắn từ ssh hiển thị lưu lượng chuyển tiếp

Nếu điều đó không hiệu quả (vì nó không phù hợp với tôi), bạn có thể theo dõi GPG của socket nào đang truy cập:

strace -econnect gpg --list-secret-keys

Đầu ra mẫu:

connect(5, {sa_family=AF_UNIX, sun_path="/run/user/14781/gnupg/S.gpg-agent"}, 35) = 0

Trong trường hợp của tôi, đường dẫn được truy cập hoàn toàn khớp ${remote_sock}, nhưng ổ cắm đó không được tạo sshdkhi tôi đăng nhập, mặc dù đã thêm StreamLocalBindUnlink yesvào /etc/ssh/sshd_config. Tôi đã được tạo bởi systemd khi đăng nhập.

(Lưu ý rằng tôi quá hèn nhát khi khởi động lại sshd, vì hiện tại tôi không có quyền truy cập vật lý vào máy chủ. service reload sshdRõ ràng là không đủ ...)

Đã thử nghiệm trên Ubuntu 16.04

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.