frp 内网穿透实现 ssh 访问内网主机
本文目的
frp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp, udp, http, https 协议。 本文将基于 frp 来实现内网穿透,从而实现从外网 ssh 登录内网主机,而不对 frp 其他的应用做过多的说明。
frp 的作用
- 利用处于内网或防火墙后的机器,对外网环境提供 http 或 https 服务。
- 对于 http, https 服务支持基于域名的虚拟主机,支持自定义域名绑定,使多个域名可以共用一个80端口。
- 利用处于内网或防火墙后的机器,对外网环境提供 tcp 和 udp 服务,例如在家里通过 ssh 访问处于公司内网环境内的主机。
架构
在具有公网IP的服务器或VPS上安装运行 frp 的服务端程序frps,并在处于内网的目标主机上面安装运行 frp 的客户端程序 frpc ,然后 User 就可以通过公网服务器来实现内网穿透从而访问内网主机。
配置 ssh 访问内网机器
根据不同的系统架构选择不同的安装包,从 frp下载链接 上下载合适的安装包。由于本人的公网服务器是 vultr 上面的一台 VPS,操作系统是 CentOS 7;内网机器也是一台 Linux 服务器,操作系统是 Ubuntu 16.04,所以我使用的安装包是 frp_0.21.0_linux_amd64.tar.gz
。配置步骤如下:
下载安装包
在公网服务器和内网机器上都要下载安装包并解压:
1
2$ wget https://github.com/fatedier/frp/releases/download/v0.21.0/frp_0.21.0_linux_amd64.tar.gz
$ tar -xzvf frp_0.21.0_linux_amd64.tar.gz解压之后的文件夹中既包含了服务端的文件又包括客户端的文件,所以可以分别在两个机器上删除掉不必要的文件,也可以不删,都没有影响。强迫症还是来删一下,在解压后的文件夹中:
在公网服务器上删除客户端相关的文件,只保留一下两个文件:
1
frps frps.ini
在内网机器上删除服务端相关的文件,只保留以下两个文件:
1
frpc frpc.ini
在公网服务器上配置并启动
修改配置文件
$ vi frps.ini
,如下:1
2[common]
bind_port = 7000 #frp服务端端口(必须)配置很简单,然后启动:
1
$ nohup ./frps -c frps.ini &
查看 nohup.out 的信息,success
1
2
3
4
5
6
7
8# tail -f nohup.out
2018/09/14 05:33:15 [I] [service.go:130] frps tcp listen on 0.0.0.0:7000
2018/09/14 05:33:15 [I] [root.go:207] Start frps success
2018/09/14 05:49:47 [I] [service.go:130] frps tcp listen on 0.0.0.0:7000
2018/09/14 05:49:47 [I] [root.go:207] Start frps success
2018/09/14 06:28:59 [I] [service.go:319] client login info: ip [125.71.219.33:37092] version [0.21.0] hostname [] os [linux] arch [amd64]
2018/09/14 06:28:59 [I] [proxy.go:217] [93eec0dde173fc68] [ssh] tcp proxy listen port [6000]
2018/09/14 06:28:59 [I] [control.go:335] [93eec0dde173fc68] new proxy [ssh] success在内网机器上配置并启动
修改配置文件
$ vi frpc.ini
,如下:1
2
3
4
5
6
7
8
9
10[common]
server_addr = 0.0.0.0 #frp服务端地址,可以填ip或者域名,这里假设为0.0.0.0
server_port = 7000 #frp服务端端口,即填写服务端配置中的 bind_port
[ssh]
type = tcp #连接类型,填tcp或udp
local_ip = 127.0.0.1 #填127.0.0.1或内网ip都可以
local_port = 22 #需要转发到的端口,ssh端口是22
remote_port = 6000 #frp服务端的远程监听端口,即你访问服务端的remote_port就相当于访
#问客户端的 local_port,如果填0则会随机分配一个端口启动客户端程序:
1
$ nohup ./frpc -c frpc.ini &
查看 nohup.out 的信息,success
1
2
3
4
5
6
7$ tail -f nohup.out
2018/09/14 14:28:58 [I] [proxy_manager.go:300] proxy removed: []
2018/09/14 14:28:58 [I] [proxy_manager.go:310] proxy added: [ssh]
2018/09/14 14:28:58 [I] [proxy_manager.go:333] visitor removed: []
2018/09/14 14:28:58 [I] [proxy_manager.go:342] visitor added: []
2018/09/14 14:28:59 [I] [control.go:246] [93eec0dde173fc68] login to server success, get run id [93eec0dde173fc68], server udp port [0]
2018/09/14 14:29:00 [I] [control.go:169] [93eec0dde173fc68] [ssh] start proxy success登录
完成前面三步的配置就可以登录对应的内网机器了,执行 ssh 命令:
1
2
3ssh -oPort=6000 username@server_addr
或者
ssh -p 6000 username@server_addr上面登录使用的 username 是内网机器的用户名,server_addr是公网服务器的IP,port 6000就是设置的 remote_port,最后的登录密码是内网机器的密码,而不是公网机器的密码,这一点一定要注意。
问题解决
在启动服务端和客户端程序之后,可能发现还是无法登录到内网内网机器,在内网机器上面执行 tail -f nohup.out
查看启动命令的执行结果,可以发现以下的问题:
1 | $ tail -f nohup.out |
仔细检查了一下,发现是我公网服务器防火墙的原因,没有允许对应端口的流量通过,所以需要配置防火墙:
1 | # firewall-cmd --zone=public --add-port=7000/tcp --permanent |
上面配置防火墙的命令是针对 CentOS 的,如果是别的系统不太一样,如 Ubuntu 通过
iptables
命令来配置。