golang实现简单可靠的SSH隧道与嵌入式SSH服务器插件rospo的使用

Golang实现简单可靠的SSH隧道与嵌入式SSH服务器插件Rospo的使用

Rospo简介

Rospo是一个用于创建安全可靠SSH隧道的工具,单个二进制文件同时包含客户端和服务器功能。它的目标是让SSH隧道变得有趣且易于理解。

Go Reference Go Report Card

主要特性

  • 易于使用(单一二进制文件实现客户端/服务器功能)
  • 通过ssh加密连接(使用crypto/ssh包)
  • 自动连接监控保持始终在线
  • 嵌入式sshd服务器
  • 支持正向和反向隧道
  • 支持跳板机(JumpHosts)
  • 支持命令行选项或人类可读的yaml配置文件
  • 支持作为Windows服务运行
  • 在Windows上通过conpty api支持Pty
  • 服务器端支持SFTP子系统
  • 客户端支持文件传输(get和put sftp子命令)
  • 通过SSH提供SOCKS5/SOCKS4代理服务器
  • 支持DNS over SSH代理

安装方法

Rospo全面支持*nix系统和Windows 10+。

macOS

使用Homebrew安装:

brew install rospo

GNU/Linux

下载二进制文件:

平台 架构
GNU/Linux amd64
arm64
arm

Microsoft Windows

下载二进制文件:

平台 架构
Microsoft Windows amd64

Docker容器

可以使用Docker镜像:

docker run ghcr.io/ferama/rospo --help

快速使用示例

Rospo支持基于密钥的认证和密码认证。基于密钥的认证始终是首选。

启动嵌入式SSH服务器并反向代理端口

$ rospo revshell user@server:port

将本地5000端口转发到远程服务器的6000端口

$ rospo tun forward -l :5000 -r :6000 user@server:port

获取详细帮助

$ rospo tun forward --help
$ rospo tun reverse --help
$ rospo sshd --help

使用配置文件

对于更复杂的用例和更多选项,可以使用配置文件:

$ rospo run config.yaml

使用场景示例

Windows反向Shell

假设你有一个Windows WSL实例,你想远程访问而不需要复杂的防火墙设置和其他麻烦。使用Rospo,只需一个简单的步骤:

$ rospo revshell remote_ssh_server

这个命令将在你的WSL实例上运行一个嵌入式sshd服务器,并将其端口反向代理到remote_ssh_server

Windows服务

Rospo支持在Windows上作为服务运行。这意味着你可以创建一个持久隧道,可以安装为服务并随机器自动启动。

创建Rospo配置文件:

sshclient:
  server: your-rospo-or-sshd-server-uri:2222
  identity: "c:\\absolute_path_to_your\\id_rsa"
  known_hosts: "C:\\absolute_path_to_your\\known_hosts"

tunnel:
  - remote: :3389
    local: :3389  # Windows远程桌面端口
    forward: false

以管理员权限启动PowerShell,执行以下操作:

# 创建rospo服务
sc.exe create rospo start= auto DisplayName= Rospo binpath= "C:\rospo.exe run C:\conf.yaml"

# 启动服务
sc.exe start rospo

# 查询服务状态
sc.exe query rospo

# 停止并删除服务
sc.exe stop rospo; sc.exe delete rospo

多个复杂隧道

Rospo支持在同一个SSH连接上建立多个隧道。要充分利用Rospo处理更复杂的情况,应该/需要使用场景配置文件。

创建config.yaml文件:

sshclient:
  server: myuser@remote_server_address
  identity: "~/.ssh/id_rsa"
  jump_hosts:
    - uri: anotheruser@jumphost_address
      identity: "~/.ssh/id_rsa"

tunnel:
  - remote: ":8000"
    local: ":8000"
    forward: yes
  - remote: ":9999"
    local: ":9999"
    forward: yes
  - remote: ":5000"
    local: ":5000"
    forward: no
    # 为此隧道使用自定义sshclient
    sshclient:
      server: myuser@another_server
      identity: "~/another_identity"

# 启动socks代理...
socksproxy:
  listen_address: :1080
  # ...使用专用客户端
  sshclient:
    server: localhost:9999

使用配置文件启动Rospo:

$ rospo run config.yaml

总结

Rospo是一个功能强大且易于使用的工具,可以简化SSH隧道的创建和管理。无论是简单的端口转发还是复杂的多隧道场景,Rospo都能提供安全可靠的解决方案。通过其嵌入式SSH服务器功能,Rospo特别适合需要远程访问的场景,如Windows WSL或远程桌面服务。


更多关于golang实现简单可靠的SSH隧道与嵌入式SSH服务器插件rospo的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang实现简单可靠的SSH隧道与嵌入式SSH服务器插件rospo的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang实现SSH隧道与嵌入式SSH服务器插件rospo

