包含标签 运维 的文章

阿里云未备案云主机申请 letsencrypt ssl 证书

用阿里云国内机房的主机有个『小问题』,备案。下面说的,一种情况是没有备案,另外一种情况是备案中,但是业务急于对外发布,等不及以周为单位的备案进程。 访问绑定到阿里云 ECS 上的、没有备案的域名,阿里云机房会劫持你的 http(80 端口)上行流量,无视你实际的返回内容,将之篡改成一个页面 title 为『TestPage』的*温馨提示*(如下图)。 而一台不能提供 http 服务的阿里云 ECS 不是真正的服务器。解决这个问题的办法,将 http 换到 https 就可以了。 https 选哪家 总所周知,自从 WoSign 被我大天朝数字公司收购之后,颇多周折,跟同袍兄弟 StarSSL 一起被业界良心 chrome 拉黑。现在使用 WoSign 签发的 ssl 证书会被 chrome 直接判定为证书无效。 最近连商务范儿最重的 Symantec 都被 chrome 一再警告之后拉黑。除了认为 chrome 真任性之外,也提醒我们选择 ssl 服务商时一定要慎重。 目前来看,从个人到中小企业,最佳选择是 google 投资的 Let’s Encrypt。运用 ACME 协议自动签发、自动续期,技术宅最爱,不是技术宅也有现成工具简单操作即可。 怎么生成 http ssl 证书 首先注明,申请 Let’s Encrypt 家的 http ssl 证书,不需要提前准备啥资料,不需要书面申请,这跟国内的『管理』方法不一样。你只需要证明这个域名归你所有,http ssl 的证书就可以签发给你使用。但是为了防止域名到期易主、中途转让等等原因,发生域名新主人拿不到 http ssl 证书的情况,所以 Let’s Encrypt 规定了每次签发的 http ssl 证书有效期只有三个月,证书生成一个月之后可以免费重签/续期,不用等到临近有效期再续签。……

阅读全文

用 openresty 来做 app api 接口的验真

app 服务器端的开发中,有一个百年不变的小东西:api 访问的验真问题。因为 http 协议是无状态的,每次 app 发起请求,我都需要验证这次请求的确是由真实的、授权的 app 发起,以此来阻止不诚实用户发起的攻击、数据爬取,确保产品的安全,和用户在产品上的信息安全。 JWT(JSON Web Token)是一个 http 之上的不错的 api 验真协议,结合 https,几乎可以安全地传输各种数据。最关键是,它原理简单,没用到啥黑科技,新瓶装老酒,但实用。 openresty 是春哥做的一款神器,在 nginx 上挂了个 lua 引擎,可以用 lua 脚本指挥 nginx 做很多事情。了解 lua 的童靴都知道,lua 的执行性能堪比 C++/Java 这些编译型语言,大家在一个量级。能做到这步,已经相当感人。用 openresty 来实现 jwt 协议,做 api 访问的验真,可以降低后台系统的复杂程度,同时还能提高系统鲁棒性,防止被恶意攻击时系统雪崩。 现在已经有 openresty 的 jwt 模块,叫 lua-resty-jwt 的,还有基于它做了二次封装的 openresty-nginx-jwt。 有了这个 jwt 的 openresty 模块,可以在 http server 这一层对 api 访问做验真,业务系统接收到的请求理论上都是真实的,避免调用庞大的业务系统做验真。这在收到 api 攻击的时候效果最明显,那时每次调用庞大的业务系统,加载若干组件,仅仅做了一次验真,然后就释放资源,销毁请求。简直是罪过。 话分两头说,直接上这个 jwt 模块存在一些风险。要在生产环境使用 jwt,还有一些工作必须做。 secret 的策略。jwt 协议中,并没有规定 secret 怎么来的,实际操作中,不同的 secret 策略会有不同的效果。 整个系统使用一个固定的 secret。不诚实用户可以注册账户,暴力穷举或内存搜索,得到 secret 明文。存在系统性风险。风险高。 一台服务器使用一个 secret,secret 写到 openresty 的配置中。仍然有上述问题,还增加了做负载均衡的难度。风险高。 一个用户一个 secret,openresty 根据用户信息取 secret 编解码。风险低,复杂度高。 api 访问日志需要保存。特别对验真失败的访问,要能有手段及时处理日志,分析风险,对恶意用户可以屏蔽 IP 等手段规避。 经过验真的 api 访问日志结合静态资源访问日志,可以模拟真实用户的访问场景。结合 lazy load 等前端技术,甚至可以判断出用户究竟看了几页,资源加载速度快还是慢。这么好的资源,不能浪费。 接上面。第一点好解决,一个 subrequest,或者单独给 lua-resty-jwt 一个 redis 存用户的 secret,就行了。第二点和第三点说的其实是一件事情,记日志,而且是把验真失败和验真成功的日志分开记。验真失败的日志需要参与在线准实时的计算,验真成功的日志打包保存,用来做离线的大数据分析,统计用户访问指标,优化产品。……

阅读全文

另一个包管理工具——DNF

更新(2017-06-01):repo 的 url 有变化,更新之。后附更新脚本。 DNF 起源于 YUM 的一个分支,最早用在 Fedora 18,在 Fedora 22 中默认安装,成为系统工具。现在更是被广泛看作 YUM 的接班人。虽然 DNF 号称自己不错,但是幸好,至少从目前来看,都可以看做是对 YUM 的小修补。整体来说,DNF 对 YUM 的兼容做得很好,甚至于部分操作可以 yum 和 dnf 混合着来——当然,新旧掺杂绝对不是好习惯,我就这么一说,证明 YUM 和 DNF 的关联之亲近。用惯了 YUM 的朋友们一定不会抗拒换到 DNF,它们的用法非常相似,而且 DNF 的更有现代语言风格。 我常用的系统是 CentOS,虽然已经被 RedHat 收购,但是 CentOS 的品质和定位都没有变,这很难得。最新(截至 2016-10-16)的 CentOS 是 7.2.1511。下面的步骤在 CentOS 上尝试,对 Fedora/RHEL 理论上同样适用。Fedora 上应该还更加简单,下面的问题好多都不会遇到。 闲话不说,安装步骤如下。 一、手动安装全新的 yum repo 新增一个 repo,从这个 repo 中用 yum 安装 DNF。这是因为 CentOS Base repo 中的 DNF 版本太低,只有 0.……

阅读全文

再次问候方校长:我们受够了功夫网

(UPDATED) 2017-08-17: ssserver 提供服务器端的支持;sslocal 转本地 socks5 服务;再用 privoxy 提供 http/https proxy。 经过试验,这样的解决方案是最全面的了。 至于梯子哪家强,你问我,我不会不告诉你。O(∩_∩)O哈哈~ 对于功夫网不问青红皂白直接予以封杀的行为,程序猿的一贯态度是问候方校长。有些的确敏感的都不说了,facebook 旗下的工具网站 Nuclide 也被封,之前还有 Python 因为一个特定版本号被封的往事…… 各种搞笑和不能理解的规则,生活在兲朝的程序猿这种生物天生比国外的低矮一截——纯粹因为生存环境的关系,导致看世界不完整。 前两天做 grpc 的调研,为了简洁,安装 php-grpc 时准备就直接用 homebrew 搞定。brew install homebrew/php/php56-grpc,一句命令安装,升级维护也省心。 可是安装 php-grpc 的依赖却出了问题。protobuf 在 homebrew 中是从源码开始安装,用的是 protobuf 自带的 autogen.sh 脚本,脚本中正好从 googlemock.googlecode.com 域下载 googlemock 一个特定版本的发布包,因为 shell 默认不会走系统代理(我用 shadowsocks 科学上网,这是我的梯子,这是下面所列方法的前提。如果你连梯子都没有,可以不用往下看,没戏),会导致下载失败。 英雄汉不能被一泡尿憋死。折腾一会儿,终于找到办法。 后来想想,自动化脚本里面其实挺多这种应用场景的,没谁写个脚本还要兼顾其它国家特色网络,那技术宅成天别干别的事儿,光跟堂吉诃德战斗好了。因此,记一下吧,以后用得着。 下面提供两种办法供选用。两种都简洁,改动都不大,主要看应用场景和个人的习惯吧。 方法一:修改下载程序配置 protobuf 安装脚本中的下载程序使用的是 curl,因此先得配置它。新增或修改 ~/.curlrc 这个文件,加入 socks5 这个选项(因为 shadowsocks 是用的 socks5)。 # 我用的是影梭,所以设置 socks5 选项 socks5 = 127.……

阅读全文

解决了一个 curl 库导致的 https 访问错误

使用 EasyWeChat 库调用微信服务的时候,在 laravel tinker 里面调试,发现每次进入 tinker 之后,第一次调用接口没有问题,第二次之后,就会报一个很诡异的错误。 $app = app('wechat'); // EasyWeChat\Foundation\Application {#628} $users = $app->user->lists(); // EasyWeChat\Support\Collection {#756} $user = $app->user->get('o7qrUviv1tkcDFMJ5wdXrpng9NNQ'); // GuzzleHttp\Exception\ConnectException with message 'cURL error 35: A PKCS #11 module returned CKR_DEVICE_ERROR, indicating that a problem has occurred with the token or slot. (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)' PKCS #11 返回的错误,好高端啊。 中间的曲折就不说了。答案在一篇歪果仁的博客上找到,在 github 的评论上得到印证及解决问题的思路。 NSS error -8023 using AWS SDK for PHP Consecutive API calls return curl error code 35 on CentOS 6.……

