关于httpdns

概要

httpdns就是通过http的方式进行域名解析;阿里云有提供httpdns服务(目前2016-4-9 还处于公测阶段,需要申请公测资格才能用)。

传统dns解析存在的问题:

  1. 由于传统dns解析采用udp方式,而且是明文,所以
    1. 可能会被篡改
    2. 可能会被投毒(什么叫“投毒”?且看下文)

httpdns的实现原理:

  1. 通过http的方式进行域名解析,如:
  2. 通过设置http host header的方式发起http请求,如:

 

问题:

  1. httpdns server的域名如何解析?
    httpdns server 不通过域名提供服务,(只能)直接通过一个固定IP提供服务;服务提供商有足够的手段让这个IP不会出现宕机,而且世界各地(或者是全国各地)访问都能很快(就近访问),这个IP在世界上存在多份。
  2. 如何保证连接的这个ip是没被劫持呢?
    1. 或许可以给这个IP买个https证书,https证书提供商是可以给IP颁发证书的(比较少见),不过可能贵的多

 

优点:(参考文档: https://www.aliyun.com/product/httpdns?spm=5176.7960203.223922.4.2JohAO

  1. 防劫持
  2. 避免dns服务商莫名其妙的cache,可以做到立即修改理解生效
  3. 精准调度

问题:

  1. https请求问题及解决方案: https://help.aliyun.com/document_detail/httpdns/practice/https.html?spm=5176.7947101.220063.5.9DtXGS
    1. 这里回避了单个IP上多个https证书的问题,或许也可以通过钩子解决,但是不一定存在这样的钩子; ssl握手的时候,必须告知正确的host信息,否则,服务器无法知道该返回哪个证书,而不仅仅是验证证书的问题
  2. httpdns只适用于app、client的情况,对于web浏览器是不行的,还好现在大家都是在玩app了;
  3. 对于app里面适用webview的情况需要特殊处理一下:https://help.aliyun.com/document_detail/httpdns/practice/webview.html?spm=5176.dochttpdns/user-guide/resolve-stats.6.127.VFTz3N
  4. 对于通过react native来开发app的情况不知道是否方便使用

 

dns投毒:

因为域名解析是udp的,只要我已dns server的ip不断地向你的机器发送域名解析结果响应的话,你可能就会认为确实是dns server响应的结果;当然,有几个关键点需要注意:

  1. 用户确实需要解析某域名(一般来讲,解析完了会cache一段时间的)
  2. 伪造的响应里面是需要包含用户正在查询的域名的,域名不匹配自然不会被接受
  3. 用户发起请求的端口号(2字节)是随机的,响应的数据包需要能匹配上这个端口,否则不会被接受
  4. 用户发起的请求有一个随机的请求标识(2字节),响应的数据包需要能匹配上这个请求标识,否则不会被接受
  5. 我咋感觉这个难度其实并不算小啊,除非你是个中间人

httpdns示例:

 

更多参考:

全局精确流量调度新思路-HttpDNS服务详解: http://www.zmke.com/i/8705.html

渗透测试:内网DNS投毒技术劫持会话:http://www.freebuf.com/articles/web/43157.html

http://www.onedns.net/  需要特殊的dns客户端

加密的dns: https://www.opendns.com/about/innovations/dnscrypt/   需要特殊的dns客户端

wireshark分析dns协议: http://blog.csdn.net/hunanchenxingyu/article/details/21488291

dns协议格式: http://cjhust.blog.163.com/blog/static/1758271572014111875652363/

关于shell一些小知识点

关于 [[]] 和 [] 的区别

实例1:

说明:

[]  和 [[]]  是不同的语法;

对于 [

事实上, bash 中没有 [] 语法, [ 是一个命令,出于美观考虑,要求有一个 ] 与之配对; 所以 [ 的前后是要有空格的

对于 [[

[[]] 是bash的内建语法

  1. 如果是 == ,则右边被视为 Pattern; 如果是 =~ ,则右边视为正则; 也就是说,左边和右边是不等价的
  2. [[]] 允许内部 与、或、非; 如: [[ 1 == 1 && 2 == 2 ]]; 而 [] 则不可以,只能: [ 1 == 1 ] && [ 2 == 2 ]

bash基本概念

  1. bash中有保留字(reserved word)和元字符(meta charactor)的区别的,这个很重要
    1. 关键字:
    2. 元字符:
    3. xx
  2. 对于关键字,和其他非元字符的字符都需要用空白字符分开,否则,关键字就识别不出来了; 因为元字符是被特殊对待的,所以,关键字挨着元字符是允许的,所以,如果分不清关键字和元字符的话,就不知道什么时候需要用空白符分隔,什么时候不需要空白符分隔

 

 

man bash

关于元字符、保留字

关于 花括弧

 

命令替换

 

 

docker虚拟机设置固定IP

参考文章: http://www.tuicool.com/articles/v2yQ7bA

创建网桥(可以写成一个脚本):

创建容器

稍微整理一下原作者的命令,写一个脚本:

注: 最新版本的iproute (至少在iproute-3.10.0-54.el7.x86_64 中)支持 -n 选项,功能为:

至少 iproute-3.10.0-21.el7.x86_64 中还没有该选项, 也就是说

等价于

 

如下br1是我做的网桥:

当docker容器stop时,这里的q7443也就消失了,但是网络名字空间中依然会存在; 可以通过 ip netns delete 来删除

 

一种情况,由于我的docker宿主机是virtualbox做的虚拟机,virtualbox虚拟机使用的桥接模式,所以,我这么做出来的docker虚拟机是访问不了外网的;因为,尽管docker虚拟机可以往docker宿主机的网卡上写数据,virtualbox的宿主机上的后台进程也不会发送该数据的(至少不会接受响应的数据)。

 

其实,有一个叫做pipework的工具可以很方便地给容器设置ip; 但是都没有提供卸载容器网卡的功能,有一种比较方便的办法: nsenter 进去 ifdown 就可以了

关于网桥

为什么virtualbox网卡桥接模式下在宿主机上看不到网桥?

virtualbox在后台启动了一个进程,很牛B,能从指定的网卡读取数据和写入数据,如此,就可以做到将某个虚拟机要发送出去的数据写入到指定网卡,而且网卡上收到的传给某个虚拟机(IP)的数据转发给指定虚拟机; 就这么简单。

参考: http://superuser.com/questions/594550/how-does-bridged-networking-work-in-virtualbox

 

 

dnsmasq 的一个小配置

 

 

 

PHP中sessionid的那点儿事儿

PHP中默认的sessionid为PHPSESSID;

当然,也可以通过

string session_name ([ string $name ] )

来修改, 官方说明:

name

The session name references the name of the session, which is used in cookies and URLs (e.g. PHPSESSID). It should contain only alphanumeric characters; it should be short and descriptive (i.e. for users with enabled cookie warnings). If name is specified, the name of the current session is changed to its value.

 

疑问: 只能包含字母和数字?

参考源码:

  1. 不能全数字
  2. 当然,sessionid毕竟是个cookie name,也会遵循cookie name的检查(参看: http://phpor.net/blog/post/1122 )
  3. 没有发现哪里体现“只能包含字母和数字”,实测也发现,其实 dot、_ 都是可以的

 

 

 

php-redis benchmark

脚本:

 

阿里云的1G标准的redis,当同时40个这样的PHP进程压测的话,会有8个进程最终出现select时 1s 超时异常; 但是人家给的指标是支持 300并发的

关于syslog协议

在使用rsyslog的时候,一般来讲,如果消息中含有换行符的话,这条消息会以换行符为分隔,视为多条消息;即: rsyslog协议是基于行处理的,而且,默认单个消息大小为2k(rsyslogd v5),rsyslogd v8默认单个消息大小为8k。

问题: 一般来讲,程序出错时的堆栈信息都是多行的,这种情况该如何处理呢?

办法1: 先将堆栈信息中的换行替换成其它字符

办法2: 其实rsyslog是可以支持换行的,只是不是想换就换的,在structure data中可以小心地换行

 

关于syslog协议有两个rfc:

  1. The BSD syslog Protocol rfc3164
  2. The Syslog Protocol rfc5424

其中:

rfc3164 定义的syslog协议是比较原始的用法,不支持消息的换行

rfc5424 是所谓的version为1的syslog协议,支持 structure data;就是这个structure data中是可以包含换行的; 当然,要严格遵照定义的格式的哦

两种协议格式解析的golang实现: https://github.com/jeromer/syslogparser

 

rsyslog (rsyslog-8.17.0)源码学习:

  1. runtime/stream.c 中是这么解析的

翻译下:

mode=0 单行模式,遇到回车算做消息结束

mode=1 空行分隔模式,遇到空行算作消息结束(就是相邻消息之间要已空行分隔)

mode=2 非空开头模式, 只要下一行空白(应该也包含tab吧)开头就算作上个消息的一部分,不视为新消息

不幸的是,目前发现只有imfile模块才支持这三种模式之间的选择,更不幸的时,imfile模块使用inotify配置时,mode=2有bug(我测试时不是有bug,是根本不能用)