Odwrotny tunel SSH: jak mogę wysłać mój numer portu na serwer?

12

Mam dwie maszyny, klienta i serwer.

Klient (który stoi za firmową zaporą ogniową) otwiera tunel zwrotny SSH do serwera, który ma publicznie dostępny adres IP, za pomocą tego polecenia:

ssh -nNT -R0: localhost: 2222 [email protected]

W OpenSSH 5.3+ 0występowanie tuż po -Roznacza „wybierz dostępny port”, a nie jawnie go wzywając. Powodem tego jest to, że nie chcę wybierać używanego portu. W rzeczywistości istnieje wielu Klientów, którzy muszą założyć podobne tunele.

Problem polega na tym, że serwer nie wie, który klient jest który. Jeśli chcemy ponownie połączyć się z jednym z tych klientów (za pośrednictwem hosta lokalnego), to skąd wiemy, który port odnosi się do którego klienta?

Wiem, że ssh zgłasza numer portu w wierszu poleceń, gdy jest używany w powyższy sposób. Jednak chciałbym również użyć autossh, aby utrzymać sesje przy życiu. autossh uruchamia proces potomny prawdopodobnie przez fork / exec, tak że dane wyjściowe rzeczywistego polecenia ssh są tracone w eterze.

Ponadto nie mogę wymyślić żadnego innego sposobu uzyskania zdalnego portu od klienta. Zastanawiam się więc, czy istnieje sposób na określenie tego portu na serwerze.

Jednym z moich pomysłów jest użycie / etc / sshrc, który jest podobno skryptem uruchamianym dla każdego połączenia. Jednak nie wiem, w jaki sposób można uzyskać tutaj istotne informacje (być może PID konkretnego procesu sshd obsługującego to połączenie?) Chciałbym kilka wskazówek.

Dzięki!

Tomek
źródło
2
Czy VPN nie byłby bardziej odpowiedni? OpenVPN jest bardzo prosty w konfiguracji.
Ben Lessani - Sonassi
Brzmi interesująco. Nie wiem dużo o VPN. Czy to może działać, nawet jeśli komputer kliencki jest skonfigurowany do korzystania z DHCP?
Tom
1
Tak, działa z innym interfejsem TUN / TAP, więc inne interfejsy są nieistotne.
Ben Lessani - Sonassi
@sonassi, wygląda na to, że ta rzecz VPN załatwi sprawę. Dzięki za informację.
Tom
Poniżej dodałem odpowiedź, która poprowadzi Cię przez proces VPN z OpenVPN (oparty na Debian / Ubuntu)
Ben Lessani - Sonassi

Odpowiedzi:

4

Czy VPN nie byłby bardziej odpowiedni? OpenVPN jest bardzo prosty w konfiguracji. Oto przykładowa konfiguracja i kilka linków prowadzących przez proces tworzenia certyfikatu:

apt-get install openvpn
mkdir /etc/openvpn/easy-rsa
mkdir -p /etc/openvpn/ccd/client_server
touch /etc/openvpn/ipp.txt
cp -a /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa
source ./vars
./clean-all
./build-ca 
./build-dh
./build-key-server server
cd /etc/openvpn/easy-rsa/keys
openssl pkcs12 -export -out server.p12 -inkey server.key -in server.crt -certfile ca.crt

Następnie utwórz nowy plik /etc/openvpn/client_server.confi umieść w nim następujące elementy, zmieniając SERVER_IP_ADDRESSodpowiednio

local SERVER_IP_ADDRESS
port 8443
proto udp
dev tun
ca /etc/openvpn/easy-rsa/keys/ca.crt
pkcs12 /etc/openvpn/easy-rsa/keys/server.p12
dh /etc/openvpn/easy-rsa/keys/dh1024.pem
ifconfig-pool-persist /etc/openvpn/ipp.txt
server 192.168.100.0 255.255.255.0
client-config-dir /etc/openvpn/ccd/client_server
ccd-exclusive
keepalive 10 120
comp-lzo
persist-key
persist-tun
status /var/log/openvpn-status.log
verb 3
reneg-sec 0

