ssh -D9999 username@example.com
在
localhost
上设置端口9999作为通往example.com
的隧道,但是我有一个更具体的需求:我正在
localhost
上本地工作host1
可以访问localhost
host2
仅接受来自host1
我需要创建一个从
localhost
到host2
的隧道有效地,我想创建一个“多跳” SSH隧道。我怎样才能做到这一点?理想情况下,我想执行此操作而无需成为任何计算机上的超级用户。
#1 楼
您基本上有以下三种可能性:从
localhost
到host1
的隧道:ssh -L 9999:host2:1234 -N host1
如上所述,从
host1
到host2
的连接将无法固定。从
localhost
到host1
以及从host1
到host2
的隧道:ssh -L 9999:localhost:9999 host1 ssh -L 9999:localhost:1234 -N host2
这将打开从
localhost
到host1
的隧道,以及另一个从host1
到host2
的隧道。但是,9999
上的任何人都可以使用端口host2:1234
到host1
。这可能是问题,也可能不是问题。从
localhost
到host1
以及从localhost
到host2
的隧道:ssh -L 9998:host2:22 -N host1
ssh -L 9999:localhost:1234 -N -p 9998 localhost
此将打开从
localhost
到host1
的隧道,通过该隧道可以使用host2
上的SSH服务。然后从第一个隧道打开从localhost
到host2
的第二个隧道。通常,我会选择选项1。如果需要保护从
host1
到host2
的连接,请转到带有选项2。选项3主要用于访问host2
上只能从host2
本身访问的服务。评论
选项3是我一直在寻找的东西,谢谢!
–马拉
2010-1-25的1:38
我想以这种方式浏览。哪一个最好?我尝试了第一个,但是没有用。我在浏览器localhost:1234中设置了一个袜子代理,但是没有运气。 :( 请帮忙..
– rong
2012年2月29日在13:54
@prongs尝试选项3
–马拉
2012年5月3日在6:49
@Noli如果使用ssh-agent(应使用),则可以使用ssh的-A选项通过连接转发它。
– Mika Fischer
2012-12-19 11:36
@musically_ut-正确的是,第二个ssh命令在host1上处于后台,因此,如果要在本地重新连接它,则只需再次运行第一部分。如果添加-f,它将立即在本地后台运行,因此,如果在第一种情况下按ctrl-c,则ssh -f -L 9999:localhost:9999 host1将重新连接。或在首次运行它以立即使所有背景后台运行时,将-f添加到原始double ssh命令中。
–马克·费舍尔
17-2-25在15:10
#2 楼
有一个很好的答案说明了如何将ProxyCommand
配置指令用于SSH:将其添加到您的
~/.ssh/config
(有关详细信息,请参见man 5 ssh_config
): br />然后ssh host2
将自动通过host1
进行隧道传输(也适用于X11转发等)。通过域标识:Host host2
ProxyCommand ssh host1 -W %h:%p
更新
OpenSSH 7.3引入了
ProxyJump
指令,将第一个示例简化为Host *.mycompany.com
ProxyCommand ssh gateway.mycompany.com -W %h:%p
评论
有条件的方法吗?有时候我只想这样做。另外,这是专门针对命令的,但是我正在为22端口(ssh,sftp等)寻找所有东西。
– Stephane
2013年9月11日15:08
@Stephane专门用于命令是什么意思?使用ssh的任何人都可以使用您的SSH配置,包括git,sftp等afaik。
– kynan
2013年9月11日20:58
@Stephane我不知道有条件地启用此功能的方法(例如,仅当您不在目标主机的网络范围内时)。我在配置块中为所有有问题的主机设置了此选项,然后根据需要(取消)注释该行。并不完美,但是可以。
– kynan
2013年9月11日20:58在
@Stephane确保:ssh -F / path / to / altconfig。请注意,这将忽略系统范围内的/ etc / ssh / ssh_config。
– kynan
2013年9月12日上午11:39
一种使设置“有条件”的简单方法是在.ssh / config中定义两个具有相同HostName的不同主机。当需要隧道时,连接到host2-tunnel,而当不需要隧道时,连接到host2。
–史蒂夫·贝内特(Steve Bennett)
2013年9月23日下午6:55
#3 楼
OpenSSH v7.3及更高版本支持-J
开关和ProxyJump
选项,它们允许一个或多个逗号分隔的跳转主机,因此,您现在就可以轻松执行以下操作:ssh -J jumpuser1@jumphost1,jumpuser2@jumphost2,...,jumpuserN@jumphostN user@host
评论
ssh -J user1 @ host1 -YC4c arcfour,blowfish-cbc user2 @ host2 firefox -no-remote这将加快将firefox从host2获取到本地主机的速度。
– Jaur
18年5月21日在16:28
我不知道你可以这样做。感谢分享!
–Stephen Quan
19/12/11在23:35
#4 楼
我们有一个进入我们专用网络的ssh网关。如果我在外面,并且想要在专用网络内部的计算机上安装远程Shell,则必须ssh进入网关,然后从那里进入专用计算机。要使此过程自动化,请使用以下脚本:
#!/bin/bash
ssh -f -L some_port:private_machine:22 user@gateway "sleep 10" && ssh -p some_port private_user@localhost
发生了什么事情:
建立用于ssh协议(端口22)到专用端口的隧道
只有成功,才可以使用隧道将其SSH到专用计算机中。 (&&操作员确保这一点。)
关闭私有ssh会话后,我也希望ssh隧道也关闭。这是通过“睡眠10”技巧完成的。通常,第一个ssh命令将在10秒后关闭,但是在此期间,第二个ssh命令将使用隧道建立连接。结果,第一个ssh命令使隧道保持打开状态,直到满足以下两个条件:sleep 10完成并且不再使用隧道。
评论
非常聪明!!!爱它!
–亨拉·爱侣湾
2012年5月6日在6:37
#5 楼
阅读以上内容并将所有内容粘合在一起之后,我创建了以下Perl脚本(将其保存为/ sh / usr中的mssh并使其可执行):#!/usr/bin/perl
$iport = 13021;
$first = 1;
foreach (@ARGV) {
if (/^-/) {
$args .= " $_";
}
elsif (/^((.+)@)?([^:]+):?(\d+)?$/) {
$user = ;
$host = ;
$port = || 22;
if ($first) {
$cmd = "ssh ${user}${host} -p $port -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no";
$args = '';
$first = 0;
}
else {
$cmd .= " -L $iport:$host:$port";
push @cmds, "$cmd -f sleep 10 $args";
$cmd = "ssh ${user}localhost -p $iport -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no";
$args = '';
$iport ++;
}
}
}
push @cmds, "$cmd $args";
foreach (@cmds) {
print "$_\n";
system($_);
}
用法:
通过HOSTA和HOSTB(同一用户)访问HOSTC:
mssh HOSTA HOSTB HOSTC
通过HOSTA和HOSTB访问HOSTC并使用非默认SSH端口号和不同的用户:
mssh user1@HOSTA:1234 user2@HOSTB:1222 user3@HOSTC:78231
要通过HOSTA和HOSTB访问HOSTC并使用X转发:
mssh HOSTA HOSTB HOSTC -X
通过HOSTA和HOSTB访问HOSTC上的端口8080:
mssh HOSTA HOSTB -L8080:HOSTC:8080
评论
这太棒了
–马拉
2012年3月25日在1:20
我真的很感谢您,此脚本每天使我的生活更加轻松。我唯一更改的是将int(rand(1000))添加到iport,以允许多个实例同时运行。我绝对欠你一杯啤酒。
–马拉
2012年5月3日在7:20
这真的很好。进一步的改进是使用本地主机的/ etc / hosts和〜/ .ssh / config来解析HOSTB,HOSTC等
–史蒂夫·贝内特(Steve Bennett)
2013年9月23日在7:03
我也赞同马拉的评论。如果没有随机端口,那么如果您尝试使用mssh HOSTA HOSTD,您实际上将以HOSTB结尾(也许不会意识到..)
–史蒂夫·贝内特(Steve Bennett)
2013年9月24日下午2:39
#6 楼
这个答案与kynan相似,因为它涉及到ProxyCommand的使用。但是使用IMO更为方便。如果您的跃点计算机中安装了netcat,则可以将此代码段添加到〜/ .ssh / config中:
Host *+*
ProxyCommand ssh $(echo %h | sed 's/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/ -l /;s/:/ -p /') nc $(echo %h | sed 's/^.*+//;/:/!s/$/ %p/;s/:/ /')
然后
ssh -D9999 host1+host2 -l username
会按照您的要求做。招。找到链接后,我会发布一个链接。
评论
我相信这是技巧的起源:wiki.gentoo.org/wiki/SSH_jump_host
–slm
2014年3月28日21:00
#7 楼
我做了我认为您想使用的操作ssh -D 9999 -J host1 host2
我都提示输入两个密码,然后可以使用localhost:9999作为host2的SOCKS代理。这是我想到的最接近您首先显示的示例的内容。
评论
这很好用!
– Arthur Silva
19年6月28日在11:03
不适用于三位房东
–弗拉基米尔·伊辛(Vladimir Iashin)
2月22日6:44
#8 楼
我的答案与这里的所有其他答案确实相同,但是,我想澄清一下~/.ssh/config
和ProxyJump的用处。说我需要3跳才能到达目的地。每跳,我需要一个特定的用户名,主机,端口和身份。由于身份标准,只能使用
~/.ssh/config
配置文件来完成此操作: [yourpc] $ ssh hop1 # will go from your PC to host1 in a single step
[host1] $ exit
[yourpc] $ ssh hop2 # will go from your PC to host2 via host1 (i.e. two steps)
[host2] $ exit
[yourpc] $ ssh hop3 # will go from your PC to host3 via host1 and host2 (i.e. three steps)
[host3] $ exit
[yourpc] $
关于
~/.ssh/config
文件的另一个很酷的事情是,这还将使sftp
可以通过以下任何方式进行文件传输:啤酒花,例如 [yourpc] $ sftp hop1 # for file transfers between your PC and host1
Connected to hop1.
sftp> quit
[yourpc] $ sftp hop2 # for file transfers between your PC and host2
Connected to hop2.
sftp> quit
[yourpc] $ sftp hop3 # for file transfers between your PC and host3
Connected to hop3.
sftp> quit
#9 楼
ssh -L 9999:host2:80 -R 9999:localhost:9999 host1
-L 9999:host2:80
意味着绑定到localhost:9999,并且发送到localhost:9999的任何数据包都将其转发到host2 :80
-R 9999:localhost:9999
表示host1:9999收到的任何数据包将其转发回localhost:9999
评论
创建隧道的出色且最简单的答案,因此您可以直接从localhost:9999访问host2上的应用程序
– dvtoever
16年7月8日在15:45
按照此答案,我得到一个频道3:打开失败:在管理上被禁止:打开失败的错误消息。
–弗朗克·德农库尔
17年3月18日在18:16
#10 楼
您应该能够使用端口转发从host2
访问localhost
上的服务。好的指南位于此处。摘录:端口转发有两种:本地转发和远程转发。它们也分别称为传出隧道和传入隧道。本地端口转发将进入本地端口的流量转发到指定的远程端口。例如,如果发出命令
ssh2 -L 1234:localhost:23 username@host
all客户端上到达端口1234的流量将转发到服务器(主机)上的端口23。请注意,建立连接后,sshdserver将解析localhost。因此,在这种情况下,本地主机是指服务器(主机)本身。
远程端口转发的作用与此相反:它将来自远程端口的流量转发到指定的本地端口。
例如,如果发出命令
ssh2 -R 1234:localhost:23 username@host
服务器(主机)上到达端口1234的所有流量都将转发到客户端(本地主机)上的端口23 )。
在您的演员表中,将示例中的
localhost
替换为host2
,将host
替换为host1
。评论
根据该文章,连接将仅在中间机器(host1)之前得到保护。有没有办法确保整个事情安全?
–马拉
2010-1-16的7:21
我从来没有尝试过,但是如果host1和host2都是ssh服务器,则您可以设置从host1到host2的隧道,然后为相同的服务设置从localhost到host1的隧道(获取本地和远程)端口正确)。我不知道在本地主机的一个命令中是否可行。
– fideli
2010-1-16的16:13
#11 楼
在这个答案中,我将举一个具体的例子。您只需将计算机的主机名,用户名和密码替换为您的主机名,用户名和密码。问题声明
假设我们具有以下网络拓扑:
our local computer <---> server 1 <---> server 2
为具体起见,我们假设我们具有以下计算机的主机名,用户名和密码:
LocalPC <---> hostname: mit.edu <---> hec.edu
username: bob username: john
password: dylan123 password: doe456
目标:我们想要设置一个侦听
9991
的端口LocalPC
的SOCKS代理,以便每次从端口LocalPC
启动9991
上的连接时,该连接都先经过mit.edu
,然后再经过hec.edu
。用例示例:
hec.edu
具有HTTP出于安全原因,只能在http://127.0.0.1:8001上访问的服务器。我们希望能够通过在LocalPC
上打开Web浏览器来访问http://127.0.0.1:8001。配置
在
LocalPC
中,添加在~/.ssh/config
中:Host HEC
HostName hec.edu
User john
ProxyCommand ssh bob@mit.edu -W %h:%p
然后在
LocalPC
的终端中,运行:ssh -D9991 HEC
它会问你
bob
(即mit.edu
)上的dylan123
的密码,那么它将询问您john
(即hec.edu
)上的doe456
的密码。此时,SOCKS代理现在在端口
9991
上运行例如,如果您想使用SOCKS代理访问LocalPC
上的网页,则可以在Firefox中进行:一些说明:
在
LocalPC
中,~/.ssh/config
是连接名称:您可以将其更改为所需的任何名称。HEC
告诉-D9991
在端口上设置SOCKS4代理ssh
。 评论
ssh -D9991 HEC只是在这里sshs到hec.edu
–olejorgenb
3月12日19:57
#12 楼
如果可以同时在两台计算机上使用SSH,请查看ssh的ProxyCommand指令。这将使您直接从localhost进入host2(如果使用公共密钥,只需一个简单的命令!)。然后,您可以对host2做任何您想做的事情。http://www.statusq.org/archives/2008/07/03/1916/
#13 楼
最佳答案的选项2可以用于与当前aka用户不同的ssh用户:user @ host export local_host_port=30000
export host1_user=xyz
export host1=mac-host
export host1_port=30000
export host2=192.168.56.115
export host2_user=ysg
export host2_port=13306
# Tunnel from localhost to host1 and from host1 to host2
# you could chain those as well to host3 ... hostn
ssh -tt -L $local_host_port:localhost:$host1_port $host1_user@$host1 \
ssh -tt -L $host1_port:localhost:$host2_port $host2_user@$host2
#14 楼
就我而言,我确实做到了localhost$ ssh -D 9999 host1
host1$ ssh -L 8890:localhost:8890 host2
其中
host2:8890
在Jupyter Notebook上运行。 。所以现在我的笔记本在
localhost:9999
上运行了,可通过Firefox在我的机器上通过host2
进行访问。#15 楼
接受的答案中提到的三个选项对我根本不起作用。由于我对这两个主机的权限均不大,并且看来我们的DevOps团队在进行身份验证和执行MFA时拥有非常严格的规则。某种程度上,上面的命令不能很好地与我们的身份验证配合使用。 />还有另一种解决方案-天真的一个解决方案
我最终以一种非常幼稚的方式做到了这一点:我没有尝试在笔记本电脑上运行所有命令,而是在每个笔记本上运行命令如下所示:
SSH进入您的跳转服务器,然后运行
ssh -v -L 6969:localhost:2222 -N your-protected.dest.server
。如果提示您输入任何密码,请键入。现在在笔记本电脑上,运行
ssh -v -L 6969:localhost:6969 -N your-jump-server.host.name
。这会将您在笔记本电脑上端口6969上的任何请求转发到跳转服务器。然后,依次,由于我们在上一步中进行了配置,跳转服务器将再次将端口6969的请求转发到受保护的目标服务器上的端口2222。打印后您应该看到命令“挂起”一些消息-这意味着他们正在工作!一个例外-您应该不会看到类似
Could not request local forwarding.
的错误消息,如果看到该错误消息,则它仍然不起作用:(。您现在可以尝试从笔记本电脑向端口6969发出请求,并查看它是否起作用。< br希望如果您未能通过上述所有方法,也许可以尝试一下。
#16 楼
只有这样,才能在超过两个主机上帮助我:ssh -L 6010:localhost:6010 user1@host1 \
-t ssh -L 6010:localhost:6010 user2@host2 \
-t ssh -L 6010:localhost:6010 user3@host3
它将提示您输入三个密码。
受此答案启发>
评论
你是用来干什么的?我想将其用于袜子代理。能行吗?是的,除非host2拒绝转发
,否则您应该能够将隧道连接用作SOCKS代理。
我当时正在考虑通过SSH创建包装器,该包装器将通过多次使用ProxyCommand进行设置。
@prongs(所有年前)您是否已将其用于SOCKS代理?