delphij's Chaos
选择chaos这个词是因为~~实在很难找到一个更合适的词来形容这儿了……
续前。
除了硬件上直接采用的降噪措施之外,一些软件方面的配置也可以提高其效果。
首先是BIOS中的配置。风扇转速最低可调整为"Energy Saving"(即使用30%的频率)。启用Active Power State之后,可节省大约2W左右的耗电(这个选项的默认值是Disabled)。
然后是FreeBSD本身的配置。我个人采用的配置包括:
上述设置,除了ahci部分之外,可将系统闲置时的功耗降低到17W左右。
以下是实现中采用的loader.conf相关的部分:
hint.apic.0.clock=0
hint.atrtc.0.clock=0
hw.pci.do_power_nodriver=3
hint.ahcich.0.pm_level=5
hint.ahcich.1.pm_level=5
hint.ahcich.2.pm_level=5
hint.ahcich.3.pm_level=5
hint.ahcich.4.pm_level=5
hint.ahcich.5.pm_level=5
最近遇到一些奇怪的bug,因为是对恢复时间有比较高要求的系统,所以顺便研究了一下用FreeBSD的textdump来代替更早前出现的minidump的方法。
minidump是2004年初提出的,FreeBSD 6.2-RELEASE开始加入了这个功能,并且在7.x开始默认启用。具体原理是在panic时做dump的时候只存储那些映射为内核内存的物理内存页。这种做法实际上是赌VM的页表在崩溃的时候没有被写坏(绝大多数情况下这是成立的,除非在调试VM本身)。
UPDATE: 杨总 说,Solaris上有一个叫 Fast Crash Dump 的功能。看了一下介绍,是在dump的时候用指定的压缩算法去压缩再转存。先记一笔。
textdump是Robert N. M. Watson在2008年提出的一个新概念,从7.0-RELEASE开始引入:
在编译内核时,需要加入内核调试器。
指定的 ddb 脚本可以挂在某个特定的事件上,比如 panic 进入 kdb 时自动执行
系统提供一个默认的ddb脚本,保存下面这些信息:
启用textdump是需要内核调试器的,因此有一定的安全风险,例如可以从控制台进入ddb。使用时的内核编译配置是options KDB、 DDB和SC_DISABLE_KDBKEY(禁止在控制台热键呼出调试器),然后在 /etc/rc.conf 中加入 ddb_enable=“YES” 令系统在引导过程中将ddb脚本汇入内核,并指定dumpdev。
需要注意的是目前textdump与KDB_UNATTENDED不兼容,因为后者会令内核不调用调试器而直接重启。
textdump保存的内容非常少,因此可以大大减少dump所需的时间。
Read more...最近找时间做了一个家用的路由器。用基于 Intel Atom 处理器的解决方案并不便宜(与传统的嵌入式解决方案相比),但因为软硬件都是 x86,因此开发起来会方便一些。另一方面,Atom的计算性能要远高于其他的传统嵌入式方案。
配置:
SMCI这款X7SPA-H主板采用的是ICH9R芯片组,有6个SATA接口,支持AHCI。采用4G内存的原因主要是希望使用ZFS,同时作为存储服务器使用。由于空间原因,这款CPU使用被动散热片。
PC-781机箱可以配置外接的直流电源(类似笔记本的电源)。采用这种配置的考虑是外接电源不需要使用风扇散热,整个机箱总共只有1个小风扇(题外话:因为功率不大,实际上这个风扇并不是必须的),从而减少噪声。
由于没有光驱,因此使用U盘以memstick映像来安装。在 sysinstall 中选 FixIt » USB 之后就可以手动安装了。
关于磁盘布局:WD AV-25使用的是WD的"Advanced Format",即4k扇区的格式。由于对系统而言扇区仍然是512字节,因此在分区时应以8扇区对齐。这块硬盘的GPT分区为:
34开始,94扇区:boot
128开始,16777216扇区:swap
16777344开始到结尾:zfs
(待续)
Read more...早期版本的 FreeBSD 有一个问题是,如果使用 ntpd 来校准系统时钟的话,如果长期开机,则在重启之后,时间会差很远,之前一直没仔细研究这个问题。最近突然发现 FreeBSD 8.1-RELEASE 里面没有这个问题了,于是翻看了一下代码和之前的一些邮件才明白是怎么回事,总结一下:
一般来说操作系统在引导以后会自行维护时钟,简单地说,就是操作系统根据某个时钟源,例如单CPU系统中的TSC,或多CPU系统中比较常用的高精度事件计时器HPET等等,计算出时间的流逝并修改系统时间。只有在系统刚刚引导的时候,才会直接取 RTC 时间(在关机时,主板上的电池仍可维持 RTC 电路的计时功能)。
我们知道,任何测量工具都是有误差的,普通的 PC 系统上配置的计时装置肯定不会做的非常精密,这也是我们为什么要运行 ntpd 的主要原因。在系统运行的过程中,这些误差不断地积累,使用 ntpd 时,系统可以计算出所采用的时钟源与实际的时间之间的误差,并逐步调整时间源的计数周期与实际时间的比例,从而维持系统时钟的精确性。
在重启时,在内存中维护的系统时刻数据便随之丢弃了,操作系统再次启动时读取的是先前未经修正过的、继续在积累误差的 RTC 时间数据(注意:RTC是不依赖于OS运行的;OS可以修改其时刻数据,但无论开机还是关机,只要维持其需要的电流即可确保 RTC 继续自行更新,而无需 OS 干预)。
FreeBSD先前的实现中,只有非常少的地方调用了 resettodr(9) 来修正 RTC 时间,这些地方主要是settimeofday()之类的直接设置内核时刻数据的点,而对于 ntp 的情况,则没有相应的处理。
新的实现 (以r207360为主体,包含r207359, r207362)则增加了一个callout,每半小时将系统时钟刷回RTC一次,从而解决了这个问题。
关于为什么不应该使用 ntpdate 来对时(ntpdate会使用settimeofday()),请参考 A core 的 这篇 介绍 NTP 的文章,以及我的 这篇 文章。
Read more...这几天改 FreeBSD 的 coretemp(4) 遇到了一个问题。直接使用 rdmsr 的话,如果那个 MSR 不存在,则会触发 #GP(0),不了解 CPU 型号的情况下直接去杵肯定是不行的。后来翻了一下 cpuctl(4) 的代码发现 FreeBSD 上也有 rdmsr_safe。它的实现并不复杂( sys/amd64/amd64/support.S):
movq PCPU(CURPCB),%r8 // %r8 = PCPU(CURPCB); 将当前CPU的编号保存到r8。
movq $msr_onfault,PCB_ONFAULT(%r8) // 设置发生异常时调用msr_onfault。
然后是翻译 AMD64 ABI:
movl %edi,%ecx // 参数1放到ecx
rdmsr // 实际执行rdmsr(将ecx指定的MSR的高、低32bit结果放到edx、eax中)
salq $32,%rdx // rdx <<= 32
movl %eax,%eax // 将rax最高32 bit清零
orq %rdx,%rax // rax |= rdx
movq %rax,(%rsi) // rax 存入 *rsi
xorq %rax,%rax // 返回值默认为0
最后恢复先前的异常处理状态。
Read more...SSH提供了很多种不同的身份验证,其中最常用的两种便是密码验证和基于公钥/私钥的身份验证。
基于公钥/私钥的身份验证有非常多的优点。
首先,公钥/私钥可以从根本上挫败监听来截取验证信息的企图。
公钥/私钥验证本质上是一种 零知识证明。即,在身份验证的过程中,服务器并不需要知道用户的私钥是什么。【注:公钥/私钥验证并不是零知识证明,感谢 snnn 指正。】
公钥/私钥验证在身份验证的过程中,服务器只需要知道用户的公钥,而用户则使用自己的私钥对一组数据签名,并在服务器端进行验证。服务器并不需要知道用户的私钥。目前为止,还没有有效的方法能从这些信息推导出私钥。
与密码相比,这种方法有显著的优点:在验证身份的那一方,没有任何办法可以拿到用户的私钥,即使获得了那台机器的root权限。验证信息只能使用一次—-这意味着,也没有办法把这个验证信息用于在其他地方再次验证身份。
其次,公钥/私钥要比密码长的多,因而可以挫败通过穷举的方式破解的可能性。
典型的密码是8位字符,假设可以使用大小写字母、数字和特殊符号,可选的范围无非是96^8而已,我们不妨算它128^8。典型的私钥有2048个bit,如果按7个来分组的话,有128^(2048/7)。当然,最高位和最低位一定是1,但向下取整,也有128^292种。
最后,除了吃点带宽之外,SSH口令穷举对于仅采用公钥/私钥验证的服务器安全不构成任何威胁。
通过适当的配置sshd,可以让其直接明确地告诉对方此处不支持口令验证,并且能够容易地将攻击者记录在案,并将数据反馈给防火墙来减少带宽的占用。
Read more...本文主要是笔记,不保证其正确性,也不保证其不导致死机、崩溃或任何其他问题。
CPU的Tj(max)值可以通过读 MSR IA32_TEMPERATURE_TARGET,即 0x1a2 来获得【1】。目前,Intel正式的开发文档中并没有明确对这一MSR进行说明。早期的CPU中,Tj(max)值需要加上40到50摄氏度,目前不清楚具体哪些CPU必须如此,但从公开文档来看,已知:
Xeon 7100系列需要加修正值。其中,150W TDP的CPU需要加50摄氏度;95W TDP的CPU需要加40摄氏度。【2】
Xeon 5200系列不需要加修正值。【3】从文字上推测,5200以后的系列都不需要加修正值。
Xeon 5400系列不需要加修正值。【4】
使用LGA771 SMT socket、L3 cache不超过8M的Xeon MP系列需要加修正值50摄氏度。【5】
双核 Xeon 2.8G 处理器(根据文档推测,Prescott、Nocona和Potomac系列)需要加修正值50摄氏度。【6】
系统总线800MHz的Xeon处理器需要加修正值50摄氏度。【7】
双核Xeon 5000系列需要加修正值60摄氏度(没错,是60摄氏度,不是50摄氏度)。【8】
Xeon 7400系列不需要加修正值。【9】
支持超线程的Mobile Pentium 4处理器需要加修正值50摄氏度,同时,这个值的范围是0-30摄氏度。【10】
姑且推断5200系列之后不需要修正值?(model 0x17之后)能够公开获得的文献中,提到这个寄存器最早的一份是2004年6月出的第一版。
FreeBSD目前不支持从这个MSR直接搞Tj(max)温度出来,我做了个patch,测试了Xeon L5630和Core i7 CPU,不过其他的暂时还没测过。
Linux驱动这部分逻辑很让人费解(drivers/hwmon/coretemp.c):如果读MSR得到了有效的值(80-120之间,而文档【1】上说的至少70度是存在的。如果读MSR失败,或驱动认为值无效,则用了一套相当奇怪的逻辑去猜测实际的数值,某些型号的Atom使用旧的逻辑去判断,等等。问题是(1)这段相当的混乱,而且与文档有很多不一致的地方;(2)为什么不先判断CPU型号再访问MSR呢?
参考文献
【1】CPU Monitoring With DTS/PECI。Intel 文档编号322683。
【2】Dual-Core Intel® Xeon® Processor 7100 Series Datasheet.Intel 文档编号314553。
【3】Dual-Core Intel® Xeon® Processor 5200 Series in Embedded Applications, Thermal/Mechanical Design Guidelines。Intel文档编号319012。
【4】Quad-Core Intel® Xeon® Processor 5400 Series, Thermal/Mechanical Design Guidelines。Intel文档编号318611。
Read more...“如果我当年去问顾客他们想要什么,他们肯定会告诉我:‘一匹更快的马。’” 这告诉我们:顾客的意见虽然重要,但是只问用户的意见是做不出突破性的新产品的。
Read more...FreeBSDChina 最近又出现了很多垃圾广告等信息。针对一些常见的灌水机实现了一些临时的workaround,并且删除了大约3万2千的用户。
越忙越有人添乱。
补充:为论坛的链接增加了 rel=“nofollow” 的标记。
Read more...nginx可以作为很多种不同的用途。对Web服务器来说,nginx可以直接用作https服务器,也可以用于为现有的http Web服务器作为前端代理和负载平衡的同时提供https之用。
nginx支持TLS协议的SNI扩展(Server Name Indication,简单地说这个扩展使得在同一个IP上可以以不同的证书serv不同的域名;较早前唯一的办法是签署一个通配证书,即 CNAME 中为 *.delphij.net 这样的证书)。不过,SNI扩展还必须有客户端的支持,另外本地的密码学函数库,例如OpenSSL也必须支持它。
如果启用了SSL支持,nginx便会自动识别OpenSSL并启用SNI。是否启用SNI支持,是在编译时由当时的 ssl.h 决定的(SSL_CTRL_SET_TLSEXT_HOSTNAME),如果编译时使用的OpenSSL库支持SNI,则目标系统的OpenSSL库只要支持它就可以正常使用SNI了。
FreeBSD 8.0起的所有版本附带的OpenSSL均启用了SNI支持。这一特性是OpenSSL 1.0才开始默认启用的新功能,如果系统不是 FreeBSD 并且采用的是较早版本的 OpenSSL, 可能需要自行重新编译,并在config的时候指定enable-tlsext。注意:OpenSSL在多数系统中都有重要的其他用途,重新安装OpenSSL时,最好不要与厂商采用的参数差别太大;另外还有一种解决办法是安装到不同的目录并在运行程序的时候指定搜索路径或静态联编;FreeBSD不需要做这些配置,故不再赘述。
检查nginx是否支持SNI的方法是使用 nginx -V
来查看。
nginx version: nginx/0.8.45
__TLS SNI support enabled__
configure arguments: --prefix=/usr/local/etc/nginx --with-cc-opt='-I /usr/local/include' --with-ld-opt='-L /usr/local/lib' --conf-path=/usr/local/etc/nginx/nginx.conf --sbin-path=/usr/local/sbin/nginx --pid-path=/var/run/nginx.pid --error-log-path=/var/log/nginx-error.log --user=www --group=www --with-ipv6 --http-client-body-temp-path=/var/tmp/nginx/client_body_temp --http-fastcgi-temp-path=/var/tmp/nginx/fastcgi_temp --http-proxy-temp-path=/var/tmp/nginx/proxy_temp --http-scgi-temp-path=/var/tmp/nginx/scgi_temp --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi_temp --http-log-path=/var/log/nginx-access.log --with-http_gzip_static_module --with-http_ssl_module --with-http_stub_status_module --with-pcre
以上标红的一行表示以目前的方式运行nginx时可以使用SNI。
使用SNI并不需要额外的配置,对nginx来说只需和HTTP主机一样配置多个https主机的server配置段即可。
以下是nginx中用于TLS的配置。可将其保存为一个单独的文件,例如 tls_param:
listen 443; # 端口(IPv4)
listen [::]:443; # 端口(IPv6)
ssl on; # 启用SSL
ssl_session_timeout 5m; # SSL会话超时时间
ssl_protocols TLSv1; # 只启用TLSv1
ssl_ciphers TLSv1:+HIGH:-MEDIUM:-LOW:-EXPORT:-aNULL:-eNULL:@STRENGTH # 启用的加密算法,见下
ssl_prefer_server_ciphers on; # 协商时优先使用服务器指定的加密算法
采用的加密算法集具体请参见 OpenSSL 联机手册 ciphers(1)。这里只解释采用的选项:
Read more...