forked from acabal/scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
socks-tunnel
executable file
·214 lines (175 loc) · 5.87 KB
/
socks-tunnel
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#!/bin/bash
usage(){
fmt <<EOF
DESCRIPTION
Control a transparent system-level or browser-level SOCKS tunnel through a remote proxy.
By default, socks-tunnel uses openvpn/badvpn-tun2socks to create a network-layer SOCKS tunnel to a remote proxy. This transparently routes all traffic, including DNS, from the host through the proxy, on the network-layer level.
With the --browser option, socks-tunnel instead creates a SOCKS tunnel to a remote proxy using SSH, then configures Firefox's proxy settings to use that tunnel. This requires a Firefox restart.
USAGE
socks-tunnel -s,--start [-b,--browser] [-h,--host=USER@HOSTNAME]
If the -h option is ommitted, socks-tunnel looks in ~/.config/socks-tunnel/host for a USER@HOSTNAME string to connect to.
socks-tunnel -x,--stop
socks-tunnel -u,--status
EOF
exit
}
die(){ printf "Error: ${1}\n" 1>&2; exit 1; }
require(){ command -v $1 > /dev/null 2>&1 || { suggestion=""; if [ ! -z "$2" ]; then suggestion=" $2"; fi; die "$1 is not installed.${suggestion}"; } }
if [ $# -eq 1 ]; then if [ "$1" = "--help" -o "$1" = "-h" ]; then usage; fi fi
#End boilerplate
localPort="12345"
socksPort="11080" #The default socks port is 1080, but we use an alternate in case other services want to use that port
remoteConnection=""
tempFilePath="/tmp/socks-tunnel"
configFilePath="${HOME}/.config/socks-tunnel/host"
command=""
type="tun"
if [ $# -eq 0 ]; then
usage
fi
require "openvpn" "Try: apt-get install openvpn"
require "badvpn-tun2socks" "Try:\napt-add-repository ppa:ambrop7/badvpn\napt-get install badvpn"
for i in "$@"
do
case "${i}" in
-s|--start)
command="start"
;;
-x|--stop)
command="stop"
;;
-u|--status)
command="status"
;;
-b|--browser)
type="browser"
;;
-h=*|--host=*)
remoteConnection="$(echo "${i}" | sed 's/[-a-zA-Z0-9]*=//')"
;;
esac
done
error(){
die "Invalid options. Use -h for help."
}
checkIfRunning(){
if [ -f "${tempFilePath}" ]; then
if [ -s "${tempFilePath}" ]; then
die "Network-layer-level SOCKS tunnel open."
else
die "Browser-level SOCKS tunnel open."
fi
fi
}
isFirefoxRunning(){
#Get the PID for the Firefox process
ffpid=$(ps ux | awk '/firefox/ && !/awk/ && !/socks/ {print $2}')
[ -n "${ffpid}" ]
}
startTun(){
#Save our detected settings
remoteUser=`echo "${remoteConnection}" | cut -d"@" -f1-1`
remoteHost=`echo "${remoteConnection}" | cut -d"@" -f2-2`
gatewayIp=$(/sbin/ip route | awk '/default/ { print $3 }')
remoteIp=$(host -t a "${remoteHost}" | awk '{print $4}')
printf "${gatewayIp}\n${remoteIp}" > "${tempFilePath}"
#Create the tun0 device
sudo openvpn --mktun --dev tun0 > /dev/null
#Configure the tun0 device
sudo ifconfig tun0 10.0.0.1 netmask 255.255.255.0 > /dev/null
#Enable the tun2socks program
badvpn-tun2socks --tundev tun0 --netif-ipaddr 10.0.0.2 --netif-netmask 255.255.255.0 --socks-server-addr 127.0.0.1:${socksPort} > /dev/null &
disown %badvpn
#Open our socks proxy
ssh -D localhost:${socksPort} -N -f ${remoteConnection}
#Connect to tun2socks instead of our default gateway (router)
sudo route add "${remoteIp}" gw "${gatewayIp}" metric 5
sudo route add default gw 10.0.0.2 metric 6 #connect to tun2socks instead of our default gateway (router)
sudo route del default gw "${gatewayIp}" metric 0 #delete our default gateway connection
}
stopTun(){
#Restore our detected settings
gatewayIp=$(awk "NR==1" "${tempFilePath}")
remoteIp=$(awk "NR==2" "${tempFilePath}")
#Get the pid for the ssh and badvpn processes
sshPid=$(ps ux | awk '/ssh -D/ && !/awk/ {print $2}')
badvpnPid=$(ps ux | awk '/badvpn/ && !/awk/ {print $2}')
#Remove our socks routes and restore our default gateway route
sudo route del "${remoteIp}" gw "${gatewayIp}" metric 5 > /dev/null 2>&1
sudo route del default gw 10.0.0.2 metric 6 > /dev/null 2>&1
sudo route add default gw "${gatewayIp}" metric 0 > /dev/null 2>&1
#Kill the ssh and badvpn processes
kill -HUP ${sshPid} > /dev/null 2>&1
kill -HUP ${badvpnPid} > /dev/null 2>&1
#Remove the tun0 device
sudo openvpn --rmtun --dev tun0 > /dev/null
rm "${tempFilePath}"
}
startFirefox(){
ssh -D ${localPort} -N -f ${remoteConnection}
if [ $? -ne 0 ]; then
die "Could not establish SSH connection."
else
touch "${tempFilePath}"
printf "user_pref(\"network.proxy.socks\", \"localhost\");\nuser_pref(\"network.proxy.socks_port\", ${localPort});\nuser_pref(\"network.proxy.socks_version\", 5);\nuser_pref(\"network.proxy.type\", 1);" > $(echo $(find ~/.mozilla/firefox -name '*.default')/user.js)
if isFirefoxRunning; then
echo "Restart Firefox to apply proxy changes."
fi
fi
}
stopFirefox(){
if isFirefoxRunning; then
die "Firefox is still running."
fi
rm "${tempFilePath}"
echo "user_pref(\"network.proxy.type\", 5);" > $(echo $(find ~/.mozilla/firefox -name '*.default')/user.js)
#Get the PID for the SSH process
pid=$(ps ux | awk '/ssh -D/ && !/awk/ {print $2}')
if [ -z "${pid}" ]; then
die "Could not find SSH process ID."
else
kill -HUP "${pid}" > /dev/null 2>&1
if isFirefoxRunning; then
echo "Restart Firefox to apply proxy changes."
fi
fi
}
if [ "${command}" = "start" ]; then
checkIfRunning
#If we haven't specified a host on the command line, try to find it in our config directory
if [ "${remoteConnection}" = "" ]; then
if [ -f "${configFilePath}" ]; then
remoteConnection=$(cat "${configFilePath}")
fi
fi
if [ "${remoteConnection}" = "" ]; then
error
fi
if [ "${type}" = "tun" ]; then
startTun
elif [ "${type}" = "browser" ]; then
startFirefox
else
error
fi
elif [ "${command}" = "stop" ]; then
if [ -f "${tempFilePath}" ]; then
if [ -s "${tempFilePath}" ]; then
stopTun
else
stopFirefox
fi
fi
elif [ "${command}" = "status" ]; then
if [ -f "${tempFilePath}" ]; then
if [ -s "${tempFilePath}" ]; then
echo "Socks proxy running using tun."
else
echo "Socks proxy running using SSH/Firefox."
fi
else
echo "Socks proxy not running."
fi
else
error
fi