网络寻租

Programmer, Gamer, Hacker

Windows服务器远程跑命令行代码

| Comments

windows服务器的管理都是通过远程桌面来登录,但是我们程序员不喜欢用GUI操作, 更喜欢执行脚本命令,因为这样更容易自动化。 这里整理一下如何用命令行登录到windows服务器上面执行任务。

windows有一个win-rm服务,类似于ssh,可以让远程连进去执行命令。

在服务器上面用管理员的powershell跑:Enable-PSRemoting 就可以了,默认使用http 5985端口。记得设置服务器或者云的安全设置把对应端口开启。 如果要开放给外网,要用https,这里是配置方法。

如果没有把服务器加到域里面,就必须用https,如果加到了域里面,登录只要用服务器的账户就可以了。 如果在同一个域的其他服务器里面,甚至不需要输入密码。

使用方法:Enter-PSSession -ComputerName COMPUTER-NAME -Port 5985

我们可以用ruby代码来执行命令,可以用Gem winfm

更多资料见这里

赚钱就是正义

| Comments

我认为,对于一个有追求的人来说,赚钱是非常值得骄傲,以及值得去做的。

我们先限定条件:这里的赚钱,是在自愿交易下赚钱,抢劫赚钱是另外一回事,我们这里不考虑这种极端状况。

赚钱一般是通过交易产生。在自愿交易情况下,交易能够进行,说明交易能够给对方带来价值。 然后赚钱的数量和交易带来的价值成正比。赚钱越多,带来的价值越大。

根据经济学原理,交易中的价格,由供给和需求共同决定。供给越少,需求越大,那么成交的价格就越高,而交易活动带来的价值就越大。 一些行业因为供给稀缺,从业者可以获得大量的收益。

不赚钱不一定代表没有带来价值,但是赚钱一定代表带来了价值,不然交易根本无法进行。

我们可以看一些具体的例子,从微观上理解为什么赚钱带来价值。

比如网红。为什么网红那么赚钱?我们可以看到有大量的付费欲望,推高了市场价格。说明需求旺盛。 市场告诉你这是老百姓更喜闻乐见的,虽然显得更低俗一些。

比如黄牛。观众无法买到票,找黄牛可以买到票。这个情况比较复杂。 为什么观众买不到票?可能票是预先售的,观众没有时间去关注。 更大可能是出票方无法预期合理票价,造成票价过低,如果没有黄牛,可能大家都得排队,浪费有钱人的时间。 有了黄牛大家只需要出钱,时间成本低于黄牛的去排队,时间成本高的可以购买黄牛票。 黄牛节省了观众的时间精力成本。 同理,所有的商人也是类似的。

比如炒房。普通人会觉得是倒买倒卖赚钱,实际上是在房东需要卖房的时候把钱给了房东,在买房人需要房子的时候把房子交出来, 和普通商人没有区别。普通人看到炒房赚钱,没有看到如果没有炒房人,房东可能无法卖房去治病/换大房子/救企业,买房人根本无房可买。

展开来,每个赚钱的行当都可以写一篇文章,微观上面说明清楚它带来的价值。

综上所述,我们可以从理论上证明,和实际事实上发现,只要赚钱,就是是带来价值的,赚钱越多带来的价值越大。 因此,我们可以说,赚钱不只是一个私利的事情,从公义上说,也是光荣,正义的,值得推崇的。 如果你想要给社会带来更大价值,就要去往赚钱多的方向走,市场会告诉你什么最稀缺,社会最需要的是什么。

论普通人的弱

| Comments

普通人其实是非常非常弱的,一个人只要发现这点,针对性地稍微努力一下,很容易可以从普通人中脱颖而出。

