Proxy service Extensions

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Before the implementation of a proxy service, at that time to consider is as long as support SOCKS5, because I often use chrome, with switchysharp, experience is very good. But now I'm a little annoyed with Chrome, which is now too big to occupy too much resources. And I have the habit of locking the Web page, one open chrome, on more than 10 or even more than 20 process up, let me very uncomfortable. But it has to be said that Chrome's security design is great. Then I tried the Firefox, the amount, I think it is similar to ie. then give up, and then see the IE on hand has reached 11, usually used to feel very good, so I want to support IE agent.

IE proxy mechanism is more embarrassing, for example, it only supports SOCKS4, does not support SOCKS5, and then divided into HTTP proxy, HTTPS proxy, as well as FTP proxy. Nor is there a powerful proxy plug-in mechanism like chrome. Although IE provides PAC mechanism, but have to say, this mechanism is also very chicken, not like switchysharp can do real-time increase and decrease rules. For the above reasons, I have in the original code based on the addition of the above several agents, but does not support the FTP proxy.

SOCKS4 Agent

SOCKS4 protocol is relatively simple, you can refer to the document is the wiki of this, and openssh this article. There is a socks4a agreement behind it, but this socks4a is basically not seen by anyone. The SOCKS4 Protocol's Connect command format is simple, just a request packet and a response packet. The first field of the request package is the version number, takes 1 bytes, is the 0x04, the second field is the command type, consumes 1 bytes, and 0x01 represents the Connect command, that is, the request link which ip:port,0x02 is bind, generally used for the FTP scene, I did not implement. The third field is the peer port, occupies 2 bytes, the byte order is the network byte sequence, the fourth field is the peer IP, takes 4 bytes, the byte order is the network byte order, and the fifth field is the UserID, variable length, ending in 0x00. It is important to note that under IE11, the UserID is the current user name and will not be empty. So to read the full UserID and the last 0x00.

The first field in the response packet occupies one byte, the data is 0, the second field occupies one byte, indicates the state, 0x5a indicates success, 0x5b indicates rejection or failure, and so on; the third byte and the fourth field are 6 bytes, which are ignored and 0 can be filled directly.

The whole protocol is a lot simpler, much simpler than SOCKS5, but not SOCKS5 powerful. Because SOCKS4 only support ip:port way, also means that iefq, will go to the local DNS, and then get the address to go socks agent. The problem here is that if DNS is contaminated, it means that FQ failed. So we have to use the HTTP proxy and the HTTP tunnel behind it.

HTTP tunnel (HTTP tunneling)

HTTP tunneling is relatively straightforward. Is that the client is linked to the server through the HTTP protocol, requesting the server to link a domain name or a port on the IP. The protocol is very simple, that is, the client sends connect Domain:port http/1.0\r\n\r\n. After receiving the request, the server will link to the specified domain name and port, and when the link succeeds, it will reply to the client http/1.0 Connection established\r\n\r\n the client receives the reply and begins to forward the data through the proxy. This time the agent is blind turn, and the SOCKS protocol is the same.

With go implementation of the time is relatively simple, through the Net/http package can be completed. Implement a Servehttp method, and then find that the Connect method requests that the connection hijacked off. The specific code is as follows:

HJ, OK: = response. ( http. Hijacker)if ! OK {    "hijacker failed", http. Statusinternalservererror)    return}conn, _, err:= HJ. Hijack ()if err ! = Nil {    http. Error (response, Err. Error (), HTTP. Statusinternalservererror)    return}defer Conn. Close ()

One thing to note is that after hijack, if you want to reply to the HTTP protocol format data, it is necessary to operate, there is no way to use net/http. Responsewriter provides the method. Fortunately, Go's FMT package provides the fprint/fprintf function, so it's also easy to operate.

Another point is that this HTTP tunnel allows additional data to be carried in the body for optimization purposes when connect is initiated. Therefore, after establishing the remote link, check if there is still body data, if any, send out the data.

HTTP Proxy

I originally thought that since has the HTTP tunnel way proxy mechanism, that all uses this set Bai, the result IE is not so, the HTTP tunnel only uses in the HTTPS type URL, but the ordinary HTTP URL goes is the ordinary HTTP proxy mechanism. HTTP normal requests are similar to the following: get/xxx/yyyy/zzzz.html http/1.0, while HTTP proxies are GET http://www.qqqq.com/xxx/yyy/zzz.html http/ 1.0, then an additional HTTP header proxy-connection will be added. This is the first to do what Google. When processing an HTTP proxy request from a client, my approach is to replace the URL with a normal relative URI, then check for proxy-connection, if present, get the corresponding value, delete the header, and add the Connection header, The value is the value corresponding to the original proxy-connection. Then forward to the peer server. Go provides a package net/http/httputil that encapsulates the implementation of a reverse proxy. You only need to provide the function that establishes the link as well as the HTTP. The function that the request handles. The code is specific as follows:

Func newhttpproxy (Remotesocks, Cryptomethodstring, Password []byte) *Httpproxy {return&httpproxy{Reverseproxy:&Httputil. reverseproxy{Director:director, Transport:&http. transport{Dial:func (Network, addrstring) (NET. Conn, error) {returnDial (network, addr, remotesocks, Cryptomethod, Password)},},}}func dial (net Work, addr, remotesocks, Cryptomethodstring, Password []byte) (NET. Conn, error) {tcpaddr, err:=Net. RESOLVETCPADDR (Network, addr)ifErr! =Nil {returnnil, err} remotesvr, err:=newremotesocks (remotesocks, Cryptomethod, password)ifErr! =Nil {returnnil, err}//version (1) + cmd (1) + reserved (1) + addrtype (1) + domainlength (1) + maxdomainlength (+ +) + port (2)Req: = []byte{0x05,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00} copy (req[4:8], []byte(TcpAddr.IP.To4 ())) binary. Bigendian.putuint16 (req[8:Ten], UInt16 (tcpaddr.port)) Err=Remotesvr.handshake (req)ifErr! =Nil {remotesvr.close ()returnNil, err} conn:= &httpproxyconn{Remotesocks:remotesvr,}returnConn, NIL}FUNC Director (Request*http. Request) {u, err:=URL. Parse (Request. RequestUri)ifErr! =Nil {return} request. RequestUri=U.requesturi () V:= Request. Header.get ("proxy-connection")    ifV! =""{request. Header.del ("proxy-connection") Request. Header.del ("Connection") Request. Header.add ("Connection", V)}}

Summarize:

essentially HTTP proxies and HTTP tunnels can be implemented on the same port, but I'm not doing this because I think it's easier to test and modify the code apart. Can save a lot of trouble. But the same port can be reused with a simple combination, and I'll try to modify it later . HTTP Proxy and tunnel are now implemented on the same port, and the corresponding functions are implemented by a simple combination. and SOCKS4 and SOCKS5 are supposed to be able to use the same port, but considering the code to determine the version of the problem, I think this is not as straightforward as the implementation of the simple.

The following can also be considered is to switchysharp agent policy to the agent service, and then write an IE plug-in to achieve similar switchysharp functions, so it will be more convenient. By the way, in fact, now IE is doing very well.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.