服务器(容器)开发指南——SSH打洞开发

文章目录

  • SSH容器服务打包
    • 测试服务文件
    • 镜像打包
  • SSH打洞开发
    • 部署带SSH的容器
    • SSH连接服务器(容器内部)
      • SSH访问容器内的缺陷
    • IDE远程SSH开发
      • VSCode远程SSH开发
      • Jetbrains系列产品SSH远程开发

在进行定制化的服务开发时,我们有时候只能在固定的服务器上进行服务的开发。此时,通过命令行的方式进行开发的难度较大。我们可以考虑通过SSH打洞的方式,通过本地IDE的SSH连接功能来获取远程的环境进行代码的开发修改。
随着容器化技术的发展,越来越多的产品服务打包进容器内运行,对容器内部代码的定制化开发需求越来越多。容器本身可以简单理解为一个更轻量的虚拟机,针对容器的定制化开发的实现也可以参考服务器开发相关技术。
本文为更好的讲解SSH打洞开发的方式,采用容器化开发技术进行讲解。

SSH容器服务打包

测试服务文件

为更好的测试SSH打洞功能,特开发一个简易的Python的Flask框架脚本以供测试。
requirements.txt:

Flask==2.3.2

app.py

from flask import Flaskapp = Flask(__name__)@app.route("/")
def hello():return "Hello World!"if __name__ == "__main__":app.run(host="0.0.0.0", port=5000, debug=True)

Flask在启动时,默认绑定127.0.0.1:5000的IP和端口。当启动容器的ports参数进行端口映射时,会将容器内绑定在0.0.0.0IP上的服务映射到主机端口上而不是容器内的127.0.0.1,所以我们在启动Flask或相关服务时,需要指定绑定host为0.0.0.0
.entrypoint.sh

cd /data# 启动SSH服务
/etc/init.d/ssh start# 启动Flask服务
python app.py
  • 启动SSH服务和Flask服务的顺序不能更改。直接调用python app.py会启动一个前台进程,若python app.py命令在前,其后的启动/etc/init.d/ssh start命令将不会执行。
  • 容器在启动时会执行CMDENTRYPOINT中指定的命令启动一个PID=1的守护进程,该进程负责整个容器的初始化,监控子进程运行情况,信号传输、退出容器等操作。当这个进程销毁时,整个容器也会停止运行,所以一般情况下,需要在启动的命令或脚本中启动一个一直运行的守护进程,保证PID=1的进程不会因为执行完毕而默认销毁导致容器的停止。
  • python app.py命令在这里主要就是作为守护进程的存在确保PID=1的进程不会主动销毁。
    • 以Flask程序作为守护进程固然可以很好的使容器运行起来,但是当我们在进行开发时,可能会多次重启Flask进程以测试代码,此时一旦最开始的Flask进程关闭,PID=1进程也会主动销毁,导致容器退出
    • 当容器内包含有Python服务时,我们可以通过Python自带的脚本启动一个简易的守护进程,其他服务也可以参考启动一个守护进程来代替应用程序的守护进程

优化后.entrypoint.sh

cd /data# 启动SSH服务
/etc/init.d/ssh start# 启动Flask服务
nohup python app.py &# 启动python自带脚本http.server作为守护进程
python -m http.server

镜像打包

镜像打包文件

# 接收docker build参数
ARG ROOT_PASSWORD=focusFROM python:3.8.17# 重新声明所有参数以继承入口的参数传递
ARG ROOT_PASSWORDCOPY ./data /dataWORKDIR /data# 安装操作系统依赖库
RUN  \apt update && \apt -y upgrade && \# 安装SSHapt -y install sudo openssh-client openssh-server sshpass && \pip install -r /data/requirements.txt && \# root免密设置echo "root ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers && \# 设置root密码echo "root:${ROOT_PASSWORD:-focus}" | chpasswd && \# ssh配置修改# 允许root用户登录sed -i "/PermitRootLogin/c PermitRootLogin yes" /etc/ssh/sshd_config && \# 允许使用密码登录sed -i "/PasswordAuthentication/c PasswordAuthentication yes" /etc/ssh/sshd_configCMD [ "sh", "/data/.entrypoint.sh" ]
  • 打包镜像主要是为了在容器中安装SSH相关服务,也可根据现有的镜像启动容器后在容器内安装SSH服务(需要每次新建容器后都要安装)
