setup reverse tunnel with stunnel

Unlike ssh,  stunnel dosen’t support the reverse tunnel by it’s self.

With the help of tgcd ( TCP/IP Gender Changer Daemon ), we are able to setup a reverse tunnel by chain the tgcd and stunnel:

For example:

We try to access the corp server from home,  but due to the NAT firewall of the corp, only out going 80/443 port are opened:

client  ==> tgcd LL node (home server)  ==> tgcd CC node (corp agent) ==> corp server:

Home Server:

Launching tgcd daemon in LL mode:

   tgcd -L -q 2222 -p 22222

Listen on port 2222 for client access

Listen on port 22222 for tgcd CC access

 

Launching stunnel in server mode:

       /usr/local/bin/stunnel /etc/stunnel/stunnel_server.conf

Listen on port 443 for incoming ssl connection

Forward link with sni=tgcd to port 2222

cat /etc/stunnel/stunnel_server.conf

[tls]
accept = 0.0.0.0:443
connect = 127.0.0.1:1080

[tgcd]
sni = tls:tgcd
connect = 127.0.0.1:2222

 

Corp Agent Server:

Launching tgcd daemon in CC mode:

tgcd -C -s 127.0.0.1:222 -c 127.0.0.227:2222

Connect to tgcd LL node at:   127.0.0.227:2222

Connect to sshd server at:     127.0.0.1:222

Launching stunnel in client mode:

/usr/local/bin/stunnel /etc/stunnel/stunnel_client.conf

Listen on port 127.0.0.227:2222 from tgcd CC, and

Access Home server via port 443 behind NAT and http proxy

cat /etc/stunnel/stunnel_client.conf

 

[ssh-tgcd-home]
accept = 127.0.0.227:2222
protocolHost = home.serverip:443

connect = http_proxy_ip:http_proxy_port
protocol = connect
sni = tgcd

 

******************************************

With such configuration, we can login into the corp server by means of:

ssh -p 22222   home.server.ip

road warrior & ssh share port 443

With help of SNI in stunnel,  we can  support both  road warrior and ssh function on the same TCP/443 port.

 

VPS Server:

Install  stunnel v5.31 with  openssl  v1.0.2, and listen on port 443

Install dante v1.4.1,  and listen on port 1080

Install openssh, and listen on port 22

 

Stunnel config for VPS server

chroot = /var/lib/stunnel/
pid=/stunnel.pid
setuid = stunnel
setgid = stunnel

;debug =debug
debug = err
;foreground = yes

log = append
;log = overwrite
output = /stunnel.log

cert = /etc/stunnel/stunnel.pem
;key = /etc/stunnel/stunnel.pem

verify = 3
CApath = /certs

; performance
socket = l:TCP_NODELAY=1

;compression = deflate
compression = zlib

[tls]
accept = 0.0.0.0:443
connect = 127.0.0.1:1080

[ssh]
sni = tls:22.vps.server.net
connect = 127.0.0.1:22

[socks]
sni = tls:vps.server.net
connect = 127.0.0.1:1080

 

stunnel listen on 22 for ssh connection

stunnel listen on 1080 for socks connection

 

Stunnel config for client within Corp’s network:

chroot = /var/lib/stunnel/
pid=/stunnel.pid
setuid = stunnel
setgid = stunnel

;debug = alert/crit/err/warning/notice/info/debug
debug = err

;foreground = yes

cert = /etc/stunnel/stunnel.pem

;compression = deflate | zlib
compression = zlib

client = yes

; performance
socket = l:TCP_NODELAY=1

[socks-http-proxy]
accept = 127.0.0.1:1080
connect = http_proxy_ip:http_proxy_port

protocol = connect
protocolHost = vps.server.net:443

[ssh-http-proxy]
accept = 0.0.0.0:22
connect = http_proxy_ip:http_proxy_port
protocol = connect
protocolHost = vps.server.net:443
sni = 22.vps.server.net

 

 

How to

Road Warrier: 

set socks proxy of browser to 127.0.0.1:1080

 

SSH to vps.server.net

ssh -p 22  user@localhost

 

转:通过 stunnel 搭建安全高性能的 sockts 代理服务器

http://bird1110.blogspot.com/2011/01/using-stunnel-through-proxy.html

 

一般来说要搭建一个本地的 socks 代理只需要简单的 ssh -D, 就可以生成一个代理了. 这样作为零时方案挺不错的, 工作上服务器一般会被反向代理, 通过 ssh 就可以隐射到本地通过浏览器进行调试了, 但如果需要长期使用的话. 这样的方案也有不少的麻烦.

通过 ssh -D 他和服务器之间只会有一个连接, 这样网络性能上并不是最好的.
必须使用 openssh 才可以 -D, 一般路由器常用的 dropbear ssh 客户端不能使用 -D.
需要通过 autossh 自动重连, 但如果网络频繁切换(诸如 3G 和 wifi) 还需要辅助脚本来重启 autossh.
也不能提供例如用户名密码交验这样的安全认证功能.

