May 30

量子效应代码 不指定

felix021 @ 2014-5-30 16:47 [IT » Python] 评论(1) , 引用(0) , 阅读(13922) | Via 本站原创
好久没写Blog了,今天来发一段带有量子效应的冷代码。

我们知道在杨氏双缝实验里面,观测与否会导致迥异的实验结果——即使是在电子通过双缝以后再观测也一样。

这段代码也有类似的效应:相信你注意到了,第6/7行被我注释掉了。你可以理解吗?是否注释这两行,会导致第5行print的结果不同哟。
a = 1

def foo():
    locals().update(globals())
    print locals()
    #print a
    #a += 1

foo()
Apr 15

为SSH添加两步验证 不指定

felix021 @ 2014-4-15 21:42 [IT » 网络] 评论(2) , 引用(0) , 阅读(18991) | Via 本站原创
今天从@Zavior同学那里听说了Google的开源项目Google Authenticator,它除了为Google帐号的两步验证功能提供了对应的app(安卓/iOS/黑莓)之外,还将这个功能开放出来、配套一个PAM模块,使得将两步验证功能代入ssh变得非常简单,回想起以前在B公司实习时用的那个硬件token,那真是又贵又麻烦。

步骤非常简单:

注意:如果是远程操作,请先开启一个应急连接,万一失败了还有救……

0. 安装对应的app,详见项目主页

1. 编译安装(@ubuntu)

$ sudo apt-get install libpam0g-dev libqrencode3 libtool
$ git clone https://github.com/google/google-authenticator.git
$ cd google-authenticator/libpam
$ ./bootstrap.sh && ./configure
$ make && sudo make install

[update@2016-01-04] 不知道从哪个版本开始,在ubuntu下,make install不会把pam模块拷贝到指定地点,需要手工操作:
$ sudo cp .libs/pam_google_authenticator.so /lib/security/

2. 配置openssh

$ sudo vi /etc/pam.d/sshd
  #最上方加一行 "auth required pam_google_authenticator.so"
  #这个配置可以更复杂一些,加上一些参数,详见 libpam/README
  #注:如果遇到仍然需要输入密码的情况,改成 "auth sufficient pam_google_authenticator.so" 试试。

$ sudo vi /etc/ssh/sshd_config
  #将 ChallengeResponseAuthentication 选项的 no 改成 yes
$ sudo /etc/init.d/ssh restart

3. 生成密钥

$ google-authenticator    #注:运行这个命令的是需要登录的用户,不是root用户
Do you want authentication tokens to be time-based (y/n) y  (确认:基于时间的认证token)
【这里会显示生成二维码的地址、二维码、密钥明文、应急码】
Do you want me to update your "/var/www/.google_authenticator" file (y/n) y (确认:更新配置文件)
......
size of 1:30min to about 4min. Do you want to do so (y/n) n (token有效期是1.5min,选y就是4min)
......
Do you want to enable rate-limiting (y/n) y (30s内只允许尝试三次)

4. 在app里扫二维码,或者手动输入密钥,即可看到token每隔30s更新一次了

5. 尝试登录
$ ssh localhost
verification code: 【输入验证码】
password: 【输入密码】


最后,提醒一下使用SecureCRT的同学,你需要在Session Options -> Connection -> SSH2,将Authentication中只选用 "Keyboard Interactive" ,否则没法正常登录。
Jan 22
本系列的上一篇已经是两年多前的事情了……

当时那个版本一直用到今天,已经有点勉强了,主要是基于XP的PE不能识别这两年新出的主板SATA(比如现在这块B85),很蛋疼,得先到BIOS里改成IDE模式再进PE才能操作磁盘。于是今天找了下小聪同学的TonPE,发现也已经物是人非,TonPE已经出售,风格大变,也不太好用了(安装包里的关键文件都用密码加密了,至于吗),哎,后妈就是不一样啊。幸好万能的互联网保存了早先发布的版本,于是找到了基于Win7的PE,Ton7PE_V3.3(基于Win8的Ton8PE_V4.0也能找到,但是在VBox里测试有问题,所以就没用它)。V3.3这个版本做得很赞,不仅能识别SATA,连USB3接口都能识别,而且所有文件都打包到一个WIM里头,不需要像上次那样做一些蛋疼的改动就能用。

装到U盘第二个分区的好处如上一篇所说:1. 跟U盘的正常数据区分开来,不会误删,甚至格式化U盘分区都无所谓;2. PE是单独的分区,而且永远不会被Windows载入,不用担心病毒感染;3. (相比于量产+ISO的U盘)在资源管理器里不会显示多余的分区。

具体的操作流程如下:

1. 用Disk Genius给U盘最后留下90M的空间,格式化成FAT16分区,激活该分区(即设置启动标志)

2. 用Disk Genius把TonPE_V3.3.iso里的内容导入(新版是在邮件菜单中选择“复制文件到当前分区”)到该分区(在分区参数右边有个“浏览文件”的TAB),或者可以在Linux下挂载后拷贝进去

3. 用BOOTICE.exe修改第二个分区的引导记录为“BOOTMGR引导程序”

然后就可以用这个U盘启动啦。

上面涉及到的所有工具/文件都放在这里啦: http://pan.baidu.com/s/1qW4PogW ,包括最原始的安装文件。
Jan 5
UPDATE@2014.02.19 升级到windows8.1以后似乎一切都正常了,买了个start8,慢慢习惯不习惯的地方吧……

最近给机器升级了CPU(i5 4570s)和主板(ASRock B85M-Pro4,C2步进),然后经常出现机器卡死的情况(一天一次的频率),有时候等上一两分钟还能活过来,有时候不行。事后查看windows事件查看器,没发现什么异常的地方。

升级之后的另一个蛋疼问题是,手头这块PLU ML-G3000青轴在打字的时候偶尔会出现几个随机按键(有次还“随机”到直接关机了)。频率也是一天1~2次的样子。前两天把键盘换成以前的Dell 8115以后暂时没有再出现,可能是键盘自己有点问题。

升级之前是AMD X3 450 + GigaByte 880GM-USB3,机箱内其他配件都没动(海盗船DDR3.1600[4G×2]、日立1TB、三星830.64G、TT XP420),升级之前系统相当正常,使用了2年几乎没遇到什么问题,用得挺爽的,平时中度使用,VBox虚拟机也常驻后台,机器是长期不关机,晚上都让它待机。

先怀疑是待机有问题(8系列主板C1步进的那个BUG也跟睡眠有关,但是我的主板是C2步进),这几天都没有用睡眠,但还是出现卡死的情况。

又怀疑硬盘出了问题,用HDTune的错误扫描把SSD和HDD都扫了一遍,全都是绿块很正常。

So,暂时不知道还可以做些什么,求建议。


== UPDATE@2014-01-05 23:59 ==
有人说可能跟Intel Rapid Storage Technology(就是Intel的SATA AHCI驱动)有关,在AS SSD Benchmark里面显示是iaStor,卸掉后变成了msahci(微软的驱动),但是刚刚还是假死了十几秒(然后恢复了)。

看到有人说到Windows 7 的这个BUG: “当你将磁盘设备使用的SATA模式更改为AHCI标准后,使用Windows 7和Server 2008 R2的计算机或某些应用程序会出现随机假死、60秒或更长时间没反应的情况。” 按照这个页面的说法,是M$的驱动有问题,我装了Intel的RST驱动应该正常了才对。搞不明白是咋回事啊……上面这个知识库里给的hotfix下载了提示“此更新不适用于您的计算机”……仔细看了下,这个页面提到的受影响的msahci.sys的文件日期是2009年的,我系统里的是2010的,可能已经修复了。

== UPDATE@2014-01-11 23:43 ==
升级到最新版的Intel RST驱动12.9.0.1001版以后,到目前为止没有再出现过假死的情况。

== UPDATE@2014-01-15 22:51 ==
又出现了一次,没死彻底,又恢复了。

