~smoser/+junk/sstack-proxy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/bin/bash
# wget http://bazaar.launchpad.net/~smoser/+junk/sstack-proxy/download/head:/sstackproxy-20140707182314-ru4pedwgnuzn1lgz-1/sstack-proxy -O - | sudo UPDATE=1 bash
#

upstream="squid.internal:3128"
no_upstreams=( .ubuntu.com .launchpad.net 127.0.0.0/8 )
# no_proxies go into default 'no_proxy' environment variable
no_proxies="localhost,127.0.0.1,127.0.1.1"
no_proxies="${no_proxies:+${no_proxies},}ubuntu.com,launchpad.net,maas.io"
myaddr=$(ifconfig eth0 | awk '$1 == "inet" { sub(/addr:/, "", $2); print $2; }')
# turn W.X.Y.Z into W.X.0.0/16
myrange="${myaddr%.*}"
myrange="${myrange%.*}.0.0/16"

TINYPROXY_CONF=${TINYPROXY_CONF:-/etc/tinyproxy.conf}
ETC_ENVIRONMENT=${ETC_ENVIRONMENT:-/etc/environment}
TINYPROXY_URL="http://127.0.0.1:8888/"
MYNAME="sstack_local"

no_upstreams=( "${no_upstreams[@]}" $myrange )
no_proxies="${no_proxies:+${no_proxies},}${myaddr}"

[ "$1" = "update" -o "${UPDATE:-0}" != "0" ] && update=true || update=false

Usage() {
   cat <<EOF
${0##*/} [update]

set up tinyproxy and /etc/environment for system wide proxy.

By default, this only reports how you can set this up.  No changes
to the system will be made unless the first argument is 'update'
or UPDATE=1 is found in the environment.

No root access is required for dry-run.

The values configured at the top of the script are for an internal
cloud I have access to.  They should be easily modifyable to your liking.

Once set up, all new shells should receive 'http_proxy' and 'https_proxy'
in their environment, and then "just work" to send all requests
through the local proxy.

If you need to add or remove 'no_upstream' entries to tinyproxy config
you can do so later, and then just restart it.  There is then no need
to re-set environment variables for existing programs, the changes 
will just be immediate.
EOF
}


error() { echo "$@" 1>&2; }
write_tinyproxy_conf() {
   local upstream="$1"
   shift
   echo "# begin $MYNAME"
   echo "upstream $upstream"
   for i in "$@"; do echo "no upstream \"$i\""; done
   echo "no upstream \"169.254.169.254\""
   [ -n "$myaddr" ] && echo "no upstream \"$myaddr\""
   echo "# end $MYNAME" 
}

write_environment() {
  local no_proxy="$1"
  echo "# begin $MYNAME"
  echo "http_proxy=http://127.0.0.1:8888/"
  echo "https_proxy=http://127.0.0.1:8888/"
  [ -n "$no_proxy" ] && echo "no_proxy=$no_proxy"
  echo "# end $MYNAME"
}

set_output() {
    local targ="$2" bk=""
    bk="$targ.dist"
    if ! "$1"; then
        echo "### append to $2"
        exec 3>&1; return
    fi
    if [ -f "$targ" ]; then
      cp "$targ" "$bk" || { error "failed backup of $targ"; return 1; }
      error "backed up $targ to $bk"
    fi
    [ ! -f "$targ" ] || sed -i "/# begin $MYNAME/,/# end $MYNAME/d" "$targ" ||
       { error "failed removing entries from $targ"; return 1; }
    exec 3>>"$targ" || { error "failed opening $targ for append"; return 1; }
}

[ "$1" = "--help" -o "$1" = "-h" ] && { Usage; exit 0; }

if $update && [ ! "$(id -u)" = "0" ]; then
   error "must be root for update"
   exit 1
fi

if ! which tinyproxy >/dev/null 2>&1; then
   if $update; then
      which eatmydata >/dev/null 2>&1 && emd="eatmydata" || emd=""
      DEBIAN_FRONTEND=noninteractive $emd apt-get install \
          --assume-yes --quiet tinyproxy </dev/null || exit
   else
      echo "## apt-get install --assume-yes --quiet tinyproxy"
   fi
fi

set_output "$update" "${TINYPROXY_CONF}" || exit
write_tinyproxy_conf "$upstream" "${no_upstreams[@]}" 1>&3 || exit
if $update; then
   service tinyproxy restart
else
   echo "## service restart tinyproxy"
fi

set_output "$update" "${ETC_ENVIRONMENT}"
write_environment "$no_proxies" 1>&3 || exit