javascript 之文件下载

一般来讲,浏览器中下载文件都是一个链接给浏览器,下载进度有浏览器来显示;比较先进一些的实现就是通过js不断地循环请求服务器端,来获取下载的百分比。

最近发现一个网站(https://mega.nz/#F!nJR3BTjJ!N5wZsncqDkdKyFQLELU1wQ )在下载文件时,并没有立即调出文件保存对话框,而是直接在网页中显示下载进度,直到下载完毕才弹出文件保存对话框,点击保存就完成了。觉得很新鲜,研究了一下,是通过blob实现的; 关于blob的学习:百度: js blob

文亮同学提到了: URL.createObjectURL  ,稍后再研究这个东西

关于VPN的纠结

需求

公司内网需要搭建一个VPN服务,这是一个非常常见的功能性需求;为了安全,要求VPN登录时使用动态口令,这是一个非常合理的非功能性需求。

探索

VPN服务比较多,如: L2TP/PPTP/OPENVPN/SSLVPN 等等; 但是支持动态口令的VPN就找不到了;不过,有些VPN支持pam,如:openvpn; 由于vpn代码比较多,编译也比较麻烦,未敢擅自修改;但是openldap的代码看了下不太复杂,于是,通过修改ldap中的验证逻辑,实现了openvpn + pam_ldap的动态口令验证功能。

突然有一天,发现xx宽带连接公司的vpn总是失败,电话询问xx客服,得知根据国家xxxx规定,xx宽带不允许使用vpn。后来发现,其实也不完全禁止,或许是具体实现封杀的技术问题,有时候还是可以使用openvpn的; 尽管如此,关于无法使用vpn的事情总会发生的,还得想其他办法。

据说shadowsocks很有名气,能否借助这个实现呢?尤其openvpn其实也是走某个指定端口的应用层面的服务;搜了一下,果然有: https://github.com/shadowsocks/shadowsocks/wiki/Connect-to-OpenVPN-over-Shadowsocks (点进去才发现,该项目已被我star多时了)

不过,这个有两个问题:

  1. 对于不懂技术的同事来讲,使用起来有点儿难度,需要配置shadowsocks客户端(如果能写个包装器,把shadowsocks和openvpn包装起来就方便多了)
  2. 如果要shadowsocks到公司内部,也必然要考虑到同样的验证问题,就是:shadowsocks需要支持动态口令; 还好这个修改起来应该不太复杂,应该比修改openldap要简单的多吧!

 

参考资料:

  1. http://hyspace.io/posts/2015/08/22/%E7%BA%AA%E5%BF%B5shadowsocks/
  2. https://ericfu.me/fight-with-greatwall-conclusion/

 

vpn自动安装脚本(配置过程太酸爽)

 

site-to-site vpn : http://ostolc.org/category/vpn.html

PHP 内存管理

 

测试脚本:

 

  1. php每次问系统要内存不是需要多少就要多少,而是最少申请 256KB,这样就有可能有一部分属于申请了,但是没使用;于是php函数memory_get_usage($real)的参数就能理解了; real = true,即:向系统确实申请了多少; real = false 即: php真正用到了多少。
  2. 每次申请系统内存的单位为 256KB,这个在 ./configure:#define SEG_SIZE (256*1024)    中有定义; 也可以通过环境变量ZEND_MM_SEG_SIZE 来设置;需要注意的是,该值必须为2的n次方,如:4096 可以,40960就不可以

安全领域工具

Nmap、Netcat、Hping3

 

在网络安全领域,Nmap、Netcat、Hping3都是安全工程师必备的工具。Nmap主要作为端口扫描器,侦查目标机的端口及服务状态;而Netcat则整合了网络中各种常用功能(如后门、文件传输、端口扫描、端口转发等等),能辅助完成丰富的操作;Hping3主要作为特定的TCPIP数据包产生与解析的工具,当然也可用于Ping操作。

 

参考资料:

  1. http://www.2cto.com/Article/201210/158961.html
  2. nmap使用: http://www.2cto.com/Article/201210/158960.html
  3. hping原理、安装、使用详解介绍: http://blog.itechol.com/space-33-do-blog-id-5772.html
  4. 利用hping3和伪造IP地址执行DOS攻击: http://sec.chinabyte.com/222/13522222.shtml
  5. hping3命令详解: http://man.linuxde.net/hping3

systemtap初体验

写在前面:

systemtap依赖的debuginfo可以从这里(http://debuginfo.centos.org/6/x86_64/)找到,如果幸运的话,你可以直接yum install kernel-debuginfo kernel-debuginfo-common来安装;

不过,正确的安装姿势应该是:

  1. yum update kernel-*      (没有这个将可能出现很多不必要的麻烦)
  2. reboot
  3. yum install systemstap
  4. stap-prep

话说systemtap是一个非常强悍的linux调试工具,但是似乎并不是特别的常用,今天尝试用了一下,确实有一些心得。

安装:

然后就有systap命令了,弄个脚本试试跑跑吧:

有错误了:

大致如上,可能版本号有所差异;好歹有提示,那就照做;不过,可能你确实已经安装了对应版本的kernel-devel; 你们不防rpm -ql kernel-devel 看看安装到哪里了,如果是 /usr/src/kernels/2.6.32-431.el6.x86_64 那么不妨执行:

 

其实可以这样:

该命令可以帮你安装需要的依赖,主要是kernel-devel 和 kernel-debuginfo; 关键是要安装指定的版本,版本错了不行,如果使用的是本地的yum源,可能找不到指定的版本号的包,这样可以修改为使用官方的yum源,这可能是一个比较慢的过程,因为kernel-debuginfo 大小可能超过1G;单从这个来看,该工具的使用成本还是不小的; 也很有可能你配置了debuginfo的yum源,但是没有enable,可以在yum时候临时enable一下,eg:

安装完后再次执行:

果然有hello world输出,再来一个 profile.stp:

使用场景

  1. 看看哪个进程在查询dns
    dns.stp:

参考资料:

关于限速

出于各种需要,经常需要限速

  1. 针对进程限速
  2. 针对ip、port限速
  3. 针对一组进程限速
  4. 模拟低速环境
  5. 程序上实现限速
  6. 针对下载限速
  7. 针对上传限速

真实需求:

调用第三方接口发邮件,经常会有很大的附件,当发送大量这类邮件时,就会将带宽占满。(第三方出口带宽还挺大)

 

限速工具:

  1. tc
    1. tc只能控制发送的速率,不能控制收包的速率(来了就收呗,干嘛要限速)
  2. iptables
  3. iptables + tc
  4. pv (pipe view)
  5. chrome开发者工具直接限速
  6. 程序自身支持限速 ,如:curl
  7. 通过特定编程语言实现
    1. PHP: https://github.com/bandwidth-throttle/bandwidth-throttle  (利用了stream_filter_append )
    2. PHP: https://packagist.org/search/?tags=rate%20limit
    3. Go: https://github.com/juju/ratelimit

通过nginx限速

nginx可以做http代理、tcp代理,而程序上设置代理也都比较方便,如果能在nginx上限速,会比较通用一些,目前发现有2个nginx限速模块:

  1. http://nginx.org/en/docs/http/ngx_http_limit_req_module.html   限制单个IP每秒最大请求数
  2. http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html   限制单个IP每秒最大并发

但是目前还没有一个限制流量的模块

(注:这些模块提供的时间段为‘秒’是不够灵活的,应该允许指定n秒,参考限速方面知识的其他参数)

通过apache限速

apache是一个老牌的web server,模块很多,果然有限速模块:

  1. http://bwmod.sourceforge.net/   这是是实现带宽限制的
  2. http://dembol.org/blog/mod_cband/   这个支持对单个虚拟主机限速,主要用于卖服务的
  3. http://www.zdziarski.com/blog/?page_id=442   这个类似于nginx的那两个模块
  4. http://dominia.org/djao/limitipconn.html 这个只是限制连接数的
  5. http://www.topology.org/src/bwshare/README.html

 

参考: http://serverfault.com/questions/540743/how-to-rate-limit-apache-server-on-ip-basis

注意: 一般来讲,这些模块都是针对下行进行限速,很少对上行也限速的;如果对上行也要限速,则未必好使。对于代理的情况呢?

通过haproxy限速

参考文章: http://blog.serverfault.com/2010/08/26/1016491873/

        haproxy 是代理,不是隧道,如果仅仅作为一个限速的隧道或许还不行

注意:有些限制策略是超过限制就加入黑名单,并且直接返回错误(或许这不是你想要的)

通过squid限速

参考: http://wiki.squid-cache.org/Features/DelayPools

squid.conf 中添加:

测试发现: 这个限速也是针对下行的限速,上行不限速

自定义proxy

goproxy( https://github.com/elazarl/goproxy ) 是一个开发proxy的golang库,在此基础上开发自定义功能的proxy是很方便的

关于iptables限速

  1. 至少两条规则
    1. 允许的速度
    2. 默认的丢弃
  2. 问题
    1. 如果发快了,则系统调用不是被阻塞,而是“Operation not permitted”, 这可能导致进程逻辑异常,尤其是tcp三次握手时候,可能会导致连接失败

其他:

关于phpmailer的发邮件限速:

php 的curl限速:

http://php.net/manual/en/function.curl-setopt.php

CURLOPT_MAX_RECV_SPEED_LARGE

CURLOPT_MAX_SEND_SPEED_LARGE

 

http://m.blog.csdn.net/tianyaleixiaowu/article/details/74942405

PHP finally block aborts on autoload

参考: http://stackoverflow.com/questions/26204315/php-finally-block-aborts-on-autoload

Person.php

 

main.php

解决办法:

  1. 升级PHP
  2. 提前加载,如: class_exists(“Person”); 但是,如果Person相关方法执行起来需要自动加载其它类,依然失败,所以,此法基本不可行
  3. 不使用finally

 

docker run 之 -it 选项

docker run -it 的这个选项是啥意思?

一半来讲,如果启动的1号进程是 /bin/bash (或者类似程序)的话, -i 是交互的意思,如果没有 -i 选项,/bin/bash 不需要交互就没事干,会立即退出,然后容器就会退出; -t是分配终端,如果没有-t ,则 docker attach 进去的话,就没法和/bin/bash 进行交互,当然,如果你压根儿不知道attach或者压根儿没用过attach的话,你可能永远不知道这个-t有啥用;

所以说, -it 选项是和 /bin/bash    attach 有直接关系

ssh 慢的问题

解决办法: https://injustfiveminutes.com/2013/03/13/fixing-ssh-login-long-delay/

ssh时候,服务器端可能需要进行域名解析,这个过程可能会比较慢,抓包如下:

 

strace 的部分结果:

查问题的过程:

  1. 问题定位到: dns查询时,一个请求同时查询A记录和AAAA记录而服务器端只返回一个响应所致
    可能是dns不靠谱,也可能是协议定义有缺陷
  2. 一般来讲,dns查询是有底层的libnss实现的,直接使用host 来查询应该也是相同效果吧? 结果不是
    host 查询时发现,A记录和AAAA记录虽然都查询了,但是是两次请求完成的; 看来二者用的库可能不一样
  3. google search “ sshd dns resolve ipv6” 发现文章: https://injustfiveminutes.com/2013/03/13/fixing-ssh-login-long-delay/
    可以通过在/etc/resolve.conf中添加

    来使得A和AAAA分作两次请求; 问题解决
  4. 一般来讲,我们只要使得ssh配置UseDNS no就可以了,但是,我们这里的情况是登录时使用了ldap(通过域名访问)认证,所以,域名解析就避不开了
  5. 遗留问题: 为什么client一次请求查询A和AAAA时,client不能和server好好配合呢?

其他参考: http://xxrenzhe.blog.51cto.com/4036116/1340103