阅读全文

redis + supervisor 时苦大仇深的问题

在我记忆中,CentOS 从很早开始,就没有和各种的问题挂钩过。得益于它保守的升级策略,它自己几乎从来不是问题专业户,我对它的印象更多是因为太过保守导致的库升级不及时问题。 可是最近,CentOS7 某个版本发行之后,偶尔的,会出现 supervisor 拉 redis 失败的问题。从日志的内容来看,全是 Permission denied 相关的问题,bind socket 的时候权限不够,write log 的时候权限不够,dump snapshot 的时候权限不够,只要跟写磁盘相关的,都有这个问题。 单独执行 /usr/bin/redis-server /etc/redis.conf,又一点儿问题没有,命令本身没有问题,一切正常。 关键,supervisor 是以 root 去拉 redis 的啊!表示很无辜 (o´・ェ・`o) supervisor 的配置如下: [program:redis] command = /usr/bin/redis-server /etc/redis.conf ;process_name=%(program_name)s ; process_name expr (default %(program_name)s) numprocs=1 ; number of processes copies to start (def 1) directory=/data ; directory to cwd to before exec (def no cwd) ;umask=022 ; umask for process (default None) ;priority=999 ; the relative start priority (default 999) autostart=true ; start at supervisord start (default: true) autorestart=true ; whether/when to restart (default: unexpected) startsecs=1 ; number of secs prog must stay running (def.……

阅读全文

发现 Gitlab 的一个权限问题

用了好几年的 gitlab,前前后后搭建了好几次系统,解决了不少问题,还是非常熟悉了。昨天又遇到 gitlab 搭建中的一个新的问题。 现象 gitlab 搭建好之后,建账号,加 ssh key,建项目,本地 push,然后就遇到 gitlab 问我要密码。 git@some.domain.name password: 项目是我创建的,ssh key 也有添加,还找我要密码,明显不科学。 尝试解决 首先,检查了服务器的 sshd 设定,确认启用了 ssh 登录。 cat /etc/ssh/sshd_config | grep PubkeyAuthentication PubkeyAuthentication yes 以为是缓存,分别重启了 redis 和 gitlab。(PS:我的 redis 用 supervisor 管理起来的) supervisorctl restart redis service gitlab restart 然后等了五分钟再试(其实没有必要),还是不行。 上网查,stackoverflow 上有一个非推荐答案说,重启服务器之后就好了。于是,又重启了服务器。 shutdown -r now 还是不行…… 用 ssh -T 命令测试一下,看看结果。 ssh -vvvT git@some.domain.name …… 一串无关的日志我就省略了,只说重点。 …… debug3: send_pubkey_test debug2: we sent a publickey packet, wait for reply debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password debug2: we did not send a packet, disable method debug3: authmethod_lookup password debug3: remaining preferred: ,password debug3: authmethod_is_enabled password debug1: Next authentication method: password git@some.……

阅读全文

再学习 Linux 下的文件权限

最近遇到一个比较搞的问题,有关 linux 下的文件权限。因为发现解决问题之后的答案是我们很多工作多年的攻城狮以前都没有重视过的,所以特别写下来,帮助加深记忆。 【背景】 同事学习 lnmp,搭好 CentOS 6.5 的环境之后,新建了一个用户组 test,在该组别下新建了一个用户 test,然后准备用这个用户模拟 nginx 和 php-fpm 进程的启动用户,跟着手册上做实践。 【关键信息】 用户:test:test 目录:/www/test 目录权限:drwxrwxrwx. 2 root root 40 Oct 21 16:43 test 文件:/www/test/index.html 文件权限:-rw-r--r--. 1 root root 0 Oct 22 10:04 index.html 【现象】 先用 root 的身份 touch 了一个空文件 index.html; su test,然后以 test 用户的身份去删除这个空文件; WTF!!! 竟然删除文件成功了???!!! 普通用户删除了 root 用户的文件,我保证,刚看到这个现象的时候,我内心绝对是崩溃的。 【解决的途径】 首先,检查了 test 用户的用户组,确认的确是 test 组。 其次,检查文件和目录的权限,除了 test 目录没有按照惯例,被设置成 0777 之外,没有什么特别的。不可能一个 0777 还能捣蛋吧?!……

阅读全文