docker+frp,轻松实现内网穿透,访问内网服务




frp概念

frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。

frp原理

1.frp 主要由 客户端(frpc) 和 服务端(frps) 组成,服务端通常部署在具有公网 IP 的机器上,客户端通常部署在需要穿透的内网服务所在的机器上。
2.内网服务由于没有公网 IP,不能被非局域网内的其他用户访问。
3.用户通过访问服务端的 frps,由 frp 负责根据请求的端口或其他信息将请求路由到对应的内网机器,从而实现通信。

frp特性

通过在具有公网 IP 的节点上部署 frp 服务端,可以轻松地将内网服务穿透到公网,同时提供诸多专业的功能特性,这包括:

  • 客户端服务端通信支持 TCP、KCP 以及 Websocket 等多种协议。
  • 采用 TCP 连接流式复用,在单个连接间承载更多请求,节省连接建立时间。
  • 代理组间的负载均衡。
  • 端口复用,多个服务通过同一个服务端端口暴露。
  • 多个原生支持的客户端插件(静态文件查看,HTTP、SOCK5 代理等),便于独立使用 frp 客户端完成某些工作。
  • 高度扩展性的服务端插件系统,方便结合自身需求进行功能扩展。
  • 服务端和客户端 UI 页面。

frp 支持多种代理类型来适配不同的使用场景

类型描述
tcp单纯的 TCP 端口映射,服务端会根据不同的端口路由到不同的内网服务。
udp单纯的 UDP 端口映射,服务端会根据不同的端口路由到不同的内网服务。
http针对 HTTP 应用定制了一些额外的功能,例如修改 Host Header,增加鉴权。
https针对 HTTPS 应用定制了一些额外的功能。
stcp安全的 TCP 内网代理,需要在被访问者和访问者的机器上都部署 frpc,不需要在服务端暴露端口。
sudp安全的 UDP 内网代理,需要在被访问者和访问者的机器上都部署 frpc,不需要在服务端暴露端口。
xtcp点对点内网穿透代理,功能同 stcp,但是流量不需要经过服务器中转。
tcpmux支持服务端 TCP 端口的多路复用,通过同一个端口访问不同的内网服务。

frp docker镜像构建

# 1. docker-entrypoint.sh
cat >> docker-entrypoint.sh << EOF
#!/bin/sh

FRP_COMPONENT=$1
shift

FRP_HOME=${FRP_HOME:-/opt/frp}
if [ "$FRP_COMPONENT" = "frps" ]; then
    $FRP_HOME/bin/frps -c $FRP_HOME/conf/frps.ini $@
elif [ "$FRP_COMPONENT" = "frpc" ]; then
    $FRP_HOME/bin/frpc -c $FRP_HOME/conf/frpc.ini $@
else
    $@
fi
EOF

# 2. Dockerfile
cat >> Dockerfile << EOF
FROM alpine:3.7

MAINTAINER darebeat

ENV SYS_ARCH=amd64 \
    FRP_VER=0.34.1 \
    FRP_HOME=/opt/frp \
    PATH=$PATH:$FRP_HOME/bin

COPY docker-entrypoint.sh /

RUN apk --no-cache add wget tar tzdata \
  && cp -r -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
  && wget --no-check-certificate https://github.com/fatedier/frp/releases/download/v${FRP_VER}/frp_${FRP_VER}_linux_${SYS_ARCH}.tar.gz && tar zxvf frp_${FRP_VER}_linux_${SYS_ARCH}.tar.gz \
  && rm -rf frp_${FRP_VER}_linux_${SYS_ARCH}.tar.gz \
  && mkdir -p /opt/frp/conf \
  && mkdir -p /opt/frp/bin \ 
  && cp frp_${FRP_VER}_linux_${SYS_ARCH}/frps /opt/frp/bin \
  && cp frp_${FRP_VER}_linux_${SYS_ARCH}/frpc /opt/frp/bin \
  && cp frp_${FRP_VER}_linux_${SYS_ARCH}/frps.ini /opt/frp/conf \
  && cp frp_${FRP_VER}_linux_${SYS_ARCH}/frpc.ini /opt/frp/conf \
  && rm -rf frp_${FRP_VER}_linux_${SYS_ARCH} \
  && chmod +x /opt/frp/bin/frps \
  && chmod +x /opt/frp/bin/frpc \
  && apk del --purge wget tar

WORKDIR /opt/frp

ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["sh", "-c"]

在有外网IP的主机中部署frps

mkdir -p conf
cat >> conf/frps.ini << EOF [common] bind_port=17000 token=myToken vhost_http_port=10080 vhost_https_port=10443 dashboard_port=17500 dashboard_user=admin dashboard_pwd=admin tcp_mux=true max_pool_count=10 EOF cat>> docker-compose.yaml << EOF
version: "3"
services:
  frp:
    image: darebeat/frp:${FRP_VERSION:-0.34.1}
    command: ${FRP_NODE:-frps}
    container_name: ${FRP_NODE:-frps}
    ports:
      - "17000:17000"
      - "17500:17500"
      - "10022:10022" # ssh 
      - "13306:13306" # mysql
    volumes:
      - ./conf/${FRP_NODE:-frps}.ini:/opt/frp/conf/${FRP_NODE:-frps}.ini
EOF

docker-compose up -d

在需要穿透的内网主机上部署frpc

# 加入公网IP为 183.123.45.21
# 本机局域网IP为 192.168.23.99
mkdir -p conf
cat >> conf/frpc.ini << EOF [common] server_addr=183.123.45.21 server_port=17000 token=myToken [ssh] type=tcp local_ip=192.168.23.99 local_port=22 remote_port=10022 use_encryption=true use_compression=true [mysql] type=tcp local_ip=192.168.23.99 local_port=3306 remote_port=13306 EOF cat>> docker-compose.yaml << EOF
version: "3"
services:
  frp:
    image: darebeat/frp:${FRP_VERSION:-0.34.1}
    command: ${FRP_NODE:-frpc}
    container_name: ${FRP_NODE:-frpc}
    network_mode: host 
    volumes:
      - ./conf/${FRP_NODE:-frpc}.ini:/opt/frp/conf/${FRP_NODE:-frpc}.ini
EOF
docker-compose up -d

在别的机器上访问内网服务

ssh -p 10022 user@183.123.45.21 # ssh
http://183.123.45.21:17500 # dashboard
mysql -h 183.123.45.21 -P 13306 -u root -p # mysql

dashboard 预览



文章作者: darebeat
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 darebeat !
 上一篇
Redis基础知识 Redis基础知识
Redis是完全开源的,遵守BSD协议,是一个高性能的key-value数据库.为了保证效率,数据都是缓存在内存中,他也可以周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件。
2020-10-29
下一篇 
Java基础知识 Java基础知识
一篇关于java基础知识的文章。
2020-10-26
  目录