Làm thế nào để bạn có được màn hình để tự động kết nối với tác nhân ssh hiện tại khi gắn lại vào màn hình hiện tại?


48

Nếu bạn bắt đầu một phiên màn hình trong khi ssh-agent đang chạy (từ chuyển tiếp tác nhân ssh -A), truy cập ssh-agent hoạt động tốt. Tuy nhiên, nếu bạn tách ra khỏi phiên đó, hãy đăng xuất, đăng nhập lại (với chuyển tiếp tác nhân ssh) và đính kèm lại vào phiên màn hình của bạn, truy cập ssh-agent không hoạt động.

Làm thế nào để sửa cái này?

Câu trả lời:


41

1) Trong tập lệnh SSH RC của bạn (~ / .ssh / rc), bạn sẽ thiết lập một liên kết tượng trưng từ một vị trí chính tắc đến "SSH_AUTH_SOCK" hiện tại. Đây là cách tôi làm trong bash (nội dung của ~ / .ssh / rc):

#!/bin/bash
if test "$SSH_AUTH_SOCK" ; then
    ln -sf $SSH_AUTH_SOCK ~/.ssh/ssh_auth_sock
fi

(và đảm bảo chmod 755 ~ / .ssh / rc). "Kiểm tra" chỉ là để ngăn lỗi hiển thị nếu bạn không chạy ssh-agent (tức là bạn ssh không có -A). Nửa sau của lệnh đó thiết lập một liên kết tượng trưng ở vị trí chính tắc tự cập nhật thành SSH_AUTH_SOCK "thực" tại thời điểm đăng nhập. Điều này độc lập với việc sử dụng shell trong ssh hoặc gọi lệnh trực tiếp, cũng hoạt động với "ssh -t screen -RRD".

Lưu ý: sự tồn tại của ~ / .ssh / rc thay đổi hành vi của sshd. Đáng chú ý, nó sẽ không gọi xauth. Xem người đàn ông sshd để biết thêm thông tin và cách khắc phục điều này.

Ngoài ra, bạn không nên sử dụng "-v" với ln ngay khi nó sẽ phá vỡ rsync-over-ssh với các chẩn đoán sau:

$ rsync -n addr.maps.dev.yandex.net: .
protocol version mismatch -- is your shell clean?
(see the rsync man page for an explanation)
rsync error: protocol incompatibility (code 2) at compat.c(173) [Receiver=3.0.7]

2) Trong .screenrc của bạn, bạn chỉ cần ghi đè SSH_AUTH_SOCK vào vị trí chính tắc:

setenv SSH_AUTH_SOCK $HOME/.ssh/ssh_auth_sock

Lưu ý rằng bạn sử dụng setenv cho dù bạn sử dụng shell nào; Tôi nghĩ rằng setenv là cú pháp màn hình, không phải shell.

Giải pháp ban đầu được điều chỉnh từ bài đăng này , không hoạt động, nhưng có ý tưởng đúng.


Điều này giả định rằng bạn đăng nhập đầu tiên, sau đó bắt đầu màn hình. Đúng?
innaM

1
Làm thế nào nó có thể là bất kỳ cách nào khác? Làm thế nào bạn sẽ bắt đầu màn hình mà không cần đăng nhập?

1
Bạn đúng. Câu hỏi được đặt ra một cách ngu ngốc. Nhưng bạn có cần phải đăng nhập, khởi động một vỏ và từ đó bắt đầu màn hình? Tôi thường làm một cái gì đó như "ssh -t some.machine screen -R".
innaM

1
À được rồi Chà, tôi vừa thử cái này và nó không hoạt động (tức là ssh-agent không được kết nối). Tôi đoán ssh không thiết lập các ổ cắm thích hợp khi được sử dụng trong thời trang này. Có lẽ một số đối số-foo có thể làm sạch nó?

SSH không thiết lập các socket, nó chỉ không bao giờ khởi động shell. Nhưng mẹo này hữu ích đến mức tôi nghĩ rằng tôi có thể thay đổi thói quen của mình.
innaM

