Tại sao $ PATH của lệnh từ xa ssh khác với lệnh tương tác?


20

Tôi có một người dùng đã không thực hiện sửa đổi đối với $ PATH trong bất kỳ tệp chấm nào: đó chính xác là cài đặt mặc định của hệ thống. Từ một vỏ đăng nhập:

$ ssh example.com
user@example.com:~$ cat /tmp/hello.hs
#!/bin/bash

echo "$SHELL"
echo "$PATH"

user@example.com:~$ /tmp/hello.hs
/bin/bash
/usr/local/bin:/usr/bin:/bin

Chính xác như được chỉ định trong /etc/profile. Điều này tôi thấy khá bất ngờ:

$ ssh example.com '/tmp/hello.sh'
/bin/bash       
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games

Như tôi đã nói, không có sửa đổi nào về $ PATH trong ~/.bashrc, cũng như không /etc/bash.bashrc. Không ~/.ssh/environmentcó. Các ssh(1)tuyên bố rằng biến môi trường PATH

Đặt thành PATH mặc định, như được chỉ định khi biên dịch ssh.

nhưng luồng này từ StackOverflow và bài viết danh sách gửi thư này cho thấy rằng tôi sẽ có thể ảnh hưởng đến $ PATH cho một lệnh đã cho chỉ bằng cách sửa đổi / etc / profile, một trong các tệp khởi động shell, v.v.

Những gì đang xảy ra ở đây?

Câu trả lời:


16

Từ ssh(1)trang thủ công: "Nếu lệnh được chỉ định, nó được thực thi trên máy chủ từ xa thay vì vỏ đăng nhập."

Vì vậy, trong ngắn hạn khi bạn thực sự đăng nhập vào bash máy được bắt đầu như một vỏ đăng nhập và tải các tệp phù hợp, khi bạn kết nối từ xa và đưa ra lệnh, nó sẽ chạy ở vị trí bash, có nghĩa là các tệp này KHÔNG tải. Bạn có thể làm việc xung quanh nó bằng cách sử dụng su -l -choặc tương tự trong phần lệnh của ssh.

Trong một số trường hợp, tôi cũng thấy -tđối số cho ssh làm việc (phân bổ tty).

Chỉnh sửa 1 :
Tôi nghĩ rằng thông tin PATH mà bạn tìm thấy, rằng đường dẫn mặc định (trừ khi chúng tôi ghi đè lên nó) là thông tin được biên dịch thành sshd. Tôi chắc chắn rằng / etc / profile, / etc / bash *, dotfiles cục bộ, v.v. không có bất kỳ thông tin PATH nào trong đó, sau đó tôi đăng nhập và vẫn còn PATH. Tôi đã tìm kiếm cái này trong sshd và tìm thấy nó ở đó. Vì vậy, cách trang web nói:

ahnberg@remote$ strings /usr/sbin/sshd | grep -i x11 | grep bin
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games

Sau đó, tôi thêm PATH=$PATH:/my/testvào phần trên cùng của .bashrctệp trên điều khiển từ xa và kiểm tra lại:

ahnberg@local$ ssh ahnberg@remote "env | grep PATH"
PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/my/test

Vì vậy, tôi hoàn toàn có thể ảnh hưởng đến nó, và PATH mặc định là cái được biên dịch thành sshd. :)


Hmm, cụm từ "được thực hiện trên máy chủ từ xa" có nghĩa là nhiều hơn nó nói, tôi nghĩ. Một điều thú vị hơn, mà tôi đã bỏ lỡ trước đó, xuất hiện trong phần 'MÔI TRƯỜNG' của cùng một trang: "PATH Đặt thành PATH mặc định, như được chỉ định khi biên dịch ssh." Ngoại trừ điều này cho thấy rằng tôi sẽ có thể ảnh hưởng đến PATH của một lệnh.
cá hồi

Vấn đề là nó không phải là vỏ đăng nhập nên nó không chạy / nguồn / bao gồm các tệp khởi động giống như đối với vỏ đăng nhập, do đó tôi nên thử các đề xuất của mình. Đưa mọi thứ vào cũng .bashrccó thể hoạt động, nhưng nhìn chung tôi sẽ làm việc xung quanh nó nếu PATH quan trọng. Hoặc tại sao không chỉ định tên đường dẫn đầy đủ nếu bạn có nhu cầu về cách chạy 'lệnh' ssh? :)
Mattias Ahnberg

