Created
March 22, 2010 00:10
-
-
Save fcoury/339672 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /bin/sh | |
## Web proxy, following the grand tradition of Web things being handled by | |
## gross scripts. Uses netcat to listen on a high port [default 8000], | |
## picks apart requests and sends them on to the right place. Point this | |
## at the browser client machine you'll be coming from [to limit access to | |
## only it], and point the browser's concept of an HTTP proxy to the | |
## machine running this. Takes a single argument of the client that will | |
## be using it, and rejects connections from elsewhere. LOGS the queries | |
## to a configurable logfile, which can be an interesting read later on! | |
## If the argument is "reset", the listener and logfile are cleaned up. | |
## | |
## This works surprisingly fast and well, for a shell script, although may | |
## randomly fail when hammered by a browser that tries to open several | |
## connections at once. Drop the "maximum connections" in your browser if | |
## this is a problem. | |
## | |
## A more degenerate case of this, or preferably a small C program that | |
## does the same thing under inetd, could handle a small site's worth of | |
## proxy queries. Given the way browsers are evolving, proxies like this | |
## can play an important role in protecting your own privacy. | |
## | |
## If you grabbed this in ASCII mode, search down for "eew" and make sure | |
## the embedded-CR check is intact, or requests might hang. | |
## | |
## Doesn't handle POST forms. Who cares, if you're just watching HTTV? | |
## Dumbness here has a highly desirable side effect: it only sends the first | |
## GET line, since that's all you really ever need to send, and suppresses | |
## the other somewhat revealing trash that most browsers insist on sending. | |
# set these as you wish: proxy port... | |
PORT=8000 | |
# logfile spec: a real file or /dev/null if you don't care | |
LFILE=${0}.log | |
# optional: where to dump connect info, so you can see if anything went wrong | |
# CFILE=${0}.conn | |
# optional extra args to the listener "nc", for instance "-s inside-net-addr" | |
# XNC='' | |
# functionality switch has to be done fast, so the next listener can start | |
# prelaunch check: if no current client and no args, bail. | |
case "${1}${CLIENT}" in | |
"") | |
echo needs client hostname | |
exit 1 | |
;; | |
esac | |
case "${1}" in | |
"") | |
# Make like inetd, and run the next relayer process NOW. All the redirection | |
# is necessary so this shell has NO remaining channel open to the net. | |
# This will hang around for 10 minutes, and exit if no new connections arrive. | |
# Using -n for speed, avoiding any DNS/port lookups. | |
nc -w 600 -n -l -p $PORT -e "$0" $XNC "$CLIENT" < /dev/null > /dev/null \ | |
2> $CFILE & | |
;; | |
esac | |
# no client yet and had an arg, this checking can be much slower now | |
umask 077 | |
if test "$1" ; then | |
# if magic arg, just clean up and then hit our own port to cause server exit | |
if test "$1" = "reset" ; then | |
rm -f $LFILE | |
test -f "$CFILE" && rm -f $CFILE | |
nc -w 1 -n 127.0.0.1 $PORT < /dev/null > /dev/null 2>&1 | |
exit 0 | |
fi | |
# find our ass with both hands | |
test ! -f "$0" && echo "Oops, cannot find my own corporeal being" && exit 1 | |
# correct launch: set up client access control, passed along thru environment. | |
CLIENT="$1" | |
export CLIENT | |
test "$CFILE" || CFILE=/dev/null | |
export CFILE | |
touch "$CFILE" | |
# tell us what happened during the last run, if possible | |
if test -f "$CFILE" ; then | |
echo "Last connection results:" | |
cat $CFILE | |
fi | |
# ping client machine and get its bare IP address | |
CLIENT=`nc -z -v -w 8 "$1" 22000 2>&1 | sed 's/.*\[\(..*\)\].*/\1/'` | |
test ! "$CLIENT" && echo "Can't find address of $1" && exit 1 | |
# if this was an initial launch, be informative about it | |
echo "=== Launch: $CLIENT" >> $LFILE | |
echo "Proxy running -- will accept connections on $PORT from $CLIENT" | |
echo " Logging queries to $LFILE" | |
test -f "$CFILE" && echo " and connection fuckups to $CFILE" | |
# and run the first listener, showing us output just for the first hit | |
nc -v -w 600 -n -l -p $PORT -e "$0" $XNC "$CLIENT" & | |
exit 0 | |
fi | |
# Fall here to handle a page. | |
# GET type://host.name:80/file/path HTTP/1.0 | |
# Additional: trash | |
# More: trash | |
# <newline> | |
read x1 x2 x3 x4 | |
echo "=== query: $x1 $x2 $x3 $x4" >> $LFILE | |
test "$x4" && echo "extra junk after request: $x4" && exit 0 | |
# nuke questionable characters and split up the request | |
hurl=`echo "$x2" | sed -e "s+.*//++" -e 's+[\`'\''|$;<>{}\\!*()"]++g'` | |
# echo massaged hurl: $hurl >> $LFILE | |
hh=`echo "$hurl" | sed -e "s+/.*++" -e "s+:.*++"` | |
hp=`echo "$hurl" | sed -e "s+.*:++" -e "s+/.*++"` | |
test "$hp" = "$hh" && hp=80 | |
hf=`echo "$hurl" | sed -e "s+[^/]*++"` | |
# echo total split: $hh : $hp : $hf >> $LFILE | |
# suck in and log the entire request, because we're curious | |
# Fails on multipart stuff like forms; oh well... | |
if test "$x3" ; then | |
while read xx ; do | |
echo "${xx}" >> $LFILE | |
test "${xx}" || break | |
# eew, buried returns, gross but necessary for DOS stupidity: | |
test "${xx}" = " | |
" && break | |
done | |
fi | |
# check for non-GET *after* we log the query... | |
test "$x1" != "GET" && echo "sorry, this proxy only does GETs" && exit 0 | |
# no, you can *not* phone home, you miserable piece of shit | |
test "`echo $hh | fgrep -i netscap`" && \ | |
echo "access to Netscam's servers <b>DENIED.</b>" && exit 0 | |
# Do it. 30 sec net-wait time oughta be *plenty*... | |
# Some braindead servers have forgotten how to handle the simple-query syntax. | |
# If necessary, replace below with (echo "$x1 $hf" ; echo '') | nc... | |
echo "$x1 $hf" | nc -w 30 "$hh" "$hp" 2> /dev/null || \ | |
echo "oops, can't get to $hh : $hp". | |
echo "sent \"$x1 $hf\" to $hh : $hp" >> $LFILE | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment