利用ngrok和shadowsocks穿透内网

老生常谈的话题,这里记录下

scheme-ngrok-ssvsdx

服务端(公网VPS)操作

  1. 安装golang环境
1
yum install gcc golang
  1. 下载ngrok项目包
1
2
cd /
git clone https://github.com/mamboer/ngrok.git
  1. 设置域名解析,假设准备通过 ngrok.heiljo.com 充当代理域名穿透内网服务,因为我的域名使用dnspod解析的,所以登录dnspod解析 io*.io 的A记录到公网VPS IP

QQ20180616-091247

  1. 生产代理域名的自签名证书
1
2
3
4
5
6
7
cd /ngrok
domain="io.heiljo.com" //这里替换成自己的代理域名
openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=$domain" -days 5000 -out rootCA.pem
openssl genrsa -out device.key 2048
openssl req -new -key device.key -subj "/CN=$domain" -out device.csr
openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000
  1. 覆盖ngrok的默认证书
1
2
3
\cp rootCA.pem assets/client/tls/ngrokroot.crt -f
\cp device.crt assets/server/tls/snakeoil.crt -f
\cp device.key assets/server/tls/snakeoil.key -f
  1. 编译ngrok服务端
1
make release-server
  1. 编译ngrok客户端(依然在公网vps中)
1
export GOOS=linux GOARCH=amd64 && make release-client

ps: 上面的命令是linux 64位的执行命令,如果你的内网系统是其他的,请对号入座

Linux 平台 32 位系统:GOOS=linux GOARCH=386
Linux 平台 64 位系统:GOOS=linux GOARCH=amd64

Windows 平台 32 位系统:GOOS=windows GOARCH=386
Windows 平台 64 位系统:GOOS=windows GOARCH=amd64

MAC 平台 32 位系统:GOOS=darwin GOARCH=386
MAC 平台 64 位系统:GOOS=darwin GOARCH=amd64

  1. 运行服务端ngrok服务
1
nohup /ngrok/bin/ngrokd -domain="io.heiljo.com" -httpAddr=":6060" -httpsAddr=":6061" -tunnelAddr=":6062" >/dev/null 2>&1 &

ps: 修改-domain值为自己的代理域名 & 以上端口都是可以改变的,httpAddr以及httpsAddr分别是反向代理http以及https站点的端口。而tunnelAddr是ngrok客户端连接服务端的端口。

  1. 防火墙开启服务端端口tcp请求
1
2
3
4
firewall-cmd --zone=public --add-port=6060/tcp --permanent
firewall-cmd --zone=public --add-port=6061/tcp --permanent
firewall-cmd --zone=public --add-port=6062/tcp --permanent
firewall-cmd --reload

客户端(内网)操作

  1. 通过ftp或scp将公网vps中编译好的客户端程序上传到内网客户端上,客户端程序位于公网如下目录
1
/ngrok/bin/ngrok
  1. 安装shadowsocks
1
2
yum install python-setuptools && easy_install pip
pip install shadowsocks
  1. 启动shadowsocks, 注意修改password && shadowsocks端口(默认5432) && 加密方法 (默认rc4-md5)
1
ssserver -p 5432 -k {password} -m rc4-md5 --user nobody -d start
  1. 假设我们在第一步将客户端程序ngrok存放到了/ngrok/ngrok目录,则在/ngrok文件夹内创建和服务端的端口映射配置文件ngrok.yml
1
2
3
4
5
6
7
server_addr: "io.heiljo.com:6062"
trust_host_root_certs: false
tunnels:
ss:
remote_port: 38382
proto:
tcp: 5432

ps: server_addr 修改为自己的,如果启动shadowsocks时的端口修改过,那么tunnels:ss:tcp的配置项也需要修改成自己的,remote_port时反向代理的端口,默认38382,可以修改成自己想要的。

  1. 切换到服务端,在服务端(公网vps中开启38382的访问权限)
1
2
firewall-cmd --zone=public --add-port=38382/tcp --permanent
firewall-cmd --reload
  1. 切换回客户端,启动ngrok客户端服务
1
2
chmod a+x /ngrok/ngrok
nohup /ngrok/ngrok -log=/ngrok.log -config=/ngrok/ngrok.yml start ss >/dev/null 2>&1 &
  1. 如果有连接ssh的需求,需要在ngrok.yml中增加ssh的端口映射,记得在服务端开启相关端口的访问权限
1
2
3
4
ssh:
remote_port: 60622
proto:
tcp: "127.0.0.1:22"

然后启动的时候增加ssh

1
nohup /ngrok/ngrok -log=/ngrok.log -config=/ngrok/ngrok.yml start ss ssh >/dev/null 2>&1 &

ps: 建议用supervisord替代nohup命令,具体方法请百度,贴一个配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[program:ngrok]
command=/ngrok/ngrok -log=/ngrok/ngrok.log -config=/ngrok/ngrok.yml start ss
directory=/ngrok
numprocs=1
process_name=%(program_name)s
priority=999
umask=022
startsecs=2
startretries=3
exitcodes=0,2
autorestart=true
stopsignal=INT
user=root
stdout_logfile=/var/log/supervisor/ngrok.log
stdout_logfile_maxbytes=1MB
stdout_logfile_backups=10
stdout_capture_maxbytes=1MB
stderr_logfile=/var/log/supervisor/ngrok.error.log
stderr_logfile_maxbytes=1MB
stderr_logfile_backups=10
stderr_capture_maxbytes=1MB

终端,也就是自己的电脑上

  1. 下载一个shadowsocks客户端,创建一个配置项目
1
2
3
4
"server" : "io.heiljo.com",
"server_port" : 38382,
"password" : "{填写客户端上的shadowsocks服务的密码}",
"method" : "rc4-md5",

ps: 修改server和password为自己的值

  1. 连接ssh
1
ssh root@io.heiljo.com -p 60622