Truy cập SSH từ bên trong và bên ngoài mạng LAN bằng cùng một lệnh đầu cuối


10

Tôi có Raspberry Pi (RPi) và tôi đang thực hiện kết nối từ xa với nó bằng ssh. Tôi đã quản lý để thiết lập ssh chính xác để tôi có thể truy cập RPi cả từ mạng cục bộ và từ internet (sử dụng một cổng cụ thể mà tôi đã mở trên bộ định tuyến của mình).

Giả sử tên người dùng johnvà RPi có tên raspi:

Bên trong truy cập mạng LAN

ssh john@192.168.2.7
ssh john@raspi
ssh raspi

Truy cập mạng LAN bên ngoài

ssh -p 1234 john@12.345.67.89
ssh -p 1234 12.345.67.89

Nhưng làm thế nào tôi có thể đơn giản làm ssh raspitừ bên ngoài mạng LAN của mình?. Có cách nào để định cấu hình raspi để trỏ đến hai địa chỉ IP, một trong mạng LAN và một qua internet không?

Điều tôi về cơ bản muốn là truy cập RPi của tôi theo một cách duy nhất, bất kể tôi đang ở nhà hay đi làm.


Bạn có thể chạy máy chủ DNS trên mạng cục bộ đáp ứng yêu cầu tên "raspi" với địa chỉ ip lan cục bộ. Bây giờ việc phân giải cùng tên đó sang một địa chỉ bên ngoài khác sẽ yêu cầu tên đó được điền (dns động) theo cách mà nó cũng giải quyết. Nhưng bạn có thể sẽ cần một cái tên dài hơn "raspi".
ChuckCottrill

Xem phần Hỏi & Đáp này: unix.stackexchange.com/questions/61655/ trên
slm

Câu trả lời:


7

Nhìn kỹ hơn vào câu hỏi của bạn, có vẻ như bạn đang sử dụng cùng một máy tính từ cả trong và ngoài mạng LAN. Tôi đã sửa đổi câu trả lời của mình cho phù hợp:

Trong của bạn ~/.ssh/config, thêm:

Host raspi-wan
    HostName 12.34.56.78
    User john
    Port 1234

Host raspi-lan
    HostName 192.168.1.2
    User john
    Port 22

Sau đó, bạn có thể ssh raspi-wantừ bên ngoài mạng LAN hoặc ssh raspi-lantừ bên trong mạng LAN mà không cần quan tâm đến máy chủ DNS hoặc chỉnh sửa /etc/hostscho tất cả người dùng hoặc thậm chí cần phải làm bất cứ điều gì với quyền root. Nếu bạn muốn tên được raspiphân giải khác nhau tùy thuộc vào vị trí của bạn, điều đó có thể sẽ yêu cầu một số phép thuật kịch bản shell để phát hiện mạng của bạn và hành động tương ứng.


1
Cảm ơn DopeGhoti, tôi rất thoải mái với giải pháp của bạn để bao gồm một -wanvà hậu tố -lan. Tuy nhiên, ssh của tôi không thích Usernametrường này (Tùy chọn cấu hình xấu). Nó hoạt động tốt mà không có nó.
Hàng không

2
Tôi xin lỗi, cú pháp chính xác là User johnkhông UserName. Tôi đang sửa câu trả lời của mình để phản ánh điều này và khi bạn đã thiết lập cấu hình của mình, bạn có thể bỏ tên người dùng khỏi sshdòng lệnh.
DopeGhoti

5

Điều này là hoàn toàn có thể thực hiện được chỉ với cấu hình ssh, mà không phải sử dụng các bí danh riêng cho lan và wan hoặc tạo bất kỳ cổng phụ nào về phía trước. (Nhưng bạn tự nhiên cần một số cách để phát hiện xem bạn có ở trong lan của mình hay không)

Trong ~/.ssh/config, bạn sẽ muốn thêm một cái gì đó như thế này:

Match host raspi exec "am_i_outside_of_my_lan"
    HostName 12.345.67.89
    Port 1234

Thay vào đó, am_i_outside_of_my_lanbạn sẽ muốn đặt một lệnh xác định xem bạn có ở trong mạng gia đình của mình hay không và trả về với mã thoát 0 nếu bạn ở ngoài nó và một cái gì khác.

Điều hostkiện có thể là tự giải thích, nhưng execđiều kiện này đảm bảo một số giải thích: Nó chỉ khớp khi lệnh đã cho trả về với mã thoát 0, tức là. không có lỗi

