golang实现简单可靠的SSH隧道与嵌入式SSH服务器插件rospo的使用
Golang实现简单可靠的SSH隧道与嵌入式SSH服务器插件Rospo的使用
Rospo简介
Rospo是一个用于创建安全可靠SSH隧道的工具,单个二进制文件同时包含客户端和服务器功能。它的目标是让SSH隧道变得有趣且易于理解。
主要特性
- 易于使用(单一二进制文件实现客户端/服务器功能)
- 通过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
更多关于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)
}
}
安全注意事项
- 在生产环境中,应该使用更安全的认证方式,如公钥认证而非密码
- 考虑实现主机密钥验证,避免中间人攻击
- 限制可以访问SSH服务器的IP地址
- 使用强密码或密钥
- 定期轮换密钥
rospo提供了更多高级功能,如:
- 动态端口转发(SOCKS代理)
- 连接保持和自动重连
- 多路复用连接
- 连接监控和管理
可以根据项目需求进一步探索rospo的文档和示例。