使用frp实现内网穿透

如今办理宽带的时候,运营商都不会给你分配公网静态ip,这致使的问题就是若是你想让外部网络访问家里局域网内的某台设备,你不能使用通常路由器都自带的端口映射(虚拟服务器)来简单的让外部网络成功访问到。在运营商动态分配ip的时候,若是动态分配到的ip是公网ip,那么可使用一些收费的DDNS动态域名解析服务来访问内网中的web服务,这时候路由器的端口映射也是须要配置的。若是动态分配到的ip不是公网ip,那么DDNS也不会灵光了。咱们须要完全一点的方案,那就是内网穿透,即经过一台具备公网静态ip的电脑(服务器,vps等),来反向代理内网中的机器。python

怎么样来理解经过反向代理穿透到内网呢,首先咱们须要在具备公网静态ip的服务端,安装一个代理服务(例如本文将要提到的frp的服务端frps),而后在内网的设备上安装此代理服务的客户端,服务端跟客户端都做为后台服务启动运行(服务端首先启动运行),客户端链接到代理服务的端口,此时咱们的服务端做为反向代理服务器已经能够接受来自互联网的请求了,并可以把请求转发到客户端上设置好的相应端口(服务,例如web)上。简而言之,如今咱们能够从外部网络访问内网中的某些设置好的设备了。linux

前些日子,我想要在上班的时候也能访问家里的刷好openwrt的路由器的设置界面及ssh服务,因此经过google,最终我决定使用frp这个开源软件,下面是github上的项目主页:
github.com/fatedier/fr…
更多配置请访问项目主页自行研究。git

折腾过程记录:

前提:

  • 一台有公网静态ip的设备(服务器,vps,openwrt路由器...)。
  • 代理tcp协议不须要域名,代理http,https协议必需要准备域名。

服务端配置

首先从此处找到适合本身系统架构的编译好的软件包,点击右键,从弹出菜单中找到复制连接地址单击复制。github

支持systemd的linux系统(ubuntu,centos7)

我使用的是centos7的vps,经过ssh登录进去,使用wget命令行工具把软件包下载到 /opt目录下。web

cd /opt
sudo wget 粘贴复制的连接
复制代码

这时候将下载到的软件包进行解压。ubuntu

ls
sudo tar xzvf  软件包名
复制代码

解压成功后进入刚刚解压的文件目录。vim

ls
cd 刚解压的目录
ls
复制代码

能够看到frpc,frps,frpc_full.ini,frps_full.ini,frpc.ini,frps.ini等文件,frps是服务端二进制程序,frpc是客户端二进制程序,frps.ini是服务端的配置文件,frpc.ini是客户端的配置文件,frps_full.ini跟frpc_full.ini是示例配置文件。 centos

在centos7下,能够经过systemd来管理守护进程,根据此github项目上 issue上vc5写的systemd 的service文件修改了一份frps程序可用的service文件,文件名改成frps.service,放在 /usr/lib/systemd/system/目录下。

sudo cd /usr/lib/systemd/system
sudo vim frps.service
复制代码

输入上一行命令后,进入空的frps.service文件,点击i进入编辑模式,复制粘贴下面的内容bash

[Unit]
Description=frps daemon
After=syslog.target  network.target
Wants=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/frps -c /etc/frp/frps.ini
Restart= always
RestartSec=1min
ExecStop=/usr/bin/killall frps

[Install]
WantedBy=multi-user.target
复制代码

根据frps.service中启动frps的那一行(ExecStart=......),将frps跟frps.ini移动或者复制到相应的目录下。到这一步就能够把下载的软件包跟解压出来的文件夹删除了。服务器

cd /opt/frp文件夹名/
sudo cp frps /usr/local/bin#复制到该目录下
sudo mkdir /etc/frp#新建文件夹frp
sudo cp frps.ini /etc/frp/#复制到该目录下
sudo rm -rf 软件包 解压出来的文件夹
复制代码

如今来设置/etc/frp目录下的frps.ini,经过cd /etc/frp切换到该目录下,输入vim frps.ini 命令修改frps.ini,个人配置以下:

#frps.ini
[common]
bind_port = 1978#能够自行设定