Vì vậy, nói cách khác, phần này làm host raspihạn chế quy tắc này khi bạn cố gắng kết nối với raspi của máy chủ và exec "am_i_outside_my_lan"càng hạn chế nó để nó chỉ áp dụng khi bạn kết nối từ bên ngoài mạng gia đình. Vì vậy, bên trong mạng gia đình của bạn ssh user@raspithực hiện chính xác những gì nó thường làm, nhưng bên ngoài nó, quy tắc phù hợp và thay vào đó nó tương đương với ssh -p 1234 user@12.345.67.89.

Đối với những gì để sử dụng thay thế am_i_outside_of_my_lan, điều đó phụ thuộc hoàn toàn vào thiết lập của bạn. Tôi khuyên bạn nên đặt các lệnh trong một tập lệnh riêng biệt thay vì cố gắng viết nó theo dòng, bởi vì trích dẫn có vẻ hơi khó để làm đúng.

Cá nhân, tôi đã sử dụng tập lệnh Python sau để phát hiện xem tôi có ở trong mạng của mình không: (Vì tên miền của tôi phân giải thành một ip cục bộ trong mạng riêng của tôi)

#! /usr/bin/env python
import socket, sys

sys.exit(socket.gethostbyname('mydomain.com').startswith('192.168.1.'))

Nếu bạn không có một thiết lập tương tự, bạn có thể phải làm một cái gì đó khác. (Ví dụ: bạn có thể xem tên của mạng không dây mà bạn đã kết nối hoặc thậm chí truy vấn một số dịch vụ ip-is-my-ip để nhận ip bên ngoài của mạng mà bạn đã kết nối)


Đây là câu trả lời chính xác; thật đáng buồn khi những người khác có nhiều phiếu bầu hơn.
Jonathan Tomer

@JonathanTomer: Công bằng mà nói, tôi đã trả lời 3 năm sau khi được hỏi, trong khi câu trả lời có điểm cao hơn được đăng trong vài giờ, vì vậy đó chỉ là một trường hợp "con chim sớm bị sâu": P (Tôi cũng có để nói rằng tôi khá thích biến thể cụ thể của giải pháp chung này của Ellis Hoag - sử dụng arp khá thông minh và làm cho giải pháp chung chung hơn, như trong lệnh phát hiện mạng không phải điều chỉnh cho mọi thiết lập mạng)
Aleksi Torhamo

3

Trên máy tính của bạn (connect- ing một), bạn có thể đặt tên máy cho 12.345.67.89. Mở /etc/hoststệp của bạn và đặt mục nhập DNS:

12.345.67.89    raspi

Sau đó, máy của bạn sẽ chuyển đổi "raspi" thành "12.345.67.89" như một phần của quy trình phân giải DNS cục bộ. Nếu bạn sử dụng một số máy, thay đổi phải được thực hiện trên từng máy. Vấn đề là: nó yêu cầu quyền truy cập root để chỉnh sửa /etc/hostsvà bạn có thể không có nó ở mọi nơi.