Następnie zbuduj klucz dla każdego użytkownika, który ma się połączyć, i utwórz plik konfiguracyjny w katalogu ccd

./build-key-pkcs12 [email protected]
echo "ifconfig-push 192.168.100.2 255.255.255.0" > /etc/openvpn/ccd/client_server/[email protected]

Adres IP MUSI być odpowiedni dla podsieci / 30 (patrz http://www.subnet-calculator.com/cidr.php ), ponieważ dostępne są tylko 2 adresy (serwer i klient) na połączenie. Twój następny dostępny adres IP klienta to 192.168.100.6 i tak dalej.

Następnie masz statyczne adresy IP na podłączającego użytkownika.

Następnie dostarcz the [email protected]plik do użytkownika końcowego i użyj następującego pliku konfiguracyjnego

client
dev tun
proto udp
remote SERVER_IP_ADDRESS 8443
pkcs12 [email protected]
resolv-retry infinite
nobind
ns-cert-type server
comp-lzo
verb 3
reneg-sec 0
Ben Lessani - Sonassi
źródło
Dzięki za dokładną odpowiedź! Mam jednak dwa pytania na ten temat. A) Określenie 255.255.255.0 dla linii ifconfig-push klienta nie wydaje się działać, ale działa, jeśli podam drugi adres IP. Dlaczego to? I B) czy to podejście oznacza, że ​​na połączenie używane są 4 adresy IP?
Tom
W niektórych systemach Linux składnia linii ifconfig-push jest inna. Na przykład. ifconfig-push 192.168.100.2 192.168.100.3- Nie mam pojęcia, dlaczego różni się na platformach. I tak, oznacza to, że 4 klientów są używane na klienta (marnotrawstwo, ale charakter bestii).
Ben Lessani - Sonassi
3

Jeśli każdy z klientów ma inną nazwę użytkownika, możesz użyć, netstataby dowiedzieć się, na jakim porcie sshdnasłuchuje proces tego użytkownika . Na przykład:

% sudo netstat -tlpn | grep 'sshd: mgorven@'
tcp        0      0 127.0.0.1:22220         0.0.0.0:*               LISTEN      5293/sshd: mgorven@
tcp        0      0 127.0.0.1:5120          0.0.0.0:*               LISTEN      5293/sshd: mgorven@
mgorven
źródło
3

Możesz zmienić efemeryczny zakres portów ( /proc/sys/net/ipv4/ip_local_port_rangedla Linuksa), a następnie użyć statycznie przydzielonych portów poza tym zakresem.

Mark Wagner
źródło
Nie trzeba w tym celu zmieniać zakresu efemerycznego. Domyślnie zakres efemeryczny kończy się na 61000, więc powyżej tego są tysiące dostępnych numerów portów. Często wybrałem echo $[61002+RANDOM%4532]numer portu w tym zakresie.
kasperd
2

Chcę taką samą konfigurację jak Ty, zwiększyłem poziom dziennika serwera SSH do DEBUG i pokazał w dziennikach, jaki był lokalny port klienta

na przykład:

polecenie klienta: ssh -N -R0:127.0.0.1:5522 [email protected]

dziennik serwera:

Jun 30 11:28:59 debsid sshd[27577]: debug1: Local forwarding listening on 127.0.0.1 port 35391

tam widzisz numer portu

Deeler
źródło
0

Powinieneś być w stanie wyodrębnić odpowiednie informacje z wyników:

lsof -i tcp

Uruchom jako root.

Thor
źródło
0

Uruchom ten skrypt na serwerze:

sudo lsof -i -n | grep "sshd" | grep "(LISTEN)" | awk '{print $2}' | while read line; do sudo lsof -i -n | egrep $line | sed 3~3d | sed 's/.*->//' | sed 's/:......*(ESTABLISHED)//' | sed 's/.*://' | sed 's/(.*//' | sed 'N;s/\n/:/' 2>&1 ;done

Możesz potrzebować dwóch sudo. Usuń, jeśli nie.

PS - To jest zmodyfikowana wersja rozwiązania, które znalazłem gdzie indziej. Myślę, że mógł pochodzić z StackOverflow, ale nie mogę znaleźć oryginalnego odwołania.

eric
źródło