About Alex Zhang

OSQDU联合创始人

最近青岛大学在部分教学楼中部署了 IPv6 实验网 (学生宿舍区以及 WLAN 暂时未覆盖)。 IPv6 的部署有一些独特的挑战,从老旧设备无法支持到 IPv6 动态路由协议需要单独配置以及地址规划与 IPv4 的方式迥异,一切都带来了较大的挑战。

好消息是,这是一个有零技术债的平台,至少可以从零开始,把 IPv4 部署中的教训吸取并采用。

最根本的挑战,是 IPv6 的地址规划方法。 CERNET 分配了一个 /48 的地址空间,因此实际的分配必须要进行精细化——为了使用 SLAC 功能,每个交换机上最小为 /64,因此只有 2^16 个 /64 可以分配。为了考虑今后的扩展性,规定每个楼宇/楼宇交换机独占一个 /60,以备在接下来三十年中的地址需求。

关于每个楼的地址需求,可以简单的进行估算。考虑到今后的传感器、物联网设备需求,每个楼层可能会有上百到上千个此类设备。在楼层满载时,每个教室大约可容纳 80 人,每个楼的容量在万人以内。假设每人携带十部联网设备,每个楼的地址需求量为十万到几十万级别。当然,一个 /64 现在看起来依然足够,但是为了避免犯“预测未来”的愚蠢错误,多分配一些又何妨?

分配 IPv6 地址的核心考虑便是如何最大程度确保地址利用率以及可扩展性。这里,考虑到青岛大学的实际情况,首先分配成几个大的区域——核心网、西院、东院、师范学院、东校区、中心宿舍区、东校区宿舍区。

在 IPv6 地址分配中,另一个考虑点便是为了容易阅读以及管理,地址应对其到单个字母。因此,从 /48 开始,分配对齐到字母时, prefix 长度应为 52, 56, 60, 64;分别对应第 9、10、11、12 位地址。

为了更好的扩展性,分配地址时,先把地址均等分为 4 或 8 或 16 份,粗略的将每个功能对应的地址数量需求进行整理,并进行分配。结合青岛大学的实际情况,将地址分为八扇区、每扇区为两个 /52 时,可以得到较好的利用。这八个扇区分别为核心网、西院、东院、师范学院、东校区、其他小型园区、宿舍区、互联区。

这种规划方式的好处是,即使当前情况下该功能区域不会用到这么多地址,在之后需要更多地址时,此区块拥有接下来的一部分连续未分配预留地址,也会更方便路由的 summarization. 接下来的楼宇分配也类似。下图为西院的分配表。

Screen Shot 2016-01-10 at 02.20.21

为了帮助追踪以及计算,使用电子表格是个不错的主意。这里,我使用了 =CONCAT(CONCAT('总分配'!$C$19, CONCAT(A6, "::")), CONCAT("/", C6))公式用于计算地址,你可以以它为基础构建你的电子表格。

在部署方面,首先的挑战是 IPv6 本身的支持。这对于我校使用的核心层设备并无任何挑战,华三也类似。

下一个挑战,其实来自于接入层。青岛大学拥有上百台接入层设备,大部分接入层设备的 IOS 版本老旧,因此作为前提条件,自动化升级变成了必要的。解决这个问题的方法有很多,常见的是使用网管软件,但由于没有购买带有这类高级功能的网管软件,因此使用 expect 来进行升级变成了次优解。

由于青岛大学也没有一份权威的接入层交换机列表,因此使用了 snmp 先扫描获取得到了所有的接入层设备列表。

下面的脚本展示了如何登陆交换机并执行命令:

#!/usr/bin/expect

set timeout 5
set hostname [lindex $argv 0]

set username "username"
set password "yourpassword"
set enablepassword "yourenablepassword"

spawn telnet $hostname

expect "Password:" {
  send "$password\n"

  expect ">" {
    send "en\n"
    expect "Password:"
    send "$enablepassword\n"
  }
}

expect "#" {
  send "show version\n"
  send "q\n"
}
interact

可以使用 for host in `cat hosts`; do ./upgrade $host; done 的方式进行处理。