# 允许root用户登录
sed -i "/PermitRootLogin/c PermitRootLogin yes" /etc/ssh/sshd_config
# 允许使用密码登录
sed -i "/PasswordAuthentication/c PasswordAuthentication yes" /etc/ssh/sshd_config
  • 以上命令是实现SSH打洞登录的关键,其本质就是修改/etc/ssh/sshd_config文件中的PermitRootLoginPasswordAuthentication配置

镜像打包脚本

docker build . \--platform 'linux/amd64' \--label 'maintainer=focus<https://focus-wind.com/>' \--build-arg 'ROOT_PASSWORD=focus' \--file ./Dockerfile \--tag "python-ssh-tunnel:3.8.17-dev"

SSH打洞开发

部署带SSH的容器

通过上述操作,我们目前已经打包好了一个带有SSH服务的镜像,通过docker compose进行服务的部署。
compose.yaml配置文件

version: '3.8'
services:ssh-tunnel:image: python-ssh-tunnel:3.8.17-devhostname: ssh-tunnelcontainer_name: ssh-tunnelports:- 8080:22- 5000:5000

启动容器

docker compose up -d

SSH连接服务器(容器内部)

通过端口映射,我们将容器内部的22端口映射到了本地的8080端口上。此时,如果我们需要访问容器内部的服务,可以通过指定IP为本机来访问容器内部。

ssh -p 8080 root@localhost

ssh-tunnel
如上所示,我们将容器内部的SSH的22端口映射到宿主机后,通过访问宿主机的相应端口即可进入到容器内部中。

SSH访问容器内的缺陷

通过上图SSH连接容器内部时的输出可以看到,SSH客户端在连接服务端时自动生成了SSH公钥。
SSH客户端在首次连接SSH服务端时,客户端会记录服务端返回的公钥保存在~/.ssh/known_hosts文件中,当再次进行SSH连接时客户端都会验证known_hosts文件中的公钥和服务端返回公钥是否一致。由于每次根据镜像新建的容器都是一个全新的容器,此时在进行SSH连接时,会导致返回的公钥和known_hosts文件中的公钥不一致,所以无法进行SSH连接。
若是因known_hosts导致的公钥不一致无法连接的问题,可以编辑~/.ssh/known_hosts文件,删除对应的IP公钥信息重新SSH连接即可。

IDE远程SSH开发

现有的IDE大部分都支持SSH远程开发,现在大部分都开发都是在IDE上进行的开发,IDE提供的环境能够很好的帮助我们提升开发效率。

VSCode远程SSH开发

VSCode自带有远程SSH功能,在VSCode的左侧功能栏的远程资源管理器中可以进行远程SSH操作。

  • 在VSCode的远程资源管理器中,在SSH管理栏右侧点击+按钮新建SSH连接

VSCode-SSH

  • VSCode会默认读取~/.ssh/config文件中已有的SSH配置,在~/.ssh/config文件中添加服务器SSH配置后,刷新即可在远程资源管理器中显示
Host ssh-tunnelHostName localhostUser rootPort 8080# %p: Port %r: User %h: HostNameLocalCommand ssh -p %p %r:%h
  • 通过VSCode连接服务器或内部容器后即可像平常使用VSCode开发一样用VSCode进行集成开发

Jetbrains系列产品SSH远程开发

Jetbrains系统虽然产品众多,但其使用SSH远程开发的逻辑是一致的,这里以PyCharm为例介绍Jetbrains系列产品的SSH远程开发。
Jetbrains-SSH
Jetbrains-SSH-config

  • Jetbrains系列产品打开后在Remote Development的SSH中新建项目完成SSH的创建
  • Jetbrains产品可在Specify private key可选配置项中配置公钥文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/15373.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

没有使用IaC的DevOps系统都是耍流氓 |IDCF

作者&#xff1a;徐磊 文章首发地址&#xff1a;https://smartide.cn/zh/blog/2022-1010-iac/ 作为现代软件工程的基础实践&#xff0c;基础设施即代码&#xff08;Infrastructure as Code, IaC&#xff09;是云原生、容器、微服务以及DevOps背后的底层逻辑。应该说&#xff…

layui框架学习(34:数据表格_基本用法)

Layui中的数据表格模块table支持动态显示并操作表格数据&#xff0c;之前学习的页面元素中的表格主要是通过使用样式及属性对表格样式进行设置&#xff0c;而table模块支持动态显示、分页显示、排序显示、搜索等形式各样的动态操作&#xff0c;参考文献3中也给出了数据表格的各…

Git初始化

查看git版本 git --version 设置Git的配置变量 方法&#xff1a; 修改全局文件&#xff08;用户主目录下.gitconfig&#xff09;修改系统文件&#xff08;如/etc/gitconfig&#xff09; 用户姓名和邮件地址 修改用户名和邮件地址 git config --global user.name "用…

LLM系列 | 18 : 如何用LangChain进行网页问答

简介 一夕轻雷落万丝&#xff0c;霁光浮瓦碧参差。 紧接之前LangChain专题文章&#xff1a; 15:如何用LangChain做长文档问答&#xff1f;16:如何基于LangChain打造联网版ChatGPT&#xff1f;17:ChatGPT应用框架LangChain速成大法 今天这篇小作文是LangChain实践专题的第4…

Qt: 查看qmake相关参数设置

Qt开发中&#xff0c;经常会遇到qmake相关问题&#xff0c;比如同时安装了多个Qt版本的情况。比如我的情况是系统自带了Qt 5.12.8, 但是开发中遇到一些兼容性问题&#xff0c;于是又手动安装了5.9.8。 查看qmake版本&#xff0c;qmake -v, 虽然项目中已经指定了5.9.8, 但是系统…

爬虫小白-如何调试列表页链接与详情链接不一样并三种方式js逆向解决AES-ECB

目录 一、网站分析二、定位监听三、熟悉AES-ECB四、调试分析五、node运行js六、Python执行js 一、网站分析 三年前的案例&#xff0c;我的原始文章网站 &#xff0c;如图我们直接点击标题进入到详情页&#xff0c;链接会发生跳转&#xff0c;且与我们在详情看到的链接&#xf…

iOS开发-格式化时间显示刚刚几分钟前几小时前等

iOS开发-格式化时间显示刚刚几分钟前几小时前等 在开发中经常遇到从服务端获取的时间戳&#xff0c;需要转换显示刚刚、几分钟前、几小时前、几天前、年月日等格式。 主要用到了NSCalendar、NSDateComponents这两个类 NSString *result nil;NSCalendarUnit components (NSC…

【后端面经】微服务构架 (1-6) | 隔离:如何确保心悦会员体验无忧?唱响隔离的鸣奏曲!

文章目录 一、前置知识1、什么是隔离?2、为什么要隔离?3、怎么进行隔离?A) 机房隔离B) 实例隔离C) 分组隔离D) 连接池隔离 与 线程池隔离E) 信号量隔离F) 第三方依赖隔离二、面试环节1、面试准备2、基本思路3、亮点方案A) 慢任务隔离B) 制作库与线上库分离三、章节总结 …

以智慧监测模式守护燃气安全 ,汉威科技“传感芯”凸显智慧力

城市燃气工程作为城市基建的重要组成部分&#xff0c;与城市居民生活、工业生产紧密相关。提升城市燃气服务质量和安全水平&#xff0c;也一直是政府和民众关注的大事。然而&#xff0c;近年来居民住宅、餐饮等工商业场所燃气事故频发&#xff0c;时刻敲响的警钟也折射出我国在…

MySQL高级篇第4章(逻辑架构)