vhost_http_port = 8081#能够自行设定
vhost_https_port = 4433#能够自行设定

token=jsljgslaljglsgsgjlsjgslgjs#请本身设置密钥
authentication_timeout=0#假如服务端与客户端的时间相差超过24小时,可能会没法链接,此处设置为0,将再也不验证服务端与客户端时间

log_file = ./frps.log
log_level = info
log_max_days = 3

subdomain_host = example.com#填写本身的域名,此处填写subdomain_host则代理http,https协议时客户端在web代理中要填写subdomain项目

复制代码

修改好frps.ini,服务端的配置基本完成,经过以下命令启动运行:

sudo systemctl  enable frps.service#容许开机自启
sudo systemctl  start frps.service#启动
sudo systemctl  status frps.service#查看运行状态

复制代码

若是使用防火墙firewalld,frps相关服务端口可能并未开放,能够经过以下命令开放相关端口:

sudo firewall-cmd --permanent --add-port=相关服务端口/tcp #此处端口是配置文件中设置好的端口,bind_port,vhost_http_port,vhost_https_port ,还有客户端配置文件中的远程端口,请逐条添加
sudo firewall-cmd --reload

复制代码

客户端配置

客户端的配置前面几步跟服务端相似,首先从此处找到适合本身系统架构的编译好的软件包并下载下来。

openwrt(LEDE)系统的路由器

把frpc复制到/usr/bin/目录,把frpc.ini复制到/etc/目录,根据网络上的教程,我尝试了在web管理界面中添加到本地启动脚本中,输入

nohup frpc -c /etc/frpc.ini > /dev/null 2>&1  &
复制代码

但这样开机启动的方式并不起做用。因此我用python编写了一个监测frpc是否运行的脚本,若是脚本检测到frpc没有运行就会启动frpc。将该脚本命名为monitor.py,放在/root目录下,内容是这样的:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import time

cmd="ps |grep frp |grep -v grep"
process=os.popen(cmd).readlines()
if process:
   time_now=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
   with open("monitor.log","at") as f:
        f.write(time_now+" running\n")
        for line in process:
            f.write(line)
else:
   time_now=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
   with open("monitor.log","at") as f:
        f.write(time_now+" no running\n")
   os.popen("frpc -c /etc/frpc.ini >/dev/null 2>&1 &")
复制代码

将monitor.py赋予执行权限

chmod a+x monitor.py
复制代码

咱们能够在linux的计划任务cron中每十分钟运行一次脚本,咱们在/etc/crontabs/root文件的末尾添加上一条计划任务

*/10 * * * * /root/monitor.py
复制代码

客户端配置文件frpc.ini:

[common]
server_addr = 0.0.0.0#填写本身服务器ip
server_port=1978 #能够自行设定
token=sgfsgsgshshshshshshshs #跟服务端必须一致

[ssh_router]#ssh链接
type = tcp
local_ip = 127.0.0.1
local_port = 22 #能够自行设定
remote_port=4555#能够自行设定

[web_router]#登陆web
type=http#或者https
local_ip=127.0.0.1
local_port =80#能够自行设定
#此处无需设定远程端口,服务端配置里已经设置了vhost_http_port或vhost_https_port的端口
#若是服务端设置了subdomain_host,这里设置subdomain,若是服务端没有设置subdomain_host,这里设置custom_domains
subdomain=router
#custom_domains = router.example.com

复制代码

当客户端配置文件修改好了,能够输入 frpc -c /etc/frpc.ini测试可否链接服务端,以下图所示说明配置正确链接成功了。

frp客户端成功链接服务端
如今重启openwrt路由器,过几分钟监测脚本运行后就能够从外网登录路由器web界面了。前面的内容也适用于没有使用systemd的其余linux系统。

支持systemd的linux系统(ubuntu,centos7)

客户端配置跟服务端几乎同样,只须要注意两点,第一点就是编写service文件时把 frps替换成frpc,第二点就是使用客户端的配置文件frpc.ini。

欢迎浏览个人我的博客,https://diwugebingren.github.io

欢迎关注个人公众号
相关文章
相关标签/搜索