Freeshell 添加强制关机和重启功能

如果 Freeshell 里有进程停止响应了,普通的关机和重启也许奈何不了它,需要等到超时才会被强制杀掉。如果已经知道有进程停止响应了,就不必要等到超时了,用 Force Shutdown 或 Force Reboot,就可以强制杀死 freeshell 内所有进程,快速关机或重启。

Capture

Freeshell 的重启功能从来就没有正常工作过(你没看错,这个按钮一直是个摆设),现在修好了。

Freeshell 修复无法新建和复制虚拟机问题

感谢 Guo, Jiahua,Vanabel 和 Yifan Gao 的 bug report。

问题于 4 天前 https://gitlab.lug.ustc.edu.cn/boj/freeshell/commit/ef13f452080e4613423559040ccae0d365ef9dbe 中引入,当时添加了 IPv4 的 DNS 解析,因此把函数名 get_node_dns_name 改成了 get_node_v6_dns_name,并新加了 get_node_v4_dns_name 函数。可能是由于敲错了命令,只在 nodes.inc.php 和 admin.php 中做了替换,但 activate.php 和 manage.php 中未做替换,结果新建虚拟机的激活操作和复制虚拟机操作会遇到 undefined function,操作失败。

Freeshell 系统从开始就存在三大问题,我一直懒得去重构代码:

  1. 函数没有为测试留下接口,也就谈不上自动测试了,提交了有问题的代码也不能发现。这次 bug 应该是这个原因。
  2. 大多数操作都没有检查返回值,例如即使虚拟机创建失败,也会发送创建成功的邮件。
  3. 操作没有加锁,例如在重装 freeshell 的过程中执行复制操作,天知道会发生什么。

Update:4月17日为 freeshell 控制面板中可能出现同步问题操作进行了加锁,并检查 SSH 的返回值,能够检查通信失败问题,但返回值检查仍不完整。

Gitlab 服务意外停止运行 1.5 小时

Gitlab 服务器上软件包版本混乱,有的是 squeeze,有的是 sid,需要修补漏洞的 OpenSSL 是 sid 中的 1.0.1f。 sid 中的 OpenSSL 包还没有针对这个安全漏洞的补丁,只好降级到 wheezy 中的 1.0.1e,导致一些包的依赖关系不满足,需要重装。

其中 nginx 配置文件还有问题,有两个重复的 default_server(原因是 /etc/nginx/sites-enabled/default 中没有注释掉默认的 server),nginx restart 起不来。

升级的时候看到 mysql 也有 security update,于是就顺手升到了 5.6,没想到这一升级闯下大祸了。GitLab 的 mysql adapter 只支持 5.5 的 client,不支持 5.6(Gemfile 里是这么写的,我不敢随便改,要是运行过程中出现不兼容问题就更麻烦了)。准备把 mysql 降级到 5.5,又有一堆版本依赖和不兼容,在 aptitude 里倒腾了半天才弄清楚。混乱的根源是 gitlab 上添加了 dotdeb 源,dotdeb 源比 debian wheezy 的要新一些,目前 dotdeb 上 mysql 的版本已经是 5.6,而 Debian wheezy 上的还是 5.5。

降级到 5.5 之后问题并未结束,数据库启动不起来了,原因是 InnoDB log 文件的大小与配置文件不符。按照网上的办法操作之后仍未解决,因此只好祭出重建数据库的杀器了。首先把 /var/lib/mysql 备份出来,在 aptitude 里删掉 mysql-server-5.5,rm -rf /var/lib/mysql,在 aptitude 里安装 mysql-server-5.5,然后把备份的 /var/lib/mysql/gitlab 目录(数据库表结构)和备份的 /var/lib/mysql/ibdata1(InnoDB 的数据文件并不放在数据库目录里)还原回去,重启数据库,MySQL 会自动解决 log 的不一致问题。由于数据库权限设置和用户名密码是在 mysql 库中保存的,而 mysql 库是 MyISAM 存储引擎,存储在 /var/lib/mysql/mysql 里,这个目录并未被恢复(我也不想恢复它),gitlab 用户的权限需要重新设置(GRANT 语句)。这下 gitlab 服务终于能正常连上数据库了。

Gitlab 服务于 4月9日凌晨 01:27 恢复,大概停机了 1.5 小时。

LUG 所有服务器升级 OpenSSL 以修复 Heartbleed 漏洞

OpenSSL 爆出重大漏洞(CVE-2014-0160),由于 TLS heartbeat extension 中没有检查长度字段与实际长度是否相符,可以溢出缓冲区,获取至多 64 KB 的服务器内存内容,包含用户请求、SSL 证书等敏感信息。此漏洞影响 OpenSSL 1.0.1a 至 1.0.1f,Debian wheezy 包含在其中。LUG 所有提供 HTTPS 的服务器都从 Debian security 源升级了 OpenSSL 并重启了相关服务。

升级过程中,发现部分服务器的 sudoers 存在问题(没有设置 sudo PATH),部分服务器的 /etc/apt/sources.list 存在问题(没有包含 security 源),一并予以解决。

漏洞技术细节详解

如何用一行命令让 mirrors 的负载破百

如何仅用不到 1 MB/s 的带宽把 mirrors.ustc.edu.cn 的负载提高到 100 以上?下面一行命令就能做到(拆开成几行写以便看清楚):