Tôi đã chỉnh sửa bài viết của mình một chút. Bây giờ, có một vỏ đăng nhập, một vỏ không đăng nhập và các biến thể tương tác / không tương tác của chúng. Các lệnh SSH được gọi trong trình bao của người dùng ở dạng không đăng nhập không tương tác. Các bash(1)gọi gợi ý rằng không có tập tin khởi động được đọc theo cách này, nhưng tôi không thể tìm thấy tài liệu về cách ssh được gọi vỏ. Điều này dường như trái ngược với các nguồn được liên kết ở trên, trừ khi các nguồn khác có nguồn / tập tin khởi động / etc / ssh / sshrc mà tôi không có. (Tất nhiên có cách giải quyết, nhưng vấn đề là hiểu chính xác cách Debian SSHD xử lý các đường dẫn theo mặc định.)
troutwine

Nếu tôi sửa đổi PATH trong /etc/profilecác bản cập nhật đường dẫn hộp từ xa cho tôi, thì ssh user@remotebox 'env'sẽ hiển thị cho tôi bản cập nhật PATH. Điều tương tự cũng xảy ra nếu tôi thêm export PATH=$PATH:/my/testpathvào .bashrc (nhưng trong trường hợp của tôi ở đầu tệp trước khi kiểm tra các vỏ tương tác ( -z "$PS1").
Mattias Ahnberg

Cập nhật với các bài kiểm tra / phát hiện của tôi.
Mattias Ahnberg

3

Tôi đã có thể nhận ssh để chạy các lệnh bằng cách sử dụng đường dẫn từ xa bằng cách chạy:

ssh dist@d6 "bash --login -c 'env'"

Ở đây env có thể được thay thế bằng những gì bạn muốn.

Tôi có khóa ủy quyền nên không cần mật khẩu để chạy lệnh hoặc ssh.


3

Tôi đã đưa ra một giải pháp khác để khắc phục vấn đề. Sở thích cá nhân của tôi là tạo các tệp cấu hình mới thay vì thay đổi các tệp hiện có. Bằng cách này, tôi có thể dễ dàng hủy bỏ các thay đổi từ cấu hình mặc định.

Dưới đây là nội dung của /etc/profile.d/ssh_login.sh:

#!/bin/sh
if [ "$SSH_CONNECTION" ]; then
    echo "User '$USER' logged in from '${SSH_CONNECTION%% *}'"
    . /etc/environment
fi

Sử dụng dropbearthay thế openssh-server(điều này cũng sẽ hoạt động với openssh), biến SSH_CONNECTION sẽ được đặt tự động khi tôi đăng nhập từ xa. Tôi đã tạo một cấu hình cấu hình shell mới để phát hiện thông tin đăng nhập SSH, hiển thị một số thông tin trên màn hình và quan trọng nhất là tải các cài đặt môi trường toàn cầu từ /etc/environmentđể thay thế các giá trị được biên dịch. Xin lưu ý rằng điều này chỉ ảnh hưởng đến các vỏ SSH tương tác, không thực hiện lệnh từ xa.

Ngoài ra , nếu bạn sử dụng openssh và luôn muốn tải môi trường toàn cầu, bất kể đó là vỏ tương tác, bạn có thể đặt một liên kết tượng trưng ~/.ssh/như thế này:

ln -s /etc/environment ~/.ssh/environment

Sau đó, bạn cần kích hoạt PermitUserEnvironmenttùy chọn trong /etc/sshd/sshd_config. Tuy nhiên, chỉ làm điều này cho người dùng đáng tin cậy, vì điều này có thể cho phép họ bỏ qua các hạn chế truy cập trong một số cấu hình bằng các cơ chế như LD_PRELOAD. Vui lòng xem man sshd_configđể biết thêm thông tin, cụ thể cách sử dụng Matchcác khối để ràng buộc các tùy chọn cho người dùng / nhóm cụ thể.


0

Nếu bạn muốn đường dẫn hồ sơ tải, hãy thử:

#!/bin/bash -i

ở đầu kịch bản Bằng cách đó, shell ở chế độ tương tác khi chạy tập lệnh.

Khi bash được gọi dưới dạng shell đăng nhập tương tác hoặc dưới dạng shell không tương tác với tùy chọn --login, trước tiên, nó sẽ đọc và thực thi các lệnh từ tệp / etc / profile, nếu tệp đó tồn tại. Sau khi đọc tệp đó, nó tìm ~ / .bash_profile, ~ / .bash_login và ~ / .profile, theo thứ tự đó, đọc và thực thi các lệnh từ lệnh đầu tiên tồn tại và có thể đọc được. Tùy chọn --noprofile có thể được sử dụng khi trình bao bắt đầu ngăn chặn hành vi này.

http://linux.die.net/man/1/bash

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.