简介
在现代网络环境中,内网穿透技术扮演着越来越重要的角色。它允许身处不同网络环境下的用户访问位于内网的服务,极大地扩展了网络应用的边界。本文将深入探讨内网穿透中的两种关键技术:正向代理和反向代理,并通过实际案例(frp反向代理、tinyproxy正向代理)详细阐述其原理与应用。
内网服务
内网服务通常指部署在局域网(LAN)内的各种应用,如Web服务器、数据库、远程桌面等。由于内网设备通常没有公网IP地址,因此无法直接从外部网络访问。内网穿透技术旨在解决这一难题,使得公网用户能够安全、便捷地访问内网资源。
http服务
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
gin.SetMode(gin.ReleaseMode)
// 1.创建路由
r := gin.Default()
// 2.绑定路由规则,执行的函数
r.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "hello World!")
})
// 3.监听端口
r.Run(":80")
}
- 运行
[root@localhost http]# ./main
[GIN] 2025/02/27 - 15:11:29 | 200 | 31.64µs | 127.0.0.1 | GET "/"
frp反向代理
frp(Fast Reverse Proxy)是一款高性能的反向代理应用,专注于内网穿透。它能够将内网服务通过具有公网IP的节点暴露到公网,支持TCP、UDP、HTTP、HTTPS等多种协议。frp由服务端(frps)和客户端(frpc)两部分组成。
frps
- 运行在外网机器上
- 默认端口为7000
- -c 参数指定配置文件
~/frp_0.61.1_linux_amd64 # ls -l
total 33856
-rw-r--r-- 1 postgres 118 11358 Dec 16 19:47 LICENSE
-rwxr-xr-x 1 postgres 118 15245464 Dec 16 19:44 frpc
-rw-r--r-- 1 postgres 118 142 Dec 16 19:47 frpc.toml
-rwxr-xr-x 1 postgres 118 19394712 Dec 16 19:44 frps
-rw-r--r-- 1 postgres 118 16 Dec 16 19:47 frps.toml
~/frp_0.61.1_linux_amd64 #
~/frp_0.61.1_linux_amd64 # cat frps.toml
bindPort = 7000
~/frp_0.61.1_linux_amd64 #
~/frp_0.61.1_linux_amd64 # ./frps -c ./frps.toml
2025-02-27 14:49:54.212 [I] [frps/root.go:105] frps uses config file: ./frps.toml
2025-02-27 14:49:54.699 [I] [server/service.go:237] frps tcp listen on 0.0.0.0:7000
2025-02-27 14:49:54.699 [I] [frps/root.go:114] frps started successfully
frpc
- -c 参数指定配置文件
- serverAddr 配置为frps外网机器IP地址
- 增加proxies节点
- name 为名称
- type 为tcp
- localIP 本地IP地址
- localPort 本地服务端口
- remotePort 远端服务端口
[xiaofeng@localhost frp_0.61.1_linux_amd64]$ ls -l
total 33856
-rwxr-xr-x 1 xiaofeng xiaofeng 15245464 Dec 16 19:44 frpc
-rw-r--r-- 1 xiaofeng xiaofeng 249 Feb 27 15:10 frpc.toml
-rwxr-xr-x 1 xiaofeng xiaofeng 19394712 Dec 16 19:44 frps
-rw-r--r-- 1 xiaofeng xiaofeng 16 Dec 16 19:47 frps.toml
-rw-r--r-- 1 xiaofeng xiaofeng 11358 Dec 16 19:47 LICENSE
[xiaofeng@localhost frp_0.61.1_linux_amd64]$
[xiaofeng@localhost frp_0.61.1_linux_amd64]$ cat frpc.toml
serverAddr = "122.187.254.45"
serverPort = 7000
[[proxies]]
name = "test-http"
type = "tcp"
localIP = "127.0.0.1"
localPort = 80
remotePort = 8000
[[proxies]]
name = "test-tcp"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000
[xiaofeng@localhost frp_0.61.1_linux_amd64]$
[xiaofeng@localhost frp_0.61.1_linux_amd64]$ ./frpc -c ./frpc.toml
2025-02-27 15:12:41.642 [I] [sub/root.go:142] start frpc service for config file [./frpc.toml]
2025-02-27 15:12:41.642 [I] [client/service.go:295] try to connect to server...
2025-02-27 15:12:41.704 [I] [client/service.go:287] [37b10632e73d03ce] login to server success, get run id [37b10632e73d03ce]
2025-02-27 15:12:41.705 [I] [proxy/proxy_manager.go:173] [37b10632e73d03ce] proxy added: [test-http test-tcp]
2025-02-27 15:12:41.724 [I] [client/control.go:168] [37b10632e73d03ce] [test-http] start proxy success
2025-02-27 15:12:41.724 [I] [client/control.go:168] [37b10632e73d03ce] [test-tcp] start proxy success
内网穿透测试
- 访问外网机器,端口为8000
- 访问路径:A(curl) --> B(frps) --> C(frpc) --> C(httpserver)
- 至此互联网机器通过访问frps机器的8000端口,实际是内网机器的80服务,实现内网穿透
- 利用的是反向代理(屏蔽服务端)
~ # curl http://122.187.254.45:8000
hello World!~ #
tinyproxy正向代理
当内网机器访问外网时,源IP为运营商分配的外网IP地址,这个IP地址过几天可能会变化,如果内网访问外网时想固定源IP地址,可以在外网机器上搭建运行tinyproxy,作为正向代理(屏蔽客户端)
tinyproxy搭建
- 编译
./configure
make
make install
- 配置
- 放开请求地址限制
#Allow 127.0.0.1
- 运行
~/tinyproxy # ls bin/
tinyproxy
~/tinyproxy #
~/tinyproxy # ls etc/tinyproxy/tinyproxy.conf
etc/tinyproxy/tinyproxy.conf
~/tinyproxy #
~/tinyproxy # ./bin/tinyproxy -c ./etc/tinyproxy/tinyproxy.conf
WARNING: logging deactivated (can't log to stdout when daemonized)
~/tinyproxy # ps aux|grep tiny
9789 nobody 0:00 ./bin/tinyproxy -c ./etc/tinyproxy/tinyproxy.conf
10950 root 0:00 grep tiny
~/tinyproxy #
~/tinyproxy # netstat -antup|grep tin
tcp 0 0 0.0.0.0:8888 0.0.0.0:* LISTEN 9789/tinyproxy
tcp 0 0 :::8888 :::* LISTEN 9789/tinyproxy
- 测试
- export http_proxy=122.187.254.45:8888
- curl -v www.baidu.com
[xiaofeng@localhost ~]$ export http_proxy=122.187.254.45:8888
[xiaofeng@localhost ~]$ curl -v www.baidu.com
* Rebuilt URL to: www.baidu.com/
* Uses proxy env variable http_proxy == '122.187.254.45:8888'
* Trying 122.187.254.45...
* TCP_NODELAY set
* Connected to 122.187.254.45 (122.187.254.45) port 8888 (#0)
> GET http://www.baidu.com/ HTTP/1.1
> Host: www.baidu.com
> User-Agent: curl/7.61.1
> Accept: */*
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 OK
< Via: 1.1 tinyproxy (tinyproxy/1.11.2)
< Accept-Ranges: bytes
< Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
< Content-Length: 2381
< Content-Type: text/html
< Date: Thu, 27 Feb 2025 08:02:42 GMT
< Etag: "588604eb-94d"
< Last-Modified: Mon, 23 Jan 2017 13:28:11 GMT
< Pragma: no-cache
< Server: bfe/1.0.8.18
< Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
<
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>©2017 Baidu <a href=http://www.baidu.com/duty/>使用百度前必读</a> <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a> 京ICP证030173号 <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
* Connection #0 to host 122.187.254.45 left intact
[xiaofeng@localhost ~]$