The goal is, being able to access the proxy anonymously, such that the host (proxy) doesn't know, where the request came from (of course with credentials).
The client should be able to acess www.example.com
over the hosts ip, without the host knowing the clients ip.
Here's a example request route to www.example.com
:
Note: OS doesn't depend, programming language preferably Python
EDIT:
first you need to create a hidden service on tor from host to be able to communicate over tor network
basic flask proxy example (for more advanced proxy you can follow this code) i didnt test this code but you can fix errors:
"""
A simple proxy server, based on original by gear11:
https://gist.github.com/gear11/8006132
Modified from original to support both GET and POST, status code passthrough, header and form data passthrough.
Usage: http://hostname:port/p/(URL to be proxied, minus protocol)
For example: http://localhost:5000/p/www.google.com
"""
from stem.control import Controller
import re
from urllib.parse import urlparse, urlunparse
from flask import Flask, render_template, request, abort, Response, redirect
import requests
import logging
app = Flask("example")
port = 5000
host = "127.0.0.1"
hidden_svc_dir = "c:/temp/"
logging.basicConfig(level=logging.INFO)
CHUNK_SIZE = 1024
LOG = logging.getLogger("app.py")
@app.route('/<path:url>', methods=["GET", "POST"])
def root(url):
# If referred from a proxy request, then redirect to a URL with the proxy prefix.
# This allows server-relative and protocol-relative URLs to work.
referer = request.headers.get('referer')
if not referer:
return Response("Relative URL sent without a a proxying request referal. Please specify a valid proxy host (/p/url)", 400)
proxy_ref = proxied_request_info(referer)
host = proxy_ref[0]
redirect_url = "/p/%s/%s%s" % (host, url, ("?" + request.query_string.decode('utf-8') if request.query_string else ""))
LOG.debug("Redirecting relative path to one under proxy: %s", redirect_url)
return redirect(redirect_url)
@app.route('/p/<path:url>', methods=["GET", "POST"])
def proxy(url):
"""Fetches the specified URL and streams it out to the client.
If the request was referred by the proxy itself (e.g. this is an image fetch
for a previously proxied HTML page), then the original Referer is passed."""
# Check if url to proxy has host only, and redirect with trailing slash
# (path component) to avoid breakage for downstream apps attempting base
# path detection
url_parts = urlparse('%s://%s' % (request.scheme, url))
if url_parts.path == "":
parts = urlparse(request.url)
LOG.warning("Proxy request without a path was sent, redirecting assuming '/': %s -> %s/" % (url, url))
return redirect(urlunparse(parts._replace(path=parts.path+'/')))
LOG.debug("%s %s with headers: %s", request.method, url, request.headers)
r = make_request(url, request.method, dict(request.headers), request.form)
LOG.debug("Got %s response from %s",r.status_code, url)
headers = dict(r.raw.headers)
def generate():
for chunk in r.raw.stream(decode_content=False):
yield chunk
out = Response(generate(), headers=headers)
out.status_code = r.status_code
return out
def make_request(url, method, headers={}, data=None):
url = 'http://%s' % url
# Pass original Referer for subsequent resource requests
referer = request.headers.get('referer')
if referer:
proxy_ref = proxied_request_info(referer)
headers.update({ "referer" : "http://%s/%s" % (proxy_ref[0], proxy_ref[1])})
# Fetch the URL, and stream it back
LOG.debug("Sending %s %s with headers: %s and data %s", method, url, headers, data)
return requests.request(method, url, params=request.args, stream=True, headers=headers, allow_redirects=False, data=data)
def proxied_request_info(proxy_url):
"""Returns information about the target (proxied) URL given a URL sent to
the proxy itself. For example, if given:
http://localhost:5000/p/google.com/search?q=foo
then the result is:
("google.com", "search?q=foo")"""
parts = urlparse(proxy_url)
if not parts.path:
return None
elif not parts.path.startswith('/p/'):
return None
matches = re.match('^/p/([^/]+)/?(.*)', parts.path)
proxied_host = matches.group(1)
proxied_path = matches.group(2) or '/'
proxied_tail = urlunparse(parts._replace(scheme="", netloc="", path=proxied_path))
LOG.debug("Referred by proxy host, uri: %s, %s", proxied_host, proxied_tail)
return [proxied_host, proxied_tail]
controller = Controller.from_port(address="127.0.0.1", port=9151)
try:
controller.authenticate(password="")
controller.set_options([
("HiddenServiceDir", hidden_svc_dir),
("HiddenServicePort", "80 %s:%s" % (host, str(port)))
])
svc_name = open(hidden_svc_dir + "/hostname", "r").read().strip()
print "onion link: %s" % svc_name
except Exception as e:
print e
app.run()
after runing this you will get a onion link like: "somelongstringwithnumber123.onion" with that onion link you can connect to host from client over tor network
Than you need to make request over tor network from host:
import requests
session = requests.session()
session.proxies = {}
session.proxies['http'] = 'socks5h://localhost:9050'
session.proxies['https'] = 'socks5h://localhost:9050'
r = session.get("http://somelongstringwithnumber123.onion/p/alpwebtasarim.com")
print(r.text)
im not gonna test that codes but i hope you understand the main idea.