Docker系列 通过FRP实现内网穿透

转自我的个人博客https://blognas.hwb0307.com。欢迎关注!

前言

有小伙伴提醒,fatedier/frps才是frp官方的Docker镜像。但我看这个官方镜像都没有详细的使用说明,所以不太想折腾。我下面用的镜像是我以前用过的,以前没有注意它们不是官方,所以不确定是否有潜在安全问题。如果担心安全的话,小伙伴可以看看fatedier/frps怎么用,比如参考《容器化FRP使用方案》教程。也可通过其它方式使用frp,具体可以看官方Github地址:Repo。

最近有小伙伴问我:如果我有一个VPS,如何给自己家里的设备设置内网穿透服务呢?今天,我这里给一个比较简单且久经考验方案,就是利用Docker搭建frp实现内网穿透

frp实现内网穿透的大致工作原理如下:

  • 在一个有公网ip的VPS中搭建frp server(frps)服务。将域名test.sample.com解析到VPS里。
  • 给frps开放某些特定的端口,比如1234
  • 在本地电脑安装frp customer(frpc)服务。通过common系列参数保证frps-frpc的通信正常。
  • 本地某服务上线,比如localapp:6534
  • frpc进行内部连接,比如frpc:1234
  • 穿透路线:test.sample.comVPSfrps:1234frpc:1234localapp:6534

差不多是这样吧,可能实际的情况有些出入。本文不深入探讨frps:1234→frpc:1234是怎么工作的,有兴趣自己Google一下即可(我也没怎么研究过,这才是重点,哈哈)。你只需要知道,frp是内网穿透的常用方案之一,且frp确实是好用即可

由于我的本地宽带已经开通公网ip,所以内网穿透对我而言没有太大意义了。但是很多小伙伴家里的宽带没办法申请到公网ip。所以我还是搞一期内网穿透的教程吧,希望对他们有所帮助!

这一期的知识储备和安装一般Docker的基础差不多。所以如果你看我过的Linux基础和Docker系列,这一期十分简单。话不多说,冲!

服务器端

准备工作

  
  
  
  
# 工作目录。按需修改work=~/docker/frps# 创建并进入目录mkdir -p $work/{conf,log} && cd $work# 日志文件touch $work/log/frps.log# 拉取docker镜像docker pull ruiny/frps:latest

按需要修改配置文件

  
  
  
  
vim ./conf/frps.ini

内容如下(有中文标记的项要自己改好):

  
  
  
  
# [common] is integral section[common]# A literal address or host name for IPv6 must be enclosed# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"bind_addr = 0.0.0.0bind_port = 7000# udp port to help make udp hole to penetrate natbind_udp_port = 7001# udp port used for kcp protocol, it can be same with 'bind_port'# if not set, kcp is disabled in frpskcp_bind_port = 7000# specify which address proxy will listen for, default value is same with bind_addr# proxy_bind_addr = 127.0.0.1# if you want to support virtual host, you must set the http port for listening (optional)# Note: http port and https port can be same with bind_portvhost_http_port = 80vhost_https_port = 443# set dashboard_addr and dashboard_port to view dashboard of frps# dashboard_addr's default value is same with bind_addr# dashboard is available only if dashboard_port is setdashboard_addr = 0.0.0.0dashboard_port = 7500# 按需修改,Web管理frps时需要dashboard_user = supermandashboard_pwd = test0test# dashboard assets directory(only for debug mode)# assets_dir = ./static# console or real logFile path like ./frps.loglog_file = /var/log/frps.log# trace, debug, info, warn, errorlog_level = infolog_max_days = 3# 按需修改,在frpc的common系列参数中需要token = 12345678# heartbeat configure, it's not recommended to modify the default value# the default value of heartbeat_timeout is 90# heartbeat_timeout = 90# 按需修改,选自己要开放的网段allow_ports = 3505-3510# pool_count in each proxy will change to max_pool_count if they exceed the maximum valuemax_pool_count = 5# max ports can be used for each client, default value is 0 means no limitmax_ports_per_client = 0# authentication_timeout means the timeout interval (seconds) when the frpc connects frps# if authentication_timeout is zero, the time is not verified, default is 900sauthentication_timeout = 900# if subdomain_host is not empty, you can set subdomain when type is http or https in frpc's configure file# when subdomain is test, the host used by routing is test.frps.com# subdomain_host = frps.imgki.com# if tcp stream multiplexing is used, default is truetcp_mux = true

配置yml文件

新建一个docker-compose文件:

  
  
  
  
vim $work/docker-compose.yml

填入以下内容:

  
  
  
  
version: '3'services: frps: image: 'ruiny/frps' container_name: frps1 restart: unless-stopped ports: - '6500:7000' - '6501:7500' - '6502:7001' # http端口 - '6503:80' # https端口 - '6504:443' # 这里写自己要开放给frpc的端口 - '3505-3510:3505-3510' volumes: - ./conf:/var/frp/conf - ./log/frps.log:/var/log/frps.log

注意:

  • 如果你的VPS是专门做内网穿透用的,可以将- '6503:80'- '6504:443'直接改成- '80:80'- '443:443'。否则,一般你要定义一个其它的端口,以免和Nginx类应用冲突。

  • 如果你的VPS安装了宝塔或者ufw等防火墙,你需要开放相应端口!在本示范中,需要开放的端口号为:6500-65043505-3510。ufw就不演示了,自己看我以前的Docker文章吧!

