USTC Blog 近几天的 502 Bad Gateway

近几天 blog.ustc.edu.cn 频繁发生 502 Bad Gateway 故障。之前多次发生的内存溢出(OOM Kill)是由于 php-fpm worker 内存泄漏。开始以为是有攻击者频繁访问那个特殊 URL 导致的,但事实上我频繁访问其他的 URL,也能观察到内存泄漏。频繁访问 phpinfo 没有检测到内存泄漏,因此怀疑是数据库连接部分捣的鬼。

临时解决方案是,在 php-fpm.conf 里设置了 pm.max_requests = 500,即每个 worker 处理 500 个请求后就自动退出,respawn 新的 worker,这样内存泄漏的数量就是可控的。

今天又发生了 502 Bad Gateway,不过从 status.lug.ustc.edu.cn 上看到的各项系统指标都比较正常。但 php-fpm master 所监听的 socket 就是不接受连接。

为了应对这种古怪的情况,我们添加了 cron 脚本,每分钟检查 USTC Blog 首页和一个用户 blog 首页的可用性,发现错误就立即重启 php-sandbox 服务,如果还没有恢复就再重启 mysql 和 php-sandbox 服务。希望这个自动重启服务的程序能在关键时刻起作用,缩短服务中断时间。

Freeshell 9月19日的 IPv6 故障

9月19日23时许至9月20日上午9时许,freeshell 的 IPv6 地址无法访问,IPv4 正常。原因是晚上机房管理员将学生机房电源关掉了(非服务器所在的主控室),而有一台路由器放在学生机房内,所以导致了断网。我们已经将网线连接方式更改,将重要的路由器放在主控室里,防止再有人关掉机房的电源。

我们还修复了长久以来 6 号节点无法使用 IPv6 的问题,因为连接 IPv6 子网的 eth1 网线头松了。更换一根网线后正常了。

GitLab SSH 无 key 时不再提示输入密码

之前 git clone [email protected]:namespace/project.git 的时候,如果没设置好 SSH key,会提示输入密码,很多用户对此感到迷惑。现在在 sshd_config 中加了下面两行,会直接提示访问被拒绝。

Match User git
PasswordAuthentication no

Tips:GitLab 的代码仓库支持 SSH 和 HTTPS 两种访问方式:

  1. SSH 访问,需要用 ssh-keygen 生成密钥,把公钥(id_rsa.pub)添加到 GitLab 个人管理区域的 public key。
  2. HTTPS 访问,每次连接服务器都要输入用户名(注册邮箱)和密码。可以作为在公用电脑上的临时访问方式。

Blog 502 Bad Gateway 恢复

9月20日17时许,USTC Blog 发生了 502 Bad Gateway 故障。现已恢复。我们对此次故障对您带来的不便深表歉意。

已经确认此问题与前几天发生的故障原因相同,是恶意攻击引发的 OOM Kill。攻击从 14:50 左右开始,一直持续到现在。15:37 引发了第一轮 OOM Kill,于 15:53 造成第一次服务中断,不过很快被自动恢复;16:55 造成第二次服务中断,且未能自动恢复。由于报警机制在上次故障后尚未恢复,直到 20 时许问题才被发现。

USTC Freeshell 走进新时代

USTC freeshell

虽然有些标题党,我们还是高兴地宣布 USTC Freeshell 升级了:

  • 每人可以注册多个虚拟机
  • 支持三级域名
  • 修复在线管理功能,支持在线重置密码

Multiple Shells

一个 freeshell 做多种事情,不符合隔离的原则。今天,每个科大邮箱都可以注册至多5个 freeshell。不同的 freeshell 可以设置不同的密码,登录时会默认进入密码匹配的 freeshell 管理界面,也可以随时切换到其他的 freeshell(如下图)。

freeshell-select

Subdomain

blog.ustc.edu.cn 支持三级域名,freeshell 今天起也可以了。每个 freeshell 都可以设置一个三级域名作为 HTTP Proxy,这样在 freeshell 上建的小站就能摆上台面了~

freeshell-admin-2

喜欢折腾的同学可能会发现,不存在的域名是公益 404 页面,让我们一起为他们祈福。

Start / Shutdown / Reboot / Reset Password

很抱歉地跟大家说,自从上次 Freeshell 控制节点与运算节点间 API 升级后,下面这几个 Start / Shutdown / Reboot 按钮就一直是坏的,我也没发现。这次不仅修好了已有的 bug,还在用户体验上做了些许改进(Processing 提示,邮件提醒)。

freeshell-admin-1

更重要的是,Freeshell 增加了千呼万唤的重置 root 密码功能。重置后的 root 密码会通过邮件发送。如果邮件被丢进了垃圾箱,请把 [email protected] 加入联系人。

Let The Source Be With You

Freeshell 的代码是开源的,注册登录 USTC GitLab 即可:https://gitgeek.net/boj/freeshell

LUG 网络服务将使用 freeshell 作为 testbed,freeshell 也会在今后的 LUG 活动中持续推广。Enjoy freeshell at freeshell.ustc.edu.cn, 欢迎报 bug!

GitLab 挂上小绿锁了

