The presumed platform is Linux, but OS X might probably be fine.
Configure SSH
Now you have acquired an SSH account. You usually get a username/password pair, but you find it a bit inconvenient having to type the password every time you log in. Good news is you don't have to: by using public key authentication instead of password authentication.Generate a new public/private key pair locally:
$ ssh-keygen -t rsa -C "Bye bye GFW" -f ~/.ssh/id_rsa_gfw
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/cckpg/.ssh/id_rsa_gfw.
Your public key has been saved in /home/cckpg/.ssh/id_rsa_gfw.pub.
The key fingerprint is:
01:0f:f4:3b:ca:85:d6:17:a1:7d:f0:68:9d:f0:a2:db Bye bye GFW
The key's randomart image is:
+--[ RSA 2048]----+
| .+ + |
| = o O . |
| = * * |
| o = + |
| o S . |
| o o = |
| o . E |
| |
| |
+-----------------+
Here we leave the passphrase empty for convenience.Now upload the public key to the server (
sshd(8)
, scp(1)
):$ scp -p ~/.ssh/id_rsa_gfw.pub ssh.gfw:.ssh/authorized_keys
You will be prompted for your password (for the last time, yeah!).
In the command above, ssh.gfw
is a Host
I defined in ~/.ssh/config
:Host ssh.gfw HostName 75.186.63.204 Port 22 User cckpg IdentityFile ~/.ssh/id_rsa_gfw HashKnownHosts yes StrictHostKeyChecking askSee
ssh_config(5)
if something is unclear.OK. SSH configuration is done. Now you don't ever have to type that password again. Just keep your private key
~/.ssh/id_rsa_gfw
safe.SSH As SOCKS Proxy
The famousssh -D
is something hard to not have heard of. Basically the -D
option provides a SOCKS proxy listening at the address:port specified.Here I just give you an example with several additional sane flags:
$ ssh -v24NnD 127.0.0.1:7127 ssh.gfw
See ssh(1)
for explanations. You may also want -C
for a slow connection.To quickly test it out, set your browser to use SOCKS5 proxy at 127.0.0.1:7127.
For Firefox, the setting goes like this:
Edit -> Preferences -> Advanced -> Network -> Settings -> Manual proxy configuration -> SOCKS Host:127.0.0.1 Port:7127 SOCKS v_5Now, open some long-time-no-see websites, like twitter.com.
Use Proxy Auto-Config
Since our purpose is just to unblock the blocked contents, we don't really need to connect to all web sites through the proxy. In fact, some contents inside the GFW are not available from outside of it.It is wise to only proxify connections that otherwise would be blocked or faked. How do you do that? One answer is Proxy Auto-Config.
OK, I see, but just how the GFW do I write a PAC file that covers all blocked sites? There're simply too many of them!
The answer is, as usual, Open Source: the autoproxy-gfwlist project maintains a GFW list, which covers a large list of blocked URLs, for the Firefox AutoProxy addon. You may just use this addon, but I'd like something lighter, and being Firefox-only, the addon is not as universal as a PAC file.
Next into the spotlight is, tada! the autoproxy2pac project! What it does is convert the autoproxy-gfwlist list to a PAC file. The URL to the PAC file is:
http://autoproxy2pac.appspot.com/pac/TYPE/IP/PORT
TYPE
being either proxy
or socks
, and IP
and PORT
being the
IP and port of your proxy. So in my case:http://autoproxy2pac.appspot.com/pac/socks/127.0.0.1/7127There is also an autoproxy2pac mirror provided by @yegle. Say thanks :)
The PAC file retrieved is cryptically encoded in order to bypass the GFW keyword filtering. It's OK to use it as is, but for the sake of readability and possible further modifications, I always decode it:
#!/bin/bash
# Produce an anti-GFW PAC (Proxy Auto Configuration), the easy way.
host=${1%:*} port=${1#*:} # e.g. 127.0.0.1:7127 as $1
url=https://yegle.net/autoproxy2pac/socks/$host/$port
js <(wget -O- "$url" | sed 's/eval(/print(/')
Look into the humanized PAC file, Line 7:var PROXY = "SOCKS 127.0.0.1:7127";which corresponds to what we specified in the autoproxy2pac URL. For Firefox, the proxy type specified can be
PROXY | SOCKS | SOCKS4 | SOCKS5
(nsIProxyAutoConfig). PROXY
is for HTTP(S) proxies, the rest for SOCKS.OK. The hard part is resolved. Now you just point your browser to this PAC file. All major browsers support this feature. For Firefox 4, the setting goes:
Edit -> Preferences -> Advanced -> Network -> Settings -> Automatic proxy configuration URL: file:///home/cckpg/gfw/autoproxy.pac
Proxify DNS Queries
Setting a SOCKS proxy for your browser does not necessarily proxify your DNS queries, meaning you still may not reach some of the sites (e.g. twitter.com) due to DNS cache pollution or hijacking. In Firefox, this can be eliminated by setting the following preference throughabout:config
:network.proxy.socks_remote_dns = trueFor manual proxy configuration, this will bypass local DNS resolution totally, and request DNS resolutions from the remote host, ensuring better reliability and privacy at the same time.
For Proxy Auto-Config setups, even with
socks_remote_dns
, URLs that should
be requested through SOCKS proxy still trigger local DNS queries. This does
not affect browsing, since the effective DNS resolution is done remotely, but
the counterintuitive behavior may be a privacy concern for some. To solve this
issue, set the preference network.dns.disablePrefetch
to true
through
about:config
to disable DNS prefetch. Hosts that are not proxied will,
of course, be resolved by your local DNS resolver.There are other more general ways to do DNS queries on the remote side. We will cover those later.
Proxify Any Program
Not everything is done inside your browser, but not every program supports all types of proxies. Luckily, every problem tends to have got an answer for us ;)For example, the excellent downloader
wget
does not understand SOCKS. This
is where tsocks comes in:$ tsocks wget -qO- http://ip.appspot.com
will print the IP address of the remote host. Cool? Indeed.And there's something even cooler: proxychains. Apart from its ability to chain mixed types of proxies all into one proxy chain, it supports DNS tunneling. This is important, as I explained earlier regarding the Firefox preference
network.proxy.socks_remote_dns
.To see the difference:
$ tsocks curl twitter.com --head --verbose
* About to connect() to twitter.com port 80 (#0)
* Trying 159.24.3.173...
^C
$ proxychains curl twitter.com --head --verbose
ProxyChains-3.1 (http://proxychains.sf.net)
|DNS-request| twitter.com
|S-chain|-<>-127.0.0.1:7127-<><>-4.2.2.2:53-<><>-OK
|DNS-response| twitter.com is 199.59.148.10
* About to connect() to twitter.com port 80 (#0)
* Trying 199.59.148.10...
|S-chain|-<>-127.0.0.1:7127-<><>-199.59.148.10:80-<><>-OK
connected
* Connected to twitter.com (199.59.148.10) port 80 (#0)
...
A WHOIS query reveals 159.24.3.173
to be "MCI Telecommunications Corporation",
way too long a name for a microblogging system ("Twitter Inc." that is.)The config
/etc/proxychains.conf
is quite self-explanatory:strict_chain proxy_dns tcp_read_time_out 15000 tcp_connect_time_out 8000 [ProxyList] socks5 127.0.0.1 7127A potential glitch: setuid programs will not be proxified. I haven't tested it.
Privoxy As HTTP Proxy
By far, we have been focusing on proxying connections directly through the SOCKS proxy, and have managed to do so for almost all types of applications. In this section, I'm gonna introduce you an alternative approach.Privoxy is an HTTP proxy that supports forwarding reqests to HTTP or SOCKS proxies. It is widely used in conjunction with Tor, for example.
Basically, we put privoxy between applications and the SSH SOCKS server, acting as an HTTP proxy as far as the applications are concerned.
This alternative approach simplifies things for HTTP(S) connections:
- Any program that understands HTTP proxy, can talk to privoxy directly.
- With SOCKS5, all DNS resolution will happen on the remote server, rendering
network.proxy.socks_remote_dns
moot, and all programs using this HTTP proxy will get correct DNS resolutions as well. - Privoxy supports flexible forwarding rules, effectively voiding the need for a PAC file, and being universal for any program.
To setup privoxy to forward requests to your SSH SOCKS5 server, put this in
/etc/privoxy/config
:forward-socks5 / 127.0.0.1:7127 .Now make sure you have
ssh -D
running, and start the privoxy daemon with
the command rc start privoxy
, for example.By default, privoxy listens on
localhost:8118
. Quickly test it out with
your browser; for Firefox users:Edit -> Preferences -> Advanced -> Network -> Settings -> Manual proxy configuration -> HTTP Host:127.0.0.1 Port:8118As for PAC, you need to configure the proxy type to
PROXY
. Note also, for
PAC setups, DNS prefetch will always query local DNS resolvers regardless
whether the proxy will do DNS resolution or not. Set network.dns.disablePrefetch
to true
to disable this behavior, as mentioned before.Wait, screw Proxy Auto-Config! (Yes I promised.) Let's opt for privoxy's builtin, flexible pattern-based forward rules. I'm not going to cover the details here, but give you the answer to the question that is now on your mind: Yes, there is a written list of GFW proxy forward rules for privoxy! And of course, it's based on autoproxy-gfwlist, no doubt about that :)
You should read the README on the AutoProxy2Privoxy page for instructions, but here is what you need to do in brief. First you need to edit the following line in
gfw.action
according to address:port of your SOCKS proxy:{+forward-override{forward-socks5 127.0.0.1:7127 .}}Then issue the following commands as root:
# cp gfw.action /etc/privoxy/
# chown privoxy:privoxy /etc/privoxy/gfw.action
# chmod 660 /etc/privoxy/gfw.action
Now edit /etc/privoxy/config
, adding this line:actionsfile gfw.actionAlso, comment out the SOCKS5 forward rule which we set before:
#forward-socks5 / 127.0.0.1:7127 .Privoxy should automatically pick up the new config. Now just point your program to privoxy, who will automatically determine whether to forward to SOCKS or not.
As a sidenote, privoxy originally stands for "Privacy Enhancing Proxy". It has advanced filtering capabilities and can be used to enhance your privacy, or block obnoxious advertisements. I suggest you read more about it.
Share Your Proxy
In the examples above, we always set up the proxy to listen on the loop device, providing service exclusively to our own computer. In reality, you probably want to share this proxy with others. For example, to allow your iPhone to twitter through this proxy.Usually it's safe to allow access from clients in your local home network, but if you want to serve clients from the internet, make sure you set up your firewall correctly.
Example for a privoxy setup (
/etc/privoxy/config
):listen-address 192.168.1.100:8118
192.168.1.100
is the static address assigned to my computer by my
router, so that I don't have to change this address every now and then.Of course, you can put the proxy on your router, which is better. It just might take a little more work to set it up.
Now if you have your iPhone connected to the same wireless network, point it to the HTTP proxy at
192.168.1.100:8118
. If it doesn't work, try
restarting privoxy.Another example to share the SOCKS proxy on all interfaces:
$ ssh -v24NnD :7127 ssh.gfw
Be careful with that.That's about it briefly. For more, read the manpages and Google is your friend.
相关帖子: http://briteming.blogspot.co.uk/2012/11/ssh-tunnel-proxy-how-to-set-it-up-with.html