Linux
使用多跳 ssh 隧道訪問數據庫
我們有一些只能通過跳轉主機訪問的遠端伺服器。在這個遠端伺服器上執行 vms,它託管我想在本地訪問的數據庫。每個盒子都是一個linux系統。我在本地電腦、遠端主機及其虛擬機上只有 su 權限。
這意味著我們的設置如下所示:
My local pc --> jumphost --> remotehost --> vm with mysql on 127.0.0.1:3306
通常我會 ssh 三次,然後使用 mysql cli。
現在我需要設置一條從我的本地電腦到託管數據庫的盒子的隧道。
Ulitmatly 我想使用類似 python lib ssh-tunnel及其類 SSHTunnelForwarder 的東西。但我想從 bash 命令開始設置這種代理。
ssh 身份驗證是基於密碼的,每個躍點需要不同的使用者。理想情況下,該解決方案不需要更改 ~/.ssh/config
我找到了這篇文章,我認為選項 3 非常接近我的需要。
一個例子來說明清楚。假設 jumphost 是:
user1@192.168.11.29
,我的 remotehost 是user2@172.1.1.1
,帶有數據庫的 vm 是user3@10.100.1.1
我會嘗試的是:
ssh -L 9998:172.1.1.1:22 -N user1@192.168.11.29
從我的本地 pc 埠 9998 到遠端主機上的埠 22 的隧道
這裡開始我的問題,我將如何指定用於 ssh 隧道旁邊的使用者。任何人都可以引導我走向正確的方向嗎?
ssh -L 9999:10.100.1.1:22-N -p 9998 user2@localhost
從我的本地 pc 埠 9999 通過第一條隧道到遠端主機上的埠 22 的隧道
ssh -L 10000:locahost:3306 -N -p 9999 user3@localhost
從本地 pc 埠 10000 通過埠 9999 上的隧道到 vm 上的埠 3306 的隧道。
之後,據我所知,我應該能夠從我的本地 pc 訪問具有 127.0.0.1:3306 的 vm 上的數據庫。
我希望這是有道理的,我感謝每一個答案。
我能夠解決它,感謝這篇文章
class TunnelNetwork(object): def __init__(self, tunnel_info, target_ip, target_port): self.tunnel_info = tunnel_info self.target_ip = target_ip self.target_port = target_port def start_tunnels(self): self.tunnels = [] for idx, info in enumerate(self.tunnel_info): # if we're not the first element, set the bastion to the local port of the previous tunnel if idx > 0: info['ssh_address_or_host'] = ('localhost', self.tunnels[-1].local_bind_port) # if we are the last element, the target is the real target if idx == len(self.tunnel_info) - 1: target = (self.target_ip, self.target_port) # else, the target is the next bastion else: if isinstance(self.tunnel_info[idx+1]['ssh_address_or_host'], tuple): target = self.tunnel_info[idx+1]['ssh_address_or_host'] else: target = (self.tunnel_info[idx+1]['ssh_address_or_host'], 22) self.tunnels.append(SSHTunnelForwarder(remote_bind_address=target, **info)) try: self.tunnels[idx].start() except: return False return True def stop_tunnels(self): for tunnel in reversed(self.tunnels): tunnel.stop() def are_tunnels_active(self): return self.tunnels and all([t.is_active for t in self.tunnels]) def get_local_connect_port(self): if self.tunnels: return self.tunnels[-1].local_bind_port else: return None
並將其用於:
tunnel_i = [ {"ssh_address_or_host": "192.168.11.29", "ssh_username": "user1", "ssh_password": "", }, {"ssh_address_or_host": "172.1.1.1 ", "ssh_username": "user2", "ssh_password": "", }, {"ssh_address_or_host": "10.100.1.1", "ssh_username": "user3", "ssh_password": "", } ] target_ip = "127.0.0.1" target_port = 3306 tn = TunnelNetwork(tunnel_i, target_ip, target_port) tn.start_tunnels()
確保在您使用的每個躍點上將 AllowTcpForwarding 設置為 On。