Tôi có thể lấy SSH để sử dụng chương trình hỏi không ngay cả khi nó được chạy từ thiết bị đầu cuối?


9

man ssh nói:

SSH_ASKPASS
   If  ssh needs a passphrase, it will read the passphrase from the
   current terminal if it was run from a terminal.  If ssh does not
   have  a  terminal associated with it but DISPLAY and SSH_ASKPASS
   are set, it will execute the program  specified  by  SSH_ASKPASS
   and open an X11 window to read the passphrase.

Tôi muốn SSH sử dụng chương trình hỏi thăm ngay cả khi nó được chạy từ thiết bị đầu cuối.

Thỉnh thoảng, tôi phải kết nối với các máy chủ, trong đó có một số chậm trễ trong việc hiển thị lời nhắc mật khẩu (có thể do sự cố mạng, có thể do cố gắng tra cứu DNS ngược, lỗi). Tôi bực mình và chuyển sang thứ khác, và quên đi kết nối đã cố gắng. (Chèn trò đùa về khoảng chú ý của một con cá vàng.) Khi cuối cùng tôi quay lại với nó, dấu nhắc đã hết thời gian và ngay cả một mật khẩu chính xác cũng sẽ dẫn đến kết nối đóng.

Khóa sẽ là một giải pháp, nhưng không phải mọi hệ thống tôi sử dụng đều có khóa SSH thông thường. Tuy nhiên, tôi thường sử dụng các hệ thống Ubuntu và Ubuntu có chương trình hỏi đáp SSH được cài đặt theo mặc định.

Tuy nhiên, nếu một cửa sổ hỏi mở xuất hiện, tôi sẽ nhận ra ngay lập tức. Đó là một sự thỏa hiệp đủ tốt cho tôi, nếu tôi có thể làm cho nó hoạt động.


Câu hỏi hay. Từ việc nhìn vào mã nguồn, nó không giống như vậy. Bạn sẽ phải lừa nó để không mở /dev/tty( LD_PRELOAD?).
Celada

@Celada sẽ gây ra vấn đề khi bắt đầu shell?
muru

Có lẽ là không ...
Celada

Câu trả lời:


7

Điều này sẽ phức tạp hơn một chút, nhưng sự kết hợp của nhiều mảnh sẽ khiến nó hoạt động:

Giải trình

  1. Để buộc sshsử dụng $SSH_ASKPASSchương trình, bạn không thể cho phép sshxem thực tế tty. Nó chỉ là điều kiện. Điều này có thể được thực hiện bằng cách sử dụng setsidvà sử dụng -nchuyển sang ssh.

    Trường hợp này sẽ bắt đầu kết nối, nhưng bạn sẽ không thể tương tác với trình bao, đây có thể cũng là yêu cầu của bạn;) (và cũng phá vỡ TTY cục bộ của bạn).

    Nhưng bạn có thể từ bỏ "phiên đầu tiên". Bạn cũng nên thêm -Nswitch, nó sẽ chặn lệnh từ xa và sẽ chỉ thực hiện xác thực .

    Ngoài ra, "rác" đầu ra có thể có thể được chuyển hướng đến &> /dev/nullnếu bạn không quan tâm đến nó.

  2. Thiết lập ControlMastertrong ssh_config. Đây là một tính năng thú vị và một khi kết nối được thiết lập, bạn có thể "kích hoạt" các phiên khá nhanh. Đoạn trích này ~/.ssh/confignên làm điều đó:

    ControlPath ~/.ssh/controlmasters/%r@%h:%p
    ControlMaster auto
    ControlPersist 5m
    

    Bạn có thể thêm nó vào một số hostkhối liệt kê "ứng cử viên chậm" của bạn, hoặc chỉ ở mọi nơi. Nó gần như không có chi phí.

Dòng cuối cùng

Sau đó, bạn sẽ có thể kết nối theo cách này với máy chủ mà bạn mong đợi sẽ mất một lúc:

setsid ssh -nN host
# wait, insert password in the X11 prompt
ssh host
# will bring you directly to your session

Toàn bộ quá trình có thể được đơn giản hóa bằng aliashoặc hàm bash thực hiện cả hai trong một bước, nhưng nó để lại cho trí tưởng tượng của độc giả.

Chỉ các đối số dòng lệnh

Bạn có thể nối cả hai thứ với nhau trên dòng lệnh mà không cần ssh_configmột phần:

setsid ssh -nNMS ~/.ssh/masters/%C host
# wait, insert password in the X11 prompt
ssh -S ~/.ssh/masters/%C host
# will bring you directly to your session

Chức năng sau sẽ hoạt động khi các tùy chọn SSH không được chỉ định:

ssh() {
    if ! command ssh -o PasswordAuthentication=no "$1" true
    then
        setsid -w ssh -fnN "$1"
    fi
    command ssh "$@"
}
  • -f hướng dẫn SSH đi đến nền ngay trước khi thực hiện chương trình, đó là sau khi nó đã có mật khẩu.
  • -wnói setsidđể chờ chương trình kết thúc. Trong trường hợp này, điều đó xảy ra khi SSH đi vào nền. Kết hợp với ssh -f, việc chờ thủ công giữa hai lệnh SSH có thể được loại bỏ.
  • Hàm giả định đối số đầu tiên là tên máy chủ.
  • Thử nghiệm chỉ là để ngăn chặn các kết nối SSH không cần thiết.

ControlMasterđã được thiết lập, chính xác bởi vì thật khó để nhập mật khẩu trong những trường hợp như vậy. Không khó để viết một hàm kiểm tra một bản gốc hiện có và sử dụng bộ hỏi nếu nó không thể tìm thấy một hàm. Cảm ơn!
muru

3

Hướng dẫn sử dụng cho mỗi SSH ( man ssh):

Nếu sshkhông có thiết bị đầu cuối được liên kết với nó nhưng HIỂN THỊ và SSH_ASKPASS được đặt, nó sẽ thực thi chương trình được chỉ định bởi SSH_ASKPASS.

Do đó, bạn cần tách liên kết thiết bị đầu cuối (ví dụ: bằng cách thêm một đường ống) và đảm bảo DISPLAYkhông được đặt (nếu bạn muốn sử dụng thiết bị đầu cuối cho cụm mật khẩu thay thế).

Ví dụ đơn giản:

echo foo | SSH_ASKPASS=/my/cmd DISPLAY= ssh ...

Tương tự với ssh-add:

$ echo foo | SSH_ASKPASS=/my/cmd DISPLAY= ssh-add id_rsa
ssh_askpass: exec(/my/cmd): No such file or directory

Thật không may, điều này không làm việc cho tôi. Nó nói Pseudo-terminal will not be allocated because stdin is not a terminal, vì vậy có vẻ như các đường ống đang làm một cái gì đó. ssh </dev/nullcó tác dụng tương tự. Tuy nhiên, trong cả hai trường hợp, nó vẫn yêu cầu mật khẩu và tôi vẫn có thể nhập mật khẩu. Tôi đã thử trên Linux và Mac. Tôi đã thử ssh -vvvnhưng nó không nói gì hữu ích.
Timmmm

1
SSH_ASKPASS=/foo DISPLAY= setsid ssh hosthoạt động mặc dù.
Timmmm
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.