go庫中內建的反向 Proxy功能和內網代理

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

先看反向 Proxy庫

type ReverseProxy struct {// Director must be a function which modifies// the request into a new request to be sent// using Transport. Its response is then copied// back to the original client unmodified.Director func(*http.Request)// The transport used to perform proxy requests.// If nil, http.DefaultTransport is used.Transport http.RoundTripper// FlushInterval specifies the flush interval// to flush to the client while copying the// response body.// If zero, no periodic flushing is done.FlushInterval time.Duration// ErrorLog specifies an optional logger for errors// that occur when attempting to proxy the request.// If nil, logging goes to os.Stderr via the log package's// standard logger.ErrorLog *log.Logger// BufferPool optionally specifies a buffer pool to// get byte slices for use by io.CopyBuffer when// copying HTTP response bodies.BufferPool BufferPool}
接著我們看一個例子(網上拷的)

package mainimport ("log""net/http""net/http/httputil""net/url")type handle struct {host stringport string}func (this *handle) ServeHTTP(w http.ResponseWriter, r *http.Request) {remote, err := url.Parse("http://" + this.host + ":" + this.port)if err != nil {panic(err)}proxy := httputil.NewSingleHostReverseProxy(remote)proxy.ServeHTTP(w, r)}func startServer() {//被代理的伺服器host和porth := &handle{host: "127.0.0.1", port: "80"}err := http.ListenAndServe(":8888", h)if err != nil {log.Fatalln("ListenAndServe: ", err)}}func main() {startServer()}

使用起來很簡單。但是我有時有一種特殊需求。如內網代理(想訪問的目標伺服器在內網),那該如何辦呢?一般方向代理是Proxy 伺服器可以主動訪問目標伺服器的,現在目標伺服器在內網,Proxy 伺服器不能主動去訪問目標伺服器。通常我們的Proxy 伺服器在公網(對於客戶和目標伺服器),我們讓內網的目標伺服器先主動與Proxy 伺服器建立一個串連,當客戶需要經過Proxy 伺服器訪問目標內網伺服器時,再將請求經過內網伺服器與Proxy 伺服器預先建立的串連發送到內網伺服器。

我們有兩個服務程式,一個運行在Proxy 伺服器,一個運行在內網伺服器。

將上面代碼稍微改造就成為運行在Proxy 伺服器的程式:

package mainimport ("log""net/http""net/http/httputil""net/url")var conntype handle struct {}func (this *handle) ServeHTTP(w http.ResponseWriter, r *http.Request) {remote, err := url.Parse("http://127.0.0.1:443")if err != nil {panic(err)}proxy := httputil.NewSingleHostReverseProxy(remote)var pTransport http.RoundTripper = &http.Transport{Proxy:                 http.ProxyFromEnvironment,Dial:                  Dial,TLSHandshakeTimeout:   10 * time.Second,ExpectContinueTimeout: 1 * time.Second,}proxy.Transport = pTransportproxy.ServeHTTP(w,r)}func startServer() {//接受內網伺服器主動串連8088連接埠l, err := net.Listen("tcp", "0.0.0.0:8088")if err != nil {return }go func() {for {conn, err = l.Accept() //迴圈接受用戶端和裝置的串連請求if err != nil {beego.Error("Can't Accept: ", err)return}}}()//接受用戶端的串連h := &handle{}err := http.ListenAndServe(":8888", h)if err != nil {log.Fatalln("ListenAndServe: ", err)}}func Dial(network, address string) (net.Conn, error) {return conn, nil}func main() {startServer()}

具體架構就是在這樣,文法不一定對。

用戶端代碼(大概):

func proxy(local, remote string) {conf := &tls.Config{InsecureSkipVerify: true,}rp, err := tls.Dial("tcp", remote, conf)if err != nil {beego.Error("Can't' connect:", remote, " err:", err)return}defer util.CloseConn(rp)config := &tls.Config{InsecureSkipVerify: true} //不做認證校正lp, err := tls.Dial("tcp", local, config)if err != nil {beego.Error("Can't' connect:", other, " err:", err)rp.Close()return}defer util.CloseConn(lp)//buf = make([]byte, 1024*1024)rp.SetReadDeadline(time.Time{})lp.SetReadDeadline(time.Time{})flag := make(chan error)go Transfer(rp, lp, flag)}func Transfer(a, b net.Conn, flag chan error) {cp := func(r, w net.Conn) {n, err := io.Copy(r, w)r.Close()w.Close()beego.Debug("Transfer", n, " bytes between ", a.RemoteAddr(), " and ", b.RemoteAddr())flag <- err}go cp(a, b)go cp(b, a)}main(){//本地服務地址和Proxy 伺服器接受內網伺服器串連的地址 proxy("127.0.0.1:443","192.168.16.110:8088")}

以上僅是大概架構,以供參考

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.