0.2.35:支持http代理

This commit is contained in:
chenjia404
2026-04-07 10:29:53 +08:00
parent 6b59b036dd
commit 7744ddd916
5 changed files with 169 additions and 27 deletions
+17 -7
View File
@@ -18,9 +18,10 @@ The node private key file is in the current directory, the suffix of the file na
| nodisc | bool | Prohibit broadcasting to improve performance, connecting nodes must use links with ip and port |
| user | string | specify which local key file to use |
| update | bool | Update the latest version from GitHub, it will verify the upgrade package signature, sha512 |
| auto_update | bool | auto update |
| max_peers | int | Maximum number of connections, default 500 |
| socks5 | ip | socks5 listens to ip, for example 127.0.0.1:10086, if the l field is empty, use this field |
| auto_update | bool | auto update |
| max_peers | int | Maximum number of connections, default 500 |
| socks5 | ip | socks5 listens to ip, for example 127.0.0.1:10086, if the l field is empty, use this field |
| http | ip | http proxy listens to ip, for example 127.0.0.1:10087, if the l field is empty, use this field. Supports both HTTP and HTTPS CONNECT |
### build
` go build -trimpath -ldflags="-w -s" `
@@ -50,12 +51,21 @@ Note that your node id will be output here, and then sent to your friends throug
The complete ip plus port is required here.
### connect
`./go-p2ptunnel -id 12D3 -l 127.0.0.1:10089`
### connect
`./go-p2ptunnel -id 12D3 -l 127.0.0.1:10089`
The connection may take a few seconds to 1 minute. After the connection is successful, the remote port is mapped to 127.0.0.1:10089
Then a friend can connect to 127.0.0.1:10089 on the remote desktop.
Then a friend can connect to 127.0.0.1:10089 on the remote desktop.
### start local HTTP/HTTPS proxy
Remote side:
`./go-p2ptunnel -nodisc -http 127.0.0.1:10087`
Local side:
`./go-p2ptunnel -id 12D3 -l 127.0.0.1:10087`
Then configure the client program to use `http://127.0.0.1:10087` as its proxy. HTTPS is supported through the `CONNECT` method.
### releases
@@ -87,4 +97,4 @@ Service naming `Protocol of this application + / + Protocol of the service name`
## Upstream project
[go-libp2p](https://github.com/libp2p/go-libp2p)
[go-libp2p](https://github.com/libp2p/go-libp2p)
+21 -7
View File
@@ -17,9 +17,10 @@
| nodisc | bool | 禁止广播提高性能,连接节点必须使用带ip和端口的链接 |
| user | string | 指定使用本地的哪一个key文件 |
| update | bool | 从GitHub更新最新版,会验证升级包签名、sha512 |
| auto_update | bool | 开启自动更新 |
| max_peers | int | 最大连接数,默认500 |
| socks5 | ip | socks5监听ip,例如 127.0.0.1:10086,如果l字段为空,就使用这个字段 |
| auto_update | bool | 开启自动更新 |
| max_peers | int | 最大连接数,默认500 |
| socks5 | ip | socks5监听ip,例如 127.0.0.1:10086,如果l字段为空,就使用这个字段 |
| http | ip | http代理监听ip,例如 127.0.0.1:10087,如果l字段为空,就使用这个字段,支持 HTTP 和 HTTPS CONNECT |
### 流量特征
@@ -68,17 +69,30 @@ v0.0.6 以后,程序会自动从GitHub更新最新版版本,会验证文件
这里需要完整的ip加端口。
### 连接
`./go-p2ptunnel -id 12D3 -l 127.0.0.1:10089`
### 连接
`./go-p2ptunnel -id 12D3 -l 127.0.0.1:10089`
连接可能需要几秒到1分钟,连接成功后,就把远程端口映射到了 127.0.0.1:10089
然后朋友在远程桌面连接 127.0.0.1:10089 即可。
然后朋友在远程桌面连接 127.0.0.1:10089 即可。
### 启动本地 HTTP/HTTPS 代理
服务端:
`./go-p2ptunnel -nodisc -http 127.0.0.1:10087`
本地客户端:
`./go-p2ptunnel -id 12D3 -l 127.0.0.1:10087`
然后在需要代理的程序中把 HTTP 代理设置为 `http://127.0.0.1:10087`HTTPS 会通过 `CONNECT` 自动转发。
### 打包
`goreleaser release --skip-publish --skip-validate --clean`
### 发布
`goreleaser release --skip=validate --clean`
### 验证签名
```
@@ -106,4 +120,4 @@ gpg --verify .\ethtweet_0.7.4_windows_amd64.zip.asc .\ethtweet_0.7.4_windows_amd
## 上游项目
[go-libp2p](https://github.com/libp2p/go-libp2p)
[go-libp2p](https://github.com/libp2p/go-libp2p)
+6 -4
View File
@@ -1,10 +1,12 @@
net:
listen: 127.0.0.1:10086
id: 12D3KooWLHjy7DM6omRpgBsU2Bpi2UcywDN8FwX9UNwnzEsZep1C
net:
listen: 127.0.0.1:10086
# socks5: 127.0.0.1:10086
# http: 127.0.0.1:10087
id: 12D3KooWLHjy7DM6omRpgBsU2Bpi2UcywDN8FwX9UNwnzEsZep1C
p2p_port: 4001
max_peers: 500
no_disc: false
key:
user: user #当前使用的key id
store: ./ #存储目录
store: ./ #存储目录
+16 -8
View File
@@ -19,6 +19,7 @@ var flag_update = flag.Bool("update", false, "update form github")
var flag_auto_update = flag.Bool("auto_update", false, "update form github")
var configPath = flag.String("config", "", "config file")
var socks5 = flag.String("socks5", "", "socks5 listen ip")
var httpProxy = flag.String("http", "", "http proxy listen ip")
var Cfg *Conf
@@ -26,6 +27,7 @@ type Conf struct {
User string
Listen string
Socks5 string
HTTPProxy string
Id string
P2pPort int
MaxPeers int
@@ -50,17 +52,20 @@ func LoadConfigByPath(p string) error {
}
if p == "" {
Cfg = &Conf{
User: *flag_user,
Listen: *ip,
Socks5: *socks5,
Id: *id,
P2pPort: *p2p_port,
MaxPeers: *max_peers,
Nodisc: *flag_nodisc,
Update: *flag_update,
User: *flag_user,
Listen: *ip,
Socks5: *socks5,
HTTPProxy: *httpProxy,
Id: *id,
P2pPort: *p2p_port,
MaxPeers: *max_peers,
Nodisc: *flag_nodisc,
Update: *flag_update,
}
if len(Cfg.Socks5) >= 6 && len(Cfg.Listen) == 0 {
Cfg.Listen = Cfg.Socks5
} else if len(Cfg.HTTPProxy) >= 6 && len(Cfg.Listen) == 0 {
Cfg.Listen = Cfg.HTTPProxy
}
return nil
}
@@ -78,6 +83,7 @@ func LoadConfigByPath(p string) error {
Cfg.User = viper.GetString("key.user")
Cfg.Listen = viper.GetString("net.listen")
Cfg.Socks5 = viper.GetString("net.socks5")
Cfg.HTTPProxy = viper.GetString("net.http")
Cfg.Id = viper.GetString("net.id")
Cfg.P2pPort = viper.GetInt("net.p2p_port")
Cfg.MaxPeers = viper.GetInt("net.max_peers")
@@ -86,6 +92,8 @@ func LoadConfigByPath(p string) error {
Cfg.AutoUpdate = *flag_auto_update
if len(Cfg.Socks5) >= 6 && len(Cfg.Listen) == 0 {
Cfg.Listen = Cfg.Socks5
} else if len(Cfg.HTTPProxy) >= 6 && len(Cfg.Listen) == 0 {
Cfg.Listen = Cfg.HTTPProxy
}
return nil
}
+109 -1
View File
@@ -6,6 +6,7 @@ import (
"io"
"log"
"net"
"net/http"
"os"
"path/filepath"
"runtime"
@@ -84,7 +85,7 @@ func loadUserPrivKey() (priv crypto.PrivKey, err error) {
}
var (
version = "0.2.33"
version = "0.2.35"
gitRev = ""
buildTime = ""
)
@@ -182,6 +183,14 @@ RE:
}()
log.Printf("socks5 open:%s\n", config.Cfg.Socks5)
}
if len(config.Cfg.HTTPProxy) >= 6 {
go func() {
if err := startHTTPProxy(config.Cfg.HTTPProxy); err != nil {
panic(err)
}
}()
log.Printf("http proxy open:%s\n", config.Cfg.HTTPProxy)
}
//打开隧道
if config.Cfg.Id == "" {
@@ -332,3 +341,102 @@ func pipe(src net.Conn, dest network.Stream) {
}()
wg.Wait()
}
func startHTTPProxy(listenAddr string) error {
server := &http.Server{
Addr: listenAddr,
Handler: http.HandlerFunc(handleHTTPProxy),
}
return server.ListenAndServe()
}
func handleHTTPProxy(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodConnect {
handleHTTPConnect(w, r)
return
}
transport := http.DefaultTransport.(*http.Transport).Clone()
transport.Proxy = nil
req := r.Clone(r.Context())
req.RequestURI = ""
removeHopHeaders(req.Header)
if req.URL.Scheme == "" {
req.URL.Scheme = "http"
}
if req.URL.Host == "" {
req.URL.Host = r.Host
}
resp, err := transport.RoundTrip(req)
if err != nil {
http.Error(w, err.Error(), http.StatusBadGateway)
return
}
defer resp.Body.Close()
removeHopHeaders(resp.Header)
copyHeader(w.Header(), resp.Header)
w.WriteHeader(resp.StatusCode)
_, _ = io.Copy(w, resp.Body)
}
func handleHTTPConnect(w http.ResponseWriter, r *http.Request) {
dstConn, err := net.Dial("tcp", r.Host)
if err != nil {
http.Error(w, err.Error(), http.StatusBadGateway)
return
}
hijacker, ok := w.(http.Hijacker)
if !ok {
_ = dstConn.Close()
http.Error(w, "proxy does not support hijacking", http.StatusInternalServerError)
return
}
clientConn, buf, err := hijacker.Hijack()
if err != nil {
_ = dstConn.Close()
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
_, _ = clientConn.Write([]byte("HTTP/1.1 200 Connection Established\r\n\r\n"))
if n := buf.Reader.Buffered(); n > 0 {
_, _ = io.CopyN(dstConn, buf, int64(n))
}
go proxyConn(dstConn, clientConn)
go proxyConn(clientConn, dstConn)
}
func proxyConn(dst net.Conn, src net.Conn) {
defer dst.Close()
defer src.Close()
_, _ = io.Copy(dst, src)
}
func copyHeader(dst, src http.Header) {
for k, vv := range src {
for _, v := range vv {
dst.Add(k, v)
}
}
}
func removeHopHeaders(header http.Header) {
for _, key := range []string{
"Connection",
"Proxy-Connection",
"Keep-Alive",
"Proxy-Authenticate",
"Proxy-Authorization",
"Te",
"Trailer",
"Transfer-Encoding",
"Upgrade",
} {
header.Del(key)
}
}