centos7 firewall设置

原文:https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Security_Guide/sec-Using_Firewalls.html#sec-Introduction_to_firewalld1

参考译文:http://blog.csdn.net/steveguoshao/article/details/45999645

查看运行状态

firewall-cmd --state

获取支持的区域列表

firewall-cmd --get-zones

查看区域开放端口:

firewall-cmd --zone=public --list-all

添加端口

firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --zone=public --add-port=3306/tcp --permanent

重启服务

firewall-cmd --reload

mysql批量备份脚本

如何实现自动备份数据路里面所有业务表的功能:

#!/bin/bash
echo "Dump mysql databases..."

DB_USER=xxx
DB_PASSWORD=xxx

DB_LIST=$(echo "show databases;" | mysql -u${DB_USER} -p${DB_PASSWORD})
for db in ${DB_LIST}
do
  if [ $db != "Database" ] && [ $db != "mysql" ] &&
      [ $db != "phpmyadmin" ] && [ $db != "information_schema" ] &&
      [ $db != "performance_schema" ]; then
    echo "  backup "$db
    mysqldump -u${DB_USER} -p${DB_PASSWORD} $db > ./$db.sql
  fi
done

这一生,至少当一次傻瓜-奇迹的苹果

如果把读书比多银海拾贝,这本书就是沙粒中一颗精致优美的贝壳。

本书很精薄,我基本上是一口气读完的,从晚上9点多到临晨1点多。

全书讲述了主人公木村,因执念绿色种植苹果的理念,被人当作傻子,最终经历8年的执着和等待,最终获得成功的故事。

故事里面不光有木村的执着,还有生动鲜活的果园风光,虫鸟与风草。文章细致描写了绿色种植理念的起因和主人公实际操作后面临的真实果园处境,采用第三视角和第一视角口述的方式交叉推进,显得真实而生动。

当主人公经历8年的辛苦,孤独,嘲讽,最终看到开花结果,而他的岳父母去世的时候,我的眼眶湿润了,有多少奋斗的人能等到亲人共享的时刻。

当因为自己的执念而让妻子和孩子受苦时,木村的心里苦不甘言,只能默默承受,恰似无数正在奋斗的人们。

最终执念和傻得到了回报,而我经历了一次难得的心灵旅程。

人生难得执念,主人公的成功也不必介怀,真实的人生,大部分人面临的最终可能是失败。

but:
人生只有一次,这种执念傻瓜的经历,又何尝不是一种幸福和境界?

OpenResty最佳实践-随笔

简介

完整内容地址:https://moonbingbing.gitbooks.io/openresty-best-practices/content/index.html

决定在动手之前先把这本书浅读一遍,磨刀不误砍柴工。

这里记录的都是我自己的理解和观点,或者需要强调的知识点,并不代表书的详细内容,详细还是请参见原文。

纪要

  1. lua葡萄牙语里面表示美丽的月亮。
  2. 纯c编写,能被当作c库嵌入和调用,能方便和c/c++相互调用。
  3. 变量没有类型,可以动态绑定。
  4. 运行期能编译字符串形式的程序文本并载入虚拟机执行。(这个有点意思)
  5. nil 是一种类型,Lua 将 nil 用于表示“无效值”。Lua 中 nil 和 false 为“假”,其它所有值均为“真”。比如 0 和空字符串就是“真”;(惊讶)
  6. table:“关联数组” 是一种具有特殊索引方式的数组,索引通常是字符串(string)或者 number 类型,但也可以是除 nil 以外的任意类型的值。
  7. 与或是and or,结果不再是0或者1
  8. do return end 实现代码return的随意打桩
  9. 函数支持变长参数 …
  10. 做函数参数时,table是传引用,其他类型都是传值
  11. 模块的全局变量检测用工具releng
  12. 字符串下标是从1开始的,跟物理位置次序一致
  13. openresety支持防止sql注入的方法
  14. 支持匿名对象 ” _ “,用来占位,这个和golang一致
  15. 压力测试的好工具wrk
  16. 规则中尽量不要使用if
  17. 代码中不要使用阻塞操作,尽量不要使用lua的原生接口,使用openresty的相应接口
  18. 火焰图是个定位底层调用栈的好东西
  19. cosocket是好东西

openresty安装篇

环境版本

OS:CentOS Linux release 7.1.1503 (Core)
openresty:1.9.15.1

安装准备

除非你要修改源码,如果只是运行官方的包,官方建议优先考虑预编译包,centos 系统支持如下:

版本号 支持的体系结构
5.x x86_64, i386
6.x x86_64, i386
7.x x86_64

配置yum源

你可以在你的 CentOS 系统中添加 openresty 资源库,这样就可以方便的安装我们的包,以后也可以更新(通过 yum update 命令)。添加资源库,你只用创建一个名为 /etc/yum.repos.d/OpenResty.repo 的文件,内容如下:

[openresty]
name=Official OpenResty Repository
baseurl=https://copr-be.cloud.fedoraproject.org/results/openresty/openresty/epel-$releasever-$basearch/
skip_if_unavailable=True
gpgcheck=1
gpgkey=https://copr-be.cloud.fedoraproject.org/results/openresty/openresty/pubkey.gpg
enabled=1
enabled_metadata=1

显示支持的包

sudo yum –disablerepo=”*” –enablerepo=”openresty” list available

Loaded plugins: fastestmirror
openresty                                         | 3.5 kB     00:00     
openresty/7/x86_64/primary_db                       |  32 kB   00:01     
Determining fastest mirrors
Available Packages
openresty.x86_64                         1.9.15.1-16.el7.centos openresty
openresty-debug.x86_64                   1.9.15.1-7.el7.centos  openresty
openresty-debug-debuginfo.x86_64         1.9.15.1-7.el7.centos  openresty
openresty-debuginfo.x86_64               1.9.15.1-16.el7.centos openresty
openresty-doc.noarch                     1.9.15.1-16.el7.centos openresty
openresty-openssl.x86_64                 1.0.2h-3.el7.centos    openresty
openresty-openssl-debug.x86_64           1.0.2h-4.el7.centos    openresty
openresty-openssl-debug-debuginfo.x86_64 1.0.2h-4.el7.centos    openresty
openresty-openssl-debug-devel.x86_64     1.0.2h-4.el7.centos    openresty
openresty-openssl-debuginfo.x86_64       1.0.2h-3.el7.centos    openresty
openresty-openssl-devel.x86_64           1.0.2h-3.el7.centos    openresty
openresty-resty.noarch                   1.9.15.1-16.el7.centos openresty
openresty-valgrind.x86_64                1.9.15.1-6.el7.centos  openresty
openresty-valgrind-debuginfo.x86_64      1.9.15.1-6.el7.centos  openresty
perl-Lemplate.noarch                     0.07-3.el7.centos      openresty
perl-Test-Nginx.noarch                   0.25-3.el7.centos      openresty

安装

关于openresty的rpm包的介绍见这里:http://openresty.org/cn/rpm-packages.html

按照文档的说明,我们暂时只需要安装openresty,openresty-resty,openresty-doc三个包就可以了

yum install openresty
yum install openresty-resty
yum install openresty-doc

运行

sudo /sbin/service openresty start

stop, restart, 和 reload 这些指令也是支持的。

默认网站实例是加载在/usr/local/openresty/nginx/ 目录下的,如果要改变成自定义的目录使用 -p 选项:

sudo openresty -p /opt/my-fancy-app/

这个命令实测,是需要手动创建目录的,记得要先停止openresty。

其他问题

防火墙

在centos7下面,防火墙由iptables变更为firewalld,测试时需要增加相应的80端口,或者暂时关闭防火墙。

配置firewalld 使用firewall-cmd,默认需要安装:

yum install firewalld firewalld-config

查看当前开放zone,端口,服务:

firewall-cmd --get-active-zones
firewall-cmd --zone=public --list-ports
firewall-cmd --zone=public --list-service

增加80端口:

firewall-cmd --zone=public --add-port=80/tcp

自启动

添加openresty的开机自启动:

chkconfig --add openresty
chkconfig openresty on

由于centos已经用systemD代替了systemV,系统不再有rc-local服务了,所以我们也不能简单添加rc.local了(网上流传的给增加运行权限的,在本机验证不成功)。标准的做法就是创建新的任务,通过chkconfig来启动了。

因为firewallD的规则是不能保存的,所以我们要放到开机自启动脚本中。

libreswan libevent错误

安装libreswan时遇到如下的错误:

/data/l2tp/l2tp/libreswan-3.17/programs/pluto/state.c:800: undefined reference to event_free'
server.o: In function
init_event_base’:
/data/l2tp/l2tp/libreswan-3.17/programs/pluto/server.c:582: undefined reference to evthread_make_base_notifiable'
server.o: In function
pluto_event_new’:
/data/l2tp/l2tp/libreswan-3.17/programs/pluto/server.c:442: undefined reference to event_new'
server.o: In function
pluto_event_free’:
/data/l2tp/l2tp/libreswan-3.17/programs/pluto/server.c:588: undefined reference to event_free'
/data/l2tp/l2tp/libreswan-3.17/programs/pluto/server.c:589: undefined reference to
event_free’
/data/l2tp/l2tp/libreswan-3.17/programs/pluto/server.c:590: undefined reference to event_free'
/data/l2tp/l2tp/libreswan-3.17/programs/pluto/server.c:591: undefined reference to
event_free’
timer.o: In function delete_pluto_event':
/data/l2tp/l2tp/libreswan-3.17/programs/pluto/timer.c:814: undefined reference to
event_free’
ikev2_parent.o:/data/l2tp/l2tp/libreswan-3.17/programs/pluto/ikev2_parent.c:2704: more undefined references to event_free' follow
/usr/local/lib/libevent_pthreads.so: undefined reference to
evthread_set_condition_callbacks’
/usr/local/lib/libevent_pthreads.so: undefined reference to event_mm_malloc_'
/usr/local/lib/libevent_pthreads.so: undefined reference to
event_mm_free_’
/usr/local/lib/libevent_pthreads.so: undefined reference to evthread_set_id_callback'
/usr/local/lib/libevent_pthreads.so: undefined reference to
evthread_set_lock_callbacks’
collect2: ld returned 1 exit status
make[3]: *** [pluto] Error 1
make[3]: Leaving directory /data/l2tp/l2tp/libreswan-3.17/OBJ.linux.x86_64/programs/pluto'
make[2]: *** [local-base] Error 2
make[2]: Leaving directory
/data/l2tp/l2tp/libreswan-3.17/programs/pluto’
make[1]: *** [all] Error 2
make[1]: Leaving directory `/data/l2tp/l2tp/libreswan-3.17/programs’
make: *** [all] Error 2
libreswan-3.17 install failed.

问题分析:
1. 检查libreswan的版本和代码包的正确性,去官网下载比对,确认下载是最新的代码。
2. 查看日志,根据event_free关键词,判断出问题的应该是libevent库,所以确认libevent,发现已经按照说明成功下载了libevent2了。
3. 继续查找日志细节:
—> Package libevent2.x86_64 0:2.0.21-2.el6 will be installed
–> Processing Conflict: libevent2-devel-2.0.21-2.el6.x86_64 conflicts libevent-devel
–> Finished Dependency Resolution
Error: libevent2-devel conflicts with libevent-devel-1.4.13-4.el6.x8664
从上面的提示看到是libevent2跟系统默认自带的libevent冲突了

解决:
yum remove libevent-devel-1.4.13-4.el6.x86_64

yum install libevent2-devel

strongswan charon logging 配置

系统:ubuntu 14.04

strongswan 配置文件路径 /usr/local/etc/

默认的strongwan的日志是打印在syslog 里面的。为了便于管理和分析,我们希望日志能打印在专门的文件里。而strongswan 自带的charon守护服务就默认包含了charon-logging功能,我们只要开启此功能即可。

相关的配置参考如下:
https://wiki.strongswan.org/projects/strongswan/wiki/LoggerConfiguration

新史太阁记-一个不世出的产品经理成长史

因为刚看完了《丰臣秀吉》,想找些其他描写日本社会文化历史以及现状的书籍时,一不小心就看到了这本司马辽太郎的《新史太阁记》。

书的内容基本沿袭大的历史框架,不再有秀吉嗜好女色的大篇幅描写,也没有更多的民间传说的影子,总之更贴近历史的脉络,少了些民间的历史玄幻。小说从秀吉的少年开始,一直到巅峰时期,戛然而止。

这期间陆陆续续看了些秀吉的书,还有影视材料,最震撼的不仅是日本战国的武士情怀,还有出于职业背景的条件反射:如何成为一个伟大的产品经理。注意,我特意使用了伟大一词。

对于技术人的成功,我一直坚持认为:技术-产品-公司,这3个梯度的进阶和成功,才是真正的成功。而这三个体度的难度系数相差远不止一个数量级。而要完成这样的转变,你要有开阔的眼界和思维,要理解社会的发展和人性的需求,要有理想主义者的坚持和奉献牺牲。

我看到过很多技术牛人,他们热衷于 一系列能让人感觉新奇的技术,但是他们却很难理解要为产品或者公司的成功去奉献和坚持,他们更关注短期的自我的收获,缺乏长远的对产品成功,公司成功的认知和追求。会新奇的技术是有价值的,但最终为大众提供价值的是产品本身,这个涵盖技术,设计,交互,服务等,远不是很多技术人想象的因为一个所谓的技术就能怎样。

好吧,扯远了,说一说我从秀吉的故事中总结的一个伟大的产品经理的一些要素吧。

我们一般说的产品经理的价值:

清晰准确的产品定义:功能需求定义,目标用户群体定义,商业模型定义,生命周期定义。
秀吉:每一次的战事秀吉都有着清晰的产品定义,他知道自己最终要的是臣服和胜利,所以他会选择合理的战术方略,而不是简单粗暴野战屠杀,故事里面每一战事秀吉都有着很深入的分析和合适的方案提出,而这一切都是因为他对目标有着清晰的定义,能外交的就不兵刃,能围城的就不破城,因为我要的是胜利,而不是摧毁对方和杀戮。

技术质量的保障:依赖自身的知识背景,采用合理的管理方式,选择正确的技术架构,来保证可靠,低成本,快速的实现产品解决方案。
秀吉:故事里的秀吉每一此都能根据天时地利提出一套低成本而且行之有效战事方略,这些战术的方案最终保证了秀吉在保存力量的情况下取得成功。

沟通协调:在遇到资源问题或者对外需求时,能高效的沟通和获取资源保证团队的进度需求,在收到内部领导的不合理需求时,也能顶住压力和风险,保证团队能按照正确的方式和方向去开发。
秀吉:毋庸置疑,历史上真正的秀吉无论跟信长还是家康比,秀吉无疑是一个善于沟通,善于外交的政治家。

士气目标管理:产品经理不是简单的让相关的设计开发坐在一起开发就好了,要了解每个人的性格,让所有人都能认识到产品项目的价值,都能认识到自身的价值,充分体现自豪感和主动性,从而发挥巨大的价值,最终形成团队超强的战斗力。在取得阶段的进步或者奖励时,也能适时的鼓励团队,鼓励成员,保证团队高昂的士气,从而取得不可能达到的成绩。
秀吉:秀吉的部下基本都是草莽出身之所以能取得最后的高水准的胜利,得益于秀吉队伍高昂的士气,无论是通过金钱的奖励还是封地的奖赏。

背黑锅:大家都是凡人,不是神仙,到最后难免有错误的决定或者失败的计划,产品经理的另外一个用户就是替大家来背黑锅。因为产品经理就是产品和团队的负责人,失败了,产品经理是最大的责任人,无需客观理由。

而要成为伟大的产品经理,还需具备:

对产品方向执着的信念:无论是早期对信长的神一般的信仰还是后面对胜利的信念,秀吉能走这么远,能在众多的力量中崛起,最重要的是秀吉是一个理想主义者,靠执着的信念在一次次的战事和政治中取得成功。

克服一切困难创造条件解决问题的能力:面对困难时,在其他人迟疑时,秀吉积极承担,克服不利,最终树立了在织田家的声望和地位,比如美浓之战的善后工作。

愿意付出一切保证产品成功的奉献精神:秀吉对每一次的任务都是倾尽全力的,可以说为达目标不择手段,甚至去做一些被人唾骂的残忍行为。

最终,秀吉从一个茅屋少年成为日本战国时代的一代枭雄,成为了一个伟大的产品经理。

丰臣秀吉

加藤广 著
曹宇 译
2014年第一版

一直一来对日本文化都很感兴趣,小时候看的很多日本动画片,还有宫崎骏,北野武(很喜欢的另一个原因是北野武事务所一直是支持贾樟柯电影的,这两个人我都很喜欢),黑泽明等大师的很多作品。记得小时候(80年代)看的一个引进的似乎叫阿香的很长的日本电视剧(里面就有主人公日常的生活和日本社会的大量描写),那时候就对日本留下了深刻的印象。

本书是作者根据大量史记和民间传说编撰的伪纪实传记小说,每一章节开始都有摘引自史记史实的事件作息行踪记录,然后精心地穿插着作者编撰的精彩故事。

因为本书大量的日本人名和地名,本文不想写成准确的读书笔记,只想把自己读完的大概思绪以作记录,想了解详情的还请移步小说。

羽柴秀吉(藤吉郎)出身贫苦,从小体弱,身高不显,少年丧父。其父是个会计,擅长算数,因担心儿子未来生计,从小训练藤吉郎算数,使得秀吉具有缜密而灵活的头脑(纵观一生,真正使其收益的应该是其谦逊和不断学习的精神)。因为穷苦,藤吉郎早期走街串巷以卖针为生,积累了大量的地理和世俗情报,后加入当时还未一统的织田信长手下,因助其逃过劫杀而得到赏识和重用,从普通士卒成为大将大名。起初秀吉最多也只能算是众多武将中一个算是能干的普通将领,排名不是很靠前,但靠一系列的战役和英勇表现,再加上所谓的天意暗示(有高僧推荐,有手相暗示)等,最终成为一代枭雄。

军事和谋略方面,秀吉是天才,越是大事件大场面越能显示出其超常人的思维和冷静决绝的判断。
个人生活和精神情感方面,其一生都是大写的悲剧,从未停止。
社会方面,幕府时代的日本是一个家臣社会,武士忍者只能对主公负责,是主公的私有财产和工具。女性普遍不被尊重,没有地位,导致可以随便被欺凌(权势)。信长时代,西方基督教已经大举入侵日本,引进了西方的知识和理念,当然紧随其后的就是铁甲舰,洋枪洋炮和梅毒。
生活物资方面,由于日本特殊的地理资源限制,日常生活清贫(从赏赐上就能看出来)。天皇家室受人尊敬,但迫于幕府威胁和生活所迫,忍辱负重,利益权谋。

半兵卫,秀吉文化水平不高,但依赖其谦逊的态度和其不嗜杀的作风,赢的半兵卫的辅佐,半兵卫乃不世奇才,类似中国的诸葛卧龙。从而使的秀吉从众臣中显身而出,鹤立鸡群。半兵卫从一开始就帮秀吉规划好了天下,再临终前,又帮秀吉赢得了官兵卫,官兵卫助其实现战术的胜利。可以说没有半兵卫,秀吉此生最多也就大名了,战死或者被清除掉。
官兵卫,因秀吉受半兵卫建议,救下官兵卫儿子,在救出官兵卫后,得到了官兵卫的感激和追随。虽然半兵卫被描述成先知之谋略,但官兵卫的实际作用丝毫不逊于半兵卫,他是实际帮助秀吉夺取天下的人,真实的水平深藏不露。官兵卫早年信仰基督,晚年改信佛教。
秀长,秀吉的弟弟,能干,但缺乏谋略,是大臣和秀吉之间的缓冲带。50多岁就死了,使的晚年的秀吉缺少了心腹很支持。
将右卫门,秀吉的左膀右臂,没有这个踏实而放心的的伙伴和下属,秀吉的事业轨迹将大大不同,他也是秀吉唯一想说和敢说心里话的干将。事业和心灵的好基友。
小六,跟将右卫门一样,得力干将,但是跟秀吉的关系没有将右卫门近。
秀次,秀吉的侄子,从知识和才干方面,是唯一一个看似能继承秀吉衣钵的人,可惜被陷害,株连。但其和妻女3p的事情很是让人不解。
光秀,信长公的忠臣,因不甘信长暴戾和对天皇的不尊,而想取而代之,却被秀吉渔翁得利。
德川家康,从不多的描写中可以看出其老奸巨猾,能屈能伸,心狠手辣(弑其子)。
宁宁,秀吉正房,忍受秀吉鬼混,终其一生陪伴和追随的人,是一个真正爱着秀吉的女人。宁宁是个下等人的女儿,但秀吉并没有在显赫时休掉宁宁,也没有加以恶意相待和冷落,并且对夫妻关系作必要的经营和维护,可以说是秀吉自己用行动获取了宁宁最终的支持和陪伴。
龙子,极其崇拜秀吉,是其心灵伴侣,在精神和肉体上都得到秀吉的信赖和喜欢。
茶茶,一个淫贱,有手腕,心狠手辣的女人。然而平心而论,最终她也许都只是她母亲的一个工具,是一个悲剧的影子。

和善,不拘小节。不忌主仆繁文缛节,平时打成一片,深受部下拥戴和喜爱。
施财而好才。先后招揽了了半兵卫,官兵卫,将右卫门,小六等当世之才。秀吉不像其主公信长那么吝啬,受封后尽将财物封地分与下属,赢得部下的效力和忠心。在急行军后,开库散银,犒赏全军。懂得用眼前的利益赢得未来的利益。善招揽人才,善用人才,这也是其脱颖而出的关键。
善谋略,不嗜杀。其大多的战术都是围城,水淹威胁,一夜城恐吓等,即使在拥重兵的情况下也不擅使暴力强攻,大部分的城池都是接受投降,甚至城主留任。
好色。以现在的眼光看是很好色,但综观后面的秀次等的表现就可以明白,秀吉的水准也许只是普通水准略高而已,毕竟权高位重嘛,获取资源门槛低。整个当时的日本都是这样的风气,也不能单怪秀吉。
谦虚好学。无论是早年对大家意见的细心听取还是后面的对诗词的虚心学习,都说明真正使秀吉强大而可怕的正是其一生的学习态度和追求。

秀吉把信长作为对手,但在除掉对方后,获得权力后,却心怀愧疚被家康持以把柄以及临死都无法释怀,恰恰是日本家臣以及武士精神的体现,在中国历代的权利斗争中很少有此方面的感情顾虑。

秀吉的整个人生就像一颗坠落的流星,从冉冉发光,到光芒万丈,最后到燃烧殆尽。秀吉用其一生的经历,说明了即使一个出类拔萃的人在面对权力和金钱时,也很难保持自我。你未疯狂,因为你还没有尝过权力的滋味。

追求金钱和权力的过程可以让一个人得到满足感,但金钱和权力本身并不能满足人精神层面的空虚和欲望。

羽柴秀吉,藤原秀吉,后来天皇赐姓丰臣,也就是大家耳熟能详的丰臣秀吉。

如果秀吉可以生育,如果他没有过早的疏远忠臣干将,如果他不是用现在的方式杀死信长,如果他当年追杀了家康,如果他没有杀秀次,如果他没有宠幸茶茶,如果他坚持收养了天皇的弟弟,秀吉的人生又应该是怎么样的呢?

但生活,没有如果。。。

东京散步

作者:藤田宜永
译:兴远

译者的水平还是不错的,让整个故事叙述显得生动,细腻,阅读起来很舒服。
建议阅读时长:1-2天

首封上写的是:幸福来时总是慢得让人难以察觉,而不幸却是毫无预兆地轰然降临。

故事讲述了一个出身悲惨,处境落魄的年轻人突然接到一个诡异而报酬诱人的陪同散步的生意。在散步的过程中双方互相倾诉心境,途中一起经历了种种怪异而有趣的事件。最终在故事的结尾,主人公得知了生意的真相,也在对方的帮助下实现了自己内心的愿望。故事最终得到了一个令人惋惜而不忍的结局,但真实的生活不就是这样吗,不完美才是我们孜孜以求。

故事娓娓道来,看似缓慢的节奏却引人入胜,结局有点想不到,整个故事在高潮中结束,一气呵成。如果你在一个周末的早上开始阅读,也许在你下午会不经意的发现你竟然一口气看完了整个故事。

从故事中你能了解当时的日本的一部分群体的生活状态和社会现状:高利贷,弹子店,情色店,援交,离家出走,婚内出轨等。通过几个相关人物的人生经历和状态,让人感受到日本特定时代下一部分群体真实的生活。

结尾福原有一段的语言显得很生硬,也许是作者构思小说时的最开始提炼的主题,所以硬生的借福原的嘴表达了出来。

推荐:细读

git 403 Forbidden

现象

error: The requested URL returned error: 403 Forbidden while accessing https://github.com/xxx/xxx.git/info/refs

fatal: HTTP request failed

分析

错误是在一个脚本中操作git时的错误提示,看错误提示初步判断是权限问题,继续google之,发现 : http://stackoverflow.com/questions/19722521/error-the-requested-url-returned-error-403-forbidden-while-accessing 。

解决

参照帖子的思路:

  1. 将https改为ssh访问,直接修改repo对应的隐藏文件.git/config 文件中的url即可。
  2. Generating an SSH key

再次运行脚本,执行成功。

hugo生成文章中不能正确显示中文字数的问题定位

问题发现

在刚切换到hugo博客的时候就发现文章的字数统计是错误的,但是因为当时也没发现有额外的副作用,就暂时懒得理了,毕竟这个只是写作工具,web前端也不是本人长项。

今天在使用多说分享文章的时候发现部分文章分享失败,于是根据分享生成的URL中的数据初步判断是获取文章content时出错了。插件获取了超长的content内容,导致接口调用失败。

问题定位

1. 多说

我们看多说插件中的相关代码:

data-content="{{ .Summary }}" 

多说只是使用了模版中的Summary变量值。

2. Summary

关于Summary变量,我们看Hugo的解释

Hugo-defined: automatic summary split

By default, Hugo automatically takes the first 70 words of your content as its summary and stores it into the .Summary variable, which you may use in your templates.

Pros: Automatic, no additional work on your part.
Cons: All HTML tags are stripped from the summary, and the first 70 words, whether they belong to a heading or to different paragraphs, are all lumped into one paragraph. Some people like it, but some people don't.

从以上的内容看到Hugo只是默认最多取70个词(words),所以这里很明显是取70个词时,实际取出了远远多于70个的内容,导致上面的url出错。

3. 长度错误

从上面我们初步判断是长度的问题。初步查看模版的代码,我们知道长度在模版中使用的是WordCount变量。于是我们查看hugo中WordCount相关的代码hugolib/page.go:

if p.isCJKLanguage {
        p.WordCount = 0
        for _, word := range p.PlainWords() {
            runeCount := utf8.RuneCountInString(word)
            if len(word) == runeCount {
                p.WordCount++
            } else {
                p.WordCount += runeCount
            }
        }
    } else {
        p.WordCount = len(p.PlainWords())
    }

从上面isCJKLanguage的变量名我们就能猜到是判断非英文的路径。简单看下代码,Hugo是有考虑CJKLanguage的问题的,也就是说可能是这个分支没有执行。

4. isCJKLanguage

我们搜索工程,找到isCJKLanguage:https://github.com/spf13/hugo/blob/2c5e4f7640e71d2a193a74e6c41109ec40bc0222/docs/content/content/front-matter.md 中的介绍,于是手动在出错的markdown文件中添加此变量,再次重新执行hugo,发现对应生成的网页中的字数统计的值正确了,分享也不出错了,说明就是字数的统计导致了系统错误。

问题验证了,但是因为博客的文章都是用工具自动从wordpress中生成的,不可能手动一个一个修改,修改工具也显得很死板,最好的方法是从Hugo这侧来找方案。

5. hugo配置文件

顺着上面的思路,开始搜索相关的关键字,发现hugo的配置中还真有相关的配置hasCJKLanguage:https://github.com/spf13/hugo/blob/b7efbdc12f0a96639b445f7920b6477d88beb744/docs/content/overview/configuration.md ,喜出望外,赶紧添加到config文件中重新编译文件,编译后发现并没有生效。于是再次查看源码hugolib/page.go:

if isCJKLanguage != nil {
        p.isCJKLanguage = *isCJKLanguage
    } else if viper.GetBool("HasCJKLanguage") {
        if cjk.Match(p.rawContent) {
            p.isCJKLanguage = true
        } else {
            p.isCJKLanguage = false
        }
    }

从上面的代码看isCJKLanguage 是由HasCJKLanguage开关控制的。

6. HasCJKLanguage

继续看代码,我们看到工程中只有一个地方有设置commands/hugo.go:

viper.SetDefault("HasCJKLanguage", false)

于是尝试修改本地的此行代码,重新编译Hugo。再次用hugo生成所有文章,发现所有文章的长度都正确了,甚是高兴。

再次检查今天发现的分享出错的文章,都全部正常了,舒服!

go编译中出现的link signal killed问题

在vps中编译hugo代码时出现:
tool/linux_amd64/link: signal: killed

经过搜索查到类似的场景:
https://github.com/beego/wetalk/issues/32

不同的是这个是beego,而我编译的是hugo,所以初步断定应该是跟go的环境有关,而不是hugo代码。所以验证了帖子中关于内存的说法,发现重启后,果然正常。

小米路由器R1D刷机手记

## update
2016.12.16:由于文章中的360 网盘的资源挂了,重新更新了tomato的刷机包的路径

缘由

小米路由器R1D已经使用了快一年,一直想刷机,主要因为:
* 后门问题,请搜索知乎“小米路由器 劫持”,虽然严格讲天朝人民是没有什么隐私,但被人强奸总是很郁闷的。
* 用了半年后,经常会掉网,很快就自动恢复,有时候莫名其妙手机就掉网开始走移动流量,很郁闷。

小米路由器R1D

小米路由器R1D是一款基于博通bcm4709( c )和OpenWRT深度定制的智能路由器。
小米路由器

准备工作

  • 了解基本的linux 常用命令,ssh,root权限等。
  • usb一个,用来制作usb刷机工具。
  • 备份你的拨号账号密码。
  • 一个备用的路由器,刷机有风险,一旦出现变砖,备用路由器至少可以让你继续使用网络,不至于影响正常的网络使用。
  • 一米的短网线,用来直连路由器,当然理论上wifi也是可以的,但是某些rom在进入特定的刷机工具状态时wifi是不可用或者启动有延迟的,有线则方便很多。

刷机的ROM备选

小米路由器是深度定制版的OpenWRT,网上大概搜了一下,可选的有OpenWRT原生系统,DD-WRT和Tomato三种系统可以尝试。

OpenWRT

ROM

首先从官方的硬件支持列表我们并没有看到R1D的支持:https://wiki.openwrt.org/toh/start 。其次从小米论坛和google也没有找到明确支持的rom。

刷机

巧妇难为无米之炊。
结果:放弃

DD-WRT

ROM

从官方的支持列表中:http://dd-wrt.com/wiki/index.php/Supported_Devices ,我们并没有看到R1D的支持ROM。但是我们可以找到非官方的rom,例如:http://bbs.xiaomi.cn/t-10691878 。

刷机

刷机流程参见:http://www.right.com.cn/forum/thread-143121-1-1.html ,本人尝试多次,均在第6步失败,初步判断是tftp server没有正常启动。

分析原因:原博是在0.4.58的rom上做的验证,本人尝试0.4.58版的USB和web页面升级的方式,均失败。web直接校验失败,USB刷机后,路由器无法正常启动,于是只能采用的最新开发版来验证。猜想是小米硬件做了升级限制或者在软件层面有专门对这个漏洞做修复。

结果:失败。如果有最近刷机成功的兄弟,也望留言指教。

Tomato

ROM

AdvancedTomato是一套基于Tomato的路由器管理界面,其核心是tomato。这个是tomato对应R1D的下载路径:

1. http://tomato.groov.pl/download/K26ARM

2. https://bitbucket.org/tsynik/tomato-arm/downloads

本次刷机实际使用的是这个:http://bbs.xiaomi.cn/t-11522784 ,因为有人验证过,并且支持中文,相对风险会小些,实际效果有待日后进一步观察。

说明:

因为文章里面的360的网盘挂了,特将rom重新发布:

链接: http://pan.baidu.com/s/1o8TRooE 密码: qe4j

因为本人验证时已经是很久以前的事情了,所以建议看到的朋友在上面的路径下载最新的版本尝试。

刷机

  1. 升级到最新开发版 :http://miwifi.com/miwifi_download.html
  2. 开ssh,http://www1.miwifi.com/miwifi_open.html
  3. ssh 192.168.31.1,ifconfig得到网卡MAC地址(或者刷机之前在web页面记录下MAC)
  4. 下载tomato固件,见前面的rom部分内容 。
  5. 下载tomato刷机包
  6. 打开CFEEdit.exe,通过菜单打开cfe.bin,修改其中的MAC地址为你的小米路由器的MAC地址,改好后覆盖。
  7. 将cfe.bin、backup.sh、flash-cfe.sh这三个文件放入U盘,插入路由U口。
  8. ssh登录路由器,登陆的账户名和密码参见 http://www1.miwifi.com/miwifi_open.html 。执行:
    nvram set boot_wait=on
    nvram set wait_time=10
    nvram commit
    进入U盘目录:cd /extdisks/sdb1 ,此路径可能会不同,请自行确认。执行:
    ./backup.sh
    ./flash-cfe.sh
    先备份系统文件,在必要时可以手动恢复。
  9. 电脑有线ip设置为192.168.1.1段,通过有线连接局域网端口。
  10. 重启路由,浏览器打开192.168.1.1,刷入tomato固件即可。

刷回小米系统

  1. 将miwifi-stock.bin和小米官网下载的小米路由器最新版U盘刷机包(改名我miwifi.bin)放到U盘中
  2. ssh登录小米路由器,执行命令:
    mtd-write2 /mnt/U盘/miwifi-stock.bin linux
  3. 按复位键,重新接电源,等黄灯闪烁后松开复位键
  4. 几分钟后黄灯常亮,拔下U盘
  5. 浏览器登录小米路由器,通过web页面更新最新开发版。

结果:成功。
启示:按照CFE的思路,理论上也可以来刷DD-WRT,但已经折腾一天了,改日有机会再试吧。

AdvancedTomato 基本安全配置

  1. 修改界面语言,修改管理员名称和密码:系统管理 - 管理员访问
  2. 设置宽带拨号,DHCP,wifi的SSID和密码:基础设置 - 网络
    注意:
    WAN设置:类别为PPPoE,不要勾选“使用DHCP”。
    LAN:默认的DHCP是有问题的,要设置正确的值,客户端才能正确使用外网。
    无线网络:设置WPA/WPA2密码。
  3. 如果为了进一步的安全,建议开启无线过滤:基础设置 - 无线过滤 - 允许以下客户端。手动添加需要wifi访问权限的设备,避免有人搞小动作

AdvancedTomato 服务配置

  1. USB&NAS
    通过设置,我们可以外接USB硬盘了,这个对某些人似乎有点用。
  2. 文件共享
    删除默认的共享,设置你要共享的目录,记得设置身份验证。这样你就可以在局域网使用路由器的1T硬盘了
  3. DLNA服务器
    如果你想在bt下完电影后,直接通过电脑或者手机观看,就要设置这个。设置一下媒体文件的目录,设置完后,DLNA客户端就可以直接在局域网发现媒体资源了。如果需要ios的客户端,你可以在APP store搜索Arkuda。
  4. BitTorrent客户端
    开启后,你可以通过路由器页面给路由器下发bt任务了,它会下载到你指定的路径,如果这个路径支持DLNA,那么下载完,你就可以直接观看大片了。
  5. DDNS+端口转发
    如果你要在远程通过互联网来玩bt,那么就需要继续设置DDNS+端口转发。

最后

如果你是其他型号的路由器,只要是刷相同类型的rom,流程基本相似,希望有帮到大家,也欢迎大家交流。
最后,有图有真相:
AdvancedTomato

刷完后,感觉整个世界都平静了。

其他参考

http://blog.icece.tw/Xiaomi-R1D-1TB-Flash-Tomato

补充:

  1. 关于发热的问题,我觉得原版其实就发热,我自己尝试的135的版本,刷机后感觉网速和发热并没有改善,期望新尝试的朋友继续反馈

LoRa技术介绍

目前看,LoRa是一个在IOT方案领域替换GSM的初步可行方案,主要从距离和功耗两个考虑方面。

介绍如下:
http://www.lora-alliance.org/What-Is-LoRa/Technology
http://www.rfwireless-world.com/Terminology/LoRa-technology-basics.html
http://www.rfwireless-world.com/Terminology/IoT-wireless-technologies.html

芯片厂商目前也已经有了量产的芯片可供评估,成本在1-2个美金。
http://www.microchip.com/design-centers/wireless-connectivity/embedded-wireless/lora-technology
http://www.semtech.com/wireless-rf/lora.html

IPSec生成证书

在很多安全服务中,我们都需要签名的安全证书。

注意 如果不生成证书,后面配置部分的配置中用 pubkey 认证的 conn 都不能用,甚至不能保留在配置中。
每一个完整的 ssl 证书都有一个公钥和一个私钥,它们可以在一起也可以分开放(当然如果你要在网络上传输,肯定只能用公钥)。公钥是在网络上传输的,而私钥是藏好用来和接收到的公钥配对的(因此私钥里也有整个公钥,用来配对)。

生成 CA 证书

生成一个私钥:

ipsec pki --gen --outform pem > ca.pem

没什么好解释的,–outform 一共有三个格式可选,但是另外两个是 der 和 pgp…

基于这个私钥自己签一个 CA 证书:

ipsec pki --self --in ca.pem --dn "C=CN, O=strongSwan, CN=strongSwan CA" --ca --outform pem > ca.cert.pem

这里 –self 表示自签证书,–in 是输入的私钥,–dn 是判别名,–ca 表示生成 CA,其它同上。这里需要解释下判别名:

C 表示国家名,同样还有 ST 州/省名,L 地区名,STREET(全大写) 街道名。
O 表示组织名。
CN 为通用名。
具体见微软的文档:Distinguished Names

生成服务器证书

同样生成私钥:

ipsec pki --gen --outform pem > server.pem

用我们刚才自签的 CA 证书给自己发一个服务器证书:

ipsec pki --pub --in server.pem | ipsec pki --issue --cacert ca.cert.pem \
--cakey ca.pem --dn "C=CN, O=strongSwan, CN=forum.suse.org.cn" \
--san="forum.suse.org.cn" --flag serverAuth --flag ikeIntermediate \
--outform pem > server.cert.pem

这条命令的意思解释下:

ipsec pki –pub –in server.pem
是从我们刚生成的私钥里把公钥提取出来,然后用公钥去参与后面的服务器证书签发(这个是 VPN 连接时候要用的,你不想把私钥也给它吧?那样跟没签证书一样…)。

–issue, –cacert 和 –cakey 就是表明要用刚才自签的 CA 证书来签这个服务器证书。

–dn, –san,–flag 是一些客户端方面的特殊要求:

iOS 客户端要求 CN 也就是通用名必须是你的服务器的 URL 或 IP 地址;
Windows 7 不但要求了上面,还要求必须显式说明这个服务器证书的用途(用于与服务器进行认证),–flag serverAuth;
非 iOS 的 Mac OS X 要求了“IP 安全网络密钥互换居间(IP Security IKE Intermediate)”这种增强型密钥用法(EKU),–flag ikdeIntermediate;
Android 和 iOS 都要求服务器别名(serverAltName)就是服务器的 URL 或 IP 地址,–san。

生成客户端证书

依然是生成私钥:

ipsec pki --gen --outform pem > client.pem

然后用刚才自签的 CA 证书来签客户端证书:

ipsec pki --pub --in client.pem | ipsec pki --issue --cacert caCert.pem \
--cakey caKey.pem --dn "C=CN, O=strongSwan, CN=client" \
--outform pem > client.cert.pem

这时命令行会提示你输入两遍密码,这个就是你的客户端证书密码。

看懂了服务器的,客户端的也就不难理解了。除了没有那一堆特殊要求别的都一样。

客户端证书可以每个客户端签一个,也可以让它们公用一个。是否多签看用途,一般用于区分设备(计费是不用这样的,是用账户来区分的)。

生成 pkcs12 证书(可选)

你可能还想生成一个可以直接导入的 pkcs12 证书(用于手机,诺基亚没这东西还不行):

openssl pkcs12 -export -inkey client.pem -in client.cert.pem -name "client" \
-certfile ca.cert.pem -caname "strongSwan CA" -out client.cert.p12

安装证书

cp -r ca.cert.pem /etc/ipsec.d/cacerts/
cp -r server.cert.pem /etc/ipsec.d/certs/
cp -r server.pem /etc/ipsec.d/private/
cp -r client.cert.pem /etc/ipsec.d/certs/
cp -r client.pem /etc/ipsec.d/private/

CA 证书、客户证书(两个)和 .p12 证书用 FTP 复制出来给客户端用。有几种 Android 配置还需要服务器证书(server.cert.pem)。

docker中的”layers”指的是什么东西

在很多的docker的说明中,我们都能看到“layer”的身影,那么到底什么是”layer“?

参见http://docker-doc.readthedocs.org/en/latest/terms/layer.html中的说明:

When Docker mounts the rootfs, it starts read-only, as in a traditional Linux boot, but then, instead of changing the file system to read-write mode, it takes advantage of a union mount to add a read-write file system over the read-only file system. In fact there may be multiple read-only file systems stacked on top of each other. We think of each one of these file systems as a layer.

简单翻译如下:
当docker加载rootfs时,和传统的linux系统中一样,它是只读的,但是随后,不是将当前文件系统变成可读写,而是利用union mount添加一个可读写的文件系统在当前的只读系统上。实际上将会有很多的只读文件系统叠加在彼此之上。我们将这里的每一层文件系统称之为”layer”。

参考阅读:
https://docs.docker.com/engine/understanding-docker/#how-does-a-docker-image-work
https://www.ctl.io/developers/blog/post/caching-docker-images/

使用docker中应避免的10件事

docker好文,短小精炼。水平有限,请不吝指教。

原文

http://developerblog.redhat.com/2016/02/24/10-things-to-avoid-in-docker-containers/

翻译正文

ps:为了保证一致性,文中的容器即container,是docker container的简称

最终,你选择了容器技术并且发现它解决了很多问题并且有着很多的优点:
1. 第一:不可变更-因为OS,库文件,配置参数,文件夹,应用等都包含在容器中,所以只要你保证你生产环境中使用的是和QA一样的镜像,那么它的行为就一定是一样的。
2. 第二:轻量级-容器的内存占用很小。不需要成百上千MB,只需要为主进程分配数十MB的内存就可以。
3. 第三:运行超快-启动容器就像开启一个单进程,不需要几分钟,只要短短几秒就可以完成。

但是很多用户仍然将容器仅仅当作虚拟机使用,而另外的人仅仅知道:容器是一次性的,而忘记了它还有其他很多优点。

关于容器的口头禅:容器是短暂的。

这一特性“本身”迫使用户去改变他们关于如何处理和管理容器的想法。而我也将阐述为了获取最佳性能而需要避免做的事情:

1)不要在容器中存储数据-容器可以被停止,销毁,或者替换。一个1.0版的应用应该很容易的就被替换成1.1而不应有任何影响和数据丢失。基于这个原因,如果你需要存储数据,把它存储在宿主的硬盘上,但是要避免两个容器同时写数据,造成数据异常,确保你的应用是将数据写到共享的数据路径的。

2)不要把你的应用分成两部分-因为很多人把容器当虚拟机使用,所以他们的做法是部署应用到已经在运行的容器中。也许开发中确实如此,因为你要不间断的部署和调试,但是在正式的QA和生产环节流程中,你的应用应该是容器的一部分。请记住:容器应该是不可变更的。

3)不要创建过大的镜像-镜像过大不易分发。请确认你只包含了必要的文件和库,不要包含不必要的开发包,也不要在容器运行时运行”updates”(yum update)。

4)不要使用单层的镜像-合理的使用分层的文件系统,OS是一层,安全和用户定义组件是一层,库文件是一层,配置文件是一层,最后是你的应用独立为一层。这样将使镜像的重建和管理变的容易同时易于分发。

译者:这里的层指得是”layer”,关于什么是”layer”,请参见docker中的”layers”指的是什么东西

5)不要从运行的容器中创建镜像-换个说法,不要用”docker commit”去创建镜像。这样创建的镜像不可准确重建和版本化管理,应该彻底避免。要使用Dockerfile或者其他可重建的S2I(source to image)方式。

6)不要只使用最新标签的版本-最新的标签就想maven中的”SNAPSHOT”。应该使用特定的标签的版本。我想你应该不想在你2个月后重新编译镜像时,收到惊奇,发现你的应用不能运行是因为顶层的layer使用了新的版本,没有向前兼容或者最新的版本是有问题的。当部署容器到生产环境时也要避免使用新的版本。

7)不要在一个容器中运行多于1个的进程-容积最好是运行单一的进程(http守护进程,应用服务器,数据库)。当你运行多个时,你将会遇到要单独管理,处理日志,以及更新的困难。

8)不要存储身份数据到镜像中,尽量使用环境变量-你应该不希望直接存储你的用户名,密码到镜像中。所以使用容器外的环境变量去获取相关的信息,一个较好的例子是postres image

9)请使用非root权限运行进程-“docker默认是以root身份运行的。当docker运行时,将会获取到默认的安全选项。而被他人获取root是危险的,并且也不是所有环境都支持的。你的镜像应该使用 USER 指令去指定一个非root用户来运行容器”(摘自Guidance for Docker image Authors)。

10)不要依赖特定的IP-每一个容器都有它们自己的内部ip,而且这个ip可能在开启或者停止时变化。假如你的应用或者微服务需要和其他的容器通讯,请使用名称或者环境变量去传递相关的信息。

更多关于容器的信息请参见:http://developers.redhat.com/containers/