Nov 07

1.绕过 GFW 和 ISP 劫持

最简单和不折腾的方法是购买 VPN,次之是购买一台海外 VPS,自己安装 VPN 或 Shadowsocks 服务端。VPN 的优点是可以全局翻墙,Shadowsocks 虽然可以设置全局模式,但是对于不支持代理的本地应用是没有办法的,当然这种情况下可以试试 ProxifierPE 强制所有连接通过代理上网。

使用 Shadowsocks 可能遇到的另一个问题是,因为 Shadowsocks 使用的是 SOCKS5 类型的代理,当本地应用只支持 HTTP/HTTPS 类型代理时,就需要自己解决 HTTP 转换为 SOCKS5 的问题。当然,这个问题使用 Privoxy 就能很好地解决。

本节主要介绍如何组合使用 Shadowsocks 和 Privoxy,并假设你已经安装并配置好了 Shadowsocks(Linux 中可以安装 shadowsocks-qt5 或 命令行版本的 Shadowsocks)。

Shadowsocks 与 Privoxy 组合使用的示意图如下所示:

Shadowsocks-Privoxy

假设你已经配置好了 Shadowsocks,接下来配置 Privoxy。

Windows 系统中右键点击 Privoxy 托盘图标,依次点击 Edit – Main Configuration 打开配置文件;Linux 系统中 Privoxy 的配置文件位于/etc/privoxy/config。
配置文件修改为:

# 把 HTTP 流量转发到本机 127.0.0.1:1080 的 Shadowsocks
forward-socks5 / 127.0.0.1:1080 .
# 可选,默认只监听本地连接 127.0.0.1:8118
# 可以允许局域网中的连接
listen-address 0.0.0.0:8118

启动 Shadowsocks 和 Privoxy 后,把本地应用的代理设置为 HTTP/HTTPS 类型的 127.0.0.1:8118,就可以绕过 GFW 和 ISP 了。如果局域网中的其他 PC 或手机也希望使用该电脑上网(假设该电脑 IP 地址为 192.168.1.10),把它们的代理设置为 19.168.1.10:8118 即可。

目前,有一个讨巧的的办法替代这两者的组合:使用 Lantern —— 一款开源的安全上网工具。它使用的是 HTTP 类型代理,本地端口为 8787,也就是说,把本地应用的代理设置为 127.0.0.1:8787 就可以使用 HTTP 类型的代理了。而且使用它,也无需自己购买 VPS。

Lantern 默认非全局代理,可以在设置中改为全局模式。

另一方面,Lantern 只监听本机 127.0.0.1:8787 的连接,如果局域网中的电脑或手机也想通过这台电脑翻墙(假设该电脑 IP 地址为 192.168.1.10),那么也需要配合 Privoxy 使用。这时,Privoxy 的配置应该如下:

# 监听局域网中连接到本地 8118 端口的连接,转发给 8787 端口的 Lantern
forward / 127.0.0.1:8787
listen-address 127.0.0.1:8118 # 可改为 0.0.0.0:8118 允许局域网的连接

2.匿名上网

网络中保持匿名的办法是使用 Tor,匿名的意思是隐藏你当前的 IP 地址。Internet 上有很多志愿者运行着 Tor 中继节点,Tor 能保证从出发点的流量至少经过三个不同的中继节点到达目的地址,而且这三个不同的中继不会每次都相同。

形象地说,你想把一封匿名信交给小明,在大街上随便找了一陌生人 A 让 A 帮忙转交,A 走了一段路程后随便找了一个陌生人 B 让 B 帮忙转交,B 走了一段路程后随便找了一个陌生人 C 让 C 帮忙转交,最终 C 按照信封上的地址找到了小明并把信交给了他。小明只知道是 C 转交了这封信,至于是谁写的这封信,他就无从得知了。A、B、C 分别对应着 Tor 网络的中继节点,这种投递匿名信的方式就起到了隐藏 IP 地址的效果。

如下图所示,使用 Tor 从本机经过三跳访问了 Google。

Shadowsocks-Privoxy

Tor 浏览器

为了方便使用 Tor,Tor 开发者把 Tor 集成到了定制版的 Firefox 中,简单设置一下就能正常使用。

