Freeshell 关于禁止科学计算的公告

随着 Freeshell 用户数量的增加和用户活跃度的提升,Freeshell 目前面临着严峻的资源短缺问题,经常由于负载过高导致服务中断。在邮件列表中讨论后,管理团队一致认为应当让 Freeshell 回归 Linux 实验平台的本质,禁止科学计算等占用大量 CPU 或内存资源的程序,以保证大多数用户的正常使用。

Freeshell 用户规则 已经更新并添加了如下条款:

用户不得利用 Freeshell 进行以下行为:……
c. 运行科学计算、分布式计算、网格计算等占用大量 CPU 或内存的程序;

需要进行科学计算的用户,请利用科大云和科大超算中心的资源。科大云(cloud.ustc.edu.cn)默认配额是双核 2G 内存,如果需要更多计算资源,可以另行申请;科大超算中心拥有用于科学计算的专业集群,可以实验室的名义申请使用。Freeshell 作为 Linux 实验平台,没有能力支持需要大量资源的科学计算服务,希望您能理解。

即日起,我们将采取技术措施来限制科学计算等占用大量 CPU 或内存资源的程序。限制方法包括但不限于降低进程优先级、暂停进程运行、杀死进程。因此带来的不便,我们深表歉意。

这不是愚人节玩笑,谢谢。

Freeshell 设置 1G swap

每个 freeshell 在 4G 内存限制基础上增加了 1G swap 空间。早先 freeshell 是没有 swap space 的,内存一旦达到限制进程分配就会失败,导致进程容易被杀死。有了 swap 之后内核会使用经典的 OOM kill 机制,给内存分配留一定的缓冲空间。

Blog、Freeshell HTTP Proxy 请求数限制

为保证服务器安全,在一定程度上抵抗拒绝服务攻击,Blog 和 Freeshell HTTP Proxy 的 HTTP(S) 服务器部署了下列限制,一般不会影响到正常使用。

并发连接数限制:

  • 每个客户端 IP 100 个并发连接;
  • 每个域名 1000 个并发连接。

HTTP/HTTPS 请求频率限制(采用令牌桶算法):

  • 每个客户端 IP 每秒 50 个请求,允许 250 个突发请求;
  • 每个域名每秒 200 个请求,允许 1000 个突发请求。

最新的配置参见 Nginx 配置文件

Freeshell 宕机通告【已恢复】

3 月 18 日晚 22 时 24 分,freeshell 1 号节点突然宕机,导致外部磁盘阵列服务中断。

我们尝试通过 IPMI 硬重启,重启后能 ping 通,但无法 SSH 登录,已弃疗。可能需要明天去机房修理。

首先通过 IPMI 关闭电源,过一会儿再启动,启动之后就能 SSH 了!现在各虚拟机正在启动中,今晚就能恢复服务了。
凌晨 0 时 53 分,经确认 1 号节点上的虚拟机启动完毕,于是恢复了 NFS 服务,凌晨 1 时确认各节点上的虚拟机恢复正常。

非常抱歉此问题给您带来的不便。

继续阅读Freeshell 宕机通告【已恢复】

Blog, freeshell 部署 Web 防火墙

今天 blog、freeshell 实验部署了 Web 防火墙。

Web 防火墙使用了 stephen 推荐的 ngx_lua_waf。当访问可能存在注入的页面时,将返回 403 错误页面。如果您正常的网页被阻止,出现下面这样的错误页,请联系我们。

为防 CC 攻击,限制每个 IP 地址每分钟访问相同 URL 不超过 200 次,若超过则返回 503 Service Temporarily Unavailable。下图使用 ab 进行压力测试,有 299 个请求被 WAF 阻止了;而每秒接近 50 个请求的速度是之前就有的 nginx 每 IP 每秒请求数限制所致。

多谢 stephen 师兄的建议。

Blog 服务器数据库故障说明

3月12日21时14分至21时35分,USTC Blog 服务和 freeshell 控制面板无法访问。我们对本次故障给您带来的不便深表歉意。

故障原因是数据库连接数最大限制过低(151 个),连接数达到最大限制后无法建立新数据库连接。需要在 MySQL 配置文件 /etc/mysql/my.cnf 中增大 max_connections

修复方法是依次重启 mysql 服务和 php-sandbox 服务。由于 mysql 连接数满,sudo service mysql restart 会失败,因而 monit 在发现数据库无法连接后,尝试自动重启 mysql 失败了;每分钟监控 blog 首页 HTTP 状态并重启相关服务的脚本,由于也是使用 service mysql restart,同样没有奏效。最后 左格非(Alkaid)kill 掉了 mysql 进程,再启动 mysql 服务,才算活过来。

造成大量数据库连接的可能是来自北京某数据中心的 Web 扫描,在21时的前5分钟,伪装成 OS X 10.10 上的 Safari 浏览器,以每秒数十个请求的速度扫描 kekao.ustc.edu.cn 的某些敏感路径。21时03分,扫描到 phpmyadmin 目录(数据库管理工具),遂以全速暴力尝试密码,但估计没有破解出密码。由于 nginx 每 IP 每秒 50 次 HTTP 请求的安全限制,每秒尝试密码的次数接近 50 次。