Nếu bạn muốn "raspi" tự động được nhận ra từ bất cứ đâu, thì xin lỗi: không thể. Điều này sẽ yêu cầu đăng ký "raspi" làm tên miền, điều này không thể xảy ra vì "raspi" không có TLD và sẽ không phụ thuộc vào bất kỳ máy chủ gốc DNS nào. Tuy nhiên, bạn có thể đăng ký một tên miền (giả sử cfbaptista.mevà trỏ nó đến địa chỉ IP WAN của bạn. Với một số chuyển tiếp cổng, bạn sẽ có thể truy cập Raspberry Pi của mình với:

ssh (you@)(raspi.)cfbaptista.me

(tuy nhiên, đó là chi tiền cho hầu như không có gì ...)

Liên quan đến user@một phần, nó phụ thuộc vào tên đăng nhập của bạn trên các máy khác nhau. Nếu bạn có cùng tên trên máy kết nối trên máy từ xa , thì không cần chỉ định. Nếu không, bạn cần chỉ định bạn là ai trên máy từ xa .


lưu ý: như đã đề cập trong câu trả lời khác, bạn có thể tạo bí danh máy chủ trong cấu hình SSH của mình, điều này tất nhiên không yêu cầu root.
strugee 31/12/13


0

Mục tiêu: ssh raspi nên hoạt động bên trong mạng LAN và trên Internet công cộng.

Để làm điều này, bạn cần đảm bảo rằng tên đó phân giải thành IP bên trong mạng LAN và IP công cộng từ bên ngoài.

Đầu tiên, bạn nên có được một tên miền như raspi.yourdomain.com. Hãy xem http://freedns.afston.org/ để biết các tên miền miễn phí cho mục đích sử dụng. Trỏ tên miền vào IP công cộng của bạn

Đối với mạng LAN, tôi khuyên bạn nên chạy DNSMasq. Chương trình cơ sở DD-WRT mở tích hợp chặt chẽ với DNSMasq, sử dụng nó cho DHCP và DNS. Bạn chỉ cần nói với miền tìm kiếm của bạn ("yourdomain.com") và nó sẽ tự động gán tên DNS dựa trên tên được yêu cầu của mỗi khách hàng. Để làm cho công việc này, nên đọc / etc / hostname của raspi raspi.

Khi điều này được thiết lập, raspi.yourdomain.com sẽ phân giải IP cục bộ trên mạng LAN của bạn (chỉ cần đảm bảo rằng bạn đang sử dụng DNS cục bộ trên tất cả các máy của mình).

Bây giờ, có lẽ bạn không muốn đưa cổng 22 ra internet công cộng, bởi vì bạn sẽ nhận được rất nhiều lưu lượng truy cập. Vì vậy, bạn có thể có bộ định tuyến của mình phơi bày raspi: 22 như một số cổng khác, giả sử 1234. Để sử dụng cùng một cổng trên cả mạng công cộng và mạng nội bộ, bạn có thể thêm quy tắc chuyển hướng cổng vào raspi. Trên Linux:

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 1234 -j REDIRECT --to-port 22
sudo sh -c 'iptables-save > /etc/iptables/iptables.rules'

(thay đổi eth0 thành tên của giao diện mạng của bạn như được hiển thị bởi ip linkhoặc ifconfig, và 1234 sang cổng công cộng của bạn)

Bây giờ bạn có thể ssh -p 1234 raspi.yourdomain.comtừ cả công cộng và LAN.

Bạn có thể thêm một mục vào ~ / .ssh / config trên máy khách của mình để rút ngắn điều này thành chỉ ssh raspi, như được đề cập bởi @DopeGhoti.

Nếu bạn muốn hiển thị các cổng SSH của máy bổ sung trên cùng một IP công cộng, chỉ cần lặp lại quy trình với một tên DNS và cổng công khai khác. Chúc mừng!


0

Đây là phiên bản ngắn gọn, hoạt động của câu trả lời của Aleksi Torhamo bằng cách sử dụng curl để lấy ip công khai hiện tại của bạn và sau đó kiểm tra xem nó có khớp với ip công khai của máy chủ của bạn không (ví dụ: bạn đang ở trên cùng một mạng cục bộ).

Trong ~/.ssh/configphần thêm của bạn

Match host raspi exec "[[ $(curl -s ipinfo.io/ip) == '12.345.67.89' ]]"
  User john
  HostName 192.168.2.7

Match host raspi exec "[[ $(curl -s ipinfo.io/ip) != '12.345.67.89' ]]"
  User john
  HostName 12.345.67.89
  Port 1234

Tôi tin rằng ssh sẽ xử lý tất cả các chỉ thị phù hợp, theo thứ tự, vì vậy về mặt lý thuyết, bạn sẽ có thể thực hiện một cái gì đó giống như Match host raspi / User john / HostName 192.168.2.7sau Match host raspi exec "[[ $(curl -s ipinfo.io/ip) != '12.345.67.89' ]]" / HostName 12.345.67.89 / Port 1234và nhận được hiệu quả tương tự chỉ với một curllời mời, hãy để == '12.345.67.89'trường hợp được giả định bởi sự thất bại của Matchquy tắc thứ hai exec.
FeRD ngày

(Bạn sẽ phải đảm bảo rằng mọi đối số được chỉ định trong lần đầu tiên Matchđều giống nhau hoặc cũng được chỉ định trong lần thứ hai - nếu bạn đã chỉ định một tiêu chuẩn không theo tiêu chuẩn Port xxxxtrong lần đầu tiên Matchvà muốn sử dụng cổng tiêu chuẩn trong lần thứ hai Match, bạn phải ghi đè lại một cách rõ ràng bằng một Port 22cổng để nó không tiếp tục sử dụng cổng xxxx.)
FeRD ngày

0

Giả sử máy của bạn có IP 192.168.1. * Khi được kết nối với mạng LAN của bạn, bạn có thể đạt được điều này với cấu hình sau ~/.ssh/configđể bạn luôn có thể sử dụng cùng một lệnh (chỉ ssh raspi) để kết nối:

Match Originalhost raspi Exec "ifconfig | grep 192\.168\.1\."
    HostName 192.168.1.2
    User john
    Port 22

Host raspi
    HostName 12.34.56.78
    User john
    Port 1234

0

Giải pháp này giả định rằng mạng gia đình của bạn có một bộ định tuyến duy nhất mà tôi tin là trường hợp phổ biến.

Thêm vào của bạn ~/.ssh/config

Match host raspi exec "test $(arp 192.168.1.1 | awk '{print $4}') = ROUTER_MAC_ADDRESS"
        Hostname 192.168.2.7
        User john

Host raspi
        Hostname 12.345.67.89
        Port 1234
        User john
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.