linux ssh端口转发的三种方式
ssh是我使用最频繁的两个命令行工具之一(另一个则必须是vim)。有了ssh,我可以远程处理各种可能出现的问题而无需肉身到现场。
这几天teamviewer被黑的事情影响挺大,于是由远程控制想到了内网穿透,自然而然的想到了ssh的端口转发也能实现内网穿透。再细想一下,发现ssh隧道、或者说端口转发,竟然实现了正向代理、反向代理和内网穿透三种常用的网络功能,更佩服其功能的强大和使用中的便利。
ssh有三种端口转发模式,本文一一对其做简要介绍。
本地转发
本地端口转发(Local Port Forwarding),是将本地主机某个端口流量转发到远程主机的指定端口。其命令行语法是:-L [bind_address]:localport:[remote_host]:remote_port。”-L”即“local”的首字母,类似的远程转发的”-R”是“remote”的首字母,动态转发的“-D”是“dynamic”的首字母,很好记。
举一个例子说明本地转发的使用场景。
CentOS 7安装GUI界面及远程连接一文中介绍了安装vnc服务并开启端口访问。在实际中,暴露出来的59xx端口每天都会源源不断的受到自动化脚本的爆破攻击。如果你的vnc和登录用户使用弱密码或字典密码,主机安全将受到极大威胁。这种情形下该如何防护?
一种简单安全的防护方法是:使用iptables/firewalld关闭端口的外网访问,有连接需求时用ssh隧道转发端口:
ssh -L5901:5901 username@host
该命令中将本地的5901端口通过ssh隧道转发到远程主机的5901端口,远程连接时输入localhost或者127.0.0.1和5901端口便连到了远程主机的5901端口。通过iptables和ssh的本地转发,实现了他人无法连接,只有自己才能访问的目的。
需要注意的是“-L”选项中的“远程主机”并不特指连接过去的机器(默认是连接上的机器),可以是任何一主机。例如可以将本机的8080端口流量转发到facebook.com的80端口:
ssh -L8080:facebook.com:80 username@host
远程转发
远程端口转发(Remote Port Forwarding),是将远程主机某个端口转发到远程主机的指定端口。其命令行语法是:-R [bind_address]:port:[local_host]:local_port。
远程转发最常用的功能是内网穿透。有一个公网ip的主机,便可以借助ssh隧道的远程转发实现内网渗透,达到外网访问内网资源的目的。需要注意的是ssh远程转发默认只能绑定远程主机的本地地址,即127.0.0.1。如果想要监听来自其他主机的连接,需要修改远程主机ssh的配置,将”GatewayPorts”改成“yes”,重启ssh后生效。
一个将远程的8080端口流量转发到本地80web端口的示例:
ssh -R0.0.0.0:8080:80 username@host
通过远程转发,访问公网ip主机的8080端口便是访问内网web主机的80端口,这样就实现了内网穿透。
动态转发
无论本地转发还是远程转发,都需要指定本地和远程主机的端口。动态转发(Dynamic Port Forwarding)则摆脱这种限制,只绑定本地端口,远程主机和端口由发起的请求决定。动态转发的语法是:”-D bind_address:port”,一个转发示例:
ssh -D 8080 username@host
该命令让ssh监听本地8080端口,经过8080端口的流量都通过ssh隧道由远程服务器代为请求,从而达到获取被屏蔽资源、隐藏真实身份的目的。
动态转发实际上实现了正向代理功能,因此可以用来访问国外网络。本地转发也可以做正向代理,但要对每一个请求的主机和端口做转发,比较繁琐,实践中不会这么用。
其它
- 从用户端角度看,本地转发是正向代理;从资源提供方角度看,本地转发是反向代理;
- ssh连接断开远程转发/内网渗透便失效。如果希望远程转发一直有效,需要ssh保活技术,建议用frp等专注于内网渗透的解决方案;
- 虽然ssh隧道中的流量都经过了加密,但防火墙对ssh隧道中承载的流量能比较智能的识别,因此用作访问国外网络很容易受到干扰;
- 如果仅做端口转发,实践中上述命令经常与”-NT -f”选项结合使用。其中”-f”选项将命令放入后台执行,断开连接需要用kill命令;
- 从代理角度看,ssh隧道是低效的,建议用专用软件;
- ssh隧道的流量都经过了加密,从安全角度是十分可靠的。
以上就是本文的全部内容,希望对大家的学习有所帮助。
- DateTime在ExtJs中无法正确序列化的问题
- ELK实时日志分析平台环境部署--完整记录
- 梳理Linux下OSI七层网络与TCP/IP五层网络架构
- 字符编码-使用c#研究
- iframe高度自适应的IE解决方案
- javascript读写本机文本文件
- 崔立鹏:腾讯云为知识竞技游戏提供解决方案
- Mysql之binlog日志说明及利用binlog日志恢复数据操作记录
- 常用的AJAX弹出层代码
- Linux下检测IP地址冲突及解决方法
- linux如何挂载windows下的共享文件
- silverlight2中的定时器,以及如何动态改变控件的坐标
- 定时备份windows机器上的文件到linux服务器上的操作梳理(rsync)
- jQuery1.3以上版本"@"的问题
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Laravel 连接(Join)示例
- 解决Laravel自定义类引入和命名空间的问题
- 详解Laravel服务容器的绑定与解析
- 修改Laravel自带的认证系统的User类的命名空间的步骤
- PHP使用递归按层级查找数据的方法
- Laravel6.2中用于用户登录的新密码确认流程详解
- PHP连接MySQL数据库的三种方式实例分析【mysql、mysqli、pdo】
- 浅谈PHP array_search 和 in_array 函数效率问题
- 仿抖音短视频APP源码,实现简单的换头像并保存
- php实现JWT(json web token)鉴权实例详解
- laravel实现上传图片,并且制作缩略图,按照日期存放的代码
- 在Laravel中使用MongoDB的方法示例
- 基于thinkphp6.0的success、error实现方法
- Yii框架模拟组件调用注入示例
- 解决laravel 表单提交-POST 异常的问题