文章目录 1、逻辑架构剖析1.1 服务器处理客户端请求1.2 Connectors1.3 第一层&#xff1a;连接层1.4 第二层&#xff1a;服务层1.5 第三层&#xff1a;引擎层1.6 存储层1.7 小结 2、SQL执行流程2.1 MySQL 中的 SQL执行流程2.2 MySQL8中SQL执行原理2.3 MySQL5.7中SQL执行原理2.4…

9条建议告诉你如何正确处理PCB设计布线

一、关于PCB布线线宽 1、布线首先应满足工厂加工能力&#xff0c;首先向客户确认生产厂家&#xff0c;确认其生产能力&#xff0c;如图1所示。如客户无要求&#xff0c;线宽参考阻抗设计模板。 图1 PCB板厂线宽要求 2、阻抗模板&#xff0c;根据客户提供的板厚及层数要求&…

LeetCode208.Implement-Trie-Prefix-Tree<实现 Trie (前缀树)>

题目&#xff1a; 思路&#xff1a; tire树&#xff0c;学过&#xff0c;模板题。一种数据结构与算法的结合吧。 代码是&#xff1a; //codeclass Trie { private:bool isEnd;Trie* next[26]; public:Trie() {isEnd false;memset(next, 0, sizeof(next));}void insert(strin…

【环境配置】使用Docker搭建LAMP环境

这篇文章不是介绍DOCKER是什么&#xff0c;也不是阐述DOCKER的核心&#xff1a;镜像/容器和仓库之间的关系,它只是一篇让刚刚接触DOCKER的初学者&#xff0c;在没有完全了解DOCKER是什么之前,也能尽快的在Linux系统下面通过DOCKER来搭建一个LAMP环境&#xff0c;这是其一&#…

工作中遇到的关于配置问题

工作中遇到的问题 想记录一下 一个程序员小白每天遇到的问题 1.创建了一个Maven的web工程&#xff0c;但是启动一直是404&#xff0c;原服务器未能找到目标资源 解决办法&#xff1a; 选择deployment&#xff0c;点击加号选择war格式就OK啦 目录里面无法创建类&#xff0…

深蓝学院C++基础与深度解析笔记 第13章 模板

1. 函数模板 ● 使用 template 关键字引入模板&#xff1a; template<typename T> //声明&#xff1a;T模板形参void fun(T); // T 函数形参template<typename T> //定义void fun(T) {...}– 函数模板不是函数 –…

【C/C++】类之间的纵向关系——继承的概念

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

分享一篇详尽的关于如何在 JavaScript 中实现刷新令牌的指南

介绍 刷新令牌允许用户无需重新进行身份验证即可获取新的访问令牌&#xff0c;从而确保更加无缝的身份验证体验。这是通过使用长期刷新令牌来获取新的访问令牌来完成的&#xff0c;即使原始访问令牌已过期也是如此。 通常&#xff0c;当用户登录时&#xff0c;服务器会生成一对…

CentOS 8 上安装 Nginx

Nginx是一款高性能的开源Web服务器和反向代理服务器&#xff0c;以其轻量级和高效能而广受欢迎。在本教程中&#xff0c;我们将学习在 CentOS 8 操作系统上安装和配置 Nginx。 步骤 1&#xff1a;更新系统 在安装任何软件之前&#xff0c;让我们先更新系统的软件包列表和已安…

关于提示词 Prompt

Prompt原则 原则1 提供清晰明确的指示 注意在提示词中添加正确的分割符号 prompt """ 请给出下面文本的摘要&#xff1a; <你的文本> """可以指定输出格式&#xff0c;如&#xff1a;Json、HTML提示词中可以提供少量实例&#xff0c;…

nosql之redis集群

文章目录 一.redis集群1.单节点redis服务器带来的问题2.集群redis3.集群的优势4.redis集群的实现方法5.redis群集的三种模式5.1 主从复制5.2 哨兵5.3 集群 二.Redis 主从复制1.主从复制概念2.主从复制的作用3.主从复制流程4.搭建Redis 主从复制4.1 安装 Redis4.2 修改 Redis 配…