Updated:

  • 2021-04-23: 更新文章,删减不恰当的段落和补充细节。

注意:本文仅作学习研究,网络并非非法之地,请约束互联网访问行为并自行承担责任,共同净化网络环境。

镜像,原意是光学里指的物体在镜面中所成之像。引用到计算机网络上,网站镜像是指对网站内容的拷贝。镜像通常用于为相同信息内容提供不同的源,特别是在下载量大的时候提供了一种可靠的网络连接。制作镜像是一种文件同步的过程。 —— 维基百科

如今翻墙的方式多种多样,把我所了解到的分享出来,有兴趣的朋友可以自己去了解。

按资源和技术成本排序(个人见解,如有出入请斧正)

  • hosts
  • 蓝灯
  • SSH 动态转发
  • 镜像站
  • Shadowsocks / v2ray
  • 去香港 :)

镜像站又分为两种,一种是通过程序爬取 Google 搜索的结果页,另外一种通过服务器(本文为Nginx)反向代理。而他们唯一的相同点都是服务器需要在大陆以外,且大陆能正常访问。

可以尝试用 tcping 来测试主机的网络情况,具体参见 tcping - PyPi

先说说通过程序爬取,这里以 PHP 为例。原理是用户访问程序,程序将搜索关键字与谷歌搜索的链接进行参数拼接,然后通过 curl 进行抓取页面并输出。当然这种手段比较暴力,以至于 Google 的很多图片、CSS、JS等资源均可能加载失败,不过也可以通过正则匹配资源路径进行缓存,然后替换页面中的地址再输出。

但不得不说,通过爬取结果页的效率是相当慢的,整个过程被下载页面和匹配替换耽搁了很长的时间。

反向代理的方法多种多样,本文以服务器常用 Nginx 论述。反向原理是用户访问代理服务器,代理服务器将请求转发给目标服务器,目标服务器接收并响应给代理服务器,而代理服务器讲结果响应给用户。

看似过程和直接爬取结果差不多,但所执行的效率远高于爬取结果。

准备

  • 境外服务器一台(需要安装Linux、Nginx)
  • 域名(子域名均可)
  • 耐心

开始

注:服务器需要安装 Nginx ,Nginx安装本文不在讨论范围,自己可以查文档进行安装。

首先,需要在服务器上新建一个虚拟主机(VirtualHost):

# 移动到 Nginx 配置目录
$ cd /usr/local/nginx/conf/vhost/
# 创建一个配置文件,格式:*.conf
$ touch google.conf
# 编辑该文件
$ vim google.conf

然后将以下配置复制入配置文件,并修改

