Hike News

V2RayX 客户端跑 ss 的简易配置及踩坑记录

碎碎念

还有一个多小时就是 2019 Google I/O 大会了,不得不感叹时间过的好快。五月谷歌,六月苹果,年复一年,技术不长反退,人也懒散起来。只好整理心情水水博客找点事情做。

两年前看好友 kiri 就在搞 V2 的轮子,狗杰哥 这几天也突然安利我下载个客户端试试看,800 米体测过后点了盒马犒劳自己,饱餐后准备和他一起折腾迷之客户端。V2RayX 是 macOS 上面的 GUI。习惯性地从 release 下载,其实读 readme 是可以从 brew 下载的,直到我写这篇博客的时候才看到,蠢哭了。

相比于 ss 有何优点?

我之前用的只是 ssX-NG 客户端,那么为什么换成 V2RayX 呢?

Proxy auto-config Mode,简称 pac 模式,大家开 ss 的时候应该经常用到,在浏览器键入 URL 之后会跑 JS 脚本来判断走代理还是直连,可是实际生活中还是会出现应用程序不能工作或者网页无法加载的问题。网络大师杰哥认为:

ss + pac 就是程序读 pac,自己执行 pac 判断请求路由到本地代理还是直连。相比之下,v2ray + global 则是程序无脑请求本地代理,代理程序来判断路由方向。在我们日常支持 pac 的程序很少的情况下,显然后者兼容性更好。

V2Ray + Global 带来了更好的兼容性,可以真全局,也可以按照规则来路由,这取决于自己选择的 routing rule。所以这次我来试试告别 ssX-NG,拥抱 V2RayX。

为了方便理解,我做了两张流程图如下:

ss
V2Ray

开箱配置

1.导入模版/配置规则

按照安装提示,需要下载一些工具插件,指纹/密码授权后无脑下载就行。这里个人有一点踩坑,菜单里面的authorize v2ray sys_conf 也要手动点击授权(其实第一次打开就默认让输入密码了,我好像手滑按了跳过,其实并不需要手动的)。之后进入菜单栏 configure,import 进一些杰哥给我的配置文件如下:

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
{
"outbounds" : [
{
"tag" : "NAME",
"protocol" : "shadowsocks",
"settings" : {
"servers" : [
{
"password" : "PASSWORD",
"port" : 1919,
"method" : "chacha20-ietf-poly1305",
"ota" : false,
"address" : "SERVER_ADDRESS"
}
]
}
}
],
"routings" : [
{
"domainStrategy" : "AsIs",
"rules" : [
{
"type" : "field",
"outboundTag" : "main",
"port" : "0-65535"
}
],
"name" : "all_to_main"
},
{
"domainStrategy" : "AsIs",
"rules" : [
{
"type" : "field",
"outboundTag" : "direct",
"port" : "0-65535"
}
],
"name" : "all_to_direct"
},
{
"domainStrategy" : "IPOnDemand",
"rules" : [
{
"type" : "field",
"outboundTag" : "direct",
"domain" : [
"geosite:cn",
"geosite:apple",
"domain:me.com",
"domain:cdn-apple.com",
"domain:aaplimg.com",
"domain:steampowered.com"
]
},
{
"type" : "field",
"outboundTag" : "main",
"domain" : [
"geosite:geolocation-!cn",
"domain:tw"
]
},
{
"type" : "field",
"ip" : [
"geoip:private",
"geoip:cn"
],
"outboundTag" : "direct"
},
{
"type" : "field",
"outboundTag" : "main",
"port" : "0-65535"
}
],
"name" : "whiltelist"
}
]
}

就这样,我倒入进来一个 ss 模版和三条路由规则:all_to_main 全走代理,all_to_direct 全直连,whiltelist 有点复杂。文档:https://www.v2ray.com/chapter_02/03_routing.html

  • 常见国内域名直连,提高判断效率

  • 常用翻墙域名走代理(含被DNS污染的)

  • 进行DNS解析(IPOnDemand),国内 IP 直连,CDN在这里解析到国内节点

  • final: 其余全走代理

2.填写 server 修改端口 勾选 Proxy