Tor 浏览器专为大陆等网络环境加入了流量混淆的选项。首次打开浏览器时会弹出 Tor 状态检查,点击设置配置 Tor 网桥,勾选互联网提供商(ISP)是否对 Tor 网络连接进行了封锁或审查中的是,把下一步中的网桥类型选择meek-amazon或meek-azure。这两者在大陆没被完全封锁,因此可以用来做跳板网桥。

不过随着网络环境的恶化,Tor 提供的网桥类型都不可用时,就需要使用自己的 Shadowsocks 或 Lantern 代理了。

首次打开 Tor 浏览器,在 Tor 设置中勾选互联网提供商(ISP)是否对 Tor 网络连接进行了封锁或审查中的否,在下一步是否需要本地代理访问互联网?中选择是,下一步中设置你的代理:

  • 使用 Shadowsocks 则设置为 SOCKS5 类型的 127.0.0.1:1080;
  • 使用 Lantern 则设置为 HTTP/HTTPS 类型的 127.0.0.1:8787;

如果通过局域网中其他计算机的配置联网,把 127.0.0.1 改为那台计算机的 IP 地址。

使用了代理的 Tor 浏览器原理示意图如下(以 Tor + Shadowsocks 组合为例):

Shadowsocks-Privoxy

Tor Expert Bundle

Tor 浏览器适用于使用浏览器匿名上网的场景,如果打算让本地应用(如其他浏览器、Linux 中的 Terminal 等)也使用 Tor 隐藏 IP 地址,那么就需要自己手动配置 Tor 了。从 Tor 官网下载 操作系统对应的 Expert Bundle,它只包含 Tor 工具,不含浏览器。

假设你已经配置好了 Shadowsocks,接下来,为 Tor 配置 Shadowsocks 代理。

Windows 系统中,打开 %AppData%/tor 目录(如果不存在则创建该目录),新建 torrc 文件,内容如下:

## 通过 SOCKS5 代理
SOCKS5Proxy 127.0.0.1:1080
## 如果使用 HTTP/HTTPS 代理
# HTTPSProxy 127.0.0.1:8118
## 如果只允许特定端口的网络连接,如 80 和 443
ReachableAddresses *:80,*:443
ReachableAddresses reject *:*

Linux 系统中,Tor 的配置文件位于 /etc/tor/torrc,配置内容同上。

启动 Shadowsocks 和 Tor,因为 Tor 监听的是 SOCKS5 类型的本地 9050 端口,把需要匿名的本地应用代理设置为 SOCKS5 类型,代理地址设置为 127.0.0.1:9050,实现匿名上网。

还是老问题,如果本地应用只支持 HTTP/HTTPS 代理类型,那么仍需要使用 Privoxy,修改其配置文件为:

forward-socks5 / 127.0.0.1:9050 .
listen-address 127.0.0.1:8118    # 可改为 0.0.0.0:8118 允许局域网的连接

这样一来,本地应用的代理设置为 HTTP/HTTPS 类型的 127.0.0.1:8118 就可以实现匿名上网了。
Privoxy + Tor + Shadowsocks 组合使用示意图如下所示:

Shadowsocks-Privoxy

使用 Tor 匿名访问网络除了应用于渗透测试,另一个应用场景是编写爬虫变换 IP 地址爬取站点,减小被网站屏蔽的可能性。

在 Linux Terminal 中,使用 export 命令设置代理,可以只在当前 Terminal 中生效,

export http_proxy=http://127.0.0.1:8118
export https_proxy=https://127.0.0.1:8118

3.总结

接下来简要归纳上述内容,给出每种组合的配置内容。

Privoxy + Shadowsocks 组合 —— 翻墙
配置 Privoxy,Linux 系统中位于 /etc/privoxy/config:

forward-socks5 / 127.0.0.1:1080 .
listen-address 127.0.0.1:8118    # 可改为 0.0.0.0:8118 允许局域网的连接

本地代理需设置为 HTTP/HTTPS 类型的 127.0.0.1:8118。
如果不使用 Privoxy,本地代理需设置为 SOCKS5 类型的 127.0.0.1:1080。

Privoxy + Tor + Shadowsocks 组合 —— 匿名上网
配置 Privoxy,Linux 系统中位于 /etc/privoxy/config:

forward-socks5 / 127.0.0.1:9050 .
listen-address 0.0.0.0:8118    # 可改为 0.0.0.0:8118 允许局域网的连接

配置 Tor,Windows 系统中位于 %AppData%/tor/torrc,Linux 系统中位于 /etc/tor/torrc:

SOCKS5Proxy 127.0.0.1:1080    # Shadowsocks 代理地址
ReachableAddresses *:80,*:443
ReachableAddresses reject *:*

本地代理需设置为 HTTP/HTTPS 类型的 127.0.0.1:8118。
如果不使用 Privoxy,本地代理需设置为 SOCKS5 类型的 127.0.0.1:9050。

Privoxy + Tor + Lantern 组合 —— 匿名上网
配置 Privoxy,Linux 系统中位于 /etc/privoxy/config:

forward-socks5 / 127.0.0.1:9050 .
listen-address 0.0.0.0:8118    # 可改为 0.0.0.0:8118 允许局域网的连接

配置 Tor,Windows 系统中位于 %AppData%/tor/torrc,Linux 系统中位于 /etc/tor/torrc:

HTTPSProxy 127.0.0.1:8787    # Lantern 代理地址
ReachableAddresses *:80,*:443
ReachableAddresses reject *:*

本地代理需设置为 HTTP/HTTPS 类型的 127.0.0.1:8118。
如果不使用 Privoxy,本地代理需设置为 SOCKS5 类型的 127.0.0.1:9050。

转自:https://g2ex.github.io/2016/05/20/Tips-on-Chinternet/

Nov 02

1.直接寻找可用的 IP.

通过网络上的 ping 工具,检测得到 Google GHS 的 IP,分别打开下面列表中的网址,查询的地方输入 ghs.google.com 或者 ghs.googlehosted.com,里面得到的每一个 A Records 或响应 IP 就对应一个可以尝试的 GHS IP 地址,然后在本地通过 ping 测试验证是否能用。

http://bgp.he.net/dns/ghs.google.com
https://cloudmonitor.ca.com/en/dnstool.php
http://ping.chinaz.com/

可以将需要绑定的域名直接绑定到 A 记录,如果你有多个域名需要绑定的话,当一个 IP 被屏蔽的话,就需要修改所有的 A 记录。这里有一个小技巧,你可以添加一个可用的 IP 到域名 ghs.domain.com,然后通过 cname 的形式绑定 GAE 域名,这样当需要修改时仅仅需要修改一条 A 记录就可以了。

或者你可以使用网上仍然可用的由 GDG 维护的 ghs 替代域名:

www.goofan.net.g.xgslb.net

当然,这个需要添加 cname 记录。

2.使用 Nginx 直接反向代理
如果有 VPS 的话,可以直接安装 Ngrok,利用 Ngrok 反向代理 GAE,这种方法简单粗暴,一定能成功。但是如果你有多个 GAE 应用的话,就需要添加多段类似的代码,如果嫌麻烦的话可以参考下面第 3 种方法。