SSH隧道实现

SSH隧道(端口转发)是一种常用的安全通信方式,下面是一个简单的Golang实现示例:

package main

import (
	"fmt"
	"golang.org/x/crypto/ssh"
	"log"
	"net"
)

func main() {
	// SSH客户端配置
	config := &ssh.ClientConfig{
		User: "username",
		Auth: []ssh.AuthMethod{
			ssh.Password("password"),
		},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	}

	// 连接到SSH服务器
	client, err := ssh.Dial("tcp", "ssh-server:22", config)
	if err != nil {
		log.Fatal("Failed to dial: ", err)
	}
	defer client.Close()

	// 监听本地端口
	localListener, err := net.Listen("tcp", "localhost:8080")
	if err != nil {
		log.Fatal("Failed to listen locally: ", err)
	}
	defer localListener.Close()

	fmt.Println("SSH tunnel established. Forwarding localhost:8080 to remote:80")

	// 接受本地连接并转发
	for {
		localConn, err := localListener.Accept()
		if err != nil {
			log.Fatal("Failed to accept local connection: ", err)
		}

		go func() {
			// 建立到远程端口的连接
			remoteConn, err := client.Dial("tcp", "localhost:80")
			if err != nil {
				log.Fatal("Failed to dial remote: ", err)
			}

			// 双向转发数据
			go copyConn(localConn, remoteConn)
			go copyConn(remoteConn, localConn)
		}()
	}
}

func copyConn(dst, src net.Conn) {
	defer dst.Close()
	defer src.Close()
	_, err := io.Copy(dst, src)
	if err != nil {
		log.Println("Copy error:", err)
	}
}

嵌入式SSH服务器 - rospo

rospo是一个轻量级的Golang库,用于创建嵌入式SSH服务器和隧道。以下是使用rospo的示例:

安装rospo

go get github.com/ferama/rospo

基本使用示例

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/ferama/rospo/pkg/sshd"
)

func main() {
	// 创建SSH服务器配置
	server := sshd.SshD{
		Key:          "./id_rsa", // SSH密钥路径
		ListenAddr:   ":2222",    // 监听地址
		AuthorizedKeys: "./authorized_keys", // 授权密钥文件
		Shell:       "/bin/bash", // 默认shell
	}

	// 启动SSH服务器
	go func() {
		if err := server.Start(); err != nil {
			log.Fatalf("Failed to start SSH server: %v", err)
		}
	}()

	fmt.Println("SSH server started on port 2222")

	// 保持程序运行
	for {
		time.Sleep(1 * time.Second)
	}
}

使用rospo创建隧道

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/ferama/rospo/pkg/sshd"
	"github.com/ferama/rospo/pkg/tunnel"
)

func main() {
	// 1. 启动SSH服务器
	server := sshd.SshD{
		Key:          "./id_rsa",
		ListenAddr:   ":2222",
		AuthorizedKeys: "./authorized_keys",
	}
	go server.Start()

	// 2. 创建本地到远程的隧道(本地端口转发)
	localTunnel := tunnel.Tunnel{
		Local:  "localhost:8080",  // 本地监听地址
		Remote: "example.com:80",  // 远程目标地址
		Server: "localhost:2222",  // SSH服务器地址
		Key:    "./id_rsa",        // 用于认证的私钥
	}
	go localTunnel.Start()

	// 3. 创建远程到本地的隧道(远程端口转发)
	remoteTunnel := tunnel.Tunnel{
		Remote: "0.0.0.0:9090",    // 远程监听地址
		Local:  "localhost:3000",   // 本地目标地址
		Server: "localhost:2222",   // SSH服务器地址
		Key:    "./id_rsa",         // 用于认证的私钥
		Reverse: true,              // 设置为反向隧道
	}
	go remoteTunnel.Start()

	fmt.Println("Tunnels established:")
	fmt.Println("- Local 8080 -> example.com:80")
	fmt.Println("- Remote 9090 -> localhost:3000")

	// 保持程序运行
	for {
		time.Sleep(1 * time.Second)
	}
}

安全注意事项

  1. 在生产环境中,应该使用更安全的认证方式,如公钥认证而非密码
  2. 考虑实现主机密钥验证,避免中间人攻击
  3. 限制可以访问SSH服务器的IP地址
  4. 使用强密码或密钥
  5. 定期轮换密钥

rospo提供了更多高级功能,如:

  • 动态端口转发(SOCKS代理)
  • 连接保持和自动重连
  • 多路复用连接
  • 连接监控和管理

可以根据项目需求进一步探索rospo的文档和示例。

回到顶部