基于以上这么多问题, 有条件的前提下还是自己在服务器端搭 socks 代理, 再通过 stunnel 或者 ssh -L 映射到本地是比较好的解决方案.

安装 socks 代理

方案上是在服务器搭建一个只能本地使用的代理, 再通过其他服务映射到本地. (这里用 danted 来搭 socks 代理. 服务器用的是 ubuntu)

apt-get install -y dante-server

安装完以后将 /etc/danted.conf 开启或加入如下配置

logoutput: syslog
internal: 127.0.0.1 port = 1080
external: eth0

clientmethod: none
method: none

user.privileged: proxy
user.notprivileged: nobody
user.libwrap: nobody

extension: bind
connecttimeout: 30
iotimeout: 86400

client pass {
from: 127.0.0.1/8 to: 127.0.0.1/8
log: connect error
method: none
}
client block {
from: 0.0.0.0/0 to: 0.0.0.0/0
method: none
}
pass {
from: 127.0.0.1/8 to: 0.0.0.0/0
command: bind connect udpassociate
log: connect error
method: none
}
pass {
from: 0.0.0.0/0 to: 127.0.0.1/8
command: bindreply udpreply
log: connect error
method: none
}
block {
from: 0.0.0.0/0 to: 0.0.0.0/0
log: connect error
}

按上述配置就可以搭出一个只能本地使用的 socks 代理, 接着用 service danted start 启动代理
服务端 stunnel 配置

stunnel 用来和客户端之间建立一条加密的链接, 这里还需要对客户端做认证, 确保只有拥有证书的客户端才可以链接. 终端输入:

apt-get install stunnel

安装好 stunnel 后还需要生成一个服务器的证书. 这里由于只用来加密通讯, 所以证书可以不用很复杂和正规.

cd /etc/stunnel
mkdir -p /var/lib/stunnel4/certs
ln -s /var/lib/stunnel4/certs /etc/stunnel/certs
openssl req -new -x509 -days 3650 -nodes -config /usr/share/doc/stunnel4/examples/stunnel.cnf -out stunnel.pem -keyout stunnel.pem

然后再编辑 /etc/stunnel/stunnel.conf

chroot = /var/lib/stunnel4/
setuid = stunnel4
setgid = stunnel4
pid = /stunnel4.pid

cert = /etc/stunnel/stunnel.pem
;key = /etc/stunnel/stunnel.pem

verify = 3
CApath = /certs

; performance
socket = l:TCP_NODELAY=1

[danted]
accept = 1081
connect = 1080

把本地的 1080 端口映射成 1081, 接着编辑 /etc/default/stunnel4 将其中的 ENABLED=0 修改成 ENABLED=1 然后再输入 service stunnel4 start 启动服务.

 

 

客户端 stunnel 配置

之前已经把服务器端配置完成了, 接下来需要在客户端配置 stunnel 好将端口映射到本地. 还是以 ubuntu 为例, 输入:

apt-get install stunnel

然后生成一个客户端的证书

cd /etc/stunnel
openssl req -new -x509 -days 3650 -nodes -out client.pem -keyout client.pem

这里需要注意的是为了区分证书, 每个证书都需要输入对应不同的信息, 然后将生成的 client.pem 复制到服务器的 /etc/stunnel/certs 目录下, 接着需要在 服务器 输入:

cd /etc/stunnel/certs
$(/usr/lib/ssl/misc/c_hash p.wido.me.pem | awk ‘{print “ln -s ” $3 ” ” $1}’)

stunnel 需要通过 c_hash 才能找到对应的证书.

然后在 客户端 加入配置文件 /etc/stunnel/client.conf

chroot = /var/lib/stunnel4/
setuid = stunnel4
setgid = stunnel4
pid = /stunnel4-client.pid

cert = /etc/stunnel/client.pem
client = yes

; performance
socket = r:TCP_NODELAY=1

[danted]
accept = 127.0.0.1:1080
connect = [HOST]:1081

其中的 [HOST] 为服务器的域名或者IP. 接着还是将 /etc/default/stunnel4 的 ENABLED=0 设置成 1, 接着启动 service stunnel4 start 就可以在客户端建立出一个端口为 1080 的 socks 代理了.

 

 

 

最后

由于服务器配了客户端证书认证, 所以只有添加证书的用户可以连上这台服务器. 同样的方法也可以映射其他的服务, 比如 polipo.

对于有些对 stunnel 支持不好的设备, 也可以用 ssh -L 来映射这个 1080 的端口而不用 -D 参数.
参考资料

http://www.bock.nu/blog/secure-firewall-bypass-danted-stunnel

多进口ip,多出口ip的socks5设置(基于dante)