代码安全是一件比较严肃的事情。看到这么多人使用 GitLab,我自己也经常在校外使用 GitLab,安全的 HTTPS 传输是必要的。由于 gitlab.lug.ustc.edu.cn 是三级域名,LUG 也没有顶级域名 ustc.edu.cn 的管理权限,搞 SSL 证书是比较麻烦的。

为此,我申请了 gitgeek.net 域名,去 StartSSL 申请了一个免费 SSL 证书。没办法,GoDaddy 非促销季的证书太贵了;要是那位高富帅给 USTC 搞个 Verisign 的 Extended Validation,我可以给TA所有服务器的 root 🙂

总之,GitLab 挂上小绿锁了:

screenshot

在 Ubuntu 和 Windows 下的主流浏览器中测试,均可以正常访问。在 Debian 和 cygwin 中用 git clone 和 curl 也可以正常访问。由于 wget 1.12 的一个 bug,会提示证书不匹配,升级 wget 即可。

如果大家发现小绿锁没有挂上,或者 HTTPS 访问出现任何问题,请把你用的操作系统、浏览器或命令行工具的名称及版本号发到 [email protected]

原来的 http://gitlab.lug.ustc.edu.cn 仍然可以使用,只不过登出之后,登录会跳到 gitgeek.net……… GitLab 就是这样的,我本来不想这样……

Tips for GitLab Maintainers

修改配置文件后,最好清除 Redis Cache。例如 Gravatar 的 URL 会缓存,今天下午我百思不得其解的小黄锁问题就是由于早先生成的 HTTP URL 被缓存了。清除缓存步骤:

  1. sudo -u git -i
  2. cd gitlab
  3. RAILS_ENV=production bundle exec rake cache:clear

重启 gitlab 服务需要比较长的时间,虽然 sudo service gitlab restart 会立即显示成功,但事实上还是原来的 sidekiq 和 unicorn 在运行。可以用 sudo service gitlab status 和 pstree -pa 来查看 gitlab 服务的状态。如果发现“残余进程”,要 kill 掉再 sudo service gitlab start。

如果 gitlab 服务起不来,可以查看 ~git/gitlab/log/ 里的日志文件。

注意,从 StartSSL 申请的免费证书是 intermediate CA 签发的,为了在 git clone 和 curl 中正常使用,需要 cat intermediate.CA.crt >> gitlab.crt,把自己的证书和 intermediate CA 证书连接在一起。

Blog 再次发生 OOM Kill

9月15日晚上23时许,USTC Blog 服务再次发生 OOM Kill,数据库进程被杀掉,导致 blog 首页显示 “0 users”,无法登录,用户博客也无法显示。

事实上,早在21:30,21:50,22:15,就已三次发生 OOM Kill。不知道为什么,monit 没有发送报警邮件。监控基本服务可用性的 servmon 由于依赖数据库,也挂掉了。因此直到16日上午 zguangyu 给 boj 打电话这事才被知道。解决方法很简单,启动 mysqld 服务,重启 php-sandbox 服务。

统计 nginx access log,每分钟的 HTTP 访问数大多在 100 以下,没有 DDoS 攻击的迹象。不过一个奇特的 IP 202.194.3.59(山东大学)很奇怪,它大量访问形如 http://lttt.blog.ustc.edu.cn/feed/p2.ajax?p2ajax=true&action=get_latest_posts&load_time=2013-09-13%2002:47:50&frontpage=0&vp=&vp=2199&_=1378861410811/wp-admin/install.php 的URL,结果是一个空页面。分析结果出来后再更新。

由于 blog 近期多次发生 OOM Kill,我们做了如下调整:

  1. 停止 blog 上占用资源较多的 BIND9 服务,换用轻量级的 DNSmasq(其实相当于把负载转移到学校DNS上了)。
  2. 调整 php-fpm.conf,最大 PHP 线程数 max_children 由 200 降低到 50。
  3. 将 servmon HTTP 监控服务迁移到 lug 服务器上。

BugFix: Blog 升级、安装插件期间访问出错

USTC Blog 升级、安装插件期间,访问首页会提示出错。原因是 WordPress 进行升级、安装插件等操作时,会生成 .maintenance 文件,wp-includes/load.php 会试图 include 这个文件以检查其存在性。为了保证安全,USTC Blog 禁止 include 非 .php 后缀的文件。因此我们将 .maintenance 修改成 .maintenance.php 以绕过此限制。相关 commit:

http://gitlab.lug.ustc.edu.cn/ustc-blog/wordpress/commit/4537059a91aea17a6d85151293b6a35c668fa6ff

感谢 Moqi Lee 同学的 bug 反馈。

9月7日 blog 数据库 OOM kill

9月7日16:30,blog 数据库(mysqld)被 OOM kill。故障在 19:00 左右恢复。

恢复方法是先后重启 mysql 和 php-sandbox 服务。php-sandbox 有一个已知的 bug,mysql 重启后不会自动重连,因此 mysql 重启后必须重启 php-sandbox 服务。

本次故障是内存溢出引起的,当天 14:30 已经收到 monit 的邮件报警,但当时唯一接收报警的 boj 没打开数据流量,没收到邮件,酿成服务中断的悲剧。我们今后将让服务器维护小组的更多人收到报警。