Yerel port veya soket dosyasını uzak soket dosyasına ilet


24

Hızlı soru - Biri kendi masaüstüm, diğeri VPS'im olan iki linux kutusu kullanıyorum. VPS ucunda güvenlik nedeniyle MySQL'e ( /var/run/mysqld/mysql.sock) soket bağlantılarını seçtim . Bu şekilde tünel yapabileceğimi biliyorum: ssh -L 3307:127.0.0.1:3306 user@site.comeğer uzak sql sunucusunu bazı ssh -L /path/to/myremotesqlserver.sock:/var/run/mysqld/mysql.sockportlarda dinlemek üzere ayarlarsam, ama bilmek istediğim şey gibi bir şey yapabilir miyim: böylece iki soketin aksine iki soketi tünellemek mi?

Mükemmel bir kabul edilebilir çözüm de yerel bir portu uzak soket dosyasına iletmek olacaktır, ancak mümkün olduğunda uzak kutuda tcp sunucularının çalışmamasına çalışıyorum.

(ve evet, tcp'nin daha kolay olacağını biliyorum).


TCP'yi mySQL kutusunda kullanmak istemediğiniz neden güvenlik endişelerinden kaynaklanıyorsa (yani uzaktaki saldırılar, vb.) Ya güvenlik duvarını kullanabilirsiniz, ve eğer bu yeterince iyi değilse, mySQL'i yalnızca 127.0.0.1 dinlemesini sağlayın TCP bağlantıları için SSH üzerinden kolayca tünel açabilirsiniz. Olmazsa, aşağıdaki socat çözümünü destekliyorum.
Mattias Ahnberg

lwn.net/Articles/609321 OpenSSH 6.7 soket iletimini getirecek
Hubbitus

@Hubbitus bu özellik şu anda mevcut, eğer öyleyse, örnek bir cevap verebilir misiniz?
CMCDragonkai

Bu yorum cevap biçimindeydi, ancak birileri tarafından yoruma çevrildi. Ve şimdi görüyorum ki, aşağıda cevabını zaten önerdin.
Hubbitus

Yanıtlar:


35

Talep üzerine yerel soketi yönlendir

  • SSH ortak anahtar kimlik doğrulamasını ayarlayın
  • socatHer iki uca kurun
  • diğer kullanıcılar tarafından erişilemez, soketleriniz için yerel olarak bir dizin oluşturun.
export SOCKET_DIR=~/.remote-sockets
mkdir -p $SOCKET_DIR
socat "UNIX-LISTEN:$SOCKET_DIR/mysqld.sock,reuseaddr,fork" \
EXEC:'ssh user@server socat STDIO UNIX-CONNECT\:/var/run/mysqld/mysqld.sock'

sonra

mysql -S $SOCKET_DIR/mysqld.sock -u mysqluser -p

unix domain soketlerini ssh ve socat ile yönlendirmekten çalındı


Bu harika ve kabul edilen cevap olmalı.
John Smith İsteğe Bağlı

32

Zaman zaman, soru sorulduğunda, gerçekten imkansızdı, ancak bugünlerde mümkün.

Her ikisine de yapabilirsiniz: UNIX => TCP ve UNIX => UNIX iletme.

Örneğin:

ssh \
  -R/var/run/mysql.sock:/var/run/mysql.sock \
  -R127.0.0.1:3306:/var/run/mysql.sock \
  somehost

OpenSSH 6.7’den beri mümkündür.


1
Yerel soketimi yukarıda kullanarak uzak sunucu soketine iletmeyi ve docker istemcisini uzaktan çalıştırmayı başardım (doğrudan ssh tarafından yapılabilir, ancak bunun neresinde eğlenceli olur :)ssh -L /home/user/docker.sock:/var/run/docker.sock dockerhost -N
sdkks

11

Bunu yapmadım, ama socat ile denerdim . belki bir şey gibi:

ssh xxx@yyy.zzz -L 9999:localhost:9999 "socat TCP-LISTEN:localhost:9999 UNIX-CONNECT:/var/run/mysqld/mysql.sock"
socat UNIX-LISTEN:/path/to/local/socket TCP:localhost:9999

yine, böyle bir şey hiç yapmadım.


Ben bir şans vereceğim ve nasıl gideceğini size bildireceğim. Tcp tabanlı uygulamayı kullanıyorum.

Şu anda çalışmasını sağlayamıyorum, ama yine de fikir için +1, hoşuma gitti. Düzeltirsem haber veririm.

+1 yararlı bir yardımcı program gibi görünüyor.
Warner

5

Ssh 6.7'den beri daha fazla socat'a ihtiyaç yok. Unix alan soketlerini doğrudan şöyle yönlendirebilirsiniz:

ssh -nNT -L $(pwd)/docker.sock:/var/run/docker.sock user@someremote

Daha fazla bilgi: https://medium.com/@dperny/forwarding-the-docker-socket-over-ssh-e6567cfab160


Bunu farklı bir kullanıcı olarak yerel bir prize bağlamak için de yararlı buldum. Bu, istemci programlarını belirli kullanıcı kimliklerini (kendi iş çalışanlarından gelen bağlantılar) kesen bir sunucu işlemine karşı çalıştırmama izin veriyor.
Warbo,

Bir soketi aynı makineye iletmek, ancak farklı bir kullanıcı tarafından kontrol edilen farklı dizinler, erişimi doğrulamak için sshd kullanarak? Senin usecase nedir
CMCDragonkai

Dizin izinleri / erişimi sorun değil. Aksine, belirli bir arka plan programı , belirli bir gruptaki kullanıcılar tarafından yapılan herhangi bir bağlantı girişimini bırakır (sözde yenilerin kafasını karıştırmamak için). Ssh kullanmak, bu gruptaki kullanıcılar sanki bu grupta olmayanlarmış gibi bağlantı kurmayacak şekilde bağlanmalarını sağlar (tünelli soket üzerinden).
Warbo,

İlginç, komik nix-daemon'u kastettiğin gibi, ben de bununla ilgili konularla ilgileniyorum. Neden nix-daemon'un belirli bir gruptaki kullanıcılara bağlantıyı bıraktığını merak ediyorum? Bu bir güvenlik yapılandırması mıdır? Ya da şunlarla ilgili: nixos.org/nix/manual/#idm140737318362784 ?
CMCDragonkai

Taahhüt mesajına göre "yanlışlıkla" kullanımını önlemek için. Konuyu açtığım burada
Warbo

2

@Mpontes '/ @ javier'in cevabındaki başka bir değişiklik

ssh user@remoteserver -L 9999:localhost:9999 'socat TCP-LISTEN:9999,fork,bind=localhost UNIX-CONNECT:/var/run/mysqld/mysql.sock& pid=$!; trap "kill $pid" 0; while echo -ne " \b"; do sleep 5; done'

temizleyici

ssh user@remoteserver -L 9999:localhost:9999 '
  socat TCP-LISTEN:9999,fork,bind=localhost UNIX-CONNECT:/var/run/mysqld/mysql.sock&
  pid=$!
  trap "kill $pid" 0
  while echo -ne " \b"; do
    sleep 5
  done
'

Artıları

  1. 6.7'den önceki openssh ile çalışır (CentOS 7 gibi)
  2. Uzak sunucuya yeniden ssh koymak zorunda kalmak yerine socat'ı ssh sonlandırmasında öldürür
  3. Herkese açık olmayan ssh girişlerine izin verir (ijk çözümünden farklı olarak)

özellik

  1. Bu -fseçenek kullanılmadığından, bir genel anahtar kullanabilir ve arka planda çalışabilir &veya etkileşimli olarak giriş yapabilir ve Ctrl + Z tuşlarını kullanarak aynı $!şeyi kullanabilirsiniz .

EKSİLERİ

  1. -fSsh seçeneğini kolayca kullanamazsınız , çünkü ssh pidini bu şekilde kaybedersiniz. Bu yöntem, ön planda çalışmaya ve öldürmek için Ctrl + C'ye dayanır.
  2. Çok daha karmaşık

açıklama

  • socat ...& - socat'ı uzak sunucuda arka planda çalıştır
  • pid=$! - ödemeyi saklamak
  • trap kill\ $pid 0- kill $pidbas fesih
  • while :; sleep... - sonsuz bir döngüde oturmak
  • echo -ne \ \b- Yankı boşluğu ve ardından geri al. Bu, ssh bağlantısı kesildiği anda başarısız olur. A ile bu sleep 5, socatssh'den 5 saniyeye kadar sürebilen anlamına gelir

Not: Aslında liman işçisi, bağlantı noktasını kullanarak test 2375, /var/run/docker.sockve çevre değişkeni DOCKER_HOST='tcp://localhost:2375', ancak mysql hepsi aynı için çalışmalıdır

Güncelleştirme

Kullanılması SSH Kontroller kullanabileceğiniz -fsadece aşağıdaki bayraklarını ekleyin yolumu kullanarak bayrağı

-f -o ControlPath=~/.ssh/%C -o ControlMaster=auto

Ve alacaksın

ssh -f -o ControlPath=~/.ssh/%C -o ControlMaster=auto user@remoteserver -L 9999:localhost:9999 'set -m; socat TCP-LISTEN:9999,fork,bind=localhost UNIX-CONNECT:/var/run/mysqld/mysql.sock& pid=$!; trap "kill $pid" 0; while echo -ne " \b"; do sleep 5; done'

Artık tüm kontrollü oturumları kullanarak sona erdirebilirsiniz

ssh -o ControlPath=~/.ssh/%C -O exit remoteserver

-oSeçenekler kaydedilebilir .ssh/configdosyası veya bunun yerine -S kullanabilirsiniz (ama hala ihtiyaç olacak -o ControlMaster)


Kodları diğer ana bilgisayarlara dağıtmak için Docker kabının içindeki komut dosyalarını kullanıyorum. Bağlantı mantığınız şaşırtıcı ancak bash oturumu sona erdiğinde biter. Bu docker run ... connect.sh, ardından gelen tüneli kurmam için çağrı yapmamı engelliyor docker run ... deploy.sh. Denedim nohup, &ve disownancak kırmaya görünüyor socatkapatarak stdoutve tetikleme kill. Tweaks'in bu davayı desteklemesi için herhangi bir fikir var mı?
claytond

TAMAM. Bu aslında bir terminalde (w / -fve & disown) iyi çalışıyor . Görünüşe göre sorun "sarmalayıcı" betiği tarafından yaratıldı. Girdiyi memnuniyetle karşılayabilirim ama şimdi daha uygun soru-cevaplara bakıyorum.
claytond

@claytond Tam olarak ne yaptığınızdan emin değilsiniz, ancak evet, diğer tüm komutlar bir konteynerin pid 1'i bittiğinde sonlandırılır. "eğer $ 1 (komut) == deploay sonra" diyecek resim ssh komutlarını ve konuşlandırma komutlarını çalıştırın ve sonra ssh bağlantısını kapatan son. Ayrıca docker run ... connect.sh, ve docker exec {container name/id} deploy.sh, böylece birlikte oynarlar.
Andy,

Haklısın. Aslında execzaten bir runkapta kullanıyorum ve SSH borusu execsona erdikten sonra da devam etmiyordu . Bunun senaryoların yürütülmesi şeklindeki bir tuhaflıktan kaynaklandığını açıklığa kavuşturdum. Eğer aramayı kendi bültenine taşıdıysam ve nohup <script.sh> & disownaradıysam, tamamlanmış olarak kalır exec.
claytond

1

Javier'in cevabını detaylandırarak, bu benim için çalışıyor:

ssh -f xxx@yyy.zzz -L 9999:localhost:9999 "socat TCP-LISTEN:9999,fork,bind=localhost UNIX-CONNECT:/var/run/mysqld/mysql.sock"

forkİlk bağlantıyı kapattıktan sonra ölmeden socat ölmeden birden fazla kez bağlanabilmek için ihtiyacınız var . Ayrıca, socat'ın bağlanacağınız bir adres belirtmenize izin vermesi, bindbağlantı noktasından önceki bir adres olarak değil , seçenek aracılığıyla olur .

Bundan sonra, localhost:9999normalde olduğu gibi bağlanın . Sonra tüneli parçalamak için:

ssh -f xxx@yyy.zzz "killall socat"

(veya benzeri bir şey varsa, socat'ın PID'sini korumayı içeren daha ayrıntılı şeyler yapabilirsiniz)


1

Evet, socat kullanabilirsiniz.

İlk önce SSH ile TCP tüneli yapın. Öyleyse bu şekilde socat kullanın:

socat unix-listen: /var/run/mysqld/mysqld.sock,fork,unlink-early tcp: 127.0.0.1: 3306

Ardından yeni oluşturulan sokete izin verin (chmod 777 olabilir)


Bu OpenSSH 6.6’dan beri mümkündür.
ysdx

3
chmod 777: hayır hayır Hayır Hayır Hayır! Asla asla koşma chmod 777. Neredeyse hiç gerekli değil! "Test amaçlı" bile değil. Dosya okunabilirse, okunabilir durumdadır. Yazabilir userveya groupyazması gereken yazıyorsa, yazılabilir. Herkese yazma izinleri verme konusunda kesinlikle sıfır bir ihtiyaç vardır ve chmodbunu aklı başında bir şeylere unutmak , tam olarak çokuluslu şirketlerin saldırıya uğramasıdır. Sadece yapma. Hiç. Unix izinlerinin tanıtımını yazdım . Lütfen onu oku!
Martin Tournoij
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.