一、场景如下:

  各个角色的对应关系如下:

角色 描述
APP 个人笔记本,属于内网IP
sshd server 公网 VPS ( 映射端口: port 2222 ),拥有公网IP
ssh client 内网机器,属于另一个内网IP
APPSRV

与 内网 ssh client 是同一台机器 ( 目的端口: hostport 22 )

  两个帐号:admin/password为“内网机器”ssh的登录帐号密码,VPS-user/password为“公网VPS”ssh的登录帐号密码

  网络连通情况:“内网机器”可以访问公网VPS,“个人笔记本”可以访问“公网VPS”,但是不可以访问“内网机器”;“公网VPS”不能访问“内网机器”,也不能访问“个人笔记本”

二、目标:实现私网的笔记本访问另一个私网的“内网机器”

三、思路:建立反向代理,把访问公网VPS某个端口的流量映射到“内网机器”的某个端口;然后建立正向代理,把“个人笔记本”对“内网机器”的访问流量、访问请求,通过代理发给“VPS”的那个映射端口

四、步骤:

  1、反向代理:“公网VPS”===>"内网机器",通过内网机器反向连接VPS

  在内网机器上配置:(ssh clinet) # ssh -CfnNT -R 2222:localhost:22 VPS-user@VPS

           (ssh clinet) # ssh -p 22 -qngfNTR 6666:localhost:22 VPS-user@VPS

  这样就把“内网机器”的22端口转发到了远程机器(VPS)的6666端口上

  查看内网机器的进程

  [ssh clinet ~]# ps aux | grep "ssh -p"
  root     14594  0.0  0.0  59856  1056 ?        Ss   11:16   0:00 ssh -p 22 -qngfNTR 6666:localhost:22 VPS-user@VPS

  查看公网VPS的端口情况,注意端口6666,只有本地环回地址可以访问

  [sshd server ~]# netstat -anpt | grep 6666
  tcp        0      0 127.0.0.1:6666              0.0.0.0:*                   LISTEN      10703/sshd

  这时候,在公网VPS上就可以通过ssh连接内网机器,打通了“公网VPS”到“内网机器”的访问通道

  [sshd server ~]# ssh -p 6666 admin@localhost
  admin@localhost's password:

  输入“内网机器”ssh帐号的密码“password”,就可以在公网VPS上实现到内网机器的ssh连接

  2、正向代理:“个人笔记本”===>“公网VPS”

  在“个人笔记本”上配置:[App ~] # ssh -p 6666 -qngfNTD 6767 VPS-user@VPS,这样,访问“个人笔记本”本机(127.0.0.1)端口6767的流量就流向了“内网机器”

  但是目前,上面配置是不生效的,因为“公网VPS”的端口6666,只允许它自己访问。解决办法有两个:

  a、思路:修改“公网VPS”的配置sshd_config,使其建立的SSH端口供所有IP访问

     方法:把“公网VPS”配置文件/etc/ssh/sshd_config里的配置“GatewayPorts no”修改为“GatewayPorts yes”,重新执行步骤1,执行完查看“公网VPS”的6666端口如下

    [sshd server ~]# netstat -anpt | grep 6666
    tcp        0      0 0.0.0.0:6666              0.0.0.0:*                   LISTEN      10703/sshd

  b、思路:不修改“公网VPS”的配置sshd_config,仍然采用默认配置“GatewayPorts no”,在“公网VPS”上增加一个本地端口映射,使新增加的端口供所有IP访问,或者供特定的IP访问

     方法:在“公网VPS”上配置:[sshd server~] # ssh -fCNL *:6667:localhost:6666 localhost,这一步执行需要“公网VPS”的root帐号密码

     查看“公网VPS”的进程和端口情况:

   [sshd server ~]# netstat -anpt | grep 6667
     tcp        0      0 0.0.0.0:6667              0.0.0.0:*                   LISTEN      1073/sshd

     [ssh server ~]# ps aux | grep "ssh -p"
     root     14594  0.0  0.0  59856  1056 ?        Ss   11:16   0:00  ssh -fCNL *:6667:localhost:6666 localhost

    然后重复执行步骤2,不过端口由6666修改为6667

    [App ~] # ssh -p 6667 -qngfNTD 6767 VPS-user@VPS,这样,访问“个人笔记本”本机(127.0.0.1)端口6767的流量就流向了“内网机器”

这个时候在“内网机器”上开启80端口的服务[ssh clinet~]# python -m SimpleHTTPServer 80

在“个人笔记本”上配置浏览器代理,要选用“socks5”

然后访问

   

五、保持连接的网络稳定

方法一、客服端发“心跳”,配置ssh_config

使用SSH客户端的ServerAliveInterval和ServerAliveCountMax选项。 ServerAliveInterval会在隧道无通信后的一段设置好的时间后发送一个请求给服务器要求服务器响应。如果服务器在 ServerAliveCountMax次请求后都没能响应,那么SSH客户端就自动断开连接并退出,将控制权交给你的监控程序。这两个选项的设置方法分别是在ssh时加入-o ServerAliveInterval=n和-o ServerAliveCountMax=m。其中n, m可以自行定义

方法二、服务端发“心跳”:配置sshd_config

ClientAliveInterval 60 服务器端向客户端请求消息的时间间隔为60秒

ClientAliveCountMax 3 表示服务器发出请求后客户端没有响应的次数达到3次, 就自动断开

这样的配置就能让一个SSH的配置保持长连接了

六、ssh配置含义:

-f 后台运行,后台认证用户/密码,通常和-N连用,不用登录到远程主机,将ssh转到后台运行,即认证之后,ssh 自动以后台运行。不再输出信息 告诉SSH客户端在后台运行

