那天注册app,要用身份证照片,我平时不带身份证,证件照都是存在家里的NAS里,但当时家里的NAS竟然访问不到了。 回家后查了下,DDNS上的DNS解析和公网IP都正常,怀疑是电信封了端口,既然这样,那只能用内网穿透来做PlanB了。

就用博客网站的机器作为跳板。这台机器只有1M带宽,偶尔拿下家里的照片也够了。

关于frp的基础知识可以直接看 Github网站 。这里主要介绍部署方案。

用途

我需要两个可配置的穿透服务,家用和工作各一个。这样可以两边互不影响,更安全。

家用

家里有三个端口需要暴露出来

  1. 路由器vpn(连上之后只有172.17段的流量进来,用来偶尔连回家里的网络)
  2. NAS的vpn(连上之后所有流量都会从这里绕一圈,在某些非常不可信的环境下,为了防止别人抓包,我会用这个)
  3. NAS上的web端口

工作

偶尔需要暴露自己电脑的服务给别人用时,会临时暴露本地端口。

开始部署

服务端-frps

直接看配置文件。家用端口是2001-60000,工作用端口是2500-3000,各自的token和登录密码也不一样。


[dudugou.cn ~]# cat /my/frp/frps-home.ini
[common]
bind_port = 2000
bind_addr = 0.0.0.0
token = xxxxxxxxxxxxxx
allow_ports = 2001-60000
log_file = /var/log/frp-home.log
log_max_days = 30

dashboard_addr = 127.0.0.1
dashboard_port = 9901
dashboard_user = xxxxxx
dashboard_pwd = xxxxxxxxxxx

[dudugou.cn ~]# cat /my/frp/frps-work.ini
[common]
bind_port = 2500
bind_addr = 0.0.0.0
token = xxxxxxx
allow_ports = 2500-3000
log_file = /var/log/frp-work.log
log_max_days = 30
dashboard_addr = 127.0.0.1
dashboard_port = 9900
dashboard_user = admin
dashboard_pwd = xxxxxxx
[dudugou.cn ~]#

那么外面怎么访问它呢?直接用9900、9901这些端口?不,太low了,Nginx加个转发搞定

[dudugou.cn ~]# cat /alidata/server/nginx/conf/vhosts/frps-work.conf
server {
    listen 443;
    ssl on;
    ssl_certificate /alidata/server/nginx/conf/cert.pem;
    ssl_certificate_key /alidata/server/nginx/conf/key.pem;
    server_name  fwork.dudugou.cn;

    charset utf-8;
    access_log  /alidata/log/nginx/access/frps-work.log;

    location / {
        proxy_pass  http://127.0.0.1:9900;

        proxy_redirect     off;
        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        proxy_max_temp_file_size 0;
        proxy_connect_timeout      90;
        proxy_send_timeout         90;
        proxy_read_timeout         90;
        proxy_buffer_size          4k;
        proxy_buffers              4 32k;
        proxy_busy_buffers_size    64k;
        proxy_temp_file_write_size 64k;
   }
}

接下来有个问题,万一服务重启了怎么办?哪天frps挂了怎么办?这是该 supervisor 出场了。 来加上配置


[program:frps-home]
command=/my/frp/frps -c /my/frp/frps-home.ini
user=frps               ; setuid to this UNIX account to run the program
autostart=true              ; start at supervisord start (default: true)
autorestart=true            ; retstart at unexpected quit (default: true)
startsecs=10                ; number of secs prog must stay running (def. 10)
startretries=10              ; max # of serial start failures (default 3)
log_stdout=true             ; if true, log program stdout (default true)
log_stderr=true             ; if true, log program stderr (def false)
logfile=/var/log/frps-home.log    ; child log path, use NONE for none; default AUTO

[program:frps-work]
command=/my/frp/frps -c /my/frp/frps-work.ini
user=frps               ; setuid to this UNIX account to run the program
autostart=true              ; start at supervisord start (default: true)
autorestart=true            ; retstart at unexpected quit (default: true)
startsecs=10                ; number of secs prog must stay running (def. 10)
startretries=10              ; max # of serial start failures (default 3)
log_stdout=true             ; if true, log program stdout (default true)
log_stderr=true             ; if true, log program stderr (def false)
logfile=/var/log/frps-work.log    ; child log path, use NONE for none; default AUTO

最后别忘了开防火墙,另外,阿里云安全策略真好用,需要开哪个端口,手机直接开,平时端口都关着。至此服务端就全部搞定了。

客户端-frpc

先上家里的配置。其中172.17.0.1是路由器,172.17.0.46是nas。vpn的链接本身就是加密的,所以不用use_encryption,而nas的数据 走的http协议,所以开启use_encryption来确保家里和服务器间的数据不被窃听。

WangSZ@OpenWrt:~# cat /etc/config/frpc-vpn
[common]
token = xxxxxxxxx
server_addr = nas.dudugou.cn
server_port = 2000
admin_addr = 172.17.0.1
admin_port = 7400
tls_enable = true

[vpn-nas]
type = tcp
local_ip = 172.17.0.46
local_port = 1199
remote_port = 2101

[vpn]
type = tcp
local_ip = 172.17.0.1
local_port = 4443
remote_port = 2100

[nas]
type = tcp
local_ip = 172.17.0.46
local_port = 8082
remote_port = 8880
use_encryption = true
use_compression = false

由于frpc是运行在路由器的,路由器的文件系统只有二十多M,所以我把frpc放在/tmp目录。/tmp目录每次重启路由都会清理,所以又必须在启动时重新下载。 为了解决这个问题,我把frpc放在了网站上,然后路由器启动时下载到/tmp。

这里有几个问题。网路故障导致没下载下来怎么办?frpc进程退出了怎么办?我总不能回家去重启路由器呀。路由器里装 supervisor 可太浪费了,空间就那么小。 这时就该 crontab 出场了,没十分钟检查一次

WangSZ@OpenWrt:~# crontab -l
*/10 * * * * /tmp/check.sh 

都检查些什么呢?

  1. frpc文件有没有下载,没下载就重新下载
  2. frpc进程在不在,不在就启动

来看看脚本怎么写

WangSZ@OpenWrt:~# cat /tmp/check.sh
frpc="/tmp/frpc"
if [ ! -f "$frpc" ]; then
  echo "$frpc not exist. Downloading ..."
  wget --no-check-certificate https://file.dudugou.cn/frpc -O /tmp/frpc && chmod +x /tmp/frpc
else
  chmod +x /tmp/frpc
  echo "$frpc found"
fi
ps |grep frpc |grep -v grep
if [ $? -ne 0 ]
then
  echo "start frpc....."
  /tmp/frpc -c /etc/config/frpc-vpn > /dev/null &
else
  echo "frpc is runing....."
fi

做完这些我能做什么呢?我可以从手机上连回家里,然后把家里任何一个设备的任何一个端口暴露出来,用完了可以再关了它,安全又方便。

手机随时改暴漏的端口配置