@23:10 发现另外一个可能导致假死的BUG(win7/server 2008 r2,跟lsass有关的,但是同样提示“不适合我的计算机”,摔!
Dec 27

popobox折腾记 不指定

felix021 @ 2013-12-27 00:49 [IT » 硬件] 评论(0) , 引用(0) , 阅读(15062) | Via 本站原创
其实这货已经到手一个多月了,最初是在v2ex上看到这个帖子,发现它居然只要29块钱(其实是因为出了2代,1代亏本清仓),虽然CPU只是arm9 360MHz的,但是有256M内存、2GB Flash、原生Linux系统,这样一个嵌入式设备能做的事情也不少了,于是果断在京东下单。

11月12号到手,然后没几天各个地方就都卖断货了。外观上看起来做工还是可以的,大小像一般家用路由器一样,有2个USB口,其中一个是USB2.0,另一个官方说仅用于向该设备供电(这样就不需要电源适配器了),但是在扣扣群里看到帖子说是可以改造。可惜sandy那套螺丝刀工具套装找不到了,那个特殊的六角形螺丝拆不了,只能先折腾软件了。

popo里头内置了一套它们的云服务(用python写的,通过它的服务器中转,可以在公网上分享USB存储设备上的内容),并且默认启用了samba服务供内网访问,而且居然还启动了一个minidlna服务。不过这些东西都太耗内存了,怪不得这样一个设备需要256M的内存,直接被吃掉了一大半。全都停掉以后,内存占用只有17M,可用200多M,比外头的好多vps可是大多了(我现在就用着一个64M的openvz vps来翻墙)……预装的Linux里头有transmission,扣扣群里还流传着一个官方给2代提供的迅雷远程下载插件,在一代也可以用,不过其实没什么意思,自从买了迅雷会员以后,都是在迅雷离线下载好再直接下载到本地。。。

系统默认的ssh很奇怪,可能是精简得太厉害了,连scp都不支持,按照群里某教程换了个dropbear上去,然后参照Yongke同学的这篇Blog,给上面倒腾了一个chroot的debian,不过我没有蛋疼地搞一个loop的img,而是直接放在一个文件夹里,拷贝和解压的时候都省了好多时间,还免了挂载这一步。有了debian以后能做的事情就很多了,可是因为手头的mk802性能比它好得多,而且稳定运行了1年多时间(最长连续200+天,因意外被重启。。),所以好像也没什么需要它干的事情,所以就放着了。

第二天远程到公司,发现有个人在群共享里放了个kernel module,可以把boot所在的nand分区显示出来,这样就可以挂载了。然后我就2乎乎地用yaffs把那个分区挂载上去了……然后……实际上那个分区并不是那样的,但是yaffs可不管这个,挂载出了一个空分区,还自动创建了一个lost+found文件夹……当时我就快哭了。经过了多番折腾,把分区dd出来,然后再用别人dd出来的对比,修改,再mtd-utils工具包里的nandwrite写回去,最后终于……砖了。

于是很无耻地向京东申请换货,京东倒是很爽快,第二天就给换了一个。原样再倒腾一遍,然后就一直撂着了,直到上周,因为给电脑升级CPU(i5 4570s)买配件,顺便买了一套螺丝刀套装,19号到货以后,按照群里的图,把NR127和NR128两个口短接了(用的就是当时给机械键盘换轴的时候买的电烙铁套装),于是那个本来仅用于供电的USB口也可以被识别成一个USB1.1口了。

点击在新窗口中浏览此图片

然后想着干脆再折腾一下,于是在淘宝上下单买了个USB转TTL适配器,杜邦线,以及一堆导线什么的(最后没用上导线),23号收到以后当晚就开始折腾,搞得房间烟雾缭绕……其实松香的味道还是挺好闻的。倒腾了几次,在扣扣群里朋友的指导下,才搞清楚原来RX是要接TXD、TX是要接RXD。用putty连上对应的COM口,设置115200的Baud Rate,终于连上了它的console,以后瞎倒腾不愁变砖了。最后成品图如下,虽然焊点很难看,但是杜邦线从底部通风口引出去的设计不错吧XD,这样就可以在不给外壳动手术的情况下把外壳合上用TTL了。

点击在新窗口中浏览此图片

大概就是这样了,只是因为有mk802在先,好像这货还是不知道可以用来干啥。。。
Nov 20
UPDATE@2014-01-09:注意,在gdb attach成功以后,这个进程会被暂停,可能会导致一些问题。

UPDATE@2017-11-11:用 lsof | grep deleted ,可以看到被删除的问题文件,记住占用该文件的PID, 到 /proc//fd (该进程打开的所有文件,按fd的值命名)下面可以看到这个文件的另一个链接,把这个链接的内容清空,也可以解决。

场景:Linux下,进程 p 打开了文件 f 并在后台持续地往 f 中写入日志。某日发现磁盘空间不够,把 f 删掉了,这时 ls 已经看不到 f 的存在,但是 df 发现磁盘空间占用并未减小,而 lsof 仍然可以看到该文件被占用(并显示一个 "(deleted)" 后缀)。更不幸的是,进程 p 是需要长期驻留在后台运行的,不能直接干掉它。

解决:简单地说就是替进程解决这个文件。

1) 根据链接文件名,可以查到该文件在进程中的 fd :

    $ ls -l /proc/[PID]/fd