举例如下:

  • 自制力差。比如只要坚持三个月运动,身材就会发生明显改变。但是普通人就是坚持不下来。
  • 努力程度太低。IT公司996(朝9晚9加星期六)就算是高强度工作了?离全周无休,每天睡4小时差远了。更别说办公室工作毫无压力。
  • 目标太低。考试及格就好?优等生的要求是上97。月薪2万?别人的要求是月薪20万。
  • 欲望太弱。告诉你明年深圳大概率会涨30%,90%以上的人会无动于衷,99%的人最后还是没有买成。
  • 放弃思考。看到一篇诉诸感觉的文章(比如幼儿园虐童)就是愤怒,然后没有思考直接攻击其中的一个主体,而没有去好好思考思考这是怎么回事。
  • 脑子弱。双十一计算优惠都算不清楚。

现代社会生产力发展,不会饿死人。进化论不再淘汰弱者。所以普通人都可以生活得很好,甚至有演化优势。 但是对于个人来说,还是要追求卓越,因为从时间效用,享受,发展都更优,比如精英一个月就可以赚普通人一年的收入。 所以追求卓越是值得的。如何追求卓越又是另外一个话题了。

论社会制度

| Comments

我们知道马克思错了很多,但是马克思理论中关于生产力和生产关系的思辩很有意义: 生产力发展水平决定了社会的高度,而生产关系,也就是社会制度,需要适应生产力。

首先具有高级生产力的文明,对低级生产力的文明几乎是压倒性的优势:热兵器战胜冷兵器,核武器国家完胜常规武器国家。 文明组织起高级生产力,需要新的生产关系来适应,不然只能倒退回旧的生产力水平。 在不同级别的生产力下,不同的社会制度相互竞争,随着时间,最后更优秀的制度得到了广泛应用。

举例:

  • 生产力级别是草原畜牧,社会制度是游牧部落
  • 生产力级别是农耕:村落聚集,中央集权(大块平整土地)或者封建(分割土地)
  • 生产力级别是工业煤铁综合体:大型公司,国家主义
  • 生产力级别是互联网:跨国公司,全球化

每次生产力变更,都会产生大量的实践探索,什么社会制度是有效的, 这个时候往往会有百家争鸣,大量的社会变革和实践产生。 经历了这一切之后,积累了经验,学界大致知道什么有效什么没有效,制度创新趋于稳固。

对于现在社会的水平,以及成功的国家,我们可以发现一些共同的特质: 自由市场,保障个人私有权,法治社会下人人平等和自由。 这是因为现代社会生产力的发展,绝大部分依赖于商业交换,以及满足个人意志下创新和创造。 这种状况还会持续很长的一段时间。

但是生产力会继续发展,或者情况发生变化,现有的制度不再能够很好应对了。这个时候新一轮的探索和实践会产生。 比如:

  • 人人都具有无法控制的超能力或者科技能力:为了控制文明不自我毁灭,会采用各种控制机制,比如来自新世界
  • 研发出只有少数人就可以控制的极端武力:国家分化出贵族阶层,不再人人平等
  • 武力可以通过血祭获得:奴隶社会,大量眷养人类,大规模血祭
  • 人类可以低成本复制:集权扩张主义国家
  • AI成熟:人类灭亡,几大核心智能,少数高级智能,以及大量的可抛弃式普通智能

综上所述,我们需要根据生产力状况来考虑适合的社会制度,而不能反过来,把社会制度作为源点, 法治,自由,平等,市场经济并不是绝对的。必要的情况下,应该做出适当的改变。

现代社会防骗指南

| Comments

现代社会陷阱很多,一不小心就中招,很多陷阱你可能自己还没有意识到。

重点:你希望得到的,你相信的一切,都会有东西来骗你。

低级的是骗术:

  • 希望得到教育,就会有垃圾学校,很贵很不值得的培训
  • 希望得到健康,就会有养生课程,保健品,中医
  • 希望得到财富,就会有传销,庞氏骗局,各类诈骗

中级的是做局:

  • 化妆品:营造你可以变美的幻觉
  • 钻石:针对爱情的吹捧
  • 健身房:和你对赌你能够坚持下来
  • 房地产:售楼部热闹的气氛让你失去判断力

