Làm cách nào để tạo người dùng SSH bị hạn chế để chuyển tiếp cổng?


106

ændrük đề xuất một kết nối ngược để có được kết nối SSH dễ dàng với người khác (để được trợ giúp từ xa). Để làm việc đó, cần có thêm một người dùng để chấp nhận kết nối. Người dùng này cần có khả năng chuyển tiếp cổng của mình thông qua máy chủ (máy chủ hoạt động như proxy).

Làm cách nào để tạo một người dùng bị hạn chế không thể làm gì hơn những gì được mô tả ở trên?

Người dùng mới phải không thể:

  • thực hiện các lệnh shell
  • truy cập tập tin hoặc tải tập tin lên máy chủ
  • sử dụng máy chủ làm proxy (ví dụ: webproxy)
  • truy cập các dịch vụ địa phương mà không thể truy cập công khai do tường lửa
  • giết máy chủ

Tóm tắt, làm cách nào để tạo một người dùng SSH bị hạn chế chỉ có thể kết nối với máy chủ SSH mà không có đặc quyền, vì vậy tôi có thể kết nối thông qua kết nối đó với máy tính của anh ta?


Câu trả lời:


166

TL; DR - đi đến cuối câu trả lời, "Áp dụng các hạn chế"

Thêm người dùng bị hạn chế bao gồm hai phần: 1. Tạo người dùng 2. Định cấu hình trình nền SSH (sshd)

Cấu hình sshd

Nơi tốt nhất để biết các khả năng của SSH là bằng cách đọc các trang hướng dẫn liên quan:

Máy khách SSH có thể thực hiện các hành động ở đâu?

Trước khi bạn có thể hạn chế một cái gì đó, bạn cần biết các tính năng của SSH. Nhổ qua các trang hướng dẫn mang lại:

  • Thực thi lệnh Shell
  • Tải tệp lên qua sftp
  • Cổng chuyển tiếp
    • Máy khách chuyển tiếp một cổng (un) đã sử dụng đến máy chủ
    • Máy chủ chuyển tiếp cổng của mình đến máy khách
    • Máy chủ chuyển tiếp một cổng của một máy chủ khác đến máy khách (proxy-ish)
  • Chuyển tiếp X11 (chuyển tiếp hiển thị)
  • Chuyển tiếp đại lý xác thực
  • Chuyển tiếp thiết bị đường hầm

Từ phần Xác thực của trang hướng dẫn của sshd (8) :

Nếu khách hàng tự xác thực thành công, một hộp thoại để chuẩn bị phiên được nhập. Tại thời điểm này, khách hàng có thể yêu cầu những thứ như phân bổ giả, chuyển tiếp kết nối X11, chuyển tiếp kết nối TCP hoặc chuyển tiếp kết nối tác nhân xác thực qua kênh bảo mật.

Sau này, máy khách yêu cầu shell hoặc thực thi lệnh . Các bên sau đó vào chế độ phiên. Trong chế độ này, một trong hai bên có thể gửi dữ liệu bất cứ lúc nào và dữ liệu đó được chuyển tiếp đến / từ trình bao hoặc lệnh ở phía máy chủ và thiết bị đầu cuối người dùng ở phía máy khách.

Tùy chọn để hạn chế các tính năng SSH