server
{
    listen 80;
    listen 443 ssl;
    server_name xxx.example.com;  #修改为你的域名
    #以下为 ssl 证书存放位置
    #ssl_certificate    /etc/.../fullchain.pem;  #修改为您的证书地址
    #ssl_certificate_key    /etc/.../privkey.pem;  #修改为你的证书地址
    #以下为强制跳转 https
    #if ($server_port !~ 443){
    #    rewrite ^(/.*)$ https://$host$1 permanent;
    #}
    error_page 497  https://$host$request_uri;
    location / {
        #需要代理的地址,这里为 谷歌香港
        proxy_pass https://www.google.com.hk/;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

测试

然后保存并退出

# 按下 Esc 键
# 输入 : (Shift + ;) 
$ qw
# 使用 nginx 命令测试配置文件 出现 successful 则通过测试
$ nginx -t

如果执行 nginx -t 命令后报错,根据行号找到报错原因并修改。

最后到域名解析商添加一个 A记录 到你的主机 IP 。

其实到这里你所搭建的镜像站就能正常访问了,但在配置中能看到,还有 ssl 证书的相关配置。在这里建议镜像站均使用 https 协议,用于加密传输内容,尽量规避 GWF 以防封锁服务器 IP,免费证书各大主机商都可以申请。然后上传保存到服务器中,修改好证书的路径,打开所有 ssl 相关的注释便能通过 https 进行访问了。

还有哪些站点能够镜像?这个就没试验过了,不过刚刚测试了 wiki 中国,CSS 样式没有。且 console 一大堆报错,就直接删掉了。Youtube 就直接不用测试了,肯定不行。有其他站点测试成功的朋友,欢迎补充。

声明

本文只做技术探讨,由此产生的法律责任后果自负。

我一直相信,每个宣称自己是黑客的青少年,一定都有着某种非主流的情怀,这情怀无法由颜值担当,就只能籍技术派遣。我也不例外。 ——来自《我的校园黑客故事》 - 王登科

很多热爱网络的人都向往着黑客,这种情愫在懵懂时最是旺盛而又随着年龄逐渐淡去。我接触互联网的时间不算早,也正是互联网聚变的时期,不过那个时候肉鸡和宽带付费最是火热的时候。

我的启蒙时期也是在那个时候开始的。懵懂时期的一些事儿实在丢人现眼,就从高中毕业开始说起吧。

考上专科几乎没有其他原因,高中不努力。而我打算报考单独招生考试,流程大概是先到意向学校官网报名,然后缴费,按考试时间参加学校的考试,最后就是等录取消息了。在各种纠结之后,还是网上报名了母校的单招考试。

而不争的事实是每个学校都有一个漏洞百出的官网。报完名之后,习惯性的翻了翻学校的站点,asp写的后台,在版权信息部分找到了管理入口,进入后习惯性的试了几个弱口令,未果。准备关掉浏览器的时候试着 SQL 注入 ' or 1=1

「欢迎回来,管理员。」

对,这么草率。抑制住内心的欣喜开始爬后台。按照以往的流程是:找上传入口上传木马或者写马,然后上传cmd.exe进行提权。

没找到上传入口!?

带着疑问,翻看已经发布的文章,居然还真没发过一张图片。只好作罢,继续看看还有什么有价值的东西。虽然没有上传入口,而这个账号的权限却不低,关闭报名入口,删改/下载学院的学生名单都不在话下,甚至在文章里追加一段恶意 javascript 还可以继续深挖。

快速浏览了后台,名单中包含的信息非常详细,姓名、年龄、身份证、手机号,甚至你家住哪儿村哪个屯。看着庞大的表格,居然有些不知所措。

这是否可以做点文章?

那是当然,在离考试前几天,我将它参照乌云的格式写成漏洞报告书然后打印了出来。详细的论述了漏洞地址,漏洞属性,漏洞测试,然后把后台截了两张图,最后,写出了两点修复意见。要么就把管理界面隐藏起来,要么就是过滤关键字或者转义。

考试前一天,特长生需要提前到学校报道,把高中的各种证书拿出来复印了一份,临走前将漏洞报告书递给招生老师,让帮忙带给网站管理员。其实提交报告书的时候,手都在抖。尽管报告书尾页标注的「以上为友情测试,本人承认未下载、删除、修改任何数据,未公开该漏洞…」,但是「未经过授权的渗透测试属于违法行为」

考试完走出校门,自豪感涌上心头。

事后发现当时的行为实在鲁莽,也十分感谢学校既往不咎:

非常感谢提交漏洞和对xxxx的支持,我们已第一时间将漏洞修复完毕,并抓捕了你。 —— 袁炜事件

后来啊。一直忙于各种闲事儿,也很少去搞破事儿了。不过大二左右,无聊逛着学校官网,找到图书馆的系统,通过机房内网尝试注入,找到上传漏洞并上传了小马,接着写了一只大马,提权进入了服务器,不过该站点长时间未更新又是一个很偏的一个子系统,C盘D盘草草翻了下也没有什么价值,然后溜达了一圈就关掉了。

从 QQ 空间翻出来的老照片

刚刚想起来还有这茬,重新打开图书馆官网看到最近有更新文章,便联系站点底部馆长邮箱,告知该漏洞信息并提醒修复,发出去两分钟就给回信了,『好的,谢谢你!』,不过该漏洞尚未修复,也就暂不公开了,邮件截图等漏洞修复完成了再补图吧。

更新:2017-8-29 补图邮件

2017-8-29 补图

是的,我始终未成为年少时理想中的黑客。

以上,我的黑客故事。

世上三大最难懂:医生的处方、道士的符、程序员的正则

学了几年编程,也写了不少项目,业务逻辑经验攒了一堆,基础知识却落下不少。其中很多还非常重要,比如:进制换算、正则表达式、算法。当初学这些东西的时候,对高数的抗拒让我对带计算的东西也十分抵触。但是,身为码农,这些基础都不懂还怎么拿代码换烟钱?于是,决定恶补一下。

正则表达式

正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。 ——来自维基百科

使用场景

正则表达式起始日常生活中也用过,比如搜索的时候用的*匹配(好吧,那个应该准确的叫做通配符,反正差不多就这意思嘛),下面谈谈正则使用的场景:

  1. 手机号、邮箱、
  2. URL判断
  3. 配置文件、检索关键字
  4. 模板引擎

使用原则

由于正则会将通常一串字符挨个检索,如果没找到匹配项,会从开头一直匹配到结尾,所以说,正则表达式的效率非常低的,能用内置函数尽量用内置函数。不过,一些特定场景正则表达式有他独有的优势

总结:能不用就尽量不用。

语法定义

能不用就不用不代表不学习啊,万一哪天面试就考到你正则不可能瞎写一通吧。即便是做项目在网上复制的现成的也要明白个大概意思。

组成部分

其实组成部分是很多的,这里只做基础介绍。以能写出简单正则,能看懂正则意思为目的。

正则的组成:

  1. 定界符
  2. 原子
  3. 元字符
  4. 模式修正符

匹配规则:

  1. 从左到右
  2. 默认贪婪匹配(简述就是匹配成功后继续匹配,参见#贪婪模式

定界符

定界符是正则表达式的边界,这个没有严格规定,通常以/作为正则的定界符。规则是:不能使用0-9a-zA-Z\和空格。

原子

原子在化学中讲过吧,是最小的单位。而正则中的原子同理,也是正则中最小的单位,不可再分割了。

  • \d:包含0-9
  • \D:不包含0-9
  • \w:包含0-9a-zA-Z_
  • \W:不包含0-9a-zA-Z_
  • \s:包含空白字符、空格、\n\t\r
  • \S:不包含上诉空白字符
  • \b:词边界
  • \B:非词边界
  • []:原子列表,可匹配列表原子或字符出串
  • [^]:取反,写在原子列表里为取反
  • .:除\n以外任意字符

元字符

元字符是用来修饰原子的,不能单独存在,写在原子之后

  • *:匹配任意次
  • +:至少出现一次
  • ?:可有可无,最多一次
  • {}:指定次数

    • {10}:指定十次
    • {3,5}:指定3-5次
    • {3,}:至少3次
    • {0,3}:0-3次
  • ^:指定以某个原子开头(千万别记混[^]^的区别)
  • \A:与^相同
  • $:指定以什么结尾
  • \Z:与$相同
  • |:或
  • ():限制优先级,括号里为一个整体。子模式:参见#子模式

模式修正符

与元字符用于修饰原子,而模式修正符用于修正整个正则表达式。而模式修正符必须写在正则表达式的后面

  • i:忽略大小写
  • m:多行匹配
  • s:让.匹配到\n
  • x:忽略正则表达式中的空格
  • A:与\A^一样
  • U:正则贪婪模式取反

组合

原子与不同元字符组合可以达到很多的效果,而多个元字符可以同时修饰一个原子

  • .+?:取消贪婪匹配,只匹配一个字符
  • .*?:取消贪婪匹配,匹配出0个字符

贪婪模式

仅从应用角度分析,可以这样认为,贪婪模式,就是在整个表达式匹配成功的前提下,尽可能多的匹配,也就是所谓的“贪婪”,通俗点讲,就是看到想要的,有多少就捡多少,除非再也没有想要的了。 ——来自[正则基础之——贪婪与非贪婪模式
](http://blog.csdn.net/lxcnn/article/details/4756030)

子模式

我们可以使用小括号给整个匹配模式进行分组,默认情况下,每个分组会自动拥有一个组号,规则是,从左到右,以分组的左括号为标志,第一个出现的分组为组号1,第二个为组号2,以此类推。其中,分组0对应整个正则表达式。对整个正则匹配模式进行了分组以后,就可以进一步使用“向后引用”来重复搜索前面的某个分组匹配的文本。例如:\1代表分组1匹配的文本,\2代表分组2匹配的文本等等 ——来自正则表达式的子模式详解

样例

由于正则的字符实在"火星",所以需要多加练习才能真正明白其匹配规则,下面写几个样例,以后需要直接用。

判断手机号

分析

手机号一般为11位纯数字,1打头,第二位号码段主要以3,4,5,7,8为主(个人猜测),第三位到最后一位为0-9的随机数。

代码

/^1[34578]\d{9}$/

判断邮箱

分析

邮箱号格式是[email protected],字符串中包含一个@和一个.,其他字符分为三段,第一段以0-9a-zA-Z-_组成且至少一位,第二段以0-9a-zA-Z-组成且至少一位,第三段以a-zA-Z组成且至少两位(中文域名就算了吧)。

代码

/\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}/

总结

在实际开发中所遇到的正则无非就那么几种,网上有很多大佬写好的直接可以用,而自己写的一些正则可以存下笔记,以便以后遇到相同的需求可以直接使用,毕竟效率最重要。

文档

个人用伪类在布居中比较频繁,因为觉得能用CSS完成的动画,尽量不用JS,总觉得JS或多或少会影响页面加载速度和流畅度,个人觉得比较经典,其中也有很多平常开发中遇到的一些小问题,也终于有了解释,所以写篇文章总结下。

伪类?

先来回顾伪类的使用方法,类/标签名:伪类类型便可以构造一个伪类:

selector:pseudo-class {
    property: value;
    ...
}

.class:pseudo-class {
    property: value;
    ...
}

常用的伪类:hoveractivevisitedlinkfirst-childlast-childnth-child(n)等等。

小问题

问题1

现在一个页面,需要实现a标签不同伪类下颜色不同,代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Pseudo - Secret Blog</title>
    <style type="text/css">
        a:hover {
            color: red;
        }

        a:visited {
            color: blue;
        }

        a:link {
            color: green;
        }

        a:active {
            color: yellow;
        }
    </style>
</head>
<body>
    <a href="#">Click it!</a>
</body>
</html>

效果演示:Pseudo - Secret Blog

有错么?代码看起来没错呀,我hover去哪儿呢?之前也遇到过类似的问题,代码没错啊,怎么没效果呢?

W3C中提到(CSS 伪类):

提示:在 CSS 定义中,a:hover 必须被置于 a:link 和 a:visited 之后,才是有效的。
提示:在 CSS 定义中,a:active 必须被置于 a:hover 之后,才是有效的。
提示:伪类名称对大小写不敏感。

上面提到hover必须放到linkvisited之后,而active又要放到hover之后,所有正确的书写顺序是:link -> visited -> hover -> active

问题2

first-childlast-child非常好用,使用方式各式各样,一般用于修改第一个或者最后一个的样式,下列代码大家来分析下,看看有什么错误:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Child - Secret Blog</title>
    <style type="text/css">
        ul li:first-child{
            color: red;
        }
        ul li:nth-child(2){
            color: blue;
        }
        ul li:nth-child(3){
            color: yellow;
        }
        ul li:last-child{
            color: green;
        }
    </style>
</head>
<body>
    <ul>
        <p>List</p>
        <li>First</li>
        <li>Second</li>
        <li>Third</li>
        <li>Last</li>
        <p>List End</p>
    </ul>
</body>
</html>

效果演示:child - Secret Blog

和预想的效果有差异?第一个不是红色字体而是是蓝色呢?第二个不是蓝色又是黄色的,还有最后一个的绿色也没了。

W3C解释(原文地址):

利用 :first-child 这个伪类,只有当元素是另一个元素的第一个子元素时才能匹配。例如,p:first-child 会选择作为另外某个元素第一个子元素的所有 p 元素。一般可能认为这会选择作为段落第一个子元素的元素,但事实上并非如此,如果要选择段落的第一个子元素,应当写为 p > *:first-child。

只有当元素是另一个元素的第一个子元素时才能匹配,通俗的讲,就是上面代码里,div li:frist-child并不是指向下面ul中的第一个li,因为li并不在ul中的一个元素。last-child同理。

nth-child的指向,仔细看一下就会发现,如果将p标签作为第一个的话,那么颜色就没错。而浏览器也正是这样解析的。

总结

CSS 中伪类是一个很奇怪的东西,很多错误发生在细节上却毫无察觉。

今天在Windows下安装了次Node.js环境,其中也涉及到了git的安装和初始化,或许是之前学习的时候太皮,很多命令、参数都忘得干干净净。这次不妨做个笔记,以后可能(一定)会用到。

环境

  • 操作系统:Windows 10 Version 10.0.15063
  • 安装工具:Bash On Ubantu On Windows(以下简称:WinBash)

注:因为WinBash还存在很多尚不明确的因素,安装环境受系统版本及网络影响。Ubantu、CentOS等Linux衍生系统安装方法类似。本次安装仅作参考。

注:若使用WinBash请先开启Windows开发者模式,开启方法请自行搜索。

开始

安装Git

使用apt-get经行安装,命令:

$ sudo apt-get install git

然后输入y,完成安装。

检查安装

可以执行git命令查看是否安装成功,命令:

$ git
usage: git [--version] [--help] [-C <path>] [-c name=value]
           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]
           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
           <command> [<args>]
$ git --version
git version 2.7.4

配置Git

git安装完成,需要初始化用户信息,这通常是全局的,命令如下:

# 配置用户名
$ git config --global user.name "your_name"
# 配置邮箱地址
$ git config --global user.email "your_email"

生成&验证SSH公匙

公匙用于Github或服务器的免密登录的一个口令,一个公匙可多方登录,由于SSH的重要性,请勿泄露公匙。

公匙存在在~/.ssh目录下的id_rsa.pub,如果不存在先生成,存在则直接查看:

# 生成公匙
$ ssh-keygen -t rsa -C "[email protected]"
# 接下来直接敲三个回车
# 查看公匙
$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCwdB8G/vCpmZu3yI7N62GqykMcBhWZ5BI34rnBXM9CNtXASGD3Pg7erkn0kuOSzSm9RkoRtnmbA/D9TNqMxNtXUxHHjEw27yFPffit1b5Zjj651Kp.......... [email protected]

关于ssh-keygen命令参数解释:

  • -t:申明密匙类型,参数:"rsa1"(SSH-1)、"rsa"(SSH-2)、"dsa"(SSH-2)
  • -C:添加注释

验证SSH公匙

将SSH公匙添加到GithubCoding中的SSH公匙管理中,下一步操作即是验证公匙是否可用,命令:

# Github与Coding验证地址不同,以下以Github为例
$ git -T [email protected]

创建远程仓库

代码管理离不开远程仓库,远程仓库能随时同步代码、多人协助、版本回滚等。

远程仓库国内推荐使用CodingGithub,当然,类似的平台还有码云。在Github上,直接点击New repository建立仓库。

比如,我现在创建一个仓库名为test的仓库:

新建仓库

配置解释:

  • Repository name: 仓库名,不可于当前用户的其他仓库名重名
  • Public / Private: 项目是否公开,这里说明一下的是Github的私有项目是收费的
  • Add README: 是否初始化时建立README.md说明文件
  • Add .gitignore: 是否创建忽略.gitignore配置文件
  • Add license: 是否添加协议

Git基础

建立仓库

创建完成远程仓库,转向本地,初始化本地Git仓库:

# 创建目录
$ mkdir your_project/
# 切换到目录
$ cd your_project/
# 初始化仓库,创建.git目录,将此目录作为git工作空间
$ git init
Initialized empty Git repository in /Users/secret/Desktop/test/.git/

初始化完成本地仓库,需要将本地仓库和远程仓库进行关联:

首先需要获取远程仓库的地址,可以打开刚刚新建的test的仓库:

获取远程仓库链接

在输入框中的内容就是该仓库的远程地址,最右边可以一键复制。

现在将本地仓库与远程仓库进行关联:

$ git remote add origin [email protected]:isecret/test.git

存入缓存区并提交

可以先尝试创建一个文件,然将它添加到缓存中:

# 创建test.txt文件
$ touch test.txt
# 编辑该文件,你同样可以选择其他编辑器
$ vim test.txt
# 保存完成后,将其添加到缓存中
$ git add test.txt
# 提交本次修改
$ git commit -m 'Create and edited test.txt'
[master (root-commit) 40a635b] Create and edited test.txt
 1 file changed, 1 insertion(+)
 create mode 100644 test.txt

参数说明:

  • git add 文件名是将此文件加入缓存区,也可以使用git add .将此目录加入缓存区
  • git commit-m参数是给此次提交的动作给一个描述,比如修改了什么地方,修复了什么Bug等
  • git add .git commit -m '描述'可以合并写为git commit -am '描述'

查看提交记录

文件修改后提交至缓存区后,便会生成一个提交记录的HEAD信息及其描述,在后续使用可以回滚到当前版本。好比于修改代码,越改越乱的情况,就可以直接回到上一个版本重新来写。

# 查看提交版本,commit后边的内容便是版本号,最后一行是注释信息
$ git log
commit c172fa948ab343276c84ec3bbf11d0c0cd027b3c
Author: isecret <[email protected]>
Date:   Sun Jul 23 12:57:36 2017 +0800

    Create and edited test.txt

查看修改记录及状态

这个顾名思义,查看当前版本的改动。在Github上能高亮显示出,不过在命令行也能查看到。

首先,我先在text.txt中再增加一段Hello World,然后查看改动:

# 增加一段Hello World!
$ vim test.txt
Hello Git!Hello World!
$ git diff
diff --git a/test.txt b/test.txt
index 106287c..d149c10 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-Hello Git!
+Hello Git! Hello World!
# 插入:2,内容 Thanks for us!
$ vim test.txt
# 查看当前状态
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   test.txt

no changes added to commit (use "git add" and/or "git commit -a")

参数说明:

  • 直接使用git diff用于查看当前未git add的内容修改
  • 已经git add但还没提交,使用git diff --cached查看内容修改
  • git diff HEAD是上面两条的合并
  • git diff HEAD1 HEAD2 src可以比较两个版本的src文件夹的差异
  • git status会列出还没添加到缓存区的文件/目录

分支

分支在Git中是一个很重要的概念,意味着你能脱离主线开发,在不影响主线的情况下还能继续工作。

而分支又简单分为基础操作、冲突合并、分支管理、bug分支、远程分支。

查看分支

# 查看当前所有分支
$ git branch -a
* master