How to implement forward proxy with Go language

Source: Internet
Author: User
Tags docker hub docker run circleci
This is a creation in Article, where the information may have evolved or changed. A forward proxy is a proxy method that handles network requests from a set of intranet clients to external machines. In fact, the forward proxy is the middleman between your app and the server you're connecting to. It works on the HTTP (S) protocol and is deployed at the edge of the network infrastructure. You can usually see a forward proxy in a large organization or university, which is used for authorization management or network security control. I find it useful to work with a container or a dynamic cloud environment, as you face a set of communication problems with the server and the external network. If you're working in a dynamic environment such as AWS and AZure, you'll have a number of servers and a number of public IP addresses that are variable. The same is true when you run an application on a Kubernetes cluster, and containers can be scattered around. Now suppose you have a client that gives you a range of public IP, because he needs to set up a firewall. How do you provide this feature? This problem is simple in some cases and can be very complex in some cases. December 1, 2015, a user raised the issue in [Circleci Forum] (https://discuss.circleci.com/t/circleci-source-ip/1202), and the problem has not been closed. Of course, Circleci is great. I'm just trying to give an example, not to blame them. One possible way to solve this problem is to use a forward proxy. You can have a group of nodes run with the same static IP, and then provide the list to the customer. Almost all cloud service providers do this, such as Digitalocean floating IP (floating IP), AWS elastic ip (elastic IP), and so on. You can forward requests to this (proxy) pool by configuring your app. In this way, the IP that the endpoint service obtains is the IP of the forward proxy node, not the internal IP. A forward proxy can be another layer of security for your network infrastructure, because you can easily scan and control the packets sent from your internal network in a centralized location. The forward proxy does not cause a single point of failure because you can run multiple forward proxy services, and they are well-scaled. At the bottom, the ' CONNECT ' method of HTTP is a forward proxy. The > Connect method converts a request connection into a transparent TCP/IP channel, typically used for SSL-encrypted communication (HTTPS) on an unencrypted HTTP proxy. Many HTTP clients written in various languages have supported this feature in a transparent way. Here, I use a small example of the Go language and [Privoxy] (https://www.privoxy.org/) toTell everyone, this is very simple. First, we create an app called ' Whoyare '. It is an HTTP server that functions to return your remote address. "' Gopackage mainimport (" Encoding/json "" Net/http ") func Main () {http. Handlefunc ("/whoyare", func (w http). Responsewriter, R *http. Request) {W.header (). Set ("Content-type", "Application/json") body, _: = json. Marshal (map[string]string{"addr": R.remoteaddr,}) W.write (Body)}) http. Listenandserve (": 8080", nil)} "If you access the path '/whoyare ' with the ' GET ' method, you will get a response similar to the following JSON format: ' {" addr ":" 34.35.23.54 "} ', where ' 34.35.23.54 ' is the address of your public network. If you are using a laptop, you should get the result of ' localhost ' after making a request on the terminal. You can try it with ' curl ': 18:36 $ curl-v http://localhost:8080/whoyare* tcp_nodelay set> get/whoyare http/1.1> user-agent:c Url/7.58.0> Accept: */*>< http/1.1 ok< content-type:application/json< date:sun, 2018 17:36:40 gmt< content-length:31<* Connection #0 to host localhost-left intact{"addr": "localhost:38606"} I wrote another program that uses ' HTTP '. Client ' Prints the response on the standard output. You can run this program with the ' Whoyare ' service already running: ' Gopackage mainimport ("Io/ioutil" "Log" "Net/http" "OS") type Whoiam struct {Addr String}func main () {URL: = "http://localhost:8080" if "! = OS. Getenv ("url") {url = os. Getenv ("URL")}log. Printf ("Target%s.", URL) resp, err: = http. Get (url + "/whoyare") if err! = Nil {log. Fatal (Err. Error ())}defer resp. Body.close () body, err: = Ioutil. ReadAll (resp. Body) If err! = Nil {log. Fatal (Err. Error ())}println ("You is" + String (Body)} "is a very simple example, but you can use it in many complex situations. To make the example clearer, I created two virtual machines on Digitalocean: One running ' privoxy ' and the other running ' Whoyare '. * Whoyare:public IP 188.166.17.88* privoxy:public IP 167.99.41.79Privoxy is an easy-to-use forward proxy. In contrast, Nginx and Haproxy are not suitable for use in this scenario because they do not support the ' CONNECT ' method. I created a Docker image on the Docker Hub and you can run it directly, using port 8118 by default. CORE@COREOS-S-1VCPU-1GB-AMS3-01 ~ $ docker run-it--rm-p 8118:8118gianarb/privoxy:latest2018-03-18 17:28:05.589 7fbbf41dab88 info:privoxy version 3.0.262018-03-18 17:28:05.589 7fbbf41dab88 info:program name:privoxy2018-03-18 17:28 : 05.591 7fbbf41dab88 info:loading filter file:/etc/privoxy/default.filter2018-03-18 17:28:05.599 7fbbf41dab88 Info: LoadinG Filter file:/etc/privoxy/user.filter2018-03-18 17:28:05.599 7fbbf41dab88 info:loading Actions file:/etc/privoxy/ match-all.action2018-03-18 17:28:05.600 7fbbf41dab88 info:loading Actions file:/etc/privoxy/ default.action2018-03-18 17:28:05.607 7fbbf41dab88 info:loading Actions file:/etc/privoxy/user.action2018-03-18 17:28:05.611 7fbbf41dab88 info:listening on port 8118 on IP address0.0.0.0 The second step, compile ' whoyare ' and transfer the executable file to the server with SCP, using the following command: $ Cgo_enabled=0 goos=linux go build-o bin/server_linux-a. After the application is running, we can use CURL to send requests either directly or via/whoyare. The direct send request is as follows: $ curl-v http://your-ip:8080/whoyarecURL Use environment variable ' http_proxy ' to configure proxy for request forwarding: $ http_proxy=http:// 167.99.41.79:8118 curl-v http://188.166.17.88:8080/whoyare* Trying 167.99.41.79...* tcp_nodelay set* Connected to 167.99.41.79 (167.99.41.79) port 8118 (#0) > GET http://188.166.17.88:8080/whoyare http/1.1> Host: 188.166.17.88:8080> user-agent:curl/7.58.0> Accept: */*> proxy-connection:keep-alive>< HTTP/1.1 OK < Content-type:application/json< Date:sun, Mar 2018 17:37:02 gmt< content-length:29< proxy-connection:keep-alive&lt ; * Connection #0 to host 167.99.41.79 left intact{"addr": "167.99.41.79:58920"} as you can see, I set the ' http_proxy=http:// 167.99.41.79:8118 ', the response no longer contains my public IP, but the proxy's IP. The following request log should be left at Privoxy: 2018-03-18 17:28:22.886 7fbbf41d5ae8 request:188.166.17.88:8080/whoyare2018-03-18 17:32:29.495 7fbbf41d5ae8 Request:188.166.17.88:8080/whoyare You have previously run a client that is connected to ' localhost:8080 ' by default, but can be set by setting the environment variable ' url=http ://188.166.17.88:8080 ' to overwrite the destination address. Run the following command to reach ' whoyare ' directly. $ url=http://188.166.17.88:8080./BIN/CLIENT_LINUX2018/03/18 18:37:59 Target Http://188.166.17.88:8080.You is {"Addr ":" 95.248.202.252:38620 "}go language of ' HTTP '. The Client ' package supports a set of environment variables that are related to the agent, and setting these environment variables can be very flexible for immediate service operation. Export Http_proxy=http://http_proxy:port/export Https_proxy=http://https_proxy:port/export NO_PROXY=127.0.0.1, LocalHost the first two environment variables are very simple, one is an HTTP proxy, and the other is an HTTPS proxy. ' No_proxy ' excludes a set of host names, and when the host to be accessed is in this list, the request does not go through the proxy. Here I am configuring ' localhost ' and 127.0.0.1. Htt_proxy=http://forwardproxy:8118 +--------------+ +----------------+ +----------------+ | | | | | | | Client +----------^+ forward proxy +--------^+ whoyare | | | | | | | +--------------+ +----------------+ +----^-----------+ | | +---------------+ | | | | | Client +-------------------------------------------+ | | +---------------+ http_proxy Not configured clients configured with environment variables will be accessed through the proxy and will be accessed directly by other clients. This granularity of control is important. You can not only follow the process to control whether through the agent, but also according to the request to control, very flexible. $ http_proxy=http://167.99.41.79:8118 URL=HTTP://188.166.17.88:8080./BIN/CLIENT_LINUX2018/03/18 18:39:18 Target Http://188.166.17.88:8080.You is {"addr": "167.99.41.79:58922"} can see that we have reached the ' whoyare ' through the agent, the response "addr" is the address of the proxy. The last command is a bit weird, but it's just to show how ' No_proxy ' works. We excluded the URL of ' whoyare ' while setting up the access agent. As we expected, the request did not go through the proxy: $ http_proxy=http://167.99.41.79:8118 url=http://188.166.17.88:8080 no_proxy=188.166.17.88. BIN/CLIENT_LINUX2018/03/18 18:42:03 Target Http://188.166.17.88:8080.You is {"addr": "95.248.202.252:38712"} This article should be used as Go A practical introduction to language and forward proxies to read. You can subscribe to my [RSS] (HTTPS://GIANARB.IT/ATOM.XML), or follow me on [Twitter] (Https://twitter.com/gianarb). Maybe I'll show you how to use Go instead of privoxy and how to deploy on a Kubernetes cluster. So, just tell me which part to write first.

Via:https://gianarb.it/blog/golang-forwarding-proxy

Author: gianarb Translator: vincent08 proofreading: Unknwon

This article by GCTT original compilation, go language Chinese network honor launches

This article was originally translated by GCTT and the Go Language Chinese network. Also want to join the ranks of translators, for open source to do some of their own contribution? Welcome to join Gctt!
Translation work and translations are published only for the purpose of learning and communication, translation work in accordance with the provisions of the CC-BY-NC-SA agreement, if our work has violated your interests, please contact us promptly.
Welcome to the CC-BY-NC-SA agreement, please mark and keep the original/translation link and author/translator information in the text.
The article only represents the author's knowledge and views, if there are different points of view, please line up downstairs to spit groove

663 Reads
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.