我们使用 ab 重试了这个尝试密码的过程,每秒几乎恰好涌入 50 个请求,不过数据库连接数一直稳定在 21~23(php-fpm 的线程数,每个线程一个持久数据库连接),没有出现异常。从服务器监控看到,服务中断之前的10分钟出现了负载高峰,而我们模拟的压力测试没有造成负载高峰。因此大量数据库连接的罪魁祸首有可能仍然藏在幕后。

     66 [12/Mar/2015 20 56
     33 [12/Mar/2015 20 57
     26 [12/Mar/2015 20 58
     70 [12/Mar/2015 20 59
    650 [12/Mar/2015 21 00
   3490 [12/Mar/2015 21 01
   2399 [12/Mar/2015 21 02
   3223 [12/Mar/2015 21 03
   5315 [12/Mar/2015 21 04
     74 [12/Mar/2015 21 05
     32 [12/Mar/2015 21 06
     82 [12/Mar/2015 21 07
     22 [12/Mar/2015 21 08
     60 [12/Mar/2015 21 09
    104 [12/Mar/2015 21 10
     50 [12/Mar/2015 21 11
     88 [12/Mar/2015 21 12
     27 [12/Mar/2015 21 13
     98 [12/Mar/2015 21 14

LUG 网络服务3月9日网络中断说明

由于 全校范围的网络故障,3 月 9 日下午 17:00 ~ 18:00 网络时断时续,3 月 10 日凌晨 0:00 ~ 6:00 大约每半小时断网一次。

昨天的故障和 3 月 5 日持续 45 分钟的故障,原因估计是 近代物理楼某接口发送大量 ARP 包导致核心交换机 CPU 过载,换句话说,就是核心交换机被拒绝服务攻击了。

现代交换机通常是使用 ASIC(专用芯片)或 FPGA 来做绝大部分数据包的转发,只有少数控制包(如 ARP、STP 包)要交给交换机 CPU 做处理,交换机的 CPU 通常计算能力非常有限。例如 MAC 地址学习功能一般是由 CPU 进行的,首先所有 ARP 包被发到 CPU,CPU 把 MAC 地址和物理端口的映射关系写入到 ASIC 或 FPGA 中的二层转发表。如果交换机收到大量 ARP 包,又没有在入站端口对 ARP 包进行限速,就会导致交换机 CPU 忙不过来。

非常抱歉近几天的网络故障给您带来的不便。同时强烈谴责(有意或无意)进行网络攻击的人,对全校师生造成了这么大的麻烦!

Freeshell 修复控制面板操作失败问题

从 3 月 1 日中午开始,freeshell 控制面板所有涉及主机名变化的操作(如创建删除虚拟机、修改主机名)都会失败,原因是 DNS 更新失败。而 DNS 更新失败的原因是 freeshell Web 服务器与 LUG 权威 DNS 服务器之间的时间不同步(相差 5 分钟),提示这个错误:dns_request_getresponse: clocks are unsynchronized

现在 freeshell Web 服务器上安装了 ntp daemon,与 time.ustc.edu.cn 同步,现在操作失败问题已经解决。非常抱歉此问题给您带来的不便!

多谢各位用户的 bug 反馈。

Freeshell HTTP Proxy 如何获取真实 IP 和 HTTPS

Freeshell 上的 HTTP 服务器在使用 HTTP Proxy 时,请求的来源 IP 是代理服务器的内网 IP,而请求协议也都是 HTTP(HTTPS 证书和加解密已经在 HTTP Proxy 上处理了)。要知道客户端的真实 IP 和 HTTP/HTTPS 协议,可以使用 HTTP header 中的下列字段:

  • X-Forwarded-For: 客户端 IP 地址,可能是 IPv4 或 IPv6 地址
  • X-Real-IP: 同 X-Forwarded-For
  • X-Forwarded-Proto: 客户端是通过 http 还是 https 访问的,值可能是 http 或 https
  • X-Scheme: 同 X-Forwarded-Proto

其中 X-Forwarded-Proto 是今天(2015年2月26日)新加的 HTTP Header,因为 X-Forwarded-ForX-Forwarded-Proto 是 HTTP 代理服务器的事实标准。

要让 WordPress、Discuz 等 PHP 程序能够正确识别用户的真实 IP 和 HTTP 请求协议,可以把上述 HTTP Header 作为服务器的环境变量传递给 PHP 程序。

Nginx

Freeshell 上如果安装的是 Nginx + FastCGI,可以在 nginx 配置文件中的 server 块以外添加如下代码:

map $http_x_forwarded_proto $proxy_https {
        default off;
        https on;
}

然后在 location 块内的 include fastcgi_params; 一行下面添加

fastcgi_param remote_addr $http_x_forwarded_for;
fastcgi_param https $proxy_https;

在 PHP 程序中,$_SERVER['REMOTE_ADDR'] 就会变成客户端的真实 IP;而客户端是否通过 https 来访问,可以通过 $_SERVER['HTTPS'] 是否为 on 来判断。

Apache

Freeshell 上如果安装的是 Apache 2,建议安装 mod_rpaf 模块,该模块可以根据 X-Forwarded-ForX-Forwarded-Proto 正确设置 PHP 环境变量。

如果不想安装模块,可以如下解决:

  • 客户端 IP:由于 Apache 不允许修改 REMOTE_ADDR,需要修改 PHP 代码,首先尝试 $_SERVER['X_FORWARDED_FOR'] 变量,如果存在就把它作为客户端 IP;如果不存在,再使用 $_SERVER['REMOTE_ADDR']。Discuz 已经这样做了,但 WordPress 没有这样做,需要自己改或安装相关插件。
  • 客户端 HTTP/HTTPS:在 Apache 配置文件中添加如下代码:
    SetEnvIf X-Forwarded-Proto https HTTPS=On
    

    PHP 程序中可以通过 $_SERVER['HTTPS'] 是否为 on 来判断。

感谢 崔天一 和 郑子涵 提出问题。