当前位置: 首页 > news >正文

ubuntu localhost可以访问 ip不能访问_通过两次ssh tunnel访问gateway后主机上的jupyter notebook服务...

9e4fbc8625909e86fb3a51a0bd99ba47.png

一、 问题描述

计算机系的内网访问限制非常严格:

  • 内网的各台机器之间只允许用ssh协议默认的22号端口通信,其它端口会被屏蔽
  • 外网无法直接访问内网机器, 除了"脚踏两只船"的gateway
  • 外网机器与gateway之间也只允许22号端口间的通信

网络拓扑如下图所示:

982b690e256fa6cb8768124e5403f2c2.png
图一:网络拓扑

现在,

  • 我在办公室里有一台机器,我们叫它office_pc,它的ip地址当然是内网ip,假设是10.37.1.2。jupyter notebook运行在9966号端口上。我在该机器上的用户名是raypc。
  • gateway具有公网ip,域名gw.cs.univ.hk,,我在上面的用户名是raygw。
  • 我的本地机器是laptop, 在该机器上的用户名是rayleizhu。

那么,我怎么才能从laptop访问放置在office_pc上的jupyter notebook服务?

二、解决方案

在laptop上依次执行

ssh gw.cs.univ.hk "ssh -N -L 9966:localhost:9966 10.37.1.2"
ssh -N -L 9966:localhost:9966 gw.cs.univ.hk

然后你就可以在浏览器中输入localhost:9966来访问jupyter notebook了。
以上步骤假设你已经将本机的公钥复制到目标远程机器的authorized_keys文件中,因而可以无密码登录ssh, 无论是在gateway上还是在laptop上, 即

  1. 你在gateway上的公钥包含在office_pc的~/.ssh/authorized_keys文件中。
  2. 你在laptop上的公钥包含在gateway的~/.ssh/authorized_keys文件中。

如果1不成立, 那么在执行上述两条命令前, 你应该先在gateway上执行

ssh-copy-id raypc@10.37.1.2

类似地,如果2不成立,则要在laptop上执行

ssh-copy-id raygw@gw.cs.univ.hk

三、解释

图示如下。实际上是分别在offiice_pc与gateway之间以及gateway与laptop之间建立了 ssh tunnel。

dd272613354b1f1f491a517a46efb6f9.png
图二:通过两次ssh tunnel连接jupyter notebook服务

关于ssh tunnel或称端口转发,可以参考[1]。简单来说,

ssh -L localport:remotehost:remoteport username@middlehost

这条命令建立起了localhost:localport <--> localhost:22 <--> middlehost:22 <--> remotehost:remoteport的双向数据链路,如下图所示

c01f765b4382c9d6a548aefa4cbb182a.png
图三:ssh tunnel图示

其中F1, F3, B1, B3段的数据是未加密的,F2, B2上段的数据被ssh加密。

四、思考

  • 为什么下面这条命令不能实现上面所述的需求?
ssh -L -N 9966:l0.37.1.2:9966 raygw@gw.cs.univ.hk

提示: 图三中的链路(F1-3, B1-3)的哪部分出了问题?

  • 如果将内网机器之间只能用22号端口通信的限制去掉,上面的命令能够工作吗?

五、其他

用ssh用户配置文件设置快捷ssh会话参考[2],将ssh tunnel变成守护进程参考[3]和[4]。

六、参考

  1. SSH原理与运用(二):远程操作与端口转发 - 阮一峰的网络日志
  2. 利用 SSH 的用户配置文件 Config 管理 SSH 会话
  3. Create SSH tunnels using systemd units – github
  4. systemd: Grant an unprivileged user permission to alter one specific service Ask – severfault

相关文章:

  • python形参和实参的含义_Python3函数的形参如何接收实参?
  • 在python将字符串中的空格转换为下划线_如何将下划线替换为空格,反之亦然?...
  • python图像锐化_opencv实现图片模糊和锐化操作
  • python中configparser函数_python基础14 ---函数模块4(configparser模块)
  • python接口自动化测试报告_python接口自动化(二十七)--html 测试报告——上(详解)...
  • python中的常量和变量_python中的常量和变量代码详解
  • 常用公差配合表图_《公差配合与测量技术》小结
  • pythonassert关键字_Python assert实现软件测试
  • php 设置会员到期_支付宝推出“轻会员”,先享受优惠再交会员费
  • 很装b那种cmd命令_CMD命令混淆分析
  • 宏定义判定x是否为整数_整数与整数都还差不多从“高斯整数”到“代数整数”...
  • python 邻接矩阵_用Python做社会网络分析(1):简介
  • python投掷骰子实验报告_用Python来掷个色子玩~
  • qt 录屏 显示鼠标_Qt官方示例系统托盘
  • redis两台机器集群_redis4.0 cluster集群安装方法
  • 深入了解以太坊
  • 10个最佳ES6特性 ES7与ES8的特性
  • Hexo+码云+git快速搭建免费的静态Blog
  • idea + plantuml 画流程图
  • Java知识点总结(JavaIO-打印流)
  • php ci框架整合银盛支付
  • socket.io+express实现聊天室的思考(三)
  • Webpack 4x 之路 ( 四 )
  • Yii源码解读-服务定位器(Service Locator)
  • 算法---两个栈实现一个队列
  • 再谈express与koa的对比
  • puppet连载22:define用法
  • Python 之网络式编程
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #### golang中【堆】的使用及底层 ####
  • #14vue3生成表单并跳转到外部地址的方式
  • #pragma data_seg 共享数据区(转)
  • (C语言)strcpy与strcpy详解,与模拟实现
  • (delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型第2节(泛型类的类构造函数)
  • (第一天)包装对象、作用域、创建对象
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (算法)硬币问题
  • (一)Linux+Windows下安装ffmpeg
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • (转)3D模板阴影原理
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • (转)iOS字体
  • (转)ObjectiveC 深浅拷贝学习
  • (自适应手机端)响应式服装服饰外贸企业网站模板
  • . Flume面试题
  • .bat批处理(三):变量声明、设置、拼接、截取
  • .mysql secret在哪_MYSQL基本操作(上)
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .net 连接达梦数据库开发环境部署
  • .NET 应用启用与禁用自动生成绑定重定向 (bindingRedirect),解决不同版本 dll 的依赖问题
  • .NET面试题解析(11)-SQL语言基础及数据库基本原理
  • .NET使用存储过程实现对数据库的增删改查
  • @EnableConfigurationProperties注解使用