之后 菜单栏 -> configure -> advanced -> outbounds 修改 ss 配置、保存 -> view current config.json:http://127.0.0.1:8070/config.json ,确认无误后 load core。这时候我发现没有跑起来,可能的原因是 local socks5 的 1080 端口被占用了,可以自己随便换一个大端口试试看。
同时本机电脑网络配置 Proxies 选项中,可以检查是否已经自动☑️勾选上 Web Proxy,Secure Web Proxy,SOSCKS Proxy。以及检查右侧的 proxy server 是否被先前授权过的程序自动填入了。这一点是在通过 Proxies 检查 sys_conf 授权的正确与否。

再次 load core。可惜 netstat -na | grep 19198 端口也在监听了,为什么还是没有跑起来呢?

3.编译 geosite.dat 覆盖原文件

因为改了上面这些还没完,上文 JSON 中 "geosite:geolocation-!cn" 包含了常见的非国内站点的域名。(https://github.com/v2ray/domain-list-community ,这个仓库在维护所有预定义域名列表。)最新 V2Ray 的才有 geolocation-!cn 这个写法,而我们在用的 V2RayX 客户端 还没支持。所以要先修改安装包中名字为geosite.dat 的文件。编译全新的 geosite.dat 文件,把原来旧文件覆盖掉。我直接把杰哥的拿来用了。

1
2
cd /Applications/V2RayX.app/Contents/Resources/
mv /Users/qianqian/Desktop/geosite.dat geosite.dat

reload core,理论上应该可以正常使用啦w。

4.读取 log 与 debug

Console APP 里面有结果。

进程起来了。

1
2
3
4
/A/V/C/Resources$ ps -ef | grep v2ray
501 89468 1 0 12:38PM ?? 0:10.81 /Applications/V2RayX.app/Contents/Resources/v2ray -config http://127.0.0.1:8070/config.json
501 89899 83458 0 1:23PM ttys001 0:00.00 grep --color=auto v2ray

Curl 谷歌也有反应。

1
2
/A/V/C/Resources$ export http_proxy=http://127.0.0.1:10011
curl -v google.com

那为什么我们查看 log 却是空空如也呢?

1
~$ cat ../../var/folders/8x/dir/T/cenmrev.v2rayx.log/error.log

直到很久之后才发现,客户端默认的 Log Level 是 None,手动勾选 debug 模式就可以正常看到 log 了。这块好坑啊!!

另补充,担心配置语法写错的话,V2Ray 有个测试功能,我们保存 config.json 并且进行测试,命令如下:

1
2
3
4
5
6
~/w/hexo$ cd /Applications/V2RayX.app/Contents/Resources
/A/V/C/Resources$ ./v2ray -test -config/Users/qianqian/Desktop/myTest.json
V2Ray 4.15.1 (Po) 20190212
A unified platform for anti-censorship.
Configuration OK.

说明配置正确。

macOS 下使用 gcc 而非 clang

今天编译一段带有 #include <bits/stdc++.h> 这样一个头文件的 c++ 代码时,遇到了报错

1
2
3
4
5
fatal error:
'bits/stdc++.h' file not found
#include <bits/stdc++.h>
^~~~~~~~~~~~~~~
1 error generated.

查了一下才知道:Mac OS X 10.9+ no longer uses GCC/libstdc++ but uses libc++ and Clang. 所以平时我们 macOS 使用的 gcc 实际上已经是 clang了。

1
2
3
4
5
6
7
~/work$ gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

如何解决呢?最方便的就是 brew install gcc。在此之前请一定检查自己是否下载过 CLT ,我没有预先下载 CLT,导致自己电脑从源下载,并且自己跑编译,CPU 瞬间 100% 占用,烫的可以煎鸡蛋才发现异常(。

1
2
3
4
5
~/work$ brew config
macOS: 10.14.4-x86_64
CLT: N/A
Xcode: 10.2.1

CLT: N/A,于是要使用 xcode-select --install 命令来下载,苹果 CDN 很迷,请关闭全局梯子。

终于下载好啦,我们应该使用什么命令编译呢?显然不是 g++ main.cpp -o main,因为不管是 gcc 还是 g++ 这个名字已经被占用了。

1
2
3
4
~/work$ ls -l /usr/local/bin | grep g++
lrwxr-xr-x 1 qianqian admin 31 May 6 19:45 g++-8 -> ../Cellar/gcc/8.3.0_2/bin/g++-8
lrwxr-xr-x 1 qianqian admin 53 May 6 19:45 x86_64-apple-darwin18-g++-8 -> ../Cellar/gcc/8.3.0_2/bin/x86_64-apple-darwin18-g++-8

所以改成 g++-8 x.cpp -o x 即可啦w

gdb

昨天的 Unix 作业很有意思,一个是让写头文件 (.h) / 源文件 (.c) 和 main.c 文件,让互相调用。

实现的在这里了 https://github.com/wwyqianqian/ccnu-unix/tree/master/p1p2

好久没写 c,居然忘记了调用函数不能直接写全局,而是应该再写一个函数包起来,想想自己居然有这种思维的原因,应该是被 python 给荼毒了……

另外一道题是让判断所输入的字符串是否为合法标识符,如果不合法请滤出并输出合法的。之前想用 C 的数组写,并自身修改自身,后来换成 C++ vector,想着删除方便,可惜 vector 开错成 string 的了,实际上应该开 char。经过点拨(,发现为啥要修改啊,另开一个数组存放不好嘛……。瞬间觉得智商被碾压…… 点击实现

到这里,第二题还没完,老师让用 gdb 调试,好古老和麻烦,但是也有必要了解,(之前群友好像为了判断 XZP 相机按钮的原因,还是判断米家台灯来着,我本地这边下载过)可惜我还是不会用,借作业的机会,简单查了查怎么玩。macOS gdb 总是报错,之后按照这个方法来 lldb :https://opensource.apple.com/source/lldb/lldb-69/docs/code-signing.txt ,(第一次知道苹果还有 opensource 这个二级域名)。Unix/Linux 挺好玩的,比较好奇为啥学校人培理论上让大二/三下才学,后悔 cmake 啊,gdb 啊等等基础,落下太多了……大一学就好了qwq。

科学的东西

今晚杰哥日常分 vps,按他的习惯用膝盖骨想都知道跑的是 Arch Linux(。于是 man pacman,好久没有见到过阿奇了,阿奇冇得顶 xd ,虽然并没有怎么用过 qwq ……

然后想起来,这条线路还是 CN2 GT,就 202.97 / 59.43,梦回 2018 年初 orzz ……

https://github.com/shadowsocks/shadowsocks-libev

1
2
3
4
5
pacman -Syu shadowsocks-libev
cd ../etc/shadowsocks
vim qian.json
systemctl start shadowsocks-libev-server@qian.service
systemctl status shadowsocks-libev-server@qian.service

Python3 爬取知乎回答下面的评论

这个迫真爬虫是年前用了和 req-ccnu 一样的方法写的(隐藏api+模拟登陆),他们都有一个特点,就是处理 curl 后,后端返回的 json。当时没有看面向对象也没有学语法,所以以后要好好学 bs4,lxml,scrapy 写真正意义上的爬虫。#flag
简单的源代码:https://github.com/wwyqianqian/ShuYu/blob/master/ZhiHuCom2File.py
后端返回字典:https://github.com/wwyqianqian/ShuYu/blob/master/ZHC.js
本文记录当时遇到的两个小问题,全是编码相关:

  • 第一个是调试时候终端打印出奇怪的字符,解决办法是在 header 里面去掉
    'accept-encoding': 'gzip, deflate, br',
    因为 requests 会自己加上 gzip(但 gzip 解压是自动的)。手动传了 requests 就假设自己处理压缩了,去掉后,这样返回内容就不会经过编码。

  • 第二个问题是,实际运行时候,有的评论会正确爬取,有的会爬出乱码,这说明代码逻辑没有问题,又是编码的错误,应该如何解决呢?

    1
    2
    3
    4
    40. 为什么不做成猫粮狗粮?
    41. èµ°é¤�é¦†æ¸ é�“,特别是ç�«é”…,酸è�œé±¼
    42. 鱼丸啊。
    43. 没有消失。都转到了农�

原因就是翻页时候 Requests 检测不到正确的编码,而且知乎又没有限定编码,所以需要我们自己手动限定,加上一句 reponse.encoding = 'utf-8' 就好了。
改过之后就可以正确运行啦~


requests 源代码节选:https://github.com/requests/requests/blob/75bdc998e2d430a35d869b2abf1779bd0d34890e/requests/utils.py#L855

这个猜测的代码先取了四个字节,通过看 \0 的个数来判断是不是某个编码,然后 requests 没有选出来合适的 encoding,于是得到 none。

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
def guess_json_utf(data):
"""
:rtype: str
"""
# JSON always starts with two ASCII characters, so detection is as
# easy as counting the nulls and from their location and count
# determine the encoding. Also detect a BOM, if present.
sample = data[:4]
if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE):
return 'utf-32' # BOM included
if sample[:3] == codecs.BOM_UTF8:
return 'utf-8-sig' # BOM included, MS style (discouraged)
if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE):
return 'utf-16' # BOM included
nullcount = sample.count(_null)
if nullcount == 0:
return 'utf-8'
if nullcount == 2:
if sample[::2] == _null2: # 1st and 3rd are null
return 'utf-16-be'
if sample[1::2] == _null2: # 2nd and 4th are null
return 'utf-16-le'
# Did not detect 2 valid UTF-16 ascii-range characters
if nullcount == 3:
if sample[:3] == _null3:
return 'utf-32-be'
if sample[1:] == _null3:
return 'utf-32-le'
# Did not detect a valid UTF-32 ascii-range character
return None
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
def get_encoding_from_headers(headers):
"""Returns encodings from given HTTP Header Dict.
:param headers: dictionary to extract encoding from.
:rtype: str
"""
content_type = headers.get('content-type')
if not content_type:
return None
content_type, params = _parse_content_type_header(content_type)
if 'charset' in params:
return params['charset'].strip("'\"")
if 'text' in content_type:
return 'ISO-8859-1'
def stream_decode_response_unicode(iterator, r):
"""Stream decodes a iterator."""
if r.encoding is None:
for item in iterator:
yield item
return
decoder = codecs.getincrementaldecoder(r.encoding)(errors='replace')
for chunk in iterator:
rv = decoder.decode(chunk)
if rv:
yield rv
rv = decoder.decode(b'', final=True)
if rv:
yield rv

Assessment-and-Progress-Records

引子

自己大二上其实课程很少,但是也是显得很忙的样子,每天忙忙碌碌疲倦不堪,沉浸在「我很累」的自我陶醉里,也不知道到底在忙什么。最近很开心被靠谱的同学和超赞的导师拉入了计算新闻组,于是大概可以静下心,开篇婆婆妈妈的博客记录一下学习进度,以后也方便回忆那年的那段时间自己做了什么。


记录正文

11.29-12.05

新人入组,第一个任务也许算老人眼里的简单,不过也够我们新人喝一壶。学长给了他写好的 py2 爬虫代码,让我和专题组的玥璇每人负责爬 5 类。吃老本改了 UA、Cookie,找微博 repostTimeline 的 api,终于跑通了代码。但是单个爬起来很慢,这个时候脑子第一个想法就觉得可以使用 screen 命令,脑子里又飘过了 systemd,但是又不会(一年前就不会,懒哭了),这点存疑。

第二点肯定有的想法是,心疼自己电脑+害怕突然断网+晚上电脑要合上盖子,于是就想丢在 VPS 里面跑,但是跑完的结果如何下载呢?第一反应是 eq 维护的 caddy,可是害怕自己不会配置浪费时间(事实上这歩真的走错了,当时就应该用 caddy 的),就想到了之前下载 searching 那部电影时候用过 Nginx,结果退步的自己浪费 2h 也没搞好,最后找我的红心苕 ssh 进来修好了,大概是我配置文件写错了,而且位置也错了。总之一天半的折腾后,终于及时交差,等着明天的组会安排下周任务。买的 py 书到了,可惜还没看,最近期末事情越来越多欸……

12.06-2.12

残忍的期末考和愉快的春节期间,断断续续也接了几个学长安排的任务,大部分和上次一样,都是爬微博转发 + 评论 + 用户,另外一个附加任务是学习并自己写某指定网站的评论爬取代码,我选择了知乎,当时遇到了一点点小问题,现在另开一个博客文章记录一下。说实话以前没有好好看过 py 语法,寒假拿出几天时间把之前买的书前十章看完了,应该还是有点浅,不过一些小细节也是曾经完全不知道的。也准备另开一文整理一下。想要深入的话,https://python3-cookbook.readthedocs.io/zh_CN/latest/index.html 立 flag 看完 cookbook。