高级的是毒教育:

  • 公务员稳定:爸妈经验过时,以及希望你不要给他们添麻烦
  • 民族主义,国家主义,大政府:政府从小进行的洗脑

我们有什么办法来防止自己掉坑?几个办法:

  • 多看:收集事实。事实是检验理论的唯一标准。如果你发现结果不尽如人意,那么一定是哪里有问题。
  • 多想:思考事物本质。
  • 多听:以别人的角度来防止自己思维进入盲区
  • 及时反应过来止损:没有绝对的方法防止自己掉坑的办法,但是一般都会形势明朗,之后赶紧跳出来,沉没成本不是成本。

一天弄懂计算机科学之体篇

| Comments

首先就是计算机科学到底是什么?这个领域主要做的是什么事情? 计算机科学并不是关于如何让你熟悉理解操作计算机的, 计算机科学考虑的是:如何理解信息,记录信息,以及处理信息。

如何理解信息

信息是什么?信息是可能性的反面:确定性。 一件事情有可能发生,然后告诉你实际发生了,这就是信息。 比如我们知道明天有可能下雨,然后有一个神仙告诉你明天实际会不会下雨,这就是信息。

信息与信息之间是有度的区别的,告诉你明天是否下雨,以及一个人生日的信息量是不同的。 那么如何衡量信息的大小呢?可以用概率来看。概率越低,信息量越大。 比如明天是否下雨的概率是1/2,一个人生日的概率是1/365。

我们定义信息量):2^信息量=1/概率,下雨的信息量是1,生日的信息量是8.5左右。

如何记录信息

知道信息是什么了之后,我们可以考虑如何记录信息。 比如我们需要存储一个字符串,一个字符的信息量就是所有可能的字符, 比如简单的ASCII编码,有255种均等可能的字符,信息量就是8。 我们可以以1-255之间的数字定义一个字符,比如A就是65。

然后我们去寻找可以存储信息的介质。 任何有状态的介质都可以存储信息,比如算盘,小石子放在格子里面之类。 我们可以根据状态的数量来判断一个介质能够存储多少信息量, 比如算盘一个5串的格子,有6种状态,可以存储的信息量就是2.5。 然后可以把字符串编码到这个介质上面,一个字符需要4个格子提供足够的信息量。

因为格子的信息量足够,我们可以有很多种方法把字符映射到算盘上面。 但是我们需要一种通用的方式来做这样的事情,这样我们可以很容易切换到其他介质上面去。 最好的方法是提供一种中间编码形式,字符编码转换成这个编码,然后这个编码转换到介质上。 我们用的是二进制,用这种0100这种方式表示。 因为一个字符只有两种状态,方便编码转换。

我们来看如何把一个字符转换到算盘上面。 A=65=01000001,二进制编码到算盘也很简单, 算盘的一格可以对应二进制的两位,算盘拨动1-4格4种状况就可以了。 当然有更省存储空间的算法,我们会在后续介绍。

我们可以寻找更便宜的存储介质, 现在用的是磁性介质(硬盘),二极管(内存,闪盘等), 一个1T磁盘可以存储10244个字符,每个字符占用二进制的8位,一个磁盘就可以存储8T多的信息量。

如何处理信息

我们来到了最有趣的部分:如何处理信息。

我们需要理解处理信息的本质,然后再思考,如何创造一个机器来实现信息的处理。

比如我们需要把一张自拍照美化,其中的一个步骤就是把图片变白。 用信息化的处理方式,就是把每个点按照RGB的方式编码, RGB代表三原色,每个原色用0-255表示亮度,000就是黑色,255-255-255就是白色。 我们把每个原色的权重加一个百分比,比如原先100就变成150,这样就实现了照片的美化处理。

也有一些简单的方法,比如打印照片,打光,重新拍一张,或者专门做一个处理照片的机器。 但是为什么要实现一台通用的处理信息的机器,来处理这个任务?