23

Tôi nghĩ rằng điều này hoạt động như một sự đơn giản hóa câu trả lời của @ sandip-bhattacharya. Đặt cái này trong ~/.bashrctệp của bạn và chạy lệnh xuất trong bất kỳ phiên màn hình nào đang chạy.

if [ -S "$SSH_AUTH_SOCK" ] && [ ! -h "$SSH_AUTH_SOCK" ]; then
    ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock
fi
export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock

Nó đọc "nếu $SSH_AUTH_SOCKlà một socket ( -S) chứ không phải là một liên kết tượng trưng ( ! -h), tạo một liên kết tượng trưng mới tại đường dẫn đã biết. Trong mọi trường hợp, hãy xác định lại SSH_AUTH_SOCKđể chỉ đến đường dẫn đã biết.

Các ! -htránh tạo ra một tham chiếu vòng tròn nếu bạn chạy nhiều lần.

Ngoài ra, nếu bạn sử dụng byobu, nó sẽ tự động thực hiện mà không cần chỉnh sửa bất kỳ tệp cấu hình nào.

Lỗi duy nhất tôi tìm thấy trong lỗi này ( byobucũng vậy) là nếu bạn mở một giây ssh -Ahoặc ForwardAgentkết nối, nó sẽ ghi đè lên ổ cắm đầu tiên và nếu bạn đóng kết nối thứ hai trước ổ cắm thứ nhất, bạn sẽ mất ổ cắm tốt duy nhất.


1
Điều này làm việc tmuxlà tốt.
Dag Høidahl

Hoạt động tuyệt vời, nhưng phá vỡ khi sử dụng các thư mục nhà được gắn từ xa. Trong trường hợp đó, sử dụng ~/.ssh/ssh_auth_sock_"$(hostname)"cho symlink của bạn. Nó sẽ giữ các ổ cắm auth riêng cho mỗi máy chủ.
Kibber

4

"Ssh -t some.machine screen -R" sẽ không chạy bash và do đó sẽ không chạy tập lệnh .bash_profile nơi tạo liên kết tượng trưng.

Bạn có thể thử: ssh -t some.machine bash -c "screen -R"

(giả sử bạn đang sử dụng bash làm vỏ của bạn)

Chỉnh sửa: "câu trả lời" đó thực sự là một nhận xét về câu trả lời đầu tiên được đưa ra ở trên :)


"Câu trả lời đầu tiên được đưa ra ở trên" không có nghĩa gì khi câu trả lời thay đổi khi chúng được bình chọn, v.v. Vui lòng bao gồm liên kết chia sẻ từ câu trả lời bạn đang đề cập, vì điều đó sẽ không thay đổi.
rjmunro

3

Tôi nghĩ bạn cần autossh. Tôi đã sử dụng nó trong nhiều năm nay và kết hợp với màn hình, nó làm cho tất cả các phiên cuối của tôi hoàn toàn di động và minh bạch. Tôi chỉ đơn giản là đóng lappy, di chuyển đến vị trí mới, mở lappy và tất cả các màn hình và màn hình lồng nhau của tôi tự động kết nối. Tôi thậm chí không nghĩ về nó nữa.

http://www.linux.com/archive/feature/134133

là những điều cơ bản ... Tôi đã viết một tập lệnh lil để tự động hóa quy trình trong .screenrc của tôi cho một máy chủ nhất định. (cũng chuyển tiếp ssh của tôi, vì vậy ở tất cả những nơi khác nhau này, tôi có thể kết nối kết nối của mình thông qua các máy chủ của mình)

trong bản phân phối tự động nên có một chương trình gọi là rscreen (và .. có!)

#!/bin/sh                                                                       
#
# sample script to use autossh to open up a remote screen
# session, or reconnect to an existing one. 
#
# $Id: rscreen,v 1.4 2002/05/07 17:54:13 harding Exp $
#
if [ "X$1" = "X" ]; then
    echo "usage: `basename $0` <host>"
    exit 1