上线服务:

  
  
  
  
cd $work && docker-compose up -d

观察日志(和一般的Docker应用有点不同):

  
  
  
  
tail -f $work/log/frps.log

(小白请忽视)高级用户可以进入docker内部观察或操作:

docker exec -it frps1 /bin/sh

你可以登陆http://:6501查询frps的工作状态,用户名/密码为superman/test0test。界面类似于:

到此,frp的服务端就准备好了。下面用Shell登陆自己的本地设备(如NAS或路由器)。

本地端

准备工作

观察一下本地电脑或NAS的ip地址。可以这样找:

  
  
  
  
ifconfig|less

在里面找enp字符。比如,我的NAS的信息就类似于:

这个inet后面的192.168.X.X的地址就是当前设备的局域网ip。下面,我们以192.168.0.125为例进行示范。

设定工作目录:

  
  
  
  
# 工作目录。按需改动work=~/docker/frpc# 创建并进入工作目录mkdir -p $work && cd $work# 拉取docker镜像docker pull chenhw2/frp:latest

新建frpc.ini文件:

  
  
  
  
vim ./frpc.ini

填入以下内容:

  
  
  
  
[common]# 填写服务器实际IP或解析该IP的某域名server_addr = sample.com# 填写服务器frps的主端口号,本示范中是6500server_port = 6500# 与frps.ini中的token要一一对应token = 12345678[ssh-3505]# 将服务端的3505端口连接到本地的22端口进行ssh连接type = tcp# 本地iplocal_ip = 192.168.0.125# 你的ssh端口。默认是22。如果有自定义ssh端口,就写那个自定义端口。local_port = 22# frps开放的端口之一。我随便写了个3505。remote_port = 3505[http-www.sample.cn]# 测试httptype = http# 本地iplocal_ip = 192.168.0.125# 比如,某个Docker应用的端口号。Emby,jellyfin之类的有Web界面的应用。local_port = 6533custom_domains = httptest.sample.com[[email protected]]# 测试httpstype = https# 填写域名custom_domains = httpstest.sample.complugin = https2httpplugin_local_addr = 192.168.0.125:6533# HTTPS 证书相关的配置plugin_crt_path = /frp/sample.com.pemplugin_key_path = /frp/sample.com.keyplugin_host_header_rewrite = 192.168.0.125plugin_header_X-From-Where = frp

最后,记得将证书通过sftp上传到$work目录里面。目录内容类似于:

  
  
  
  
$ ls -hl $work-rw-r--r-- 1 test_user test 1.1K Jun 13 13:38 frpc.ini-rw-r--r-- 1 test_user test 1.7K Jun 13 13:42 sample.com.key-rw-r--r-- 1 test_user test 3.8K Jun 13 13:42 sample.com.pem

我个人建议你申请一个顶级域名的证书,即*.sample.com, sample.com,这样所有的*.sample.com都可以用同一个证书,省去了证书维护的麻烦。你如果不想,也可以给每一个子域名单独申请一个证书。全部都上传到$work文件夹里即可。对于每一条https记录,都定义下面的规则:

  
  
  
  
# HTTPS 证书相关的配置plugin_crt_path = /frp/目标域名证书.pemplugin_key_path = /frp/目标域名证书.keyplugin_host_header_rewrite = 192.168.0.125plugin_header_X-From-Where = frp

http则比较简单,和tcp类的端口差不多。我强烈建议您使用https远程访问Web界面,这样会比较安全

细心的小伙伴可能发现,上面的操作与sample.comhttptest.sample.comhttpstest.sample.com这三个域名有关。确实!如果你要使用某域名作为内网穿透所用,你需要将该域名解析到frps所属的VPS的公网ip。以后,你每添加一个新的域名,都要对其进行域名解析。这个道理不难理解吧?

配置yml文件

新建docker-compose文件:

  
  
  
  
vim $work/docker-compose.yml

将以下内容填入:

  
  
  
  
version: '3'services: frps: image: 'chenhw2/frp' container_name: frpc1 restart: unless-stopped environment: - ARGS=frpc volumes: - .:/frp

上线服务,稍等片刻即可:

  
  
  
  
cd $work && docker-compose up -d

观察日志输出:

  
  
  
  
cd $work && docker-compose logs -f

日后想下线服务,只要:

  
  
  
  
cd $work && docker-compose down

都是常规操作。

测试

SSH

你在自己的Shell终端里测试一下即可:

  • 地址:sample.com
  • 端口号:3505
  • 帐户:<自己的帐户>
  • 密码:<自己的密码>

HTTP

访问http://httptest.sample.com:6503可成功访问应用。

HTTPS

访问https://httpstest.sample.com:6504可成功访问应用。

小结

FRP内网穿透还是蛮简单的,是吧?根据我过去2年的使用经验来看,FRP内网穿透方案还是十分稳定的,体验不错!不过,我要提醒你一下:内网穿透的流量和带宽受限于frps端,即你的VPS。平时访问一下Web界面管理应用好了,千万不要做类似于用内网穿透地址看高清视频之类的事情,否则VPS的流量很容易耗尽!

参考

  • frp 与免费 SSL证书实现内网穿透并支持 HTTPS 访问
  • frps配置文件:https://github.com/ruinny/frp-in-docker/blob/master/frps.ini

本文使用 文章同步助手 同步

你可能感兴趣的:(Docker系列 通过FRP实现内网穿透)