rsync rsync://mirrors.ustc.edu.cn | awk '{print $1}' | while read m; do 
   [ -z "$m" ] && continue
   rsync -r --list-only rsync://mirrors.ustc.edu.cn/$m >$m &
done

这行命令的作用是获取 mirrors 上每个源的文件列表,所有源并行操作。进行真正的 rsync 同步之前,都要执行获取文件列表的操作,因此这个操作是完全合法的,只是我们发起的请求并发数有点高。

执行此命令后,在 mirrors 服务器上看到的负载如下图所示,而发起“攻击”的机器仅用了不到 3 MB/s 的带宽:

┌nmon─13g──────[H for help]───Hostname=mirrors──────Refresh= 2secs ───00:08.45─┐
│ Kernel Stats ────────────────────────────────────────────────────────────────│
│ RunQueue              1   Load Average    CPU use since boot time            │
│ ContextSwitch   11384.5    1 mins 109.04    Uptime Days=106 Hours= 1 Mins=132│
│ Forks               0.0    5 mins 73.83    Idle   Days=1377 Hours=13 Mins=22 │
│ Interrupts      26381.3   15 mins 37.30    Average CPU use=-1198.96%%        │
│ Disk I/O ──/proc/diskstats────mostly in KB/s─────Warning:contains duplicates─│
│DiskName Busy  Read WriteMB|0          |25         |50          |75       100|│
│sda        5%    0.3    0.2|RRW                                    >         |│
│sda1       0%    0.0    0.0|>                                                |│
│sda2       5%    0.3    0.2|RRW                                    >         |│
│sdb        9%   11.5    0.0|RRRRR    >                                       |│
│sdc        0%    0.0    0.0|>                                                |│
│sdc1       0%    0.0    0.0|>                                                |│
│sdd      100%    3.6    0.0|RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR>│
│sde      100%    8.0    0.2|RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR>│
│sdf       94%    6.0    0.0|RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR  >│
│sdg      100%    6.9    0.0|RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR>│
│dm-0       1%    0.0    0.1|R                                      >         |│
│dm-1     100%    7.0    0.0|RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR>│
│dm-2      94%    5.9    0.0|RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR  >│
│dm-3     100%    7.9    0.0|RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR>│
│dm-4     100%    3.4    0.0|RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR>│
│dm-5       3%    0.3    0.0|RR  >                                            |│
│dm-6       0%    0.0    0.1|        >                                        |│
│sdh      100%    5.2    0.0|RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR>│
│sdh1     100%    5.2    0.0|RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR>│
│Totals Read-MB/s=71.7     Writes-MB/s=0.7      Transfers/sec=4584.9           │
│──────────────────────────────────────────────────────────────────────────────│

Mirrors 流量图(下图)中,00:07 左右的低谷就是上述“攻击”所致。

collection.modified (1)

大约 15 分钟后,“攻击”源所用平均带宽下降到 250 KB/s,而 mirrors 服务器的 load average (1 min) 仍然高达 75,这是由于一些“文件数较少”和“被缓存”的文件列表已经发送完毕,剩下的都是“难啃的骨头”需要大量磁盘随机访问了。如果精心选择要同步的源甚至子目录,应该可以用相对少的带宽把 mirrors 的负载升高到很高,进而影响正常用户的服务质量。

Freeshell 之间的 IPv4 互通

之前由于配置问题,freeshell 的 IPv4 地址(10.10.x.x)只有同一个物理节点上的可以互通。现在所有 freeshell 的内部 IP 地址都可以互通了。如果某个应用需要在几个 freeshell 之间通信且不支持 IPv6,或者不想暴露在公共 IPv6 网络中,可以使用内部 IPv4 地址。可以使用域名 ${hostname}.4.freeshell.ustc.edu.cn 访问这个 IPv4 地址。

Capture

BTW,${hostname}.4.freeshell.ustc.edu.cn 和 ${hostname}.6.freeshell.ustc.edu.cn 都支持泛域名解析,例如 subdomain.${hostname}.4.freeshell.ustc.edu.cn 也能解析到 freeshell 的内部 IPv4 地址。

Ganglia 在图像中去除噪点

现在 status.lug.ustc.edu.cn 网络流量的噪点消失了。由于我们观察到这些噪点的数值都在 1e+15 以上,而且正常的数值都没有这么大,因此用了 dirty 的做法:修改 rrdtool 源码,把 1e+15 以上的值在画图时去掉。

Based on rrdtool 1.4.7, in src/rrd_graph.c, function data_proc:

1286a1287,1291
> #define RRD_DATA_FILTER_THRESHOLD 1.0e+15
>               if (value > RRD_DATA_FILTER_THRESHOLD) {
>                   value = DNAN;
>               }
>

Freeshell 新功能:Public Endpoint

Public Endpoint 功能可以把 ssh.freeshell.ustc.edu.cn 的 40000~49999 端口映射到你的 freeshell,以便让你 freeshell 开在特殊端口的服务能够被 IPv4 国际网络访问。每个 freeshell 最多建立 10 个公共端口。

请谨慎使用此项功能,以免造成安全漏洞。另外需要重申,不准利用 freeshell 搭建代理服务器,一经发现永久封号。

Capture