fi

if [ "X$SSH_AUTH_SOCK" = "X" ]; then
    eval `ssh-agent -s`
    ssh-add $HOME/.ssh/id_rsa
fi

#AUTOSSH_POLL=600
#AUTOSSH_PORT=20000
#AUTOSSH_GATETIME=30
#AUTOSSH_LOGFILE=$HOST.log
#AUTOSSH_DEBUG=yes 
#AUTOSSH_PATH=/usr/local/bin/ssh
export AUTOSSH_POLL AUTOSSH_LOGFILE AUTOSSH_DEBUG AUTOSSH_PATH AUTOSSH_GATETIME 

autossh -M 20004 -t $1 "screen -e^Zz -D -R"

Điều này sẽ giúp với các vấn đề ssh / màn hình

Cuối cùng, để giữ cho ssh-agent của tôi hoạt động, tôi sử dụng móc khóa, vì tôi là một người đứng đầu ... Tôi nghĩ OSX có sẵn thứ gì đó để giữ đại lý của bạn xung quanh ...


2

Đây là phương pháp tôi sử dụng:

SOCK=$(sudo cat /proc/$(pgrep -f "screen -(r|DR)")/environ | tr "\0" "\n" | grep SSH_AUTH_SOCK) ; eval $SOCK ; export SSH_AUTH_SOCK
DISP=$(sudo cat /proc/$(pgrep -f "screen -(r|DR)")/environ | tr "\0" "\n" | grep DISPLAY) ; eval $DISP ; export DISP

Tôi thường thiết lập một bí danh hoặc một hàm shell với các lệnh này:

function ssh-screen-auth() {
  SOCK=$(sudo cat /proc/$(pgrep -f "screen -(r|DR)")/environ | tr "\0" "\n" | grep SSH_AUTH_SOCK)
  eval $SOCK
  export SSH_AUTH_SOCK
  DISP=$(sudo cat /proc/$(pgrep -f "screen -(r|DR)")/environ | tr "\0" "\n" | grep DISPLAY)
  eval $DISP
  export DISPLAY
}

Bạn có thể phải điều chỉnh biểu thức thông thường ' màn hình - (r | DR) ' với các lệnh chính xác bạn sử dụng để gắn lại màn hình của mình.

  • Dòng đầu tiên đọc biến môi trường SSH_AUTH_SOCK trong không gian quy trình của lệnh " screen -r " mà bạn vừa nhập và cập nhật giá trị trong trình bao hiện tại của bạn.
  • Dòng thứ hai là cần thiết nếu bạn sử dụng " ssh -X " để chuyển tiếp các kết nối X11: nó cập nhật biến HIỂN THỊ theo cách tương tự.

Một cảnh báo với phương pháp của tôi: mọi thứ có thể sai nếu có một lệnh " màn hình " khác đang chạy trên máy tính.


-1 cho việc sử dụng không cần thiết sudo.
0xC0000022L

1

Tôi thường giữ các phiên dài hạn (hơn 6 tháng) chạy tại nơi làm việc của tôi trên các máy chủ khác nhau. Vì vậy, nhiều lần gắn lại và có một đại lý chuyển tiếp ssh khả thi đã có vấn đề. Đây là những gì tôi thiết lập trên hệ thống của mình:

if [ -z "${STY}" -a -t 0 -a X${USER} = Xmyusername ]; then
    reattach () {
        if [ -n "${SSH_AUTH_SOCK}" ]; then
            ln -snf "${SSH_AUTH_SOCK}" "${HOME}/.ssh/agent-screen"
            SSH_AUTH_SOCK="${HOME}/.ssh/agent-screen" export SSH_AUTH_SOCK
        fi
        exec screen -A -D -RR ${1:+"$@"} ;
    }

    screen -wipe
    echo 'starting screen... (type Cntl-C to abort)'
    sleep 5 && reattach
