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.
- 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.
- Adding the Intermediate
We're gonna userequests
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.
- Fleshing out the Proxy
Right now, our proxy has quite a few limitations. It can only handleGET
requests, meaning that users can't submit forms and thegoogle.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.
- 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! (=^.^=)
I'd recommend using buffers and also forwarding headers. Like this: https://repl.it/@AmazingMech2418/Node-Proxy#index.js
@AmazingMech2418 :O that's really cool, I'll try using those later on, thanks!
@IreTheKID Thank you!
Cool tutorial! I've bene wanting to create a ngrok-type server hosted on repl.it for my Raspberry Pi. I want to run a UDP server, but ngrok only has tcp. Can you do a tutorial on how to build a UDP proxy?
@willuhmjs I don't know much about UDP proxies tbh, and I've been messing around with proxies in Flask, so I don't think I can make a UDP tutorial anytime soon =P
I made EveryProxyhttps://repl.it/@AverseABFun/EveryProxy#main.py. You choose which site with the Console.
Hmmm, is there a possible way to unblock webs using a proxy?
@CyberHacker101 yes actually, they
did this to unblock discord before
go to your site type anything in, the press Enter and then it reloads and brings u right back to the google page with the added url search?ie=ISO-8859-1&hl=en&source=hp&biw=&bih=&q=YOUR_SEARCH
&iflsig=AINFCbYAAAAAX9zh4GOqEExemQx1gUK-_rPCk50eOPJ1&gbv=2&oq=YOUR_SEARCH
&gs_l=... and does nothing elsey
y does it do that (besides the fact that it is an example)
@IreTheKID
@ridark IDK why it does that, it works for me just fine. I'm not sure why it's not processing the URL params for you tbh =/
You get no css when you use the proxy
@PyCoder01 sure, you do! that's just google being a weirdo =/
@IreTheKID I tried my site there was no css
@PyCoder01 well this is a proxy for Google specifically, so if you navigate to another site, it won't serve assets properly :P
Nice tutorial! very well explained
@ZDev1 thanks :)
Nice job clearing it out! It really helped me out! Thanks!
@JBYT27 no prob! ;)
I never asked what a proxy was, I wanted to explain how ur proxy worked XD. I know what a proxy is because I have "worked" with service workers (pun intended), which are, in a sense, proxies for a website.
@Baconman321 ¯\_(ツ)_/¯
If you guys need a fully working proxy you can use mine. It has already unblocked over a MILLION websites!