SSH隧道使用

Author : zbzhen,        Modified : Fri Mar 8 23:45:20 2024

1. 代理

1.1. 本地机器需要做的事

假设公网服务器的ip地址为10.10.12.34, 只需在本地终端输入

ssh -CqTnNf -D localhost:5901 root@10.10.12.34

执行上面命令, 就可以访问公网服务器的网络

其中 -C 为压缩数据,-q 安静模式,-T 禁止远程分配终端,-n 关闭标准输入,-N 不执行远程命令。 -f 参数,把 ssh 放到后台运行。

检查是否成功
ss -tnlp | grep 5901
或者
ps aux | grep ssh
如果成功的话, 会显示一串字符, 里面会出现pid=1242, pid数字是随机, 这里的1242只是举例说明

如果想关闭的话, 可以输入kill -9 1242

1.2. 使用:火狐浏览器为例

  • 浏览中输入about:preferences#general, 或者直接打开设置

  • 点击页面最右下方的设置(setting)按钮

  • 如下图, 合适位置分别填写127.0.0.15901

  • 最后火狐浏览器中打开百度搜索ip, 如果显示的是公网服务器的归属地就有惊喜

测试成功

2. 内网穿透

2.1. Web服务

2.1.1. 公开模式

未做测试

A本地搭建Web服务port:8888, 通过外网服务器10.10.12.34中转

ssh -CR 8000:10.10.12.34:8080 root@10.10.12.34

2.1.2. 非公模式

未做测试
A本地搭建Web服务(port:8888),需要B测试,但不想其他任何人访问,A,B在不同的内网,通过外网服务器10.10.12.34中转

  • A:ssh -CR 127.0.0.1:8000:127.0.0.1:8888 root@10.10.12.34

  • B:ssh -CL 127.0.0.1:8888:127.0.0.1:8000 root@10.10.12.34

2.2. 防火墙中转

测试成功

  • A本地不能访问C
  • B能访问C

在A的终端输入:

HostA$ ssh -N -L 127.0.0.1:PortA:HostC:PortC  userB@HostB

然后

HostA$ ssh -p PortA userC@127.0.0.1

可登陆到C

2.3. 内网穿透

公网服务器10.10.12.34
公网用户root

2.3.1. 反向隧道

测试成功, 成功

学校或企业内网主机A执行
HostA$ ssh -NR 9999:localhost:22 userB@HostB

-N 表示不执行远程命令,如果不加入这个选项,就会在创建隧道的时候,也直接登陆进相应主机了。此选项适用于只进行端口转发的情况。 -R 表示创建反向隧道。是Remote的简写,如果后台运行,可以添加 -f 选项

然后可在公网服务器B上执行
HostB$ ssh -p 9999 usrA@127.0.0.1
可登陆到内网主机A的22端口

但实际应用中, 我们希望能直接在本地机器C上可以连接到内网服务器A, 如果直接连接会失败, 我们希望可以借助公网主机B使得C能访问A. 总体来说就是需要两步:

  1. 确保学校或企业内网服务器A能成功登陆到公网B, 然后A上执行
  • HostA$ ssh -CqTnNf -R 9999:localhost:22 userB@HostB, 接下来访问B的9999端口等于访问A的22号端口
  1. 确保本地机器C能成功登陆到公网B, 并且如果处于内网的话, 也能成功登陆到学校或企业内网服务器A, 然后C上依次执行
  • HostC$ ssh -CqTnNf -L 127.0.0.1:44452:127.0.0.1:9999 userB@HostB, 接下来访问本地C的44452端口等于访问B的9999号端口, 由于有了第一步, 因此最终相当于访问本地C的44452端口等于访问A的22号端口

  • HostC$ ssh -p 44452 userA@127.0.0.1, 这一步就可以直接登陆到A主机

整个过程的安全性依赖于公网机器B, 因为要想访问内网机器A, 得必须能确保连接上公网机器B.

公网机器的安全问题建议:

  • 禁用密码登陆
  • 用fail2ban, 如果登陆3次失败, 封禁一段时间, 防止暴力破解
  • 私钥一定要保管好

如果还想直接用上内网A的代理, 则只需在本地C执行