fi

Nếu tôi chỉ đăng nhập vào máy chủ từ xa mà không khởi động / gắn lại màn hình, thì sẽ có hai "ổ cắm", một được sử dụng bởi screenmột cái khác bởi vỏ mới. Không nên có hai phiên "khởi động", nhưng phiên thứ hai vẫn có thể được bắt đầu sử dụng reattach -S new; trong tình huống này, các đại lý sẽ được chia sẻ với ~/.ssh/agent-screengiá trị. Để lấy lại một tác nhân chuyển tiếp hoạt động, sau đó tôi sẽ tách ra, đăng nhập lại. X${USER} = XmyusernameĐảm bảo rằng mã sẽ không được gọi sudotrên cùng một máy chủ.


1

Tôi đang sử dụng một biến thể của những gì @apinstein đang sử dụng cho .bashrc của tôi .

case "$TERM" in
    screen)
           export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock
        ;;
         *)
           if [[ -n "$SSH_AUTH_SOCK" ]]; then
               ln -sf $SSH_AUTH_SOCK ~/.ssh/ssh_auth_sock
           fi
        ;;
esac

Điều này hoạt động cho tất cả các ứng dụng đang chạy trong phiên màn hình của tôi. Điều này sẽ làm việc cho tất cả các shell mới trong phiên màn hình của bạn. Đối với các shell hiện có, bạn cần chạy export SSH_AUTH_SOCK=~/.ssh/ssh_auth_socktrên shell host để làm cho nó hoạt động.

PS Xin lỗi vì đã thêm câu này dưới dạng câu trả lời độc lập, trong khi nó chỉ được xây dựng dựa trên câu trả lời của @ apinstein. Phải làm điều này vì các bình luận trong stackoverflow không hỗ trợ các khối mã.


Tại sao không phải luôn luôn symlink và luôn xuất?
Collin Anderson

@CollinAnderson Hai hành vi khác nhau. một trong vỏ màn hình và một trong vỏ đăng nhập thông thường. biến môi trường trong shell đăng nhập được đặt bởi ssh và do đó symlink ở đó. nếu chúng ta làm điều này trong một phiên màn hình, thì chúng ta sẽ gây ra một vòng lặp symlink.
Sandip Bhattacharya

À, đúng rồi. Bạn sẽ chỉ cần liên kết nếu $ SSH_AUTH_SOCK chưa phải là một liên kết. Xem bài đăng của tôi superuser.com/a/424588/134212
Collin Anderson

0

Tôi đã thử một lớp lót đơn giản như được đề xuất trên Hãy tạo bạn bè trên màn hình và ssh-agent và nó hoạt động với tôi.

Lần đầu tiên đăng nhập vào Target. Chỉ cần thực hiện một lần.

ssh -o StrictHostKeyChecking=no -C <userid>@<server>

Khởi chạy màn hình lần đầu tiên .. Chỉ cần thực hiện một lần.

eval `ssh-agent`; /usr/bin/screen -D -R -h 10000
ssh-add

Nếu tách ra hoặc ngắt kết nối, sử dụng lệnh này để đăng nhập sau đó để kết nối với màn hình thoát.

ssh -o StrictHostKeyChecking=no -C -t <userid>@<server> ssh-agent /usr/bin/screen -D -R -h 10000

0

Đây là tất cả những câu trả lời thực sự tốt, tôi làm nó hơi khác một chút. Sau khi tôi bắt đầu một phiên ssh mới và màn hình reattach, tôi đặt lại SSH_AUTH_SOCKbiến môi trường dựa trên nội dung của môi trường bash gốc. Tôi chỉ yêu cầu truy cập ssh-agent khi tôi đang sử dụng svn vì vậy tôi chỉ cần đặt lại SSH_AUTH_SOCKyêu cầu trong các shell này.

