mirror of
https://github.com/chenjia404/go-p2ptunnel.git
synced 2026-04-23 00:27:14 +08:00
0.2.35:支持http代理
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user