2) 通过 gdb 连上该进程(一般需要root权限)

    $ sudo gdb
    (gdb) attach [PID]

3) 清除该文件所占空间

    (gdb) call ftruncate(3, 0)    #这里假定fd = 3
    $1 = 0

这种方式治标,但不治本 —— 随着进程的继续运行,被删掉的 f 仍然会占用越来越多的空间;但是又不能残暴地直接 close(3) ,否则 p 的后续写入操作会出错,可能导致进程报错结束。

但是还是有办法的:

4) 移花接木

    (gdb) call dup(3)
    $2 = 4
    (gdb) call open("/dev/null", 2)    #注:2 = O_RDWR,x86/x86_64/arm上都是这个值。
    $3 = 5
    (gdb) call dup2(5, 3)
    $4 = 3
    (gdb) call close(4)
    $5 = 0

注:未测试该招式是否可能因多线程竞争导致错误。

OVER.
Aug 22
本篇来自这个问题:python中创建父类对象的问题

也许可以认为这是Python设计的缺陷导致的,因为Python 3.0只需要用 `super().some_attr` 就行了。至于为什么需要两个参数,可以大概分析一下,如果有错,欢迎指正。

先介绍下背景知识:super是从Python 2.2开始随着 `new-style class` 一起引入的,也只能应用于所谓的 `new-style class` (即直接或间接继承于 `object` 的class),可以在一定程度上解决所谓`钻石继承`的问题。2.2起所有python内置class都是new-style class。

那么super是什么呢?实际上它是一个builtin的type,你调用 `super(Base, self)` 会返回一个 `__class__ = super` 的对象,这个对象可以作为一个代理,通过BFS的顺序(实际上列表已经保存在`Base.__mro__`里了)去访问第一个**直接定义**了目标属性的基类里的属性。`super(type, obj_or_subtype).attr` 基本上可以认为是  `find_in_mro_provide_by(obj_or_subtype, "attr")` ,有点晦涩。

**注意**,super()返回的不是“父类对象”,而是一个super类型的对象;实例化的时候,第一个参数是一个类型(type),第二个参数可以是type的instance,也可以是type的subclass。

介绍完基础知识,可以先说说为什么要有第二个参数。理由很简单 —— 我们知道 self 代表当前对象,每个对象的方法在定义的时候都需要显示地把self作为第一个参数,你本来应该写成这样
   
    some_class.some_method(obj, *args, **kwargs)