server
{
        listen   80;
        server_name xxx.com;

        location /
        {
                proxy_pass http://yyy.appspot.com;
                proxy_set_header Host "yyy.appspot.com";
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

3.使用 Nginx 反向代理 Google GHS
最好使用单独的 VPS 来反向代理 Google GHS,代码如下所示,然后添加 A 记录 ghs 到 VPS 的 IP,添加 cname 需要绑定的域名 到 ghs.domain.com。

upstream ghs {
   ip_hash;
   server ghs.google.com;
   server 72.14.203.121;
   server 72.14.207.121;
   server 74.125.43.121;
   server 74.125.47.121;
   server 74.125.53.121;
   server 74.125.77.121;
   server 74.125.93.121;
   server 74.125.95.121;
   server 74.125.113.121;
   server 216.239.32.21;
   server 216.239.34.21;
   server 216.239.36.21;
   server 216.239.38.21;
}

server {
   listen       80;
   server_name  ghs.domain.com;
#下行中的ghs换成自己定义的名称。
    log_format  ghs  '$remote_addr - $remote_user [$time_local] "$request" '
               '$status $body_bytes_sent "$http_referer" '
               '"$http_user_agent" $http_x_forwarded_for';
#下行中两处ghs换成自己定义的名称。
   access_log  /home/log/ghs.log ghs;

   location / {
     proxy_redirect off;
     proxy_set_header Host $host;
     proxy_pass http://ghs;
     proxy_set_header  X-Real-IP  $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_redirect false;
   }

}

server {
   listen       443;
   server_name  ghs.domain.com;
   log_format  mail  '$remote_addr - $remote_user [$time_local] "$request" '
               '$status $body_bytes_sent "$http_referer" '
               '"$http_user_agent" $http_x_forwarded_for';
   access_log  /home/log/mail.log mail;

   location / {
     proxy_redirect off;
     proxy_set_header Host $host;
     proxy_pass http://ghs;
     proxy_set_header  X-Real-IP  $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_redirect false;
   }
}

参考资料:
1.http://steven-wang.appspot.com/nginx-reverse-proxy-122001.html
2.Install Nginx and config Google ghs proxy

Nov 02

VPS 系统在最小化安装后,执行一些命令时候,提示 locale 设置错误,具体如下:

perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
        LANGUAGE = (unset),
        LC_ALL = (unset),
        LANG = "zh_CN"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").

错误提示是没有设置好 locale 相关环境变量,因此尝试将其设置:

export LANGUAGE=en_US.UTF-8
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8

解决办法是:

vi /etc/locale.gen,找到# en_US.UTF-8 UTF-8,去掉前面的#号;

执行一下命令,可以看到,提示 en_US.UTF-8 已经生成:

# locale-gen en_US.UTF-8
Generating locales (this might take a while)...
  en_US.UTF-8... done
Generation complete.

接着更新

# update-locale en_US.UTF-8

重新执行之前有报错的命令,已经不再报错。

参考资料:
1.http://blog.sina.com.cn/s/blog_4da051a60102vfrf.html
2.https://www.thomas-krenn.com/en/wiki/Perl_warning_Setting_locale_failed_in_Debian

Nov 01

Debian 新系统更新时,有提示:

Get:8 http://security.debian.org wheezy/updates/non-free Translation-en [14 B] 
Hit http://ftp.debian.org wheezy/contrib i386 Packages                         
Hit http://ftp.debian.org wheezy/non-free i386 Packages                   
Hit http://ftp.debian.org wheezy/contrib Translation-en
Hit http://ftp.debian.org wheezy/main Translation-en
Hit http://ftp.debian.org wheezy/non-free Translation-en
Fetched 729 kB in 2s (350 kB/s)              
Reading package lists... Done
W: There is no public key available for the following key IDs:
9D6D8F6BC857C906
W: There is no public key available for the following key IDs:
7638D0442B90D010

解决办法:

apt-get install debian-keyring debian-archive-keyring

参考资料:http://unix.stackexchange.com/questions/75807/no-public-key-available-on-apt-get-update

Nov 01

前面也写了一篇关于 Ngrok 搭建的文章:《树莓派上 Ngrok 的编译与使用》,但是看到《搭建 ngrok 服务实现外网访问局域网内的网站》这篇文章使用纯手工编译的步骤很详细,尤其是 go 语言的配置那部分内容,所以将文中的主要内容复制下来,以备不时之需。

事先的准备工作:添加 ngrok 服务域名的 DNS 解析。

选择支持泛解析的 DNS 服务商,如 Cloudns、DNSpod 国际版、zoneedit 等,分别添加 A 记录:

ngrok.chun.pro 记录值 1.2.3.4
*.ngrok.chun.pro 记录值 1.2.3.4

1.安装必要的工具和语言环境

sudo apt-get install build-essential golang mercurial git

2.升级 go 语言环境

# 看看是不是小于等于 1.2.1
go version
# 卸载
sudo apt-get purge golang*
#下载最新版并解压 https://golang.org/dl/
wget https://storage.googleapis.com/golang/go1.7.3.linux-386.tar.gz
tar -C /usr/local -xzf go1.7.3.linux-386.tar.gz
#创建目录
mkdir ~/.go
# 设置环境变量
vi ~/.profile
export GOROOT=/usr/local/go
export GOPATH=~/.go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
source .profile

# 升级
sudo update-alternatives --install "/usr/bin/go" "go" "/usr/local/go/bin/go" 0
sudo update-alternatives --set go /usr/local/go/bin/go
go version

3.下载 ngrok 源码并编译服务端

git clone https://github.com/tutumcloud/ngrok.git ngrok
cd ngrok

#生成并替换源码里默认的证书,注意域名要修改为你自己的,这里是一个虚拟的测试域名
NGROK_DOMAIN="ngrok.chun.pro"
openssl genrsa -out base.key 2048
openssl req -new -x509 -nodes -key base.key -days 10000 -subj "/CN=$NGROK_DOMAIN" -out base.pem
openssl genrsa -out server.key 2048
openssl req -new -key server.key -subj "/CN=$NGROK_DOMAIN" -out server.csr
openssl x509 -req -in server.csr -CA base.pem -CAkey base.key -CAcreateserial -days 10000 -out server.crt

cp base.pem assets/client/tls/ngrokroot.crt
cp server.crt assets/server/tls/snakeoil.crt
cp server.key assets/server/tls/snakeoil.key

#开始编译,服务端客户端会基于证书来加密通讯,保证了安全性
GOOS=linux GOARCH=amd64 make release-server release-client
GOOS=linux GOARCH=386 make release-server release-client
GOOS=linux GOARCH=arm make release-server release-client
GOOS=linux GOARCH=arm64 make release-server release-client
GOOS=linux GOARCH=ppc64 make release-server release-client
GOOS=linux GOARCH=ppc64le make release-server release-client
GOOS=linux GOARCH=mips64 make release-server release-client
GOOS=linux GOARCH=mips64le make release-server release-client

GOOS=windows GOARCH=amd64 make release-server release-client
GOOS=windows GOARCH=386 make release-server release-client

GOOS=darwin GOARCH=amd64 make release-server release-client
GOOS=darwin GOARCH=386 make release-server release-client
GOOS=darwin GOARCH=arm make release-server release-client
GOOS=darwin GOARCH=arm64 make release-server release-client

GOOS=android GOARCH=arm make release-server release-client

GOOS=dragonfly GOARCH=amd64 make release-server release-client

GOOS=freebsd GOARCH=amd64 make release-server release-client
GOOS=freebsd GOARCH=386 make release-server release-client
GOOS=freebsd GOARCH=arm make release-server release-client

GOOS=netbsd GOARCH=amd64 make release-server release-client
GOOS=netbsd GOARCH=386 make release-server release-client
GOOS=netbsd GOARCH=arm make release-server release-client

GOOS=openbsd GOARCH=amd64 make release-server release-client
GOOS=openbsd GOARCH=386 make release-server release-client
GOOS=openbsd GOARCH=arm make release-server release-client

GOOS=plan9 GOARCH=amd64 make release-server release-client
GOOS=plan9 GOARCH=386 make release-server release-client

GOOS=solaris GOARCH=amd64 make release-server release-client

4.启动服务端
在服务器上运行下面的命令启动ngrok服务端

./bin/ngrokd -domain="ngrok.chun.pro" -httpAddr=":8081" -httpsAddr=":8082"

注意,这里 httpAddr 和 httpsAddr 是 ngrok 服务转发 http 和 https 请求的端口,为了避免和 Nginx/Apache 等的 80 端口冲突,使用了 8081 和 8082。

默认还会启动一个 4443 端口,用于跟活动的客户端进行通讯,如果需要更换端口,使用 -tunnelAddr=”:xxx”参数

现在你可以在浏览器里访问 http://ngrok.chun.pro:8081了,如果有一行提示,表示 ngrok 的服务端已经运行起来了

Tunnel ngrok.yourdomain.com:8081 not found

然后再访问 http://pi.ngrok.chun.pro:8081,如果有下面的提示,表示 A 记录也已经生效了。

Tunnel pi.ngrok.chun.pro:8081 not found

5.配置客户端参数

vi ngrok.cfg
# 填写如下信息,server_addr 指定了服务端的域名和与客户端通信的端口
server_addr: ngrok.chun.pro:4443
trust_host_root_certs: false

6.启动客户端

./ngrok -config=./ngrok.cfg -subdomain pi 127.0.0.1:80

如果连接正常,会有提示:

ngrok                                                        (Ctrl+C to quit)
Tunnel Status                 online
Version                       1.7/1.7
Forwarding                    http://pi.ngrok.chun.pro:8081 -> 127.0.0.1:80
Web Interface                 127.0.0.1:4040
# Conn                        5
Avg Conn Time                 192.70ms

7.nginx 反向代理 8081 端口

server {
        listen 80;
        server_name ngrok.chun.pro;
        location / {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host:8081;
                proxy_set_header X-Nginx-Proxy true;
                proxy_set_header Connection "";
                proxy_pass http://127.0.0.1:8081;
        }
}

现在可以直接在浏览器访问 pi.ngrok.chun.pro,而不需要加 :8081 端口号。

另外,使用 Docker 搭建 Ngrok 服务器可以参考这篇文章:https://hteen.cn/docker/docker-ngrok.html