frp 使用 Docker 容器进行内网穿透

提前准备

  • 两台公网 IP 主机(轻量型服务器即可,一台备案主机可使用域名,另一台作为中转)
  • 一个备案域名(无备案可使用国外主机)
  • 一台内网主机

frpc 客户端内网主机配置

Docker Compose 文件

version: '3'
services:
  app:
    image: snowdreamtech/frpc:alpine
    restart: always
    volumes:
      - ./frpc.toml:/etc/frp/frpc.toml
    network_mode: host

frpc.toml 文件

serverAddr = "117.72.66.33"  # 连接服务端的地址(公网主机 IP 地址)
serverPort = 7000             # 连接服务端的端口,默认为 7000
auth.token = "xxx"            # 身份验证令牌,frpc 要与 frps 一致
log.to = "/usr/local/frp/frps.log"  # 日志相关
log.level = "info"
log.maxDays = 3

# 代理配置
[[proxies]]
name = "web01"  # 代理名称
type = "tcp"    # 代理类型
localIP = "127.0.0.1"  # 被代理的本地服务 IP
localPort = 8000       # 被代理的本地服务端口
remotePort = 8000      # 服务端绑定的端口

启动客户端:

docker-compose up -d

frps 服务端公网主机配置

Docker Compose 文件

version: '3'
services:
  app:
    image: snowdreamtech/frps:alpine
    restart: always
    volumes:
      - ./frps.toml:/etc/frp/frps.toml
    network_mode: host

frps.toml 文件

bindAddr = "0.0.0.0"         # 服务端监听地址
bindPort = 7000              # 服务端与客户端通信端口
kcpBindPort = 7000           # 服务端监听 KCP 协议端口
webServer.addr = "0.0.0.0"   # webServer 后台管理地址
webServer.port = 7002         # webServer 后台管理端口
webServer.user = "root"      # webServer 后台登录用户名
webServer.password = "root"   # webServer 后台登录密码
auth.token = "xxx"           # 身份验证令牌
log.to = "/usr/local/frp/frps.log"  # 日志相关
log.level = "info"
log.maxDays = 3

启动服务端:

docker-compose up -d

备案服务器配置

由于 frps 服务器没有备案,无法直接使用域名进行访问。我们可以使用另一台备案的机器来实现反向代理,并且使用 Docker 进行 HTTPS 证书的自动申请和续期。

所需镜像

  • alpine:latest:占位镜像,用于提供域名供 acme 自动申请。
  • nginxproxy/nginx-proxy:alpine:Nginx 反向代理。
  • nginxproxy/acme-companion:2.2:自动申请和续签 HTTPS 证书。

Docker Compose 文件

version: '3'
services:
  dj-gpt:
    image: alpine:latest
    restart: always
    command: tail -f /dev/null
    environment:
      - VIRTUAL_HOST=xxx.com.cn
      - LETSENCRYPT_HOST=xxx.com.cn
      - [email protected]

  nginx:
    image: nginxproxy/nginx-proxy:alpine
    restart: always
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - /srv/proxy/certs:/etc/nginx/certs:ro
      - /srv/proxy/vhost.d:/etc/nginx/vhost.d
      - /srv/proxy/html:/usr/share/nginx/html
    container_name: nginx-proxy
    ports:
      - 80:80
      - 443:443
    logging:
      driver: json-file
      options:
        max-size: "20m"
        max-file: "1"

  https:
    image: nginxproxy/acme-companion:2.2
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /srv/proxy/certs:/etc/nginx/certs
      - /srv/proxy/vhost.d:/etc/nginx/vhost.d
      - /srv/proxy/html:/usr/share/nginx/html
      - /srv/proxy/acme:/etc/acme.sh
    container_name: nginx-proxy-acme
    environment:
      - [email protected]
      - NGINX_PROXY_CONTAINER=nginx-proxy
    logging:
      driver: json-file
      options:
        max-size: "20m"
        max-file: "1"

反向代理配置

在 Nginx 容器的 /srv/proxy/vhost.d 中创建一个文件,文件名为 ${VIRTUAL_HOST}_location_override,例如 xxx.com.cn_location_override,文件内容如下:

location / {
    proxy_pass http://xxx:8000;  # frps 公网电脑可以访问内网服务的 IP 及端口号
}

完成配置

至此,启动容器后访问 xxx.com.cn 即可访问你的内网服务。虽然配置流程较繁琐,但通过该方案可以实现 证书 的自动申请与续期。

另外你的frps服务器可以设置一下ip白名单,让所有的请求都走域名

16 个赞

用黑裙搭的,frp还是挺好用的

1 个赞

感谢你的教程

1 个赞

收藏收藏,插个眼

1 个赞

他的原理是啥啊 一直很想搞 但是怕自己的電腦會被fofa佬搞

感谢分享这个教程

这个不错,可以直接套来用了。我的使用场景是:软路由docker了一个emby内网服务器,家宽拔号获得是内网IP。但我想内网穿透,把这个emby服务器放公网上,这样可以在外地观看。

现在frp如果也是docker的,那是不是上面两行,我不填frp容器的127.0.0.1,而是填emby的内网ip(192.168.1.xx) :port就行了?

同网段就行,我这是本机部署的局域网一样

这个无所谓吧,把密码强度拉高不就行了

那我先蒐藏了 之後有空來搞

有点厉害支持~~

哥 放在公网外面卡带宽多少的?我这上行20兆 有些卡…

我的配置:
流量包
200GB/月 带宽上限 3Mbps
不卡啊。。。你干啥??

我指的是看电影卡 ,不看电影都没问题的

看电影得10m起步?