HostC$ ssh -CqTnNf -D 127.0.0.1:1234 -p 44452 userA@127.0.0.1

2.3.2. 跳板打洞

未做测试, 因为真的不安全

内网主机A执行
ssh -NR *:8889:localhost:22 root@10.10.12.34 -l A_usr_name

运行之后,任何主机可以通过
ssh -p 8889 10.10.12.34
可登陆到内网主机A的22端口

3. 中转代理

  • 本地A不能访问C, 但是可以访问B,
  • 服务器B可以访问C
  • 目标是希望本地上网的ip地址是C的ip

为了简便, 不妨假设用户名都是root

下面两行代码都是在本地A中执行

ssh -CqTnNf -L 127.0.0.1:44444:hostC:22 root@hostB
ssh -CqTnN -D 127.0.0.1:1234 -p 44444 root@127.0.0.1

上面最后一行代码回车后会提示输入密码, 输入的密码不会展示出来, 只要是正确输入了密码, 然后回车就行

停止运行

查看pid
ps aux | grep ssh
停止
kill -9 pid

或者直接一行命令(kill所有ssh进程)
kill -9 $(ps aux | grep '[s]sh' | awk '{print $2}')

win一行命令删除所有的ssh进程
taskkill /F /IM ssh.exe

win上推荐在git中输入命令行,git下载地址为 https://registry.npmmirror.com/binary.html?path=git-for-windows/

后续过程可参考之前介绍的在火狐浏览器中使用

自我中转代理

win上可以把下面代码保存为xx.bat然后双击运行它

@echo off
taskkill /F /IM ssh.exe
ssh -CqTnNf -L 127.0.0.1:44444:your_ip:22 root@your_ip
ssh -CqTnNf -D 127.0.0.1:1234 -p 44444  root@127.0.0.1

4. python代理与查看ip地址

测试成功

需要安装pysocks

pip install pysocks

假设服务器的ip是10.10.12.34

本地终端输入

ssh -CqTnNf -D localhost:1234 root@10.10.12.34
import requests
import socks
import socket
socks.set_default_proxy(socks.SOCKS5, "127.0.0.1", 1234)
socket.socket = socks.socksocket 
ans = requests.get("https://httpbin.org/ip").text[13:-2]
print(ans)

运行上面python代码则可以得到10.10.12.34

其实也可以选择用比较简单的方式查看ip

curl https://httpbin.org/ip
curl ipinfo.io
curl https://forge.speedtest.cn/api/location/info

或者用markdown代码为

<p id="ipinfo"></p>
<script>
  function getIpInfo() {
    fetch('https://forge.speedtest.cn/api/location/info')
      .then(res => res.json())
      .then(res => {
        document.getElementById('ipinfo').textContent = `当前IP: ${res.ip} (${res.province} ${res.city}  ${res.distinct} ${res.isp})  `;
      })
      .catch(err => {
        console.log(err);
      });
  }
  getIpInfo();
</script>

5. ssh命令参数详解

gpt3.5的回答:

SSH(Secure Shell)是一种加密的网络协议,用于在网络上安全地传输数据。SSH命令是用于在远程计算机上执行命令的命令行工具。以下是SSH命令的常用参数:

  1. -l:指定登录用户名。

  2. -p:指定远程主机的端口号。

  3. -i:指定用于身份验证的私钥文件。

  4. -A:启用身份验证代理。

  5. -X:启用X11转发。

  6. -C:启用压缩。

  7. -v:启用详细输出模式。

  8. -q:启用安静模式。

  9. -t:强制分配伪终端。

  10. -T:禁用分配伪终端。

  11. -N:不执行远程命令。

  12. -f:将ssh会话放入后台运行。

  13. -L:本地端口转发。

  14. -R:远程端口转发。

  15. -D:动态端口转发。

  16. -o:指定配置选项。

  17. -s:指定ssh服务器。

  18. -c:指定加密算法。

  19. -k:指定密钥类型。

  20. -b:指定绑定地址。

  21. -F:指定配置文件。

  22. -e:指定转义字符。

  23. -n:禁用输入。

  24. -y:启用密钥认证。

  25. -h:显示帮助信息。


参考链接: