先说结论,对此产品不是很满意。

今天 FedEx 终于将座椅送到了车库门口。由于疫情,FedEx 往往采取的是和收件人不见面的送货方式,这个椅子 的重量大约是 35.3lb(大约16公斤),加上箱子还是比较重的,故而 FedEx 没有送到需要走三步楼梯也算是可以理解。

前文,今天 台灯终于到货了。

这款台灯使用的是LED(使用了102颗 LED 4014),标称功率为 9W,最大亮度600流明(类似于40W左右的白炽灯泡),采用了铝合金支架。触控开关位于灯的上部。

设计方面,它采用了两枚大的内六角螺丝来固定基座与竖直杆、竖直杆与灯臂之间的连接,以及一枚较小的内六角螺丝来固定灯臂与灯体之间的连接。底座("Desk clamp")与竖直杆("LED arm")之间的连接部分需要将其插入之后拧紧侧面的固定螺丝,插入时可增加一个橡胶圈(自带)来进一步减少其移动范围,不过实际测试中,即使在把相关螺丝全部拧紧以后此支点允许的活动范围依旧偏大,导致此杆的顶部可在一0.3cm左右的范围内活动。

优缺点方面,总体上这款台灯的做工还不错,不过配合27寸显示器时,其顶部控制开关可能不太方便操作(这可以通过下面的翘板开关来绕过),此外价格稍微有些贵。

geli(8)的HMAC设计

| No Comments | No TrackBacks

读到哪算哪的先记一笔。

geli(8)在启用了数据完整性检测的时候采取的设计是将HMAC数据保存在同一扇区中,换言之它在保存数据时,物理扇区(通常是512字节)中占用了32字节来保存HMAC数据。

这样做的考虑是每个扇区可以独立地读写和验证(如果把HMAC数据保存在临近的扇区中,例如每17个扇区一组,将HMAC数据全部保存到其中一个扇区中,则HMAC数据和扇区数据可能会有不同步的问题),代价是会浪费一些存储空间。这个空间的计算如下:

假如磁盘物理上是512字节的扇区,geli提供4096字节的扇区的界质的话,我们浪费的空间是:

  • 每个扇区可以保存 512 - 32 = 480 字节的数据
  • 4096/480=8.533333,向上取整需要9个扇区
  • 480*9-4096=224,即浪费掉了224个字节。

实践上,因为原本需要8个扇区存放的数据需要9个扇区来放,因此空间开销是1/9(大约11%)。

如果可以牺牲独立验证(即,一组扇区中如果有一个坏掉了就认为整组扇区都坏了,而不在意其中具体是哪个坏了),则一个潜在的替代方案是将整组的HMAC数据保存在同一个扇区内,这样一来所需的额外开销是1/16,即使用17个扇区来保存16个扇区的数据(假设扇区尺寸是512。如果扇区尺寸是4k,则是129个扇区可以保存128个扇区的数据)。

这一替代方案的优点是不改变数据扇区的尺寸,并且空间开销小一些(1/17,或1/129)。

我很小的时候就学了打字,在中间还有朱若愚老师的那句"平时多练练打字,比赛的时候除了可以减少自己写代码时出错的机会,还可以直接在心理上对周围的其他选手产生碾压"的加持,在上小学和初中的时候我花了不少的时间去练习,加上后来上学和工作一直都没少和键盘打交道,我一直有一种既然自己打字比大部分人的速度都要快(具体事例是以前在网上聊天吵架被人说你小子复制粘贴算什么好汉),因此指法应该没什么问题的错觉。

最近开始教娃学习指法和盲打,于是自己也拿软件重新练习了一下,才发现这个快背后是有问题的。举例来说,我的无名指因为速度通常会略慢一些,因此打字的时候经常会出现其他手指过来"帮忙"的情况,又比如我在按组合键的时候时常会有单手操作的倾向,而比较好的做法是平衡地使用双手来操作。

目前测试的结论是我对于o、q的准确度最差,此外左手小指和无名指需要加强练习。

声明:本文系纯个人使用观感分享,并非推荐或不推荐购买特定厂商和/或特定产品。

随着本次疫情在美国的爆发,厂里安排了一笔预算来购买办公家具。在同事的推荐下我在 autonomous.ai 下了一单包括升降桌、椅子和台灯在内的家具。

由于物流等一系列因素,在下单时对方即告知订单中的一部分可能会需要一两个月甚至更久才能送到。由于我最需要的是一个升降桌,因此并未特别在意椅子的送达时间。

最先送到的是升降桌上使用的 Cable TraySmartDesk 2 Premium 桌子本身。此系统采用了双马达,装配实际上用了一个小时左右(拆包装、标签、使用说明书)。高度方面,升降桌支持26-51.6英寸的高度,设计承重约300磅(约等于136千克)。

RIP Dr. Bruce Evans

| No Comments | No TrackBacks

Bruce Evans (bde@),那个愿意花时间在你改了三行看似无关紧要代码的时候写上整整两页回信细数为什么这么做不对,之前他们还做过什么以及为什么那么做也不行的老爷子在上周(12月18日)突然去世了。我已经开始想念他了。

RIP。

Google 在十年前提出了一套名为 BeyondCorp 的零信任网络的安全方案。 这套方案想要完整地实现还是有一定门槛的,在这种模型下,企业内网不再作为一个安全边界存在,相反即使在内网进行的访问也必须进行和外网同样的鉴权与访问控制。 最终的改造方向是内网不再是一个特权网络,每个终端上部署的客户端证书主要是作为一项身份信息来使用。

在 BeyondCorp 方案中对用户比较可见的一项便是统一登录认证 SSO 和基于用户身份进行访问控制的反向代理。之前考虑过许多其他方案,包括使用 nginx 自己山寨一套,不过后来听 @yegle 同学的建议, 直接用 Pomerium 来实现了一套鉴权反向代理,这里把大致过程记录一下。

首先是安装。 FreeBSD 没有对应的 port,于是 做了一个。新用户可以直接用 pkg install pomerium 来安装了。

必须配置的一些选项包括 pomerium_enable (显然)。如果使用 Pomerium 来的做 https 服务,那么还需要配置 pomerium_cert_file(指向一个 wildcard 证书)和 pomerium_cert_key_file。除此之外, pomerium_shared_secret 和 pomerium_cookie_secret 应分别设置为两个随机串,不过如果没设置的话系统会自动每次启动时生成新的随机串。需要注意的是,假如需要使用标准的 https 端口 443,如果以系统默认的非特权用户来运行 Pomerium 的话,需要将 net.inet.ip.portrange.reservedhigh 设为小于 443 的值才行。

然后是配置。OAuth 2.0 需要一个回调 URL,Pomerium 中这个可以是 https://authenticate.corp.{example.com}。在 IdP (如 Google、Azure等等)完成身份验证之后,IdP会将用户转回这个URL完成后续的设置。

IdP相关的主要设置是 idp_provider、idp_client_id 和 idp_client_secret,后两项信息要从 IdP 那里获得。如果 IdP 提供了群组功能,可能还需要进行一些额外的设置,例如 G Suite 就要求服务账户必须能够以某种管理员的身份运行。

代理方面,在代理服务器后面受其保护的服务器应 验证 Pomerium 的请求头签名。除此之外,代理的配置其实是很简单的,如果是比较小的系统,用 allowed_users 就足够了。大一些的系统可以用 allowed_domains 和 allowed_groups。另一个潜在的坑是要注意后端服务器不要在做 redirect 时回自己的 URL,如果发生这种情况,需要把后端服务改对或者至少搞一层重写。

许多操作系统会默认系统时钟(主板通过电池驱动的)是UTC,Windows上并不是这样。多系统并存时这会带来一些困扰。

在 64-位 Windows 10 系统中,以管理员身份运行:

reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TimeZoneInformation" /v RealTimeIsUniversal /d 1 /t REG_QWORD /f

即可让 Windows 也把系统时钟当作 UTC 而不是本地时间了。

加州光照充足,在换了油电混合车并安装了空调以后,我目前每年的用电量大约是每年6000 kWh(此前每年的用电量大约是2400 kWh)。随着加州电价的逐年提高,安装太阳能发电终于不再是一件不经济的事情了。

根据贵厂的 Project Sunroof 估计,我家屋顶每年的可用光照时间大约是 1903 小时,其中有 1357 平方英尺(大约126平方米)的面积可以用来安装太阳能板。经过和数家(马老板的 Tesla 即原 SolarCity、 Costco 合作的 SunRun,以及同事推荐的 SunWork)太阳能板安装公司的询价,最终选择了采用 10 块太阳能板、微型逆变器(microinverter)的方案。其中, SunWork 是一家致力于推广太阳能发电的 501(c)(3) 非盈利机构(他们要求客户在12个月内的电费低于 $100;对于使用了电车的用户,这些用户在购买电车之前的12个月内应满足此条件),因此报价比其他供应商低了 1/3 左右。

修复 MySQL 编码问题

| No Comments | No TrackBacks

有个疑似 OCD 患者最近抽风升级了一下 MySQL 数据库,然后发现 blog 里面全都变成了乱码。

那乱码的模式一看就是把 utf8 直接扔进了 latin1 的数据库,一看 SHOW CREATE TABLE mt_entry 发现果然如此。

略有些慌神,看了 MySQL 文档发现用 ALTER TABLE 的 CONVERT TO 硬来有点不太行好,遂想到可以试试看 mysqldump,于是做了:

当作 latin1(不然会再按 utf8 编码一次):

mysqldump mt_delphij --default-character-set=latin1 -r utf8.dump

把里面的 CHARSET=latin1 替换为 CHARSET=utf8:

sed -e s,CHARSET=latin1,CHARSET=utf8,g < utf8.dump > utf8.dump.edited

删掉其中的 SET NAMES latin1。

然后重新导入:

mysql -uroot -p --default-character-set=utf8 mt_delphij
mysql> SET names utf8;
mysql> SOURCE utf8.dump.edited;

还好没用到 zfs rollback。

这也太不注意卫生了

| No Comments | No TrackBacks

razor 同学对于 Xcode ghost 的事情的评价是:这也太不注意卫生了。个人深以为然。

技术细节、影响等等,已经有很多大牛写过很好的文章来介绍。但是我想问的是,这事完了吗?在我看来远远没有,根据有关厂商的介绍,想要装上这个下了马的 Xcode,首先得从 App Store 以外的渠道去下载,其次还得允许运行来自 'Anywhere' 的应用程序,或者开发人员习惯于绕过系统的数字签名检查。

我看到的至少有这么两个问题:1. 开发人员常态化地使用并忽略未经签名的工具(非常不重视卫生,我认为这个事情基本上和一个厨师在上班时间去上厕所,回来工作之前不洗手是一样的性质)。2. 具有这种态度的开发人员同时拥有发布权限(管理者玩忽职守)。

我认为基本上这次出现问题的 iOS 应用开发者都应该进行特别标记,并改进其发布流程之后才允许继续发布新的应用程序。自然,每一个直接导致问题的开发者都是负有责任的,但允许这样问题出现,并在事后用公关稿文过饰非的企业及其管理者更有责任。这种攻击已经持续了数月,到底有多少不同的版本受到影响?也许只有 Apple 能够提供相关数据了。

当然,对于手机应用安全厂商来说,也许这是一次难得的商机,因为 iOS 设备用户和 Apple 之间的信任被这种攻击直接打破了。事实上,国内某前越狱团队已经制作了一款采用企业证书的扫描程序(我并不怀疑该团队提供这样的程序是出于好意,但出于谨慎,个人建议不要使用,因为我们并不知道该团队手中是否拥有更多提权漏洞,或者后续版本是否会做一些其他事情)。

对于最终用户而言,我认为现在应该做的是立即删除非必要的全部应用程序,特别是那些存疑或已经知道出现过问题,而在其公关稿中淡化问题,而没有提出对前面两个问题解决方案的开发者开发的软件,并在确认手机中没有问题应用之后重新设置全部密码。

clang优化器的一个问题

| 1 Comment | No TrackBacks

今天的一个偶然的发现。FreeBSD clang version 3.6.1 (tags/RELEASE_361/final 237755) 20150525。clang 3.8 2015/07/20 的版本同样有此问题。

之前, FreeBSD 上 strndup(3) 的实现是这样的:

char *
strndup(const char *str, size_t n)
{
	size_t len;
	char *copy;

	len = strnlen(str, n);
	if ((copy = malloc(len + 1)) == NULL)
		return (NULL);
	memcpy(copy, str, len);
	copy[len] = '\0';
	return (copy);
}

而 OpenBSD 上的实现,则是这样的:

char *
strndup(const char *str, size_t maxlen)
{
	char *copy;
	size_t len;

	len = strnlen(str, maxlen);
	copy = malloc(len + 1);
	if (copy != NULL) {
		(void)memcpy(copy, str, len);
		copy[len] = '\0';
	}

	return copy;
}

Monthly Archives

Pages

OpenID accepted here Learn more about OpenID
Powered by Movable Type 5.2.11