-C 允许压缩数据

-R 将端口绑定到远程服务器,反向代理,将远程主机(服务器)的某个端口转发到本地端指定机器的指定端口。工作原理是这样的, 远程主机上分配了一个socket侦听port端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去,同本地主机host的hostport端口建立连接。可以在配置文件中指定端口的转发。

-L 将端口绑定到本地客户端,正向代理,将本地机(客户机)的某个端口转发到远端指定机器的指定端口。工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 同远程主机host的hostport端口建立连接。可以在配置文件中指定端口的转发。

-L X:Y:Z的含义是,将IP为Y的机器的Z端口通过中间服务器映射到本地机器的X端口。

-D port指定一个本地机器 “动态的’’应用程序端口转发,工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 根据应用程序的协议可以判断出远程主机将和哪里连接。

-n 将 stdio 重定向到 /dev/null,与 -f 配合使用

-N 不执行脚本或命令,即通知 sshd 不运行设定的 shell 通常与 -f 连用,告诉SSH客户端,这个连接不需要执行任何命令。仅仅做端口转发

-T 不分配 TTY 只做代理用

-q 安静模式,不输出错误/警告信息

-g  在-L/-R/-D参数中,允许远程主机连接到建立的转发的端口,如果不加这个参数,只允许本地主机建立连接

通过远程主机1跳到远程主机2:

命令格式:

ssh -t remoteserver1 ssh remoteserver2

说明:当远程主机remoteserver2无法直接到达时,可以使用-t参数,然后由remoteserver1跳转到remoteserver2。在此过程中要先输入remoteserver1的密码,然后再输入remoteserver2的密码,然后就可以操作remoteserver2了。

man sshd_config

man 5 shells

图示,正向代理:ssh -L

图示,反向代理:ssh -R

参考:

1、http://lvii.github.io/system/2013/10/08/ssh-remote-port-forwarding/

2、http://bobao.360.cn/learning/detail/4234.html

3、https://segmentfault.com/a/1190000002718360

4、http://www.dirk-loss.de/ssh-port-forwarding.htm

使用ssh从外网访问内网的更多相关文章

  1. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  2. 配置多层NAT和端口映射实现外网访问内网

    配置多层NAT和端口映射实现外网访问内网 背景和原理 通过配置NAT可以实现内网中不能直接访问外网的主机通过NAT代理访问内网,配置方法这里不再赘述(前文有介绍).本文以两层的NAT代理做模拟,通过端 ...

  3. [笔记] 使用frp从外网访问内网

    之前尝试过otunnel,也记录过使用方法,见[笔记] 使用otunnel从外网访问内网,但是用了几天发现还是不够稳定. 然后尝试frp,发现性能稳定,够用,将过程及配置分享在这里吧. 需求 内网机器 ...

  4. [笔记] 使用otunnel从外网访问内网

    需求 内网机器没有公网IP,但是可以访问外网,现在需要从外网访问内网机器. 举例,在家里机器A访问公司内网机器B. 前提 需要一台有公网IP的服务器S做中转,这样就可以打通AB两端了. A <- ...

  5. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  6. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  7. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  8. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  9. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  10. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

随机推荐

  1. MOCTF-火眼金睛

    MOCTF-火眼金睛 http://119.23.73.3:5001/web10/ 把这个题目当作python爬虫来练习. 首先要获取到文本框里面的全部信息, import requests impo ...

  2. [oldboy-django][4python面试]有关csrf跨站伪造请求攻击

    1 csrf定义 - csrf定义:Cross Site Request Forgery,跨站请求伪造 举例来说: 网站A伪造了一个图片链接: <a href="http://www. ...

  3. Python设计模式之一(单例模式)

    单例模式就是告诉你,只有一个对象 (1)单例模式不适用的场景 #单例模式就是告诉你,其实只有一个对象 class Person: def __init__(self,name,age): self.n ...

  4. PAT1033

    旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现.现在给出应该输入的一段文字.以及坏掉的那些键,打出的结果文字会是怎样? 输入格式: 输入在2行中分别给出坏掉的那些键.以及应该输入的文 ...

  5. 【转】unity自带寻路Navmesh入门教程(一)

    http://liweizhaolili.blog.163.com/blog/static/16230744201271161310135/ 说明:从今天开始,我阿赵打算写一些简单的教程,方便自己日后 ...

  6. VS2015 +.NETMVC5 +EF实践

    -- 当做笔记,以上图片按照顺序来的. 跟着 http://www.cnblogs.com/sanshi/ 一步步来的

  7. grep_awk_sed文本处理

    小技巧 1.删除0字节文件find -type f -size 0 -exec rm -rf {} \; 2.查看进程按内存从大到小排列ps -e -o “%C : %p : %z : %a”|sor ...

  8. 【翻译】Apache软件基金会1

    最近有点看不进去书,所以就找点东西翻译下,正好很想了解Apache基金会都有什么开源项目,每天找点事时间翻译翻译,还可以扩展下视野. 今天就看了两个,第一个是关于.NET的,不再兴趣范围内.第二个还挺 ...

  9. 逆向中静态分析工具——IDA初学者笔记之字符串分析

    逆向中静态分析工具——IDA初学者笔记之字符串分析 程序中往往包含很多字符串资源,这些资源存在于PE文件的rdata段,使用IDA反编译后,可以查找到这些字符串, 逆向破解程序通常需要一个突破点,而这 ...

  10. readonly和disabled区别

    1.readonly属性只对表单元素的文本框.密码框和 textarea 有效,而disabled属性对所有的表单元素都会有效. 2.设置两个属性的外观不一样,这个自己可以观察一下. 3.设置read ...