Các tệp và các tùy chọn thay đổi hành vi của chúng là:

  • ~/.ssh/authorized_keys - chứa các khóa được phép kết nối có thể được cung cấp tùy chọn:
    • command="command"- Lệnh được cung cấp bởi người dùng (nếu có) bị bỏ qua. Lưu ý rằng máy khách có thể chỉ định chuyển tiếp TCP và / hoặc X11 trừ khi chúng bị cấm rõ ràng . Lưu ý rằng tùy chọn này áp dụng cho thực thi shell, lệnh hoặc hệ thống con.
    • no-agent-forwarding - Cấm chuyển tiếp tác nhân xác thực khi khóa này được sử dụng để xác thực.
    • no-port-forwarding - Cấm chuyển tiếp TCP khi khóa này được sử dụng để xác thực
    • no-X11-forwarding - "Cấm chuyển tiếp X11 khi khóa này được sử dụng để xác thực."
    • permitopen="host:port" - Hạn chế chuyển tiếp cổng 'ssh -L' cục bộ sao cho nó chỉ có thể kết nối với máy chủ và cổng được chỉ định.
  • ~/.ssh/environment- Tập tin này được đọc vào môi trường lúc đăng nhập (nếu nó tồn tại). Xử lý môi trường bị tắt theo mặc định và được kiểm soát thông qua tùy chọn PermitUserEn Môi trường
  • ~/.ssh/rc - Chứa các thói quen khởi tạo được chạy trước khi thư mục chính của người dùng có thể truy cập được.
  • /etc/ssh/sshd_config - tệp cấu hình toàn hệ thống
    • AllowAgentForwarding - Chỉ định xem chuyển tiếp ssh-agent (1) có được phép hay không.
    • AllowTcpForwarding
    • ForceCommand - "Buộc thực thi lệnh được chỉ định bởi ForceCommand, bỏ qua mọi lệnh do khách hàng cung cấp và ~ / .ssh / rc nếu có. Lệnh được gọi bằng cách sử dụng trình đăng nhập của người dùng với tùy chọn -c."
    • GatewayPorts - "Chỉ định xem các máy chủ từ xa có được phép kết nối với các cổng được chuyển tiếp cho máy khách hay không. Theo mặc định, sshd (8) liên kết các chuyển tiếp cổng từ xa đến địa chỉ loopback. Điều này ngăn các máy chủ từ xa khác kết nối với các cổng chuyển tiếp. sshd đó sẽ cho phép các chuyển tiếp cổng từ xa liên kết với các địa chỉ không loopback, do đó cho phép các máy chủ khác kết nối. "
    • PermitOpen:

      Chỉ định các đích mà chuyển tiếp cổng TCP được phép. Đặc tả chuyển tiếp phải là một trong các hình thức sau:

      PermitOpen host:port
      PermitOpen IPv4_addr:port
      PermitOpen [IPv6_addr]:port
      

      Nhiều chuyển tiếp có thể được chỉ định bằng cách tách chúng với khoảng trắng. Một đối số 'bất kỳ' có thể được sử dụng để loại bỏ tất cả các hạn chế và cho phép mọi yêu cầu chuyển tiếp. Theo mặc định, tất cả các yêu cầu chuyển tiếp cổng được cho phép.

    • PermitTunnel- Chỉ định xem có cho phép chuyển tiếp thiết bị tun (4) hay không. Mặc định là 'không'
    • X11Forwarding- Chỉ định xem chuyển tiếp X11 có được phép hay không. Mặc định là 'không'

Áp dụng các hạn chế

Sửa đổi tệp cấu hình trên toàn hệ thống /etc/ssh/sshd_configcho phép cấu hình được áp dụng ngay cả khi xác thực dựa trên mật khẩu được áp dụng hoặc nếu các hạn chế trong ~/.ssh/authorized_keysvô tình bị xóa. Nếu bạn đã sửa đổi mặc định toàn cầu, bạn nên bỏ ghi chú các tùy chọn tương ứng.

Match User limited-user
   #AllowTcpForwarding yes
   #X11Forwarding no
   #PermitTunnel no
   #GatewayPorts no
   AllowAgentForwarding no
   PermitOpen localhost:62222
   ForceCommand echo 'This account can only be used for [reason]'

Bây giờ thêm người dùng:

sudo useradd -m limited-user

Tùy chọn ForceCommandcó thể được bỏ qua nếu shell được đặt thành không phải shell như /bin/false(hoặc /bin/true) vì /bin/false -c [command]sẽ không làm gì cả.

Bây giờ, máy khách chỉ có thể kết nối với cổng 62222 trên địa chỉ loopback của máy chủ qua SSH (nó sẽ không nghe trên địa chỉ IP công cộng)

Vô hiệu hóa AllowTcpForwardingcũng sẽ không cho phép sử dụng -R, do đó đánh bại việc sử dụng tài khoản bị hạn chế như vậy để chuyển tiếp một cổng. PermitOpen localhost:62222giả định rằng cổng 62222 trên máy chủ không bao giờ được sử dụng vì máy khách có thể vui vẻ kết nối với nó và cũng lắng nghe nó.

Nếu chuyển tiếp TCP được cho phép trong cấu hình toàn hệ thống và xác thực dựa trên mật khẩu bị vô hiệu hóa, bạn cũng có thể sử dụng cài đặt theo từng khóa. Chỉnh sửa ~/.ssh/authorized_keysvà thêm các tùy chọn tiếp theo trước ssh-(với khoảng trắng giữa các tùy chọn và ssh-):

command="echo 'This account can only be used for [reason]'",no-agent-forwarding,no-X11-forwarding,permitopen="localhost:62222"

Kiểm chứng

Để chắc chắn rằng nó hoạt động như mong đợi, một số trường hợp thử nghiệm cần phải được chạy. Trong các lệnh dưới đây, hostnên được thay thế bằng thông tin đăng nhập thực tế nếu nó không được đặt ~/.ssh/config. Đằng sau lệnh, một lệnh được hiển thị nên được thực thi trên máy khách hoặc máy chủ (như được chỉ định).

# connection closed:
ssh host
# connection closed (/bin/date is not executed):
ssh host /bin/date
# administratively prohibited (2x):
ssh host -N -D 62222 # client: curl -I --socks5 localhost:62222 example.com
ssh host -N -L 8080:example.com:80 # client: curl -I localhost:8080
sftp host
# should be possible because the client should forward his SSH server
ssh host -N -R 8080:example.com:80 # server: curl -I localhost:8080
# This works, it forwards the client SSH to the server
ssh host -N -R 62222:localhost:22
# unfortunately, the client can listen on that port too. Not a big issue
ssh host -N -L 1234:localhost:62222

Phần kết luận

Danh sách kiểm tra: Người dùng SSH không thể:

  • thực hiện các lệnh shell - thực hiện
  • truy cập tệp hoặc tải tệp lên máy chủ - xong
  • sử dụng máy chủ làm proxy (ví dụ: webproxy) - xong
  • truy cập các dịch vụ cục bộ không thể truy cập công khai do tường lửa - một phần , máy khách không thể truy cập các cổng khác ngoài 62222, nhưng có thể lắng nghe và kết nối với cổng 62222 trên máy chủ
  • giết máy chủ - xong (lưu ý rằng các kiểm tra này được giới hạn ở máy chủ SSH. Nếu bạn có một dịch vụ dễ bị tổn thương khác trên máy, nó có thể cho phép kẻ tấn công có thể chạy lệnh, giết máy chủ, v.v.)

3
Để làm việc này, tài khoản được thêm bởi useraddphải được mở khóa. Điều đó có thể được thực hiện bằng cách thay thế mật khẩu /etc/shadowbằng asteric ( *) hoặc bằng cách đặt mật khẩu bằng cách sử dụng sudo passwd limited-user.
Lekensteyn

2
SFTP hoạt động vì máy chủ SSH chạy sftp-serverlệnh. Với ForceCommand, lệnh này sẽ không được thực thi nữa.
Lekensteyn

2
Cũng hữu ích là from=tùy chọn trong authorized_keys. Nó cho phép bạn giới hạn việc sử dụng khóa đối với các nguồn có địa chỉ IP hoặc tên máy chủ cụ thể. Ví dụ, from="1.1.1.1"hoặc from="10.0.0.?,*.example.com". Xem phần "AUTHORIZED_KEYS FILE FORMAT" trong trang man ( linux.die.net/man/8/sshd ) để biết tất cả các tùy chọn ủy quyền.
Donn Lee

2
"AllowTcpForwarding local" cấm chuyển tiếp từ xa. (Tôi không biết liệu nó có tồn tại khi câu trả lời này được viết không.)
Simon Sapin

1
Lưu ý rằng điều này bị phá vỡ bởi các kết nối ssh liên tục, vì vậy bạn không nên có một cái gì đó giống như Host * ControlMaster autotrong ~/.ssh/configtệp của mình khi kết nối ssh -N. Nếu bạn cần, hãy sử dụngssh -N -o ControlMaster=no
nh2

3

Tôi chắc chắn có nhiều giải pháp cho vấn đề này, và nhiều giải pháp mạnh mẽ hơn giải pháp tôi đang đề xuất. Tuy nhiên, điều này có thể đủ cho nhu cầu của bạn. Để làm điều đó, tôi giả sử người dùng có thể thực hiện xác thực dựa trên khóa ssh (putty hoặc bất kỳ ssh unix nào nên hỗ trợ điều này).

  • Thêm người dùng như bình thường ('adduser' hoặc bất kỳ công cụ nào khác)

  • Tạo người dùng .ssh dir và .ssh / ủy quyền

your_user $ sudo -Hu ssh_forwarder /bin/bash

ssh_forwarder $ cd ~
ssh_forwarder $ mkdir .ssh
ssh_forwarder $ ( umask 066 && cat > .ssh/authorized_keys ) <<EOF
no-agent-forwarding,no-X11-forwarding,command="read a; exit" ssh-rsa AAAB3NzaC1y....2cD/VN3NtHw== smoser@brickies
EOF
  • Vô hiệu hóa truy cập mật khẩu vào tài khoản này.
your_user $ sudo usermod --lock ssh_forwarder

Bây giờ, cách duy nhất mà người dùng có thể truy cập vào hệ thống của bạn là truy cập vào khóa ssh thích hợp và ssh sẽ chạy "/ bin / bash -c 'đọc một'" cho họ, bất kể họ cố chạy gì. 'Đọc một' sẽ chỉ đơn giản là đọc cho đến khi một dòng mới, và sau đó trình bao sẽ thoát ra, vì vậy người dùng chỉ cần nhấn 'enter' để hủy kết nối.

Có rất nhiều thứ khác bạn có thể làm trong 'lệnh ='. Xem man authorized_keysvà tìm kiếm 'lệnh' để biết thêm thông tin.

Nếu bạn không thích thực tế là nhấn enter sẽ giết chết kết nối, bạn có thể sử dụng một cái gì đó như sau cho mục 'lệnh =':

command="f=./.fifo.$$ && mkfifo $f && trap \"rm -f $f\" EXIT && read a <$f && echo $a; exit;"

Điều này chỉ tạo một fifo tạm thời trong thư mục nhà của người dùng, và sau đó cố gắng đọc từ nó. Không có gì sẽ được ghi vào tập tin đó, vì vậy điều này sẽ treo vô thời hạn. Ngoài ra, nếu bạn muốn chấm dứt mạnh mẽ kết nối đó, bạn có thể làm một cái gì đó như:

 your_user$ echo GOODBYE | sudo tee ~ssh_forwarder/.fifo.*

Điều này sẽ sử dụng rất ít tài nguyên và không có gì có thể sai trong tập lệnh đó sẽ không kết thúc bằng việc kết thúc trình bao.

sleep 1h; echo You have been here too long. Good bye.

Tôi đã không thấy cách bạn có thể cho phép người dùng từ xa chuyển tiếp ( ssh -R) nhưng giới hạn ( ssh -L). Có lẽ 'allowopen' có thể được sử dụng. Googling không hữu ích lắm. Có vẻ như một cái gì đó như 'không chuyển tiếp cổng, allowremoteopen = 10001' sẽ hữu ích khi cho phép ssh -R 6901:localhost:6901.

Đây là một giải pháp. Nó chắc chắn có thể được cải thiện và bất kỳ việc mở cổng từ xa nào cũng cần được xem xét kỹ lưỡng. Nếu mục tiêu của tôi là cho phép Bà tôi kết nối vào mạng LAN của tôi để tôi có thể sử dụng vnc để xem màn hình của cô ấy và việc truy cập vào các phím đó bị giới hạn ở cô ấy, cá nhân tôi sẽ cảm thấy an toàn một cách hợp lý. Nếu điều này là cho một doanh nghiệp, điều tra kỹ lưỡng hơn sẽ là cần thiết. Một điều cần lưu ý là ssh -Nhoàn toàn không yêu cầu shell, vì vậy mã 'lệnh =' không thực thi.

Các cơ chế khác, có thể an toàn hơn có thể bao gồm tạo lớp vỏ tùy chỉnh cho người dùng và thậm chí khóa nó bằng apparmour.


3
Điều này có vẻ rất hackish, thậm chí không cần thiết phải có shell vì không cần thực thi lệnh nào. Xem trang hướng dẫn củassh cho -Ntùy chọn. Phải có một cách sạch hơn để thực hiện điều này.
Lekensteyn

Đúng. Tôi hy vọng sẽ thấy một giải pháp sạch hơn. Tôi nghĩ rằng ủy quyền_key kết hợp với chuyển tiếp không có cổng sẽ là một giải pháp khá tốt nếu có tùy chọn 'allowremoteopen'.
smoser

Tôi đã làm một số researcg (xem ở trên). Vì ssh -Nhoàn toàn không thực thi lệnh, nên không có vấn đề nào command="something"đóng phiên.
Lekensteyn

Tui bỏ lỡ điều gì vậy? Dường như đó chsh ssh_forwarder -s /bin/false là tất cả những gì nó cần.
typelogic
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.