除此之外,遇到的问题还包括互联地址的划分问题。这里的解,目前是使用地址中编码进去 VLAN ID 的。例如 Vlan 1234 = 0x4d2,因此 Vlan 1234 对应 2001:250:5823:04d2,由于 Vlan ID 最大为 4096,因此三位十六进制数正好足够编码 Vlan ID。

graph

目前,运行了一段时间的 IPv6 网络情况正常。

MMSEG 是一个开源的中文分词项目。在我们的应用开发中,我们使用了 mmseg 完成中文分词的任务。本程序是用 C++ 编写的,但是不提供 UNIX 下的 Makefile。
在 Coreseek 项目中包含了一个 mmseg,并提供了 Python 试验程序以及 mmseg 的 GNU Autotools 脚本,可以方便的进行 configure – make – make install 形式的安装。但是,其 Python 绑定并没有提供相应的脚本。为了解决这个问题,我写了一些 Python 脚本辅助进行这项编译过程。
首先,从 Coreseek 项目中下载回 Coreseek,并解包,进行 mmseg 的编译。注意应当先执行./bootstrap
其次,进入 src/css 目录,编译 libcss。这里,我使用的编译脚本如下:
Continue reading

各位校园网用户,
OSQDU一直致力于提供稳定的校园网服务。由于公安部等要求,我们必须使用802.1x方式进行用户准入控制,对UNIX用户以及Linux用户,特别是Ubuntu操作系统的初级用户带来了诸多不便。
经联系华三,我们已经得到了UNIX版本的客户端软件,请在校内访问 http://dormnet.osqdu.org/ 进行下载。包含了Windows, Linux, Mac OS X适用的版本。我们不保证其可用性。
Continue reading

最近我们在继续3P的开发。为了追踪3P的开发,我们还是在用Redmine。发现WEBrick速度慢的无法忍受,老Ruby 1.8内存泄露非常严重,于是选择自己编译Ruby,打内存补丁,升级Redmine,配置Thin以及反向代理服务器。

首先,配置好lighttpd,如何配置不赘述。

然后,编译Ruby 1.8.7。记得打MBARIp72patches(链接被墙)。我的编译参数是

./configure --bindir=/usr/bin --sysconfdir=/etc --includedir=/usr/include --libdir=/usr/lib CFLAGS=-O2 -fno-stack-protector -fomit-frame-pointer

我是很折腾的。-O3似乎速度快不了特别多,而且编译速度慢。考虑到这是个比较便宜的VPS,还是算了吧……

接着,安装Redmine。应当参考Redmine的Wiki内容。简单的说,安装Redmine的步骤是用svn抓回源码包,用RubyGems安装上去依赖,配置好数据库以及邮件服务器。我使用的MySQL,配置文件如下:

production:
  adapter: mysql
  database: DATABASE_NAME
  host: localhost
  username: USER
  password: PASS
  encoding: utf8

请自行修改参数。E-Mail我选择了用sendmail。注意修改sendmail配置文件,否则你的mail服务器被当作垃圾邮件中转服务器了我可不负责任。

生成数据库什么的可以继续参考官方文档。

Thin可以通过rubygems安装。假设你的Redmine/srv/redmine,则使用

thin config -C /srv/redmine/redmine.yml -c /srv/redmine --servers 1 -e production

生成配置文件。

使用thin -C /srv/redmine/redmine.xml -e production启动。如果你看到了下面的东西,请确认rake只有1.0.1版本。使用gems可以卸载其他版本的rake.
web# thin start
>> Using rails adapter
Missing the Rails 2.3.5 gem. Please `gem install -v=2.3.5 rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.

接着,将thin -C /server/redmine/redmine.yml start一行加入启动脚本。

最后,配置lighttpd作为反向代理服务器。这里直接贴出来我的配置:

$HTTP["host"] == "redmine.osqdu.org" {
    $HTTP["url"] =~ "^/((images|stylesheets|javascripts|assets)/(.*)$|(favicon\.ico|robots\.txt))" {
         server.document-root = "/srv/redmine/public/" 
    } 
    proxy.balance = "hash"
    proxy.server  = ( "" => ( ( "host" => "127.0.0.1" ,
                                "port" => "3000"
                             ) )
                    )
}

这样,重载lighttpd配置就可以了。