SSH隧道

客户端监控方法

Linux下客户端的连接方法:

ssh -fN -D 7070 -p port user@host

在客户端建立的SSH隧道可能会死掉。需要一些监控和重启手段。可以用autossh来帮助监控和重启隧道。尽管如此,连接还是会出问题,可用以下办法来检查问题:

tail -f /var/log/syslog

autossh的log在这里。

ps ww `pgrep ssh`

查看ssh进程情况。

ss -ap dport = :socks or sport = :socks or dport = :ssh | column -t

查看SOCKS端口连接情况以及SSH服务器连接情况。注意观察TCP的State,来得知连接的状态;看Recv-QSend-Q也可以看出是否阻塞。

autossh(1)中写到当ssh正常退出时,autossh也正常退出而不是重启。如果发现连接不通,用killall ssh后,ssh退出且返回值为0,这样autossh也就退出了,还得再启动。见下面的syslog:

Jun 13 00:00:47 dell autossh[9682]: ssh exited with status 0; autossh exiting

同时autossh(1)中也说,autossh收到SIGUSR1信号时,它会杀死ssh进程并启动一个新的。所以当连接不通的时候,不要killall ssh,而直接killall -SIGUSR1 autossh就好了。

有时候到服务器的连接一直就SYN着,是不是服务器的TCP backlog满了呢?参看TCP/IP Illustrated P257 Incoming Connection Request Queue。

服务器端SSH Tunnel用户的添加

服务器上OpenSSH服务要打开AllowTcpForwarding选项,这个选项默认是yes。

服务端用户的添加(完善脚本):

 
groupadd sshtunnel
useradd -g sshtunnel -m -k /etc/sshtunnel/ -s /bin/false -e  MM/DD/YY  user1
passwd user1
 

 

 

 

尽管用户是无法登录进去的,为什么要-m开关来建立家目录呢?因为如果想要用SSH的公钥认证,这样连接的时候就不需要输入密码了,需要把客户端的SSH公钥拷贝到服务器user1用户的家目录。

/etc/sshtunnel/是模板目录,里面要有.ssh/config文件,用来对SSH登录的并发数目等进行限制。

 

存在问题

用OpenSSH建立Tunnel,用Firefox的AutoProxy插件设置Firefox的代理服务器。时不时会出现整个浏览器上不去网的情况。这种情况下,用ss观察TCP连接,会发现到SSH服务器的Send-Q阻塞,一直没有清空。有时候,是因为到localhost的Socks链接太多了。重启浏览器,让这些连接消失后再试验可能会好。还试图改变了Firefox里面几个连接数相关的设置(about:config里面搜索connections)。这样的问题到底是什么造成的呢?是SSH的设置、Firefox,还是AutoProxy?

Windows下SSH Tunnel使用设置

在使用 Go 语言创建 SSH 隧道的场景中,开发者可以选择多个开源库来实现这一目标。以下是一些主流的方法和推荐的库。 ### 使用 `sshtunnel` 创建 SSH 隧道 `sshtunnel` 是一个为 Go 程序设计的超简单 SSH 隧道工具,它能够帮助开发者在 Go 应用中轻松实现 SSH 隧道功能,无需复杂的配置和繁琐的代码。无论是连接到远程数据库、API 服务,还是其他需要通过 SSH 隧道访问的资源,`sshtunnel` 都能提供一种简洁、高效的方式来实现这一目标[^1]。 ### 使用 `sshego` 实现 SSH 隧道 `sshego` 是一个使用 Go 语言编写的开源项目,旨在为开发者提供一个简单易用的 SSH 隧道(安全端口转发)库。该库填补了 Go 标准库中 SSH 功能的空白,提供了内嵌的 SSH 服务器功能,使得用户可以方便地为自己的应用添加 3 因素认证的 SSH 服务[^2]。 ### 使用 `go-ssh-tunnel` 进行隧道连接 `go-ssh-tunnel` 是一个用于实现 SSH 隧道的 Go 扩展包,可以通过简单的函数调用来创建 SSH 隧道。以下是一个使用 `go-ssh-tunnel` 的示例代码: ```go package main import ( "github.com/dtapps/dtapps/go-ssh-tunnel/dssh" ) func main() { dssh.Tunnel("root", "", ":22", ":3306", "localhost:13306") } ``` 这段代码展示了如何通过 `dssh.Tunnel` 函数创建一个 SSH 隧道,将本地端口 `13306` 转发到远程主机的 `3306` 端口[^5]。 ### 手动实现 SSH 隧道 如果希望手动实现 SSH 隧道,可以使用 Go 的 `golang.org/x/crypto/ssh` 包来创建 SSH 客户端并建立连接。以下是一个基本的 SSH 客户端连接示例: ```go package main import ( "fmt" "golang.org/x/crypto/ssh" "net" ) func main() { // SSH 客户端配置 config := &ssh.ClientConfig{ User: "username", Auth: []ssh.AuthMethod{ ssh.Password("password"), }, HostKeyCallback: ssh.InsecureIgnoreHostKey(), // 注意:生产环境中应使用更安全的 HostKeyCallback } // 建立 SSH 连接 conn, err := ssh.Dial("tcp", "host:port", config) if err != nil { fmt.Errorf("Failed to dial: %s", err) return } defer conn.Close() // 创建一个本地监听器 listener, err := net.Listen("tcp", "localhost:13306") if err != nil { fmt.Errorf("Failed to listen: %s", err) return } defer listener.Close() for { // 接受本地连接 localConn, err := listener.Accept() if err != nil { fmt.Errorf("Failed to accept: %s", err) continue } // 在远程主机上建立连接 remoteConn, err := conn.Dial("tcp", "localhost:3306") if err != nil { fmt.Errorf("Failed to dial remote: %s", err) localConn.Close() continue } // 转发数据 go func() { defer localConn.Close() defer remoteConn.Close() // 从本地到远程的数据转发 go func() { _, err := io.Copy(remoteConn, localConn) if err != nil { fmt.Errorf("Error copying from local to remote: %s", err) } }() // 从远程到本地的数据转发 _, err = io.Copy(localConn, remoteConn) if err != nil { fmt.Errorf("Error copying from remote to local: %s", err) } }() } } ``` 上述代码展示了如何使用 `golang.org/x/crypto/ssh` 包创建一个 SSH 客户端,并通过 SSH 隧道将本地端口转发到远程主机上的指定端口。这种方式提供了更大的灵活性,但同时也需要更多的代码来实现和维护[^3]。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值