-
-
Save shellexy/2413736 to your computer and use it in GitHub Desktop.
#!/bin/bash -x | |
SRC=$PWD/data/ | |
DEST=$PWD/web.hotot.org/ | |
echo "\033[1;31;40m[i]Sync ...\033[0m" | |
# ignore .*.swp, .hgignore, etc | |
rsync -av --exclude '.*.*' --exclude '*.coffee' --exclude 'test*' $SRC $DEST | |
# replace conf.vars.platform, key and secret | |
echo "\033[1;31;40m[i] Replace platform, key and secret ...\033[0m" | |
sed -i "s/'platform': '\w*'/'platform': 'Web'/g" ${DEST}js/conf.js | |
sed -i "s/'consumer_key': '\w*'/'consumer_key': '604L17uwIwWsT1TIyjBTQA'/g" ${DEST}js/conf.js | |
sed -i "s/'consumer_secret': '\w*'/'consumer_secret': 'eB7cjPzO9QGZi50jpdrlIPtpPvlKkdt18uahit5oYE'/g" ${DEST}js/conf.js | |
echo "\033[1;31;40m[i] Done!\033[0m" | |
## ########################### | |
cat >> ${DEST}js/hotot.js <<OOO | |
if (conf.vars.platform === 'Web') { | |
var URL = document.URL.replace(/\/[^\/]+$/, '/'); | |
window.XMLHttpRequest.prototype.open_ = window.XMLHttpRequest.prototype.open; | |
window.XMLHttpRequest.prototype.open = function(method, url, async, user, password) { | |
url = url.replace('https://', '/'); | |
url = url.replace('http://', '/'); | |
return this.open_(method, url, async, user, password); | |
} | |
ui.PinDlg.set_auth_url_ = ui.PinDlg.set_auth_url; | |
ui.PinDlg.set_auth_url = function(url){ | |
return ui.PinDlg.set_auth_url_(url.replace('https://api.twitter.com/', URL + 'itap/')); | |
} | |
} | |
OOO | |
## html5 cache | |
( | |
cd ${DEST:-.} | |
echo -e 'CACHE MANIFEST\n' > cache.manifest | |
echo -e 'NETWORK:\n*\n' >> cache.manifest | |
echo 'CACHE:' >> cache.manifest | |
find . -type f | grep -Ev '^\./itap|\.gz$|cache\.manifest|cache\.html|index\.html' | sed 's/^\.\///; s/ /%20/g' >> cache.manifest | |
echo "# `date -R`" >> cache.manifest | |
sed -i 's/<html.*>/<html lang="en" manifest="cache.manifest">/' index.html | |
mv index.html hotot.html | |
echo '<html><head><meta http-equiv="no-cache" /><title>Hotot</title></head><frameset><frame src="hotot.html"></frameset></html>' > index.html | |
) | |
sed -i "s/'use_alt_reply': \w*/'use_alt_reply': true/g" ${DEST}js/conf.js | |
convert -quality 30 ${DEST}/image/welcome_bg.jpg ${DEST}/image/welcome_bg.jpg | |
which yui-compressor && find "$DEST" -name '*.css' -exec yui-compressor -o "{}" "{}" \; | |
which uglifyjs && find "$DEST" -name '*.js' -exec uglifyjs --overwrite "{}" \; |
为了便于使用,咱使用了 itap 代理登录,
需要在 hotot 根目录下放入 itap,
并在 itap/handler.php 中 auth_post() 的 echo $response; 下方添加
echo '<script>code = document.querySelector("code").innerText; opener.$("#tbox_oauth_pin").val(code); opener.$("#btn_oauth_pin_ok").click(); setTimeout(window.close, 1000);</script>';
架设 hotot web
## 抓回 hotot
git clone --depth 0 git://github.com/shellex/Hotot.git
cd Hotot
## 生成 web.hotot.org 目录
wget https://raw.github.com/gist/2413736/mk-hotot-web.sh
bash -x mk-hotot-web.sh
cd web.hotot.org
## 抓回 itap
hg clone https://bitbucket.org/aveline/itap
## 然后照着上边修改 itap
## 最后将 web.hotot.org 目录内容发布出去
## 注意当前代码是假设 hotot web 在子域名根目录,所以代理的请求都是类似 /api.twitter.com/xxx
Cloning into Hotot...
Permission denied (publickey).
fatal: The remote end hung up unexpectedly
咱是渣渣,不会在Debian上玩git……
猫孃重新试试,改为
git clone --depth 0 git://github.com/shellex/Hotot.git
雪梨软软itap在哪改?
无限Loading Resources……
wget https://raw.github.com/gist/2413736/mk-hotot-web.sh
卡在这里了
sh.exe: wget command not found
XD
Loading Resources ...
果然子目录下要改的吗?
白熊不在服务器上 ssh 的么,
子目录而非子域名根目录的话需要改下代码,愿白熊顺利出补丁。
狗爹ssh是废的(
我这边apache的 所以还得写.htaccess啊。。。
白熊大大那么厉害一定能写好的
醒醒 鶸渣渣一只好吧
23333……其实咱也不会写……不过大家都用apache啊
暂时改用框架来强制不缓存首页
(来试试 comment 能不能张贴长篇大论)
雪梨老师前天布置的作业,于是算是交作业(草稿)
主要步骤大致整理如下:
第一部分 准备工作
源码获取以及雪梨写的脚本中用到了这些工具:
git hg (mercurial) wget convert (ImageMagick) yui-compressor uglifyjs
鉴于通常咱们的VPS都是以最精简状态安装操作系统的(从留言的评论看,甚至可能连wget命令都没有),因此我们需要将上述工具预先准备好(其中css/js压缩器yui-compressor和uglifyjs为可选)。
我的VPS操作系统是CentOS,可以通过yum自动完成安装,命令如下:
yum install git hg wget ImageMagick
使用其他操作系统的请酌情办理 =w= (谁来补充一下w
剩下的yui-compressor和uglifyjs,用于压缩js和css代码。这两个不是必需品。可选安装。
在debian/ubuntu 里可以直接 apt 安装:
sudo apt-get install yui-compressor node-uglify
如果是CentOS,则略麻烦一些(没有找到包含它们的yum源),需要手动安装。
不过反正是可选步骤,不装也可以。
其中,安装yui-compressor的主要步骤是:
wget http://yui.zenfs.com/releases/yuicompressor/yuicompressor-2.4.7.zip
unzip yuicompressor-2.4.7.zip
mkdir -p /usr/local/yuicompressor/
cp yuicompressor-2.4.7/build/yuicompressor-2.4.7.jar /usr/local/yuicompressor/yuicompressor-2.4.7.jar
cat >> /usr/bin/yui-compressor << EOF
!/bin/sh
YUI_JAR=/usr/local/yuicompressor/yuicompressor-2.4.7.jar
java -jar $YUI_JAR $1 "$2" "$3"
EOF
chmod a+rx /usr/bin/yui-compressor
(要正常使用yui-compressor,请确保系统中已安装好Java运行时环境)
yuicompressor通常情况下是以
java -jar /path/yuicompressor-x.y.z.jar [options] [input file]
的形式调用的;但是观测到雪梨的脚本中似乎是直接以yui-compressor这个命令的形式调用的,不知道是怎么实现的呢?
(于是我把它写成了 /usr/bin/yui-compressor 这个脚本;不过感觉这个方法还不够漂亮不够优美哈...于是求好方法)
安装uglifyjs的主要步骤是:
首先需要下载源码并编译安装node.js
wget http://nodejs.org/dist/v0.6.15/node-v0.6.15.tar.gz tar xzvf node-v0.6.15.tar.gz cd node-v0.6.15 ./configure make sudo make install
然后
mkdir -p /放置路径 cd /放置路径 git clone git://github.com/mishoo/UglifyJS.git mkdir -p ~/.node_libraries/ cd ~/.node_libraries/ ln -s /放置路径/UglifyJS/uglify-js.js cd /usr/local/bin ln -s /放置路径/UglifyJS/bin/uglifyjs
即可。
以上,工具的准备工作告一段落。
第二部分 生成网页版Hotot发布目录内容
雪梨写了部署脚本,因此可以很方便地实现,命令步骤如下:
## 抓回 hotot git clone --depth 0 git://github.com/shellex/Hotot.git cd Hotot ## 生成 web.hotot.org 目录 wget https://raw.github.com/gist/2413736/mk-hotot-web.sh bash -x mk-hotot-web.sh cd web.hotot.org ## 抓回 itap hg clone https://bitbucket.org/aveline/itap
上述执行完毕后应该出现一个web.hotot.org目录;在web.hotot.org目录下有一个itap目录。
编辑itap目录下的handler.php =文件。找到其中的 auth_post() 函数;在函数的 echo $response; 那一行下方添加以下内容:
echo '<script>code = document.querySelector("code").innerText; opener.$("#tbox_oauth_pin").val(code); opener.$("#btn_oauth_pin_ok").click(); setTimeout(window.close, 1000);</script>';
保存退出。此时网页版的发布内容已基本准备妥了。
第三部分 Nginx配置
- 申请SSL证书
由于大家都知道的原因,网页版Hotot是在互联网上公开地放置Play,如果数据明文传输的话,对于我们的宝贵域名、宝贵VPS、宝贵IP都不是很安全……万一被墙嗅出来然后炮灰掉,那可真的很糟糕……何况大墙最近技艺似乎确实日渐精进,非加密连接的 tw*p 们已经纷纷被ban,速度很快效率很高。因此除非手持炮灰米+炮灰主机,否则还是强烈建议去弄个证书,使用HTTPS加密连接。
申请免费SSL证书的流程可参考:
http://www.deepvps.com/apply-startssl-ssl-certificate.html
这里不再赘述。
验证域名所有者时需要使用whois记录中的管理猿邮箱,请保证whois记录真实准确(至少临时真实个几天吧w);或者使用 [email protected] 这样的域名邮箱也行,可以去借助Google提供的免费企业应用服务实现。
证书弄回来之后,还是需要小加工一下的。我们需要把 StartSSL 的根证书和sub class1的证书附上,因为是它把证书颁发给我们,浏览器需要这张证书才认识我们的证书。
如果不进行该操作,部分浏览器会报告证书不可信(据说=w=),同时一段时间后也会收到StartSSL网站类似的邮件提醒。
假设保存的私钥文件名为 ssl.key ;证书文件名为 ssl.crt ,上传到VPS的某个目录保存,然后在VPS上执行命令如下:
wget http://cert.startssl.com/certs/ca.pem wget http://cert.startssl.com/certs/sub.class1.server.ca.pem echo >> ssl.crt cat ca.pem sub.class1.server.ca.pem >> ca-certs.crt cat ca-certs.crt >> ssl.crt openssl rsa -in ssl.key -out ssl.key.decrypted
注意步骤中 echo >> ssl.crt ,其作用是在 ssl.crt 后插入回车换行,再拼接CA证书。
度娘搜出来排在头上的几篇文,都遗漏了插入换行这一步,因此拼接出的证书格式变成了有误的,Nginx启动时会报错无法启动。
此外,如果直接使用加密的私钥文件ssl.key,启动Nginx时候会要求输入密码,这样Nginx就不能开机自动启动了,很不方便。在此我们将其解密导出为PEM文档,Nginx启动时就无需输入密码了。当然这么做的话,该文件务必要保管好,切不可外流。
搞定证书之后就可进行Nginx子站的配置。请将第二部分中准备好的 web.hotot.org 文件夹作为子域名根目录发布出去。下面是我的配置文件,供参考。
本例中假定的环境情况罗列如下,实际应用时请酌情修改:
IPv4地址: 123.123.123.123
IPv6地址: AAAA:AAAA:AAAA:AAAA::AAAA
绑定的域名: Meow.Meow
发布文件夹保存路径: /home/web.hotot.org
证书文件地址: /etc/nginx/certs/Meow.Meow/ssl.crt;
私钥地址(使用解密的): /etc/nginx/certs/Meow.Meow/ssl.key.decrypted;
#非加密连接相关配置部分 server { #无IPv6地址时,IPv6那一行可直接删除; #若要支持IPv6,则所有Server的v4和v6地址必须同时全部写明,不能只写80 listen 123.123.123.123:80; listen [AAAA:AAAA:AAAA:AAAA::AAAA]:80; #DNS服务器8.8.8.8,作正向代理时必须设置 resolver 8.8.8.8; server_name Meow.Meow; index index.html index.htm index.php default.html default.htm default.php; root /home/web.hotot.org; #若想配置为HTTP/HTTPS兼用(可选加密),则注释掉下面这行即可 #默认强制跳转至加密方式入口,永远不使用非加密连接 rewrite ^(.*) https://$server_name$1 permanent; #仅支持基于WebKit引擎的浏览器(Safari/Chrome,经测试Maxthon也可用) if ($http_user_agent !~ "Chrome|Safari") { return 404; } location ~ .*\.(php|php5)?$ { fastcgi_pass unix:/tmp/php-cgi.sock; fastcgi_index index.php; fastcgi_param HTTPS on; include fcgi.conf; } location ~ (twitter\.com) { if ( $request_uri = "/" ) { return 404; } access_log off; proxy_buffering off; proxy_set_header Referer $scheme:/$request_uri; proxy_pass "https:/$request_uri"; } location ~ (img\.ly|plixi\.com|google\.com) { if ( $request_uri = "/" ) { return 404; } access_log off; proxy_buffering off; proxy_set_header Referer $scheme:/$request_uri; proxy_pass "http:/$request_uri"; } location ~ (hotot\.in\/) { if ( $request_uri = "/" ) { return 404; } access_log off; proxy_buffering off; proxy_set_header Referer $scheme:/$request_uri; proxy_pass "http:/$request_uri"; } location /itap/ { access_log off; if (!-e $request_filename) { rewrite ^(.*) /itap/index.php last; } } location / { access_log off; gzip_static on; gzip on; gzip_min_length 1000; gzip_types text/plain application/x-javascript text/css; expires 2d; add_header Cache-Control public; } access_log off; } #加密连接相关配置部分 server { #无IPv6地址时,IPv6那一行可直接删除; #需要启用IPv6时,则所有Server的v4和v6地址必须同时全部写明不能只写80 listen 123.123.123.123:80; listen [AAAA:AAAA:AAAA:AAAA::AAAA]:80; #DNS服务器8.8.8.8,作正向代理时必须设置 resolver 8.8.8.8; server_name Meow.Meow; index index.html index.htm index.php default.html default.htm default.php; root /home/web.hotot.org; #使用解密后的私钥文件,启动Ngnix时不输入密码 ssl on; ssl_certificate /etc/nginx/certs/Meow.Meow/ssl.crt; ssl_certificate_key /etc/nginx/certs/Meow.Meow/ssl.key.decrypted; #仅支持基于WebKit引擎的浏览器(Safari/Chrome,经测试Maxthon也可用) #由于主机中还托放有API代理供Android手机使用,酌情添加了相应客户端 if ($http_user_agent !~ "Chrome|Safari|Dalvik|Seesmic") { return 404; } location ~ .*\.(php|php5)?$ { fastcgi_pass unix:/tmp/php-cgi.sock; fastcgi_index index.php; fastcgi_param HTTPS on; include fcgi.conf; } location ~ (twitter\.com) { if ( $request_uri = "/" ) { return 404; } access_log off; proxy_buffering off; proxy_set_header Referer $scheme:/$request_uri; proxy_pass "https:/$request_uri"; } location ~ (img\.ly|plixi\.com|google\.com) { if ( $request_uri = "/" ) { return 404; } access_log off; proxy_buffering off; proxy_set_header Referer $scheme:/$request_uri; proxy_pass "http:/$request_uri"; } location ~ (hotot\.in\/) { if ( $request_uri = "/" ) { return 404; } access_log off; proxy_buffering off; proxy_set_header Referer $scheme:/$request_uri; proxy_pass "http:/$request_uri"; } location /itap/ { access_log off; if (!-e $request_filename) { rewrite ^(.*) /itap/index.php last; } } location / { access_log off; gzip_static on; gzip on; gzip_min_length 1000; gzip_types text/plain application/x-javascript text/css; expires 2d; add_header Cache-Control public; } access_log off; }
由于目前只有基于WebKit的浏览器能良好支持,所以加入了if ($http_user_agent !~ "Chrome|Safari") { return 404; } 这么一行,用于限制浏览器种类;不能支持的IE/FF访问时,只能看到404提示。Safari和Chrome肯定是能用的,抓来个Maxthon 3.0试试也行,还有哪些呢…不知道其他数不清的天朝产的“双核”奇葩们会是啥子模样……不过没兴趣安装折腾它们了。
因为发布目录下还寄放有API代理(给Android手机用的),因此可以酌情再添加上相应的客户端标识(Dalvik | Seesmic 等),不然API就用不起来了。
Nginx的配置中,resolver 8.8.8.8这一行挺关键的。Nginx 作为“普通青年”(基本用途)是作为Web服务器/反向代理服务器;但是在我们部署网页版Hotot用于访问Twitter的时候,作为“文艺青年”的Nginx其实是发挥了它的正向代理功能。因为Nginx不会自动读取系统的DNS去解析域名,这就需要我们定义一个resolver指定DNS服务器地址。
之前忘了加上这句resolver,于是从获取token那一步开始起就死住了。
顺便说示一个小技巧,如果你部署的Hotot时遇到各种问题玩不转,Chrome F12的开发者工具会是很不错的debug手段哦,如图所示。http://twitpic.com/9fcht3/full 可以发现问题是连不上api.twitter.com,于是顺藤摸瓜之,发现原因所在。(爬墙呢喵……爬墙呢喵……啊呜从墙上摔下来了喵…痛痛痛……啊呜啊呜终于验证通过了喵)
第四部分 一点障眼法
说起来,傲兔兔什么的最好用了……但是对于哔哔哔来说,这货的存在最讨厌了……域名私藏好,低调地用吧。
鉴于大墙已经开始无差别撒大网封禁架设无加密TW_P服务的域名了(而不像以前只抓大户),使用加密连接应该是一个靠谱的保证;此外,是不是还需要设置一些障眼法什么的呢?
一方面,肯定是要用私藏的二级域名,最好是炮灰域名;避免用顶级域名或者www._;
此外咱们也可以让Nginx绑定一个根本不存在的域名嘛……然后本机写hosts文件,直接指向这个捏造的域名(咳咳…我什么都没说……遁)
譬如使用华丽丽的Hotot.Meow(喂等一等…Hotot是兔子亚,为什么喵叫…) http://twitpic.com/9fciqw/full 这样就算通过抓包的方式被发现了,也ban不掉什么真金白银买来的宝贝域名撒……哦对了还可以直接ban主机的IP(跪
以下这段是过去时的讨论了……因为已经想通了,不会有安全隐患的说w
但是封禁直接以IP地址访问的方法,有时候还是用得着的,所以暂保留:
最后,我在担心考虑的是,虽然地址自己不会泄露出去,但是爬虫是个很讨厌的家伙……如果遭遇爬虫直接根据IP前来访问,怎么办呢?
考虑到虽然Ngnix里面绑定了域名,但是如果没有停放其他使用443端口的加密连接站点(毕竟一般服务器上都只配置了非加密的默认站点吧),用IP直接访问的时候,一旦手动发起443端口的HTTPS连接(爬虫会这样做么?)还是会直达我们的的首页。因为这是这台服务器上是唯一的加密站点,所以Ngnix把它作为了默认的(虽然会警告证书不匹配)提供给爬虫。
(于是到底会不会被爬虫抓呢?直接扫IP然后摸进来什么的?)
总之觉得这样还是不好、不安全不放心……(也许是我迫害妄想症……)所以打算要禁用IP直接访问、以及未经绑定的域名的访问。
普通青年的方法很简单,在真·站点之前绑个空的dummy站就行了,取代真·站点成为默认站点。还可外加跳转。(以下配置文字一定要写在真·站点的server段之前,才能有效哦)
#如果80端口已有默认站点的话,第一个server段可以不要 server { listen 123.123.123.123:80; listen [AAAA:AAAA:AAAA:AAAA::AAAA]:80; server_name Meow.Meow; index index.html index.htm; root /dev/null; return 404; access_log off; } server { listen 123.123.123.123:443; listen [AAAA:AAAA:AAAA:AAAA::AAAA]:443; server_name Meow.Meow; index index.html index.htm; root /dev/null; ssl on; ssl_certificate /etc/nginx/certs/Meow.Meow/ssl.crt; ssl_certificate_key /etc/nginx/certs/Meow.Meow/ssl.key.decrypted; rewrite ^(.*) http://$host$1 permanent; access_log off; }
说到拿 HTTP 返回值做障眼法,错误返回值其实可以随便写?只要是RFC协议里面定义的就行。比如:
普通青年用 return 404 Not found ;
文艺青年用 return 415 Unsupported media type ;
二逼青年用 return 402 Payment Required ;
(你够了……
如果是213青年,大概有更213的做法,类似于可以这样:
server { listen 123.123.123.123:443; listen [AAAA:AAAA:AAAA:AAAA::AAAA]:443; server_name Meow.Meow; if ($host !~ "Meow.Meow") { rewrite ^(.*) http://Nyaa.Nyaa permanent; } index index.html index.htm; root /dev/null; ssl on; ssl_certificate /etc/nginx/certs/Meow.Meow/ssl.crt; ssl_certificate_key /etc/nginx/certs/Meow.Meow/ssl.key.decrypted; access_log off; ………… ………… ………… ………… 下略 }
如果来访所使用的主机名并非绑定的域名,则直接跳转到一个根本不存在的站点……(两种方法哪种更优雅一些呢……?
最后再配合robots.txt,再把index.html改掉,这样感觉应该差不多了吧……
//补:呃,折腾那么多……刚刚才忽然想起来,爬虫bot提交的客户端肯定不会是Chrome| Safari……
Google是 Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
Baidus是 "Baiduspider+(+http://www.baidu.com/search/spider.htm)"
所以按照之前写的Ngnix规则只能抓到HTTP错误信息……
因此是我多虑了吧……
不过写都写了那么多了那还是留着吧(跪 ……好吧,不防bot防防活人也好
wwww
赞下阿喵
噢,是酱紫的,debian/ubuntu 里可以直接 apt 安装 yui-compressor 和 uglifyjs
sudo apt-get install yui-compressor node-uglify
或许需要再强调下这俩是可选的?尤其是 java 程序实在有些那啥,
不过如果装过 nodejs 的话,可以选择用无需 java 的 uglifycss 来压缩 css
跑题下,错误代码大概还是用 404 比较好些,已经删除?
402 的话有这个是用来牟利的嫌疑?
虽然我自己是用的 401
啊呜…402是我昨天耍宝耍213,自己弄着玩儿的……
配置文件直接粘贴过来了……没想到居然还遗漏了一处402没改回去
已经改了w
另外yui-compressor 和 uglifyjs的相关也做了更新。
用的 nginx 规则是
唔,我自己的完整 nginx 配置是用的