Proxy Servers for Noobs
h
frissyn (404)

Intro

After my recent post, Discord Reverse Proxy, there have been a lot of people, like @Baconman321 and @DynamicSquid and @Jeydin21 who have asked how proxies work, and what they do, so I decided to follow up that post with this one, a tutorial on how to make a proxy server and a breakdown of how it works!

The Breakdown

The official definition of a proxy server is a server application or appliance that acts as an intermediary for requests from clients seeking resources from servers that provide those resources. Take a look at this image:

In the visual, it's essential to note that Alice is not asking Bob what time it is, the proxy is asking on Alice's behalf. Because of this, Alice's privacy is protected as Bob doesn't know that the Proxy told Alice it's response. That is the core concept of a proxy server. Once you understand that, there are all kinds of crazy ideas that you do with them!

Example Proxy

In our example, I'll be using Python and Flask because most people know Python, and Flask is really lightweight. Let's make it step by step.

  1. Creating a Server
    Let's get started with setting up Flask, pretty simple:
import flask

app = flask.Flask(__name__)

@app.route('/')
def proxy():
    return "I'm Alive!"

app.run(host="0.0.0.0", port=8080)

A few lines of code and we have a web server up and running! Now let's set up the intermediate between the client and the website.

  1. Adding the Intermediate
    We're gonna use requests to handle the retrieval of resources in our proxy. Let's add a few lines to the code we have so far:
import flask
import requests

app = flask.Flask(__name__)
target = "https://google.com/"

Now that we know what site we want to proxy let's add that functionality:

@app.route('/', defaults={'path': ''})
@app.route('/<path:path>', methods=["GET", "POST"])
def proxy(path: str):
    r = requests.get(f"{target}{path}")
    return r.content

And just like that, we have our proxy up and running! It will serve as a middle man between you and google.com. The best part about a proxy is that you can do anything you want with the r variable before you return its content! This makes proxies extremely viable for tracking and filtering activities.

  1. Fleshing out the Proxy
    Right now, our proxy has quite a few limitations. It can only handle GET requests, meaning that users can't submit forms and the google.com server can't use other methods. Let's add that functionality by checking for each method and processing appropriately.
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>', methods=["GET", "POST"])
def proxy(path: str):
    if flask.request.method == "GET":
        r = requests.get(f"{target}{path}")
        return r.content
    elif flask.request.method == "POST":
        r = requests.post(f"{target}{path}", json=flask.request.get_json())
        return r.content

The GET method is the same as what we had before, but now that we're handling POST requests, we have to take the extra step of getting any JSON data that might exist in the request, which is why json=flask.request.get_json() was added to the method.

  1. Wrapping It Up
    Once we've finished all that our final product should look like this:
import flask
import requests

app = flask.Flask(__name__)
target = "https://google.com/"

@app.route('/', defaults={'path': ''})
@app.route('/<path:path>', methods=["GET", "POST"])
def proxy(path: str):
    if flask.request.method == "GET":
        r = requests.get(f"{target}{path}")
        return r.content
    elif flask.request.method == "POST":
        r = requests.post(f"{target}{path}", json=flask.request.get_json())
        return r.content

app.run(host="0.0.0.0", port=8080)

Conclusion

Thanks for reading, and I hope you learned something new today! (=^.^=)

You are viewing a single comment. View All
frissyn (404)

@PyCoder01 sure, you do! that's just google being a weirdo =/