但是因为Python语法允许 `obj.some_metod(*args, **kwargs)` (本质上是个语法糖) ,所以你可以写得简单点(不必显式地给出方法的第一个参数)。而super对象则不同,它没有语法上的直接支持,所以在内部invoke some_method的时候必须指定某个对象,而这个对象的得你自己塞给它,也就是说把这个super对象绑定(bound)到第二个参数上。所以实际上并不是非要用self作为super的第二个参数,甚至super并不是必须在class内部才能调用:
    class A(object):
        def foo(self):
            print self.name

    class B(A):
        def __init__(self, name):
            self.name = name

    b1 = B('b1')
    super(B, b1).foo() #produces 'b1'


至于为什么要有第一个参数,如果你看了 `help(super)` 就会发现它居然提供了个单参数的版本:

    super(type) -> unbound super object

这个理解起来比较困难点。先说这个`unbound`,没绑定,就是说这个super对象没有实际绑定到某个对象上,它并不是可以直接用的。要怎么用呢?那就得注意到`help(super)`里面有一个 `__get__` 方法,也就是说,super类还是一个Descriptor类!哎,这个Descriptor类展开又是好大一段,简单地说就是它可以把自己和某个object的属性绑定,使得访问这个属性的时候,实际上是在调用它的`__get__/__set__`方法:
    class Descr(object):
        def __get__(self, obj, tp): #最后一句传进来的 obj=x, tp=X
            return 'get!'

    class X(object):
        t = Descr()

    x = X()
    print x.t #this produces 'get!'


回到unbound super, 为了使用它,就要通过 __get__ 方法把它再绑定到一个对象上。由于Descriptor的属性,特别适合这么用:
    class A(object):
        def foo(self):
            print 'foo'

    class B(A):
        def foo(self):
            self._super.foo()
    B._super = super(B) #这还不能直接写在B的定义里,多蛋疼啊。

    b = B()
    b.foo() #produces 'foo'


这是它的一个可能用法。我不确定是否还有其他更合适的用途,但是在这里实际上也并不是很好,尤其是遇到staticmethod的时候还会出错,再加上绕了这么大一个弯,实在不是很推荐使用。

据说unbound super的使用非常少,不知道现实意义有多少,也不知道当初为什么设计成这个样子,总之由于Python3.0已经改了(虽然仍然保留了unbound super),所以基本上还是可以认为这是设计的历史遗留问题。

参考文献(unbound super主要参考了这个系列):Things to Know About Python Super

[1] http://www.artima.com/weblogs/viewpost.jsp?thread=236275
[2] http://www.artima.com/weblogs/viewpost.jsp?thread=236278
[3] http://www.artima.com/weblogs/viewpost.jsp?thread=237121
Aug 16

mixo:又一个翻墙socks5代理 不指定

felix021 @ 2013-8-16 17:23 [IT » 网络] 评论(0) , 引用(0) , 阅读(16062) | Via 本站原创
因为不满ssh tunnel的使用效果,所以2012年12月某天(大概是17号)心血来潮写了这个小东西,由于 [socks5协议]( http://www.openssh.com/txt/rfc1928.txt ) 本身很简单、加上gevent/greenlet使得异步开发跟同步似的,所以200行就搞定了。但是性能上问题很大——主要是加密有问题。尽管加密就是最简单的xor,但是因为python不适合处理大量的小对象,所以当时写了一个python扩展,性能上就没问题了,但是又多了一项麻烦的依赖。后来发现已经有更成熟的shadowsocks,于是就弃坑了,也一直没有发布。

今天[2013.08.16]心血来潮,用ctypes来实现同样的功能,似乎也挺合适的;不过跟shadowsocks比起来有两个地方做得不好,一是没有更“高级”的加密方式(他家用了M2Crypto,代码看起来很复杂),另一个是shadowsocks在本地先回应socks5请求,只把必要的host:port信息发送给server,减少了一个来回,而我原先的实现则是在server端实现完整的socks5(现在把step1搬到client了,因为改动很小)。

总之好歹也是个凑合能用的东西了,发布出来晾着吧,也许哪天有人就用上了呢。

项目地址: https://github.com/felix021/mixo
分页: 12/99 第一页 上页 7 8 9 10 11 12 13 14 15 16 下页 最后页 [ 显示模式: 摘要 | 列表 ]