Điều này sử dụng hệ thống tập tin Proc vì vậy là cụ thể linux. Tôi chỉ thử nghiệm điều này trên một hộp linux không đầu mà tôi chỉ có thể truy cập, có thể cần một số điều chỉnh để làm cho nó hoạt động trên các môi trường khác.

Để đặt lại SSH_AUTH_SOCK (điều này có thể được đặt thành bí danh).

$ . ~/bin/screen_auth.sh

screen_auth.sh trông như thế này

# Find the pid of putty's bash shell
tty=`who | awk '/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ { print substr($2, 5) }'`
pid=`ps -t $tty | grep bash | awk '{print $1}'`
# Find the SSH_AUTH_SOCK variable in its enviornment
auth_sock=`xargs --null --max-args=1 echo < /proc/$pid/environ | grep SSH_AUTH_SOCK`
eval "export $auth_sock"

0

Tất cả các giải pháp ở trên đều chịu các điều kiện đua xe (trong nhiều phiên SCREEN hoặc trong nhiều kết nối SSH). Giải pháp phổ biến duy nhất tôi có thể nghĩ đến là trước tiên đẩy SSH_AUTH_SOCK sang SCREEN xử lý máy chủ screen -rvà sau đó kéo nó vào phiên BASH trước mỗi lệnh không tích hợp tương tác. Thật không may, SCREEN và BASH được thiết kế mà không nhận thức được các vấn đề như vậy, vì vậy khá khó để thực hiện đúng (mặc dù không bao giờ muộn để gửi yêu cầu tính năng cho cả hai dự án). Nỗ lực của tôi đã được thực hiện để khắc phục vấn đề này cho các phiên BASH có thể tìm thấy ở đây:

Để cài đặt:

  1. đặt cả hai tập lệnh vào $HOME/bin, thêm bit thực thi;
  2. hãy chắc chắn rằng $HOME/binđi trước /usr/bintrong PATH:

    PATH = $ HOME / thùng: $ PATH

  3. thêm cái này vào .bashrc:

    nguồn $ HOME / bin / thiết lập trình trợ giúp màn hình

Bây giờ bạn có thể thử tạo phiên SCREEN trong phiên SSH, tách, ngắt kết nối, kết nối và gắn lại và hy vọng ssh-add -lsẽ hiển thị chính xác các khóa của bạn.


Lưu ý, ssh-agentdaemon vĩnh viễn (như được đề xuất ở đây superuser.com/a/412052/376867 ) không bị tình trạng đua xe, nhưng bị khóa phím cũ. Và điều quan trọng hơn là không an toàn khi để tất cả các phím của bạn trên máy chủ từ xa cùng với phiên màn hình (hoặc thậm chí lâu hơn cho đến khi khởi động lại trong trường hợp bài được đề cập).
midenok

0

Tôi lướt qua những câu trả lời khác và không thể tìm thấy tôi. Đây là những gì tôi sử dụng. Tạo một tệp ~/.screenrc-wrappercó nội dung sau:

escape ^xx
bindkey ^Ad detach

Và thêm phần này vào ~/.bashrc(hoặc ~/.zshrcnếu bạn sử dụng nó):

  if echo $TERM | grep -v 'screen' && ! screen -x -SU wrapper; then
      if echo $TERM | grep -v 'screen' && ! screen -x -SU main; then
      screen -c ~/.screenrc-wrapper -SU wrapper ssh-agent screen -SU main
      fi
  fi

Bằng cách này, bạn sẽ sử dụng hai phiên màn hình - một là "trình bao bọc" và một là phiên bên trong. Điều này sẽ giữ cho cái sau tồn tại ngay cả khi bạn đăng xuất và nó sẽ tiếp tục có ssh-agent. Một tính năng hay khác là nó sẽ ghi nhớ thiết lập cửa sổ của bạn - nếu bạn sử dụng các cửa sổ tách, nó có thể rất tiện dụng.

Bạn có thể tìm thấy tính năng này trong ngữ cảnh trong dotfiles của tôi .

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.