因为几个原因:

  • 这个机器有很大的潜能,一秒钟内就可以处理好这个照片
  • 我们只需要对机器的指令做很简单的修改,就可以支持其他类似的工作
  • 数据是信息化的,可以快速方便地无限分发

而创造这样的通用计算机器是可以做到的,方法是把所有信息处理的动作分解,一直到可以通用的动作,然后再通过机器实现就可以了。

其中的一种通用的计算机模型如下:

  • 带有存储信息和指令的存储介质(指令本身也是信息)
  • 带有一组快速存储介质(我们叫他们寄存器),可以与各类运算和处理单元交互
  • 一个寄存器指向存储介质的一个地址,地址上带有让机器执行的指令,我们叫这个指令寄存器
  • 机器根据指令寄存器指向存储介质地址的指令,控制各类运算和处理单元对寄存器上面的数据进行处理,包括这个指令寄存器本身!可以进行的操作包括:
    • 数学运算:加减乘除,逻辑运算之类
    • 状态查询:比如判断两个寄存器是否相等之类,保存结果到一个状态寄存器
    • 条件判断:根据状态寄存器的结果进行特定的操作,比如指令寄存器地址加一
    • 数据移动:把寄存器数据保存到存储介质,或者从存储介质读取数据到寄存器

比如上面的照片处理,可以用这个机器实现。机器的指令也保存在存储介质里面,具体如下:

  • 照片数据预先存放在存储介质上,按照RGB方式编码
  • 操作指令也存放在存储介质上,机器的指令寄存器设置到这个地址,开机

指令列表:

  • 起始:读取照片数据地址到寄存器A
  • 读取照片数据结尾地址到寄存器B
  • 循环:从照片数据地址读取一个点的数据到寄存器C
  • 寄存器C加10%
  • 寄存器A加一
  • 判断寄存器A和B相等,如果相等跳过下一步指令
  • 设置指令寄存器值为循环地址(下一步机器就会跳转到前面开始的地方)
  • 设置指令寄存器值为结尾地址
  • 结尾:停机

这些指令实际上的操作就是:转移数据,对数据进行运算,同时机器下一步执行的指令位置也是可以通过数据来操作的。 我们可以通过逻辑证明,带有这样功能的机器,可以把存储介质的状态,设置成任意我们想要的状态,从而证明这是一台可以进行通用信息处理的机器。

我们可以用各种方式来实现这样的通用计算机器, 比如机械齿轮,水力,算盘,甚至人工,但是最后我们会选择性能最好,价格最便宜的方案,现在就是用二极管,集成电路, 每秒可以进行几十亿次的运算。

以上内容就是信息科学的部分,我们知道信息的本质是什么,以及信息本身是以什么方式存在,然后是如何处理信息, 之后我们可以利用这些原理,创造出来计算机,以及配套的支持环境,来实现所有的信息存储,操作和处理。

一天弄懂计算机科学

| Comments

2016年底我去成都参加同学聚会,在火车上和一个大学生吹牛,说只要一天就可以教会他所有计算机科学——的基础。 整理了一下,发现其实真的可以一天教会脉络,剩下的就是细化细节了。

我会用几篇文章来讲一下。我保证讲的一定是本质的东西。

所有计算机科学的领域,可以按照体,术,用三类来划分。

  • :包括如何理解信息,如何记录信息,以及最重要的:如何处理信息,都包含在信息科学里面。
  • 术:包括如何利用信息科学的知识来创造一个可以处理信息的机器。
    • 如何设计机器(计算机体系架构)
    • 如何把程序语言转换成机器语言(计算机语言原理)
    • 如何把机器管理起来(操作系统)
  • 用:
    • 如何让机器跑得更快(算法)
    • 如何存储和交换数据(数据库系统)
    • 信息如何通讯(通讯协议,互联网)
    • 还有其他细分的领域

如何一个人管理一堆服务器

| Comments

现在有一些服务器自动化配置工具,比如ansible,chef,puppet等, 利用它们,可以实现我的一个想法:用配置文件定义服务器架构,从而实现一个人管理好一堆服务器。

比如用ansible,我们可以用一个YAML文件申明一台服务器上面有什么:安装了什么应用,存在什么配置文件,跑了什么服务。 然后用命令行工具,比如ansible-playbook,就可以构建出来这样的服务器。

这样操作的优点:

  • 可视化:原先服务器手工构建,其他人,甚至构建者自己都会不清楚服务器的状况。现在有了配置文件,大家就可以知道服务器上面有什么,是如何配置的。
  • 自动化:可以一条命令构建服务器,修改配置文件之后可以批量改动影响到的服务器,增加带有同样应用的服务器也非常简单,只要拷贝配置即可。如何搭建应用的知识可以复用。
  • 版本控制架构变更:可以用git版本库管理服务器配置文件,我们可以记录每次服务器架构的变更了。

具体操作:针对一组服务器架构,比如一个Rails应用以及附属的各个服务器, 可以创建一个git版本库记录所有的ansible playbook, 然后把敏感的配置文件,放到另外一个私密git版本库里面, 加密存储,保障安全性。

我搭建了一个演示用例,包括:

里面包含几台服务器:

  • app.yml 搭建Rails服务器,包括mysql数据库,nginx,systemd自动启动和监控脚本。
  • backup.yml 自动备份mysql数据库
  • zabbix.yml 对应的监控服务器(未完工)

私密配置版本库里面存放了所有的配置文件,构建一些应用需要的用户名和密码,一些初始化数据等。 在playbook里面会去读取这些配置文件,或者拷贝这些文件到服务器上面去。

管理Rails应用还需要一些其他的功能,限于时间,我就没有实现了,包括:

  • jenkins 自动化测试
  • sandbox,staging环境
  • mysql多主从架构
  • 多app负载均衡

综上所述,一个复杂的多服务器应用架构,可以用上面的几个版本库定义出来,并且可以根据需要动态进行修改。 这种配置方式适用于几十台机器之内的半静态架构,并且可以多人同时管理。

更进一步,如果利用aws或者digitalocean的api,服务器创建也可以采用配置文件定义。 不过我觉得使用起来并不是很方便,就没有这样做了。

如果机器数量多,或者需要动态伸缩,配置文件可能就不太适合了,可以用ansible-tower这种在线配置管理工具。 不过我觉得大多数的公司都不会达到这样的级别,因此配置文件就够用了。

我们需要淘汰一些编程语言

| Comments

在IT领域,因为从业者素质参差不齐的原因,很多垃圾东西在流传,其中危害最大的一类就是垃圾编程语言。 包括但是不限于:bash,perl,javascript,php,python。

这些语言为什么烂

他们的设计者并没有受到很好的编程语言设计教育,或者没有足够的时间进行设计, 造成的结果是,这些编程语言的设计存在很多问题。比如语法设计有问题,在语法处理上存在设计错误,写法晦涩不容易弄懂影响阅读, 缺少很多保证程序安全的设计,带有性能问题,语言本身缺少很多核心功能等。 具体内容可以去看王垠的博客

我稍微列一下烂在哪里:

  • bash: 缺少大量的编程语言抽象特性,语法是程序员乱设计的,接口是基于字符串而不是定义明确的数据结构
  • perl: 语法也是程序员乱设计的,难以阅读
  • php:乱语法,现在改进了很多,但是为了兼容还是带有一堆历史问题
  • javascript:几十天做出来的一个没有完善好的类lisp语言,早就应该被淘汰掉,因为web流行危害严重
  • python:比上述语言好一些,但是也有一堆设计缺陷,比如用缩进替代定义明确的语法块,匿名函数实现烂等

烂语言的害处

编程语言是程序的组成部分,类似于房屋的原材料。一旦你选择了编程语言,以后再要替换只能全部重写。 软件后续的维护和拓展都只能基于这种语言,会延续到软件的整个生命周期。 引入了一个烂语言,他的危害会覆盖软件的整个生命周期,并且像癌症一样,随着软件的传播而蔓延, 进而伤害其他依赖这个软件的系统,同时也给这个烂语言打了广告。

如何处理

对于旧的用了烂语言的项目,尽量以维护为主,不要增加新功能延长它们的生命周期。 比如systemd替代了旧的init系统,就淘汰掉很多垃圾bash脚本。

新的项目尽量不要用这些烂语言,可以寻找一些替代品。很多语言经过了良好的设计,值得推荐,比如java,csharp。 脚本语言和Linux下系统语言我还没有找到好的选择。我现在用Ruby但是Ruby也有很多问题,不值得长期使用。 Linux下系统语言可能有Rust,D,我不确定是否足够好,但是可以尝试。 Javascript可以用高层语言替代比如TypeScript,Webassembly推广之后会有很多好语言可以使用。

加密git远端版本库

| Comments

我打算把所有服务器的配置文件用git管理起来,这样可以记录配置变更状况。 但是有一个问题是,如何多人协作?服务器配置信息非常敏感,如果这个版本库泄漏,整个公司的服务器架构就彻底泄漏了。 这个版本库只能在开发者本地电脑里面解密,远程托管版本库的服务器不应该知道文件里面的内容。

那么解决办法就是:本地git版本库是解密的,在上传过程中内容全部加密,密钥保存在本地,同时密钥可以分享给其他开发者。

考虑了几个解决方案:

git-crypt:可以加密部分文件,原理是加上了加密的fiter和diff, 但是官方说只适合加密部分文件,而不适合全版本库加密。部分文件加密很容易造成信息泄漏,一定要全版本库加密才适合。

串联sshfs和远程服务器加密文件系统encfs:首先用sshfs加载远端文件系统,然后用encfs创建加密文件系统。 我估计无法解决多人同时push情况下的竞争条件,并且encfs有安全漏洞,使用上push/pull之前需要加载两层文件系统,不是很方便。

git-remote-gcrypt用gpg进行远端加密。 比较符合我预期的模式,但是用gpg不是特别方便协作。但是别的方法走不通,只有这个方法可用。

使用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 安装git-remote-gcrypt和gnupg
sudo apt-get install git-remote-gcrypt gnupg

# 创建一个gpg的key,需要设置用户名,邮箱,描述等,不要设置过期时间
gpg --gen-key

# 记录一下生成的key的ID,比如2048R/A0F0B575里面的A0F0B575,2048代表加密轮数,越多越不容易破解
gpg --list-keys

# 生成一个测试版本库
mkdir test1 && cd test1
git init .
echo "test" > a.txt
git add . && git ci -m "update"

# 在你的github上面创建一个project,比如:https://github.com/halida/ttt

# 配置远端加密版本库
git remote add cryptremote gcrypt::git@github.com:halida/ttt.git
# 最好指定用哪个key加密,这样可以共享这个key给其他人用
git config remote.cryptremote.gcrypt-participants "A0F0B575"
# push到远端
git push cryptremote master
# 访问远端版本库,看看文件内容,和commit里面的信息,是不是都是加密的?

如何分享给其他人

1
2
3
4
5
6
7
8
9
10
# 导出key
gpg --export-secret-key -a "share@share.com" > secretkey.asc
# 把secretkey.asc分享给其他人,拷贝的时候记得先压缩加密一下再发送,更安全

# 别人电脑里面导入
gpg --import secretkey.asc
# 下载代码
git clone gcrypt::git@github.com:halida/ttt.git test2
# 也要指定一下用什么key加密
git config remote.cryptremote.gcrypt-participants "A0F0B575"

用这种方法,可以用git管理一些私密又需要协作的信息(比如服务器配置), 也可以把github当作私密的版本控制系统来用(commit的消息还是明文的)。