我选择的是 512GB 的版本,主要考虑是 Vision Pro 上的一些软件/游戏可能会有更多的 3D 场景,会更消耗存储空间。但大多数时候又是在 Wi-Fi 环境下使用,所以 1TB 版本又没有那么有必要。
本人之前没有使用过其他 VR/AR 类产品(排除 Google Cardboard😂),所以并没有感觉到 Vision Pro 有多么的好。相反,我的感觉是 Vision Pro 的显示效果其实完全无法代替 Studio Display。与其它类型的显示器相比,它有这些特点
清晰度:5K 显示器有着明显锐利的多的画面,并且能肉眼感觉到显示器的色彩空间也更好。目前看来 Vision Pro 的显示清晰度大约相当于 2.5K 的水平,显示效果:高端显示器 >> Vision Pro > 高端投影。仔细观察,我是可以看到 Vision Pro 中的像素的。我的视力也并非完美水平,处于轻微近视,在不配矫正镜片的时候依然能察觉到像素。
HDR 效果:得益于 micro-LED,HDR 效果还是相对突出的,好于显示器和投影,但高光的亮度又比不过 iPhone 的 OLED 或者是 MacBook Pro 的 miniLED。
自适应的渲染:之前的清晰度是我将窗口调整到我平时操作显示器的大小时进行的比较。但 Vision Pro 的窗口是可以调节的,包括远近和大小。此外,眼镜在物理世界里的位移也会影响到显示:当你贴近时,可以看到更清晰的画面。如果说视网膜屏幕是 @2x-@3x,那么 Vision Pro 则是 @1x-@9x(9x是打个比方)。Vision Pro 中的所有系统UI(包括网页上的SVG/文字)都是矢量渲染的,不需要 Zoom In,只需要人走进显示区域,就会发现每一个小字/矢量图都会变的无限清晰。
亮度:感觉达不到 500nits,如果在白天摘下眼镜,会明显感觉到真实世界更亮。但这一点不是特别影响体验。
透视的清晰度则是远差于 UI 显示的清晰度,摄像头的分辨率其实不高,看真实世界完全到不了 4K 水平。但可以感觉到其曝光控制非常优秀,画面里没有过曝或者欠曝,是可以戴着它生活的(如吃饭)。但无法使用它阅读小一点的文字(过于模糊,无法阅读;比如食品配料表或者手机上的小字都是看不清的)
透视效果属于能用的水平,在家里时我佩戴并四处走动是没有任何问题的。
一开始使用 Solo Band 的时候用久了还是挺不舒服的,但我现在换用 Dual Loop 并仔细调整后,发现比刚开始戴的时候舒服了非常多,感觉用个一两小时是没问题的。Dual Loop 有两个地方可以调整,建议多试,太紧或者太松都会导致不舒服。躺着用反而不舒服,比较压脸颊。重量肯定是能感知到的,希望有一天可以做到跟眼镜一样轻。
操控总体而言比较方便,如果Mac的触摸板操控是 10/10 分,iPad 算 9/10 分的话,Vision Pro 现阶段已经能达到 8.5/10 分(除打字外)。滚动非常跟手,滚动是有高刷的感觉的,明显好于 60Hz。但有时候手放在了摄像头看不见的位置(比如桌子下面),这种神奇的体验就没了,然后就会想起:啊,原来是摄像头捕捉的我的手势。
除了捏合 🤌 控制,直接点击按钮也是可以交互的,把窗口“拉近”,然后像iPad那样拿食指直接点空中屏幕就可以操作,对电脑版网站按钮很小的还是很有用的。YouTube 网页版就属于适配的不那么好的网站之一,有一些按钮之间离得近,用点击的方式会更方便。
对于 iPad compatible 应用,操控体验也还不错。非常多软件(包括苹果曾经宣传过支持 Vision Pro 的 Apps),其实都只是 iPad compatible 版。试了 iPad 版的:Lightroom 、Paramount+、Maps 等,会发现 iPad 版的 App 体验已经惊人的好了。最大问题还是 Typing 体验差。细想起来,苹果在 iPad 上加的前台调度、鼠标指针、Apple Pencil 的 Hover 功能,都跟 Vision Pro 的交互惊人的相似,所以支持了以上功能的 iPad Apps 在 Vision Pro 上体验很好。
打字的话现在我最喜欢的方式是用双手食指点键盘。现在已经逐渐习惯了,但还是差于iPhone的小屏幕键盘。蓝牙键盘还有待尝试。
用久了 Vision Pro 后,每当我在现实世界里看到个屏幕觉得离我远/位置不对,就想要 🤌 把它调整下,但却发现不行 😂。感觉这会是未来人下意识的一种手势,类似刘慈欣三体里描述的情形。
软件我感觉只做到了苹果的后期 Beta 水平,还算不上正式版。首先就是目前只能输入英文,其他任何语言的输入(比如中文)都不支持,包括键盘和 Siri 语音。其次就是我发现 visionOS 1.0.2 并不支持 iOS 17.2 推出的 iMessage 信息联系人密钥验证。这点其实 Xcode 也已经暗示了:如果在 Xcode 15.2 中将软件的 Minimum Deployment 设置为 17.2,那软件将无法在 visionOS 1.0.2 中运行。因此得出结论:visionOS 1.0.2 = iOS 7.1。这点就可以看出 Apple 发布 Vision Pro 还是很急的,或许是苹果觉得 visionOS 1.1 的 Bug 太多了,所以苹果就没有发布,导致了现在功能不匹配。顺便一提:iOS 17.1 发布时间是 2023 年 10 月 25 日,iOS 17.2 发布时间是 2023 年 12 月 11 日。
没有任何外接 USB 的能力,这点比 iPhone 和 iPad 都差。因此 Vision Pro 也不支持 YubiKey 5C NFC,因为既没有 USB 口,也没有 NFC。如果你想登录一个网站但你只配置了 YubiKey,那抱歉,登录不了。当然 Passkey 是支持的。
很多人对扩展 Mac 屏幕很感兴趣。个人觉得扩展屏幕体验还是远差于真正的显示器的。同样价格可以买到比 Vision Pro 显示效果好得多的显示器。但如果你主打的是便携,比如希望在飞机上、酒店里也有显示器,或者希望隐私,比如不想让其他人看到你的屏幕,那它还有点用。
个人感觉 Vision Pro 显示效果是略差于中端 4K 显示器($1000 美元左右)的。延迟也还是有的,具体体验可以参考 iPad 作为扩展屏的延迟。我个人不会拿 Vision Pro 主要作这个用途。
属于能用,但只还原了人脸的 90-95%。已经有点恐怖谷效应了。有总是比没有强的,我觉得我使用它参加视频会议不会特别尴尬。
坐车使用完全不可行,哪怕启用了 Travel Mode,至少小汽车是不行的。首先Vision Pro会错误定位,因为窗户的存在,有时会认为你在快速移动,有时则定位失败。但这个其实好说,属于软件问题,但下一个问题就是物理问题了:就是因为它比较重,在有颠簸车上受加速度影响脸部会异常难受。因此起飞/降落/Taxiing/气流颠簸时都不建议用,小心脸疼。
因此坐车时还是 iPhone/iPad 体验更好。我以后不会在坐车时使用 Vision Pro。
EyeSight 非常鸡肋,亮度很低并且分辨率也很低。iFixit 的拆解也得出了原因,是为了还原眼镜的 3D 效果不得不做出的妥协。眼睛的还原必须是立体的,不然外人将无法知道你在看谁。
我认为 Vision Pro 已经接近成熟了,软件上已经达到了最后一个 Beta 版本的可用性。软件上相对欠缺,但我觉得未来几个月内会迅速弥补上。
]]>TL;DR 考虑到成本和最大容量问题,我使用 iCloud 作为小数据的 “热备份”,使用 S3 作为大文件的 “冷备份”
在进入正题前,我们来对比一下目前市面上的几个存储方案,这里只对比面向个人的存储方案;你也可以直接跳到 Nextcloud 章节。Google Workspace、Apple Business 等面向企业的存储方案往往溢价更高,这里不再做对比。这里所展示的价格为美国区不含税的价格。一些服务会对其他国家有价格歧视 (低价区),这不是本文所讨论的范围。
提供商 | 容量 | 价格 (美元) | 单价 (美元/TB/月) |
---|---|---|---|
iCloud | 50GB | 0.99 | 19.80 |
200GB | 2.99 | 14.95 | |
2TB | 9.99 | 5.00 | |
Google Drive 1 | 100G | 1.99 | 19.90 |
200G | 2.99 | 14.95 | |
2TB | 9.99 | 5.00 | |
OneDrive 1 | 100GB | 1.99 | 19.90 |
1TB | 6.99 | 6.99 | |
6TB 2 | 9.99 | 1.67 | |
Dropbox | 2TB | 11.99 | 6.00 |
3TB | 19.99 | 6.66 | |
Mega | 400GB 3 | 5.41 | 13.53 |
2TB 3 | 10.84 | 5.42 | |
8TB 3 | 21.68 | 2.71 | |
16TB 3 | 32.53 | 2.03 | |
Pay-as-you-go 4 | 16.27/3TB 起 | 2.71 | |
Adobe Creative Cloud 4 | 2TB | 9.99 | 5.00 |
4TB | 19.99 | 5.00 | |
10TB | 49.99 | 5.00 | |
20TB | 99.99 | 5.00 |
- 使用年费方案,Google Drive 和 OneDrive 会更便宜一些,详情参见官网。
- OneDrive 并不提供 6TB 的个人套餐。该套餐为家庭套餐,可供 6 个账户使用,每个账户提供 1TB 存储空间。
- Mega 的流量是有所限制的,详情参见官网
- Adobe 需要配合其他订阅 (至少 $9.99/月) 才可以购买空间
苹果和谷歌都提供了 $9.99/2TB/月 的存储方案,2TB 对于绝大多数人已经够用,甚至还有点多。苹果和谷歌的更高级的套餐可以与包含自己在内的 6 个人进行共享。微软提供了 $6.99/1TB/月的存储方案,该方案还包含了 Office 套件。相比之下,微软的家庭版套餐提供更高的总容量,但每人限制 1TB 而非 6TB 共享,使得其不是那么的灵活。
根据自己的使用习惯,苹果、谷歌和微软可能也没有多少选择。如果全家都是苹果全家桶用户,那么就直接苹果的 2TB 家人共享就很合适。如果是 Windows 用户,同时是 Office 使用者,那微软的方案是最合适的。如果是 Google Photos 的用户,或者经常使用 Google Workspace 来写文档,那么选择谷歌是更好的。
此外,苹果最新的系统中可以开启 iCloud 端到端加密,开启后所有文件、照片都是端到端加密的。而上述其他的服务商则可能不提供端到端加密,或者是只有部分文件夹是端到端加密。
Dropbox 的跨平台做的不错,我用过它的 Mac 和 Windows 客户端,都非常高效好用。我曾经在 Mac 上使用微软的 OneDrive,体验就极其糟糕。
Google Workspace、Dropbox Teams 则提供了所谓 “无限容量” 的套餐,但所谓无限容量,其实是价格不透明。当使用量足够大的时候,不排除被限制的情况。因此本文只对比有明确标明容量和价格的套餐。
如果需要更大的套餐 (>2TB),那么可以将目光转向 Mega。Mega 提供单位价格更低的网盘服务,同时支持完整的端到端加密。
值得一提的是,Mega 最近也推出了 Pro Flexi 套餐,起价 €15.00/3TB/月,在此基础上 €2.50/TB(流量也是 €2.50/TB),最高可以用到 10,000TB。
如果你使用 Lightroom CC 管理照片,且你的照片是存储大户;或者使用 Premiere Rush 剪辑视频,并且视频是存储大户,那可以选择 Adobe Creative Cloud 的存储空间,最高可以存储 20TB。
如果 2TB 对你而言足够,且在可预见的未来也不会很快超过 2TB 的存储需求,那么直接选苹果、谷歌、微软、Dropbox 中的一个就行了。如果有大量的 RAW 照片需要存储,那么 Adobe Lightroom CC 则是不错的选择,$9.99/月的 Lightroom 就包含了 1TB 存储空间,加到 $19.99/月就可以有 3TB 存储空间,能随时随地访问到整个图库还是很方便的。
我就有在用苹果的 2TB 套餐,用 iCloud 同步一些小,但经常访问的文件还是很方便的。我也用 iCloud Photos 来同步 iPhone 拍摄的照片和视频,以及导出的全尺寸的 JPEG 和剪辑后的视频。此外,我还用 iCloud 对我的 iOS 设备进行备份。iCloud 是我的 “热备份”。
此时我还需要备份相机录制的 MP4、RAW 视频和 RAW 图片,这些文件有数 TB,并且每年还会以几百 GB 的速度增长。这些文件通常不需要随时访问,此时就需要 “冷备份” 了。我体验过一年 1TB 的 Lightroom CC,1TB 的容量对我而言虽然够用,但我的存储量还是会持续增长,不想将来不停的升级到越来越贵的套餐。因此最近又换成了同样价格的 Photography Plan,少了 1TB 的云存储,但多了 Photoshop。
我没有怎么体验过 Mega,但 Mega 确实也曾在我的考虑范围内。最终我没有选择 Mega 的原因是因为它不够便宜。的确,$2.03/TB/月的 16TB 套餐是很便宜了,但如果你只需要用 9TB 呢?此时还是得订阅 16TB 的套餐。而且哪怕用到 16TB,它还是比 S3 Glacier Deep Archive 贵了一倍多。
因此我选择了部署在 Lightsail 上的 Nextcloud 作为冷备份的系统,S3 作为存储后端。同时通过 S3 桶生命周期,实现智能调整文件的存储级别,实现了最低 $0.99/TB/月的云存储。Nextcloud 可以选择开启试验性功能 “Virtual File Support”,可以有选择性的同步文件。(Mac 上需要修改 ~/Library/Preferences/Nextcloud/nextcloud.cfg
,在 [General]
下增加 showExperimentalOptions=true
)
我使用的图像编辑软件是 Adobe Lightroom Classic,我的所有 RAW 照片都是用 Lightroom 管理,原图存储在 Nextcloud 同步的文件夹中。我使用 Lightroom 对所有图像生成了 Smart Preview。在本地空间不足,Nextcloud 清除了老文件时,仍可以使用 Smart Preview 预览和编辑图片,并导出小尺寸的图片。Lightroom Classic 也可以通过 Adobe Creative Cloud,将 Smart Preview 同步到支持移动端的 Lightroom CC 上。这部分的 Smart Preview 是不占用 Adobe 的云空间的。Lightroom Catalog 我存放在本地的默认位置,但其备份存储在 iCloud。
视频剪辑软件我使用的是 Final Cut Pro,我的相机产生的所有视频都使用 Final Cut Pro 管理。Final Cut Pro 可以配置资料库中媒体的存放位置,我将其设置为 Nextcloud 的文件夹。这也是主要占空间的文件。Final Cut Pro 的资料库我存放在本地,其备份存储在 iCloud。
前年的时候,我在Mac mini 有什么用?组建家庭服务器! 里提到我使用 Mac mini 作为 NAS 使用。但当时我只是用它来进行备份,而非云存储。如果用自建 NAS 做云存储的话,出门在外访问则很成问题:最主要的就是受到 NAS 所在网络的上传速度限制,从而体验很差。在我的印象里,哪怕是成熟的 NAS 解决方案,也没有一个 NAS 能提供像 Dropbox 这样好用的全平台客户端。此外,单个的 NAS 并不可靠,因为它没有在物理上跨区域。NAS 中的硬盘也有购置成本,硬盘老化后也有更换成本,自己维护起来还有时间成本,最终未必划算。
如今,我把我的所有文件都放到了云存储,不再需要备份,因此也不再需要用 NAS 再备份一遍云存储中的东西了,只用来做 Mac 的 Time Machine。
Nextcloud 是一整套自建云存储的开源解决方案,从服务端到客户端均有,并仍在持续更新中。跟它极为相近的还有 ownCloud 也是可选的方案。本文将简单介绍我选择的 Nextcloud。不过既然使用 S3 了,为什么还需要服务端?为什么不在本地直接使用 S3 备份工具/挂载工具?因为我是想自建一个类似 Dropbox 的云存储,可多个设备本地实时的同步,没有额外服务端是实现不了或者很难实现的。
为 Nextcloud 选择一个服务器尤为重要。这里我选择 Lightsail 的原因是,Lightsail 可以与 S3 在同一个区域 (Region),之间的延迟很低,并且 Lightsail 与同可用区的 S3 之间的流量是免费的。此外,Lightsail 的很便宜的套餐也有很多的流量可以使用。
我在云服务推荐及选择指南这个文章中也列举了一些其他服务商,他们也可以作为替代 Lightsail 的选择。虽然他们并没有连接 S3 的优势,但一些服务商有提供自己的对象存储解决方案(比如 BuyVM 提供 Block Storage Slab,Google Cloud 提供 Cloud Storage 等)。
除了亚马逊的 S3 外,微软 Azure、谷歌云也提供与 S3 类似的对象存储。微软 Azure 的 Archive 与 S3 Glacier Deep Archive 在功能和价格上都十分相似,在此不再额外介绍 Azure 的对象存储。谷歌云则有些不一样,我在这里对比一下价格。这里以最便宜的区域为例:
冷存储 | S3 Glacier | S3 Glacier | ||
---|---|---|---|---|
级别名称 | Deep Archive | Instant Retrieval | Archive | Coldline |
单价 (美元/TB/月) | 0.99 | 4.00 | 1.20 | 4.00 |
最短存储周期(天) | 180 | 90 | 365 | 90 |
立即取回价格(美元/TB) | 不支持 | 20 | 50 | 20 |
12 小时取回价格(美元/TB) | 20 | 不支持 | 不支持 | 不支持 |
48 小时取回价格(美元/TB) | 2.5 | 不支持 | 不支持 | 不支持 |
流量传输到公网费用(美元/TB) | 90 | 90 | 1201 | 1201 |
- 传输到中国大陆地区为 $230/TB,传输到澳洲为 $190/TB。下面计算费用是以其他地区的 $120/TB 计算的。
假设需要存储 10 TB 的文件 10 年,S3 Glacier Deep Archive 的总费用为 $0.99 x 12 x 10 = $118.8;Google Archive 的总费用为 $1.20 x 12 x 10 = $144;S3 Glacier Instant Retrieval 或 Google Coldline 的总费用为 $4.00 x 12 x 10 = $480。
所以,对于不需要立即访问的文件,S3 Glacier Deep Archive有着绝对价格优势。但如果有立即访问的需求,S3 的 Glacier Deep Archive 是不支持的,Glacier Instant Retrieval 存储费用相比 Google 更贵,但取回费用相比 Google 更便宜。
由于 S3 的 Glacier Deep Archive 更加便宜,因此我最终选择了 S3。
Lightsail 我选择了 $5/月的套餐,这个套餐是最具性价比的,包含了 2TB 的流量,同时 CPU 基线也来到了 10%。我这几天实际体验下来,Nextcloud 在不间断上传文件时 CPU 占用在 15-20% 左右,其他时候保持同步占用仅为 1%。也就是说每天可以有 12 小时的上传文件。
Nextcloud 的安装参考 Nextcloud 官网即可。我使用的是 Ubuntu 22.04,官网上给出了这个发行版的安装指南。安装完成后,可以参考 Server tuning 进行优化。我配置了 Redis 和 APCu,开启了 JIT 等,减少 CPU 负载。
Nextcloud 可以选择将 S3 作为 Primary Storage。我不推荐这种做法,因为 S3 作为 Primary Storage 时,S3 存储桶里只保存文件本身,不包含文件的元数据 (包括文件名、目录,因为此时元数据只存在于数据库中),也就是说这时的 S3 的桶是不能直接访问的,只能通过 Nextcloud 访问文件。此外,将 S3 作为 Primary Storage 还会导致性能下降,因为 Nextcloud 会将分段上传的临时文件和 App data 也存在 S3 中,分段上传大文件 CPU 占用极大,且经常出现超时 (已经提优化 issue,欢迎点赞支持)。
Nextcloud 还提供 External Storage 功能,安装完毕后,通过 External Storage 挂载的 S3,其文件结构是保留的,也就是说此时 S3 的存储桶是可以直接访问的。我觉得这个还是很重要的,省去了我备份 Nextcloud 数据库的烦恼。此时就算 Nextcloud 整个实例挂了,我的所有文件都可以在 S3 存储桶里访问。如果将 External Storage 的挂载点配置为 /
,那么根目录下所有文件和文件夹都是和 S3 同步的,十分方便。
此外,我会关闭 Nextcloud 的 Deleted Files 功能,并通过 S3 Versioning 实现版本管理。因为 Deleted Files 开启后,删除文件时,Nextcloud 会将 External Storage 中的文件移动到本地,这样会费时、费钱且占用本地空间。
尽管已经通过 External Storage 将所有文件存储在 S3,但 Nextcloud 仍会将分段上传的视频存储在本地的 /var/www/nextcloud/data
中,此外 PHP 也会将上传的文件临时存储在 /tmp
,除非另行配置。因此,当上传的文件很大时 (比如同时上传多个十几 G 的文件),会超出 Lightsail 本地 SSD 的限制,导致本地 SSD 空间不够。
升级 Lightsail 的配置,或者在 Lightsail 上挂载 SSD 都是增加固定的存储容量,这并不划算。因此,推荐使用 EFS,将网络存储挂载到本机,修改 Nextcloud 的 data 目录到挂载点。参考 AWS 指南 How to Use Amazon EFS with Amazon Lightsail。EFS 是根据使用量按量计费的。只有存在尚未完成的分段上传时,Nextcloud 的 data 目录才会有大文件在,因此 EFS 按量计费十分划算。
EFS 使用 Burst、One Zone 模式即可,这也是最便宜的方式。实测 EFS 的性能比 s3fs
挂载 S3 好很多。
更多内容待补充,如有问题欢迎在下方评论
]]>本人是在早上起床后就发现阿里云香港服务器不可用。一开始以为是被神秘力量封锁了,但是看到报警邮件后发现,香港服务器在国外其他地区也不可用。
然后我就测了一下,发现主机能 ping,但无法 SSH 上去,HTTP/HTTPS 服务亦不可用。此外,yangxi.tech 网站服务也受到了影响。然后我登录了 AWS 中国区的 Route 53 去查看报警,结果发现 Route 53 上没有任何报警(我的 guozeyu.com 和 yangxi.tech 都在用中国区 Route 53)。查看最近的监控,发现我在 Route 53 上有一处配置错误,导致程序实际上没有在监控香港阿里云……于是修改了监测规则。此时我登录了 AWS 国际区,发现国际区的阿里云香港监控是在正常报警,发现是从 10:49 开始,全球所有监测点均不可用。
由于此时 AWS 中国区的报警已经被我改成正确的了,所以已经根据规则,在 DNS 层面进行自动宕机切换了;而且,我之前配置的 DNS TTL 也仅有 120 秒,所以我的所有网站应该在 11:20 前就已经完全恢复正常了。如果没有错误的报警规则,我的网站总共宕机时间也不会超过 5 分钟。
然后我登录了我自建的 Observium 监控,不出意外的看到了阿里云香港的机器已经宕机了。但我发现在宕机前,服务器的 CPU 是 100%。我就怀疑这是不是我自己服务器上某个程序卡死了,占用了所有资源,导致看起来 HTTP/HTTPS/SSH 服务都不可用了。
此时已经 11:30 了,我还觉得这个是我自己的问题,毕竟我也没收到阿里云任何邮件、电话提醒。于是我登录了阿里云后台,尝试进行重启。此时我没有选择强制关机。结果,关机指令已经执行了 10 分钟,机器仍未关闭。平时我使用 GCP 时,如果关机指令执行超过两分钟,那么就会自动执行强制关机,所以此时执行了 10 分钟的关机就很离谱。然后我就尝试发工单,但没能进入到工单,被转到了在线客服。我向在线客服描述了问题后,无人回复。然后我又尝试发工单,结果工单也是无人回复。只是得到了机器人回复,说在关机时,Windows 会执行系统更新,有时需要 10-15 分钟。请在等待 20 分钟后联系客服。
大概又过了半个小时,机器终于成功关闭了,但在尝试多次后,机器无法启动。即便我点了启动,机器也会在一段时间后变成 “已停止” 状态。由于此时我还是以为是我自己的问题,不是阿里云的问题,我以为是刚刚强制关机导致系统损坏了,于是尝试给现有云盘打快照,尝试回滚。但离谱的事又发生了,我发现我根本无法打快照!快照的进度一直是 0%。
在 11:55,我终于收到了工单的回复:“您好!阿里云监控发现香港地域某机房设备异常,影响香港地域可用区C的云服务器ECS、云数据库polardb等云产品使用,阿里云工程师已在紧急处理中,非常抱歉给您的使用带来不便,若您有任何问题,请随时联系我们”。此时我才知道,这次的宕机可能不是我自己的问题,我放弃了自己尝试恢复服务。
该回复没有提供解决方案,也没有预计的恢复时间,可以说无非就是告诉了我 “这个是我们阿里云的问题”,对于恢复服务没有实质性帮助。
本次事件最值得吐槽的地方是,我从未收到阿里云发来的有关通知。直至现在,我在邮箱、短信、站内信中没有收到任何阿里云关于此次服务宕机的提醒。我相信阿里云是有很多监控的,我坚信阿里云早在我发现我的服务出现问题之前,就已经知道了我的服务,以及其他人的服务器出现了问题了。但我却没有收到任何通知。唯一告知我阿里云存在问题的还是我发工单自己问出来的。
我觉得阿里云有必要向所有受影响的,以及可能受影响的客户发送相关提醒。在连续宕机了 8 小时,且仍未恢复的情况下,阿里云仍不主动通知客户,我实在是难以怀疑阿里云是否是故意不做通知,试图掩盖问题。
会的。作为中国第一大,以及全球也能排的上前几的云服务商,我不怀疑阿里云的技术实力。我现在用阿里云主要是为了阿里云香港的 CN2 精品网,用于数据跨境(价格为 3元/GB)。目前在这方面也没有什么可替代的方案。专线也考虑过,太贵了,买不起。
但是,我不会把核心业务放在阿里云上了。放在 AWS 上我更安心一些。本次阿里云香港宕机只影响了我的网站一小会儿,也正是因为我没有把核心业务放在阿里云上。
很简单,本站在四个地区,使用了四个不同服务商的服务器:
而且本站是纯静态网站。本站会在构建后,将构建产物分别同步到四个服务器上,没有主服务器的概念。本站通过 GeoDNS,将访客解析到最近的服务器,以降低延迟。在阿里云香港服务器宕机后,只需要停止响应解析即可。原本亚太地区解析到香港,现在亚洲会解析到北京,澳洲会解析到美国,这部分用户就被分流到可用的服务器上了。
本站还使用了 Route 53 的 Health Check 功能,可以实现接近实时的监控主机运行状态,在发现运行状态异常时,自动停止响应解析。目前,我的网站会在出现异常后一分钟内检测并识别到,并停止响应解析。相关 DNS 记录的时间设置在了 120 秒,因此服务发生不可用时,用户影响的时间不会超过 3 分钟。
]]>这个视频介绍了 “基本概念”,下方文字是这个视频的概要。如果你熟悉域名相关的概念,可以直接跳转到操作步骤
什么是域名?域名是互联网上的地址,用户通过域名来访问包括邮件、网站、App 在内的互联网资源。比如常见的以 .com 结尾的域名,以及新出现的 .xyz 和 .tech 结尾的域名。域名的价格大多在 40 到 200 元之间,具体的价格取决于域名后缀。
域名需要在注册商购买。那么如何选择域名注册商呢?这里推荐氧熙科技,通过与全球第七大注册商 PDR 合作,提供三百多种域名后缀的优惠注册。其特点是无需实名认证,支持支付宝或微信支付,自动发货,支持退款。
注册了域名之后,还需要有一个服务器,才可以建立自己的网站。服务器主要分为三种类型,包括虚拟主机、云服务器和独立服务器。这里推荐氧熙科技的虚拟主机,即适合新手,也适合专业人士使用。
其次是服务器位置,氧熙科技销售的虚拟主机可以选香港和美国加州两个位置,香港和美国加州的服务器都不需要备案。这里推荐香港主机,国内的访问速度更快。
这里推荐WordPress建站软件,全球有 65.3% 的网站使用WordPress 作为 CMS,并且可一键安装到虚拟主机。
这个视频介绍了 “操作步骤”,下方文字是这个视频的概要。
首先需要购买域名和主机。新购买的虚拟主机可能需要半个小时才可以使用,在可以使用时会收到邮件提醒。
主机创建成功后,需要前往域名注册商将域名的服务器修改为虚拟主机的域名服务器。
前往管理虚拟主机进入 cPanel 面板,进入 WordPress Manager 去安装 WordPress。安装时需要暂时将协议调整为 http://
开头的协议。
修改域名服务器 48 小时内,SSL 证书会自动签发,然后就可以使用 https://
协议访问网站了。
0.5GB RAM ,每月 €0.36,限速 100Mbps 不限流量(该价格为仅 IPv6 的价格,约¥2.48)购买链接
内存 | 存储 | CPU 核心数 | CPU 基线 | 带宽 | 价格 |
---|---|---|---|---|---|
1GB | 10GB SSD | 1 | N/A | 100Mbps | €0.36 |
- N/A 代表共享核心
目前只有 Paris 1 和 Amsterdam 1 有。前往上方购买链接(如果跳转到了登录/注册页面,请在登录后再点一次,即可直达 Stardust 购买页面),如果遇到无货,就拉到最底部复制 API,用 API 创建机器一般可以绕过前端的无货购买限制。
1GB RAM ,每月 CA$3.50 ,1Gbps 不限流量(约¥17.77 )。购买链接。注意,BuyVM 的计费周期是每月 1 日,所以若购买时不是 1 日,那么首月的价格会有所变化(因为到下个月或下下个月的 1 日不是整一个月)。
内存 | 存储 | CPU 核心数 | CPU 基线* | 带宽 | 价格 |
---|---|---|---|---|---|
1GB | 20GB SSD | 1 | N/A | 1000Mbps | CA$3.50 |
2GB | 40GB SSD | 1 | N/A | 1000Mbps | CA$7.00 |
4GB | 80GB SSD | 1 | 100% | 1000Mbps | CA$15.00 |
8GB | 160GB SSD | 2 | 100% | 1000Mbps | CA$30.00 |
- N/A 代表共享核心,100% 代表每个核心均为独立核心
配置更高的主机价格是同比例增加的,可以参考 4GB 版本乘以 N。
付款时使用支付宝即可使用 CA$ 同币值缴费,相对要比美元便宜很多。本网站就在使用 BuyVM,如果你从美国西部访问此页面,那就会使用 BuyVM 的服务器。
BuyVM 还可以购买 Block Storage Slab,每 TB 仅需要 $5.00,最低每月 $1.25 就可以买到 256GB。
0.5GB RAM ,每月$3.50 ,限流量 1TB ,可开日本、法兰克福、美国西部均可直连(约¥22.21 )购买链接
内存 | 存储 | CPU 核心数 | CPU 基线 | 流量 | 价格 |
---|---|---|---|---|---|
0.5GB | 20GB SSD | 1 | 5% | 1TB | $3.50 |
1GB | 40GB SSD | 1 | 10% | 2TB | $5.00 |
2GB | 60GB SSD | 1 | 20% | 3TB | $10.00 |
4GB | 80GB SSD | 2 | 20% | 4TB | $20.00 |
- 代表每个 CPU 的基线性能,均可 Burst,Lightsail CPU 基线详情
本网站就在使用 Lightsail,如果你从美国东部或者亚洲 (中国大陆外) 访问此页面,那就会使用 Lightsail 的服务器。Lightsail 可以免费附加静态 IPv4;IPv6 则是随机器附带的,暂不可保留或迁移。此外,Lightsail 的自动快照功能是免费的,可以作为自动备份。
Vultr/Linode/Digital Ocean 都是与 Lightsail 类似的产品,价格也与 Lightsail 十分接近。他们可能没有 CPU 基线的限制,但这也未必是好事,因为失去了限制更有可能受到邻居(同机器上其他用户)的影响。这里有一些优惠码:
2GB RAM,每月 $3.5(或 3 欧元),限速 100Mbps 不限流量,法兰克福可直连中国,但美国可能绕欧洲。OVH 两欧就可以买一个额外 IPv4 ,该 IPv4 没有月费,只要机器在 IP 就一直是你的。一个账户可以买 16 个额外 IPv4。美国区购买链接、国际美元区购买链接、国际欧元区购买链接
美国境内机器只有美国区可以购买,其他位置机器需去国际区购买。
内存 | 存储 | CPU 核心数 | CPU 基线* | 带宽 | 价格 |
---|---|---|---|---|---|
2GB | 20GB SSD | 1 | N/A | 100Mbps | $3.50/€3.00 |
2GB | 40GB SSD | 1 | N/A | 250Mbps | $6.00/€5.00 |
4GB | 80GB SSD | 1 | N/A | 500Mbps | $11.50/€10.00 |
8GB | 160GB SSD | 2 | N/A | 1000Mbps | $23.00/€20.00 |
- N/A 代表共享核心
本网站就在使用 OVH,如果你从欧洲访问此页面,那就会使用 OVH 的服务器。
美国 us-central-1
,us-west-1
,us-east-1
区域,1GB RAM ,30GB 最基础的盘,仅 IPv4 ,出站流量自费。这个试用期过了也免费!
内存 | 存储 | CPU 核心数 | CPU 基线* | 流量 | 价格 |
---|---|---|---|---|---|
1GB | 30GB HDD | 2 | 12.5% | 按量计费 | 永久免费 |
- 12.5% 代表每个 CPU 可以有 12.5% CPU time,可 Burst,GCP E2 共享 CPU 详情
本网站就在使用 EC2 (中国区),如果你从中国大陆访问此页面,那就会使用 EC2 的服务器。目前 AWS 中国区仅限企业注册。
Google Cloud 的按量付费可能是三者中的最便宜的,此外个人感觉 Google Cloud 的操作页面使用起来相比 Azure 和 AWS 更简单。这几家提供的产品都大同小异,此外他们也都可以预留实例一年到三年,实现最大化折扣
最大的区别是计费模式。AWS 无论是国内版还是国际版,均默认使用后付费模式,即类似信用卡,每月支付上一个月结算的账单。而阿里云和腾讯云无论是个人用户还是企业用户,均使用预付费模式。哪怕使用的是按量付费的机器,竟然也需要提前充值;余额耗尽后会直接停机。所以用阿里云或腾讯云的按量计费服务之前,无比要保证有充足的余额,不然将欠费了将直接影响生产环境。
此外,阿里云和腾讯云在 API 使用上没有 AWS 方便。虽然 AWS 国内版在国内没有阿里云那么大的占有率,但由于 AWS 国内版和国际版 API 保持了一致,因此 AWS 的文档资源要远比阿里云、腾讯云丰富的多。
个人认为,AWS 国际版完胜阿里云、腾讯云的海外区域,AWS 国内版核心问题是支持的可用区太少,只支持北京和宁夏两个区域;Azure 国内版支持的区域比 AWS 国内版要多一点;阿里云和腾讯云在国内区域数量上是远多于 AWS 的。不过在网络方面,目前 AWS 国内版也是 BGP 接入,线路完全不比阿里云差。
数据跨境方面(指中国大陆境内与境外之间的跨境),阿里云提供了香港精品网、云企业网,这是 AWS 所没有的。
这里推荐氧熙科技/TlOxygen 的虚拟主机,香港位置采用 CN2 GIA 线路,美国加州也是国内直连;均无需备案,购买后即用。相比之下,美国加州提供更多的流量和存储,带宽也更大。他们的虚拟主机还支持 SSH 访问、Let’s Encrypt 证书自动签发(不可 root)。香港/加州虚拟主机购买链接
等待补充
等待补充
等待补充
]]>[1]:由于全球 DNS 服务器同步需要时间,可能需要 24-72 小时后域名上的服务才能够使用。若注册
.cn
等中国域名还需要进行实名认证,需要额外的时间。其他国际域名(如.com
)则不需要实名认证。
首先,你需要注册一个属于自己的域名。域名的注册门槛很低,基本在几分钟内就可以完成注册,并且包括 .com 在内的众多域名后缀均不需要进行实名登记。通常,大多数域名都是按年进行购买。
本文推荐的是 氧熙域名注册 (原 TlOxygen)。该注册商是本站站长亲自建立,是全球第 7 大的域名注册商 PDR Ltd. 的最高级代理之一,提供更多的支付方式和更低的价格。从这里购买域名可以帮助本站持续发展。并且本站域名注册提供了域名删除与退款服务、免费企业邮箱和域名锁等服务。
首先,前往 氧熙域名注册主页(也可以浏览器地址输入 yangxi.tech
前往),进行域名搜索。比如,如果想要注册 guozeyu.com
,只需要在搜索框里输入这个域名并点击搜索。如果你不确定想要注册什么后缀,那么也可以不输入后缀,如 guozeyu
。如果你更习惯英语界面,或者需要以美元计费的结算方式,请前往 International Version。
可以看到,咱们心仪的域名已经被注册了。但是页面下方可以看到更多的 “其他可注册的匹配域名”。
我们这里选择 guozeyu.online
。注意划线价为域名续费的价格,为了可以方便地给域名续费,建议选择续费价格较低的域名。比如 .com
域名续费只需 CN¥79.20/年(国际版为 US$12.59/年),而 .online
的续费价为 CN¥270.00。我对域名的价格一向非常透明,我承认这绝不是市面上最低的价格。下表列出了一些注册商 .com
域名的续费价格
注册商 | 美元/年 | 人民币/年 |
---|---|---|
氧熙/TlOxygen | 13.79 | 87.60 |
阿里云万网 [2] | 10.99 | 79.00 |
DNSPod [2] | - | 72.00 |
NameCheap | 14.58 | - |
GoDaddy | 19.99 | - |
Cloudflare Registrar [3] | 9.15 | — |
NameSilo | 10.95 | — |
12.00 | — |
[2]:阿里云万网/DNSPod 注册 .com 域名需要实名认证,可能需要几天后域名才能够正常使用
[3]:Cloudflare Registrar 上注册的域名不支持修改 DNS 解析商、NS 记录,以及粘附记录(Glue Record)
完整的价格列表:中国大陆(人民币), International Version (USD)
注意,本文后续的内容仅适用于在氧熙注册的域名。在其他注册商注册的域名配置有所不同。此外,并不是所有注册商都免费提供 DNS、企业邮箱和域名转发服务。
然后进行结账。结账时建议选择免费的 “隐私保护” 功能,这样你的注册信息(包括邮箱、手机号、地址)就不会公开:
然后填写注册信息。请确保注册信息是有效的(可以通过电子邮件联系到你),否则域名注册可能会失败。注册完成后即可选择支付方式了。目前支持的支付方式有微信支付、银行卡、PayPal
付款完毕后,会自动跳转到支付成功页,点击 “继续管理订单” 进入后台管理页面。
此时,你就可以看到你新注册的域名了。
点击你刚刚注册的域名,然后前往 DNS 管理菜单,点击 “管理DNS” 以激活 DNS:
如果你看到 “您即将提交的信息不安全” 提示,请选择 “仍然发送”。随后看到如下页面即说明已经激活了:
此时我们已经拥有了域名,但该域名下还没有任何服务。我们首先配置企业邮箱,实现任何发往 @guozeyu.online
的邮件都转发到自己的邮箱里。这样有很多好处,比如你可以在注册微博的时候使用 weibo@guozeyu.online
,在注册 GitHub 时使用 github@guozeyu.online
,这样可以区分不同服务商发来的邮件;也可知道是谁卖了自己的邮箱信息,给自己发送垃圾邮件。
前往电子邮件菜单,点击 “管理电子邮件” 以激活企业邮箱:
如果看到 “待验证域所有权 (Pending Domain Ownership Verification)”,则说明 DNS 尚未完成激活,请在 24-72 小时后尝试。新注册的域名默认使用我们提供的 DNS 服务器,邮件记录已经自动配置好了,所以无需手动添加记录。同时,你也可以点击 “设置 (Settings)”,选择 “修改语言偏好 (Modify Language Preference)” 然后选择 “Chinese (Simplified)” 以切换语言到简体中文。此外,如果你知道自己在做什么,也可以将域名换到其他 DNS 服务商,手动配置 DNS 记录。
待 24-72 小时,完成域名所有权验证后,你将看到如下页面,这时我们选择 “添加只转发帐户”:
这里我们用户名输入字母 i
,“转发至” 输入自己的邮箱。这里只是拿我的邮箱演示。
添加成功后,发往 i@guozeyu.online
的邮件就会转发到你刚刚配置的 “转发至” 邮箱了。但发往其他用户名的邮件依然会被拒收。此时我们需要配置 Catch-All:
然后选择 “转发到以下用户/账户”,并输入刚刚设置的用户名 i
,然后点击 “应用” 即可。
目前,浏览器里的网站是无法访问的,因为我们还没有配置用于 Web 的服务器,也没有建立自己的网站。但我们可以配置域名转发,将访问到域名的的流量跳转到其他 URL。比如,你可以设置跳转到自己的微博、GitHub 等网站。具体操作如下:
前往域名转发菜单,点击 “管理域名转发” 以激活域名转发:
此时,你可以配置要转发的域名和要转发到的地址:
同时,也可以选择高级设置。我建议关闭 “URL掩蔽 / 重定向 / URL隐藏”。
同样,该配置需要 24-72 小时后才能生效。
本文介绍了如何注册属于自己的域名,建立以自己域名结尾的的企业邮箱,以及配置域名转发。后续的文章将会更新如何建立属于自己的个人网站。可以点击页面顶部的关于按钮订阅本网站,这样就不会错过后续的内容啦~
]]>本站使用 Hexo 博客框架生成静态网页,使用 Nginx 服务器分发静态网页、图片等。本站的静态文件和图片同时部署在全球四台服务器上,使用 Route 53 实现了分区解析和宕机后自动切换,使用 CloudFront 和 UPYUN CDN 分发视频。
本站主题是在 Claudia 的基础上进行定制与魔改。原主题就有如下功能:
我对其增加的功能主要如下:
100vw
宽度无边距<figure>
并展示图片描述<iframe>
中 src=
的内容并将其放在 srcdoc=
中减少网络请求HLS.js
)原本主题的搜索功能在电脑端只会在最右侧的边栏展示搜索结果,我对其进行了改进,实现了用户在搜索时搜索栏和搜索结果自动延长。各位可以直接前往首页体验,或者查看下方的效果视频:
我的网站目前同时部署在国内外多个主机上,使用着相同的配置。域名使用 Route 53 的延迟记录进行分区解析,并开启了 “运行状况检查” 实现宕机后自动切换服务器目前本站使用了 5 个服务器,分别部署在北京、东京(日本)和拉斯维加斯 (美国)、蒙特利尔 (加拿大) 和法兰克福 (德国)。
选择使用 Route 53 作为解析服务器的原因是:
本站视频虽然是使用 Cloudflare Stream 存储和转码,但实际分发使用的是 CloudFront 和阿里云 CDN。主要是 Cloudflare 的视频是按量计费,其单价比 CloudFront 要贵。其次是 Cloudflare Stream 不提供国内节点,因此为国内提使用阿里云 CDN。
实现双 CDN 有两种方法,第一种是使用 Nginx 根据访客国家替换 CDN URL。这样做相比分区解析的好处是即便用户配置的 DNS 服务器非用户所在地服务器,替换 CDN URL 方式依然会让用户使用正确的 CDN。可以采用了 Nginx 根据客户端 IP 的国家进行 CDN 域名的替换,具体配置——在 http
中:
geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb { auto_reload 1d; $geoip2_data_country_code default=CN country iso_code;}map $geoip2_data_country_code $tlo_domain { default "tlo.xyz"; "CN" "tloxygen.com";}
在 server
中:
sub_filter '//videodelivery.net/' "//video.${tlo_domain}/";
这样一来,用户访问网站时,服务器会根据用户访问网站时的 IP 地址(而非 DNS 提供的 IP 地址)来选择合适的 CDN。
这就不用多说了,将两个 CDN 绑定在一个域名上,使用 GeoDNS 对不同地区的访客返回不同的结果。
本站的图片均使用 Cloudflare Images 进行压缩与存储,并通过 Nginx 进行代理与缓存。Nginx 配置如下,实现了根据设备兼容性优先提供 AVIF、WebP 和 JPEG。这是因为 Cloudflare Images 在国内的速度不佳。此外 Cloudflare Images 可以在访问时自动将图片调整分辨率和格式。当用户访问相对路径 /cdn-cgi/imagedelivery/
时,网站就会加载相应的图片,还省去了与新的域名建立 HTTP 连接的时间。
在 http
中:
map $http_accept $suffix { default "jpeg"; "~image/avif" "avif"; "~image/webp" "webp"; "~image/apng" "apng";}map $http_accept $png_suffix { default "png"; "~image/avif" "avif"; "~image/webp" "webp"; "~image/apng" "apng";}map $http_accept $gif_suffix { default "gif"; "~image/avif" "avif"; "~image/webp" "webp"; "~image/apng" "apng";}map $http_accept $default_suffix { default "default"; "~image/avif" "avif"; "~image/webp" "webp"; "~image/apng" "apng";}map $sent_http_Content_Type $file_name { default "default"; "image/avif" "avif"; "image/webp" "webp"; "image/apng" "apng"; "image/jpeg" "jpeg"; "image/png" "png"; "image/gif" "gif";}
在 server
中
proxy_store /var/www/images$uri/image.$file_name;location /cdn-cgi/imagedelivery/6T-behmofKYLsxlrK0l_MQ/ { root /var/www/images/; try_files $uri/image.$suffix $uri/image.$png_suffix $uri/image.$gif_suffix $uri/image.$default_suffix @proxy;}location @proxy { proxy_ssl_name imagedelivery.net; proxy_ssl_server_name on; proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; proxy_set_header Host imagedelivery.net; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_hide_header Upgrade; proxy_hide_header Alt-Svc; proxy_hide_header Expect-CT; proxy_http_version 1.1; proxy_set_header Connection ""; if ($uri ~* '^https://cdn.tlo.xyz/6T-behmofKYLsxlrK0l_MQ/(.*)$') { add_header X-Cache-Status "MISS"; proxy_pass https://cdn.tlo.xyz/6T-behmofKYLsxlrK0l_MQ/$1; break; }}
通过 proxy_store
,图片将会在第一次请求后永久的存储在本地,并在下次访问时从本地提供。在存储时,图片的变体名和格式会作为文件名的一部分进行存储。在访问时,服务器会根据客户端发送的 http_accept
请求头去查找对应文件。
AVIF 格式比 WebP 的压缩效率更好,而 WebP 格式比 JPEG 的压缩效率更好。然而对于兼容性而言,JPEG > WebP > AVIF。尽量不要在网站上使用 GIF,如果需要展示动画,可以使用静音自动循环播放的 <video>
代替。
如果原站支持 WebP/AVIF 自适应,那么在配置 CDN 的时候,需要选择根据客户端的 Accept 头进行缓存。CloudFront 和阿里云 CDN 的配置分别如下:
本站使用 GitHub Action 在服务器上运行 SSH 脚本实现自动部署。在服务器上配置了 post-merge
的 git hooks,在有改动后自动运行脚本。具体来讲,是在一个部署专用的服务器上生成静态页面,然后将这些静态页面分发到对应的服务器。
本站使用自建的 Matomo网站统计。Matomo 是一个基于 PHP 和 MySQL 的非常强大的开源统计软件。
除此之外,本站还通过 JavaScript 实现了对视频播放,图像查看和搜索的统计。本站还使用了 Nginx 的 post_action 功能实现了异步发送统计,具体在 server
中的配置如下:
location /api/a { post_action @tracker; return 204;}location @tracker { internal; proxy_pass https://origin/matomo.php$is_args$args; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host matomo.tloxygen.com; proxy_set_header TLO-Connecting-IP $remote_addr;}
本站还启用了 HTTP/2 Server Push,用户在访问网站时,服务器会一次性直接推送首屏渲染必要的 CSS 和 JS 文件,由于用户不需要在获取到 HTML 页面后再去获取 CSS 和 JS 文件,首屏渲染的时间大大缩短。实测在模拟 Fast 3G 环境下,启用 HTTP/2 Server Push 后首屏时间减少了约 0.3 秒:
具体 Nginx 中 server
的配置如下
listen 443 ssl http2;listen [::]:443 ssl http2;location ~* \.(?:html)$ { http2_push /style/common/bulma.css; http2_push /style/base.css; http2_push /style/common/helper.css; http2_push /style/post.css; http2_push /style/widget-header.css; http2_push /style/widget-post-list.css; http2_push /style/themes/highlight-theme-light.css; http2_push /js/common.js; http2_push /js/sdk.latest.js; http2_push /js/post.js;}
]]>最近分别使用手头上的国行和美版 iPhone 对比了一下中频和毫米波 5G。都是相同运营商 (Verizon Prepaid) 的相同套餐 (Unlimited Plus),使用实体 SIM 卡,在完全相同的地理位置进行的测试。
可以看到,毫米波 5G (高频,mmWave) 轻松跑到了 2000Mbps。
如上图所示,也有人在 Reddit 上跑出了接近理论峰值的 4000Mbps。但我试了多次最高 “也就” 2000Mbps。
中频 5G (Mid-Band) “只” 跑到了 929Mbps。
就本次测试看来,毫米波 5G 要比中频 5G 快 2 倍左右。在各自的理想情况下,毫米波 5G 可以比中频 5G 快 2-3 倍。
在系统的通话页面输入 *3001#12345#*
,然后点击呼叫。随后我们就可以看到下方视频所示的 Field Test Mode。选择 5G 中的 Nr ConnectionStats。若看不到 5G 相关选项,则说明当前没有 5G 信号,或机型/运营商不支持 5G。然后看 Band 中的数字。该视频中 band 数字为 78,为中频 5G。
若数字小于 200 (如上图),则说明没有使用毫米波。若显示大于 200 (常见的有 257-262),则说明已经连接到了毫米波 5G。具体使用的频率可以参考这个表格。
并非所有支持 5G 的 iPhone 都支持毫米波 5G。目前只有在美国购买的 iPhone 12、13、14 系列在美国才能使用毫米波 5G 网络。
根据苹果官网,5G 是有多种图标的。如果只显示 5G,则是连接到了最普通的 5G,速度比较慢。若看到了 5G+、5G UW 和 5G UC,则说明可能连接到了毫米波 5G,速度更快。但实际上,显示 5G+、5G UW 和 5G UC 并不代表使用了毫米波 5G (也可能只是中频 5G)。此外,在美国之外的其他国家即使连接到了中频 5G,也只显示 5G。
低频的范围在 1 GHz 以内,中频在 1-6 GHz,毫米波则在 24-40 GHz。
低频 5G,也叫 5G Nationwide (Verizon)、Extended Range 5G (T-Mobile)、5G (AT&T)。是覆盖最广的 5G,但速度也不是很理想,有的时候甚至不如 4G/LTE 的速度。目前现有的很多 4G 基站都可以比较轻松的升级为低频 5G。在我看来只是准 5G 网络。
中频和毫米波 5G,也叫 5G Ultra Wideband (Verizon)、Ultra Capacity 5G (T-Mobile)、5G+ (AT&T)。是真正意义上的 5G 网络。
目前在中国,所有运营商的 5G 均使用中频。相比毫米波,中频在相同的基站数量情况下,覆盖的更广。这是因为中频的波长更长,传播时相比毫米波更不容易被障碍物遮挡。
LTE-Advance,也叫 5G Evolution (AT&T)。是指使用了载波聚合、4x4 MIMO 和 256 QAM 等技术的 4G 网络。这种网络根本不是 5G 网络,只是比较快的 4G 网络。
在苹果官网搜索你的手机型号(如 A2629、A2634、A2639、A2644 则为中国大陆及港澳地区的 iPhone 13 系列的型号),然后查看是否支持 n257-262 中的任何一个频段。截止到目前,只有在美国销售的 iPhone 12/13/14 支持了毫米波。你可以在机身背面看到型号。目前支持毫米波的型号有:
还有一个更简单的方法:看 iPhone 右侧是否有毫米波天线的开口(图源 Apple)
这个毫米波天线开口很像 iPad 系列 Apple Pencil 的无线充电开口,但他们确实不是一个东西,不要混淆。
其次,如果你手持 iPhone 14,判断方法更为简单,只要没有实体 SIM 卡槽,就是支持毫米波的美版。
同样的,你可以在苹果官网搜索你的 iPad 型号。你可以在机身背面看到型号。目前支持毫米波的型号有:
Mac mini 是苹果的小主机,类似 Intel® NUC 这种迷你 PC。它不配备键盘、鼠标、显示器,因此相比 iMac 也更加实惠。
这一代 Mac mini 是首款搭载 Apple Silicon 的 Mac mini,基于 ARM 架构的它拥有更优秀的能耗比以及更好的性能。它的 Geekbench 4 跑分为 7422,高于基于 Intel 芯片的最高配 Mac mini 的 5488 分。不过,受 M1 芯片限制,它只有两个雷电 3 接口,而不是 4 个,而且它只支持连接最多两个显示器。不过,相比搭载 M1 芯片的 MacBook Air 和 MacBook Pro,它的接口要更丰富——它额外有一个 HDMI 2.0、千兆网口(可升级到 10Gb 网口)和两个 USB-A 接口。
个人认为 Mac mini 的定位大于等于 MacBook Air,小于等于 iMac、MacBook Pro 系列。所以在未来,苹果也有可能推出搭载 M1 Pro/M1 Max 芯片的 Mac mini。
自动登录是非常重要的一个功能。启用自动登录可以实现在更新 macOS、重启电脑后,不需要输入密码即可自动登录到用户界面,并启动相关的服务。可以说是将 Mac mini 作为服务器,尤其是远程服务器所必须要打开的一个功能。具体的操作方式请参考这个文档。需要停用文件保险箱才可以启用这个功能。
macOS 的共享功能会监听所有的网络接口。如果你的运营商提供了公网 IPv4,则可以通过端口转发或者 DMZ 主机的方式将 SMB 暴露在公网即可。如果需要 IPv6 访问,则需要关闭光猫以及路由器上的防火墙,允许外部传入的 IPv6 连接。
开启远程登录和远程管理不仅可以方便的远程管理 Mac mini,还可以直接使用 macOS 环境去执行应用程序。开启远程登录后可以使用 SSH 连接。开启远程管理后可以进行远程屏幕连接。
在 macOS/iOS 上,我使用 Screens 去远程连接 Mac mini。如果你在 iPad 上使用,我推荐安装 SwitchResX 来自定义屏幕分辨率,实现完美适配 iPad 的效果。需要注意的是,iPad 底部可能会留有部分安全距离,这在设置分辨率时需要减去。在我的 11-inch iPad Pro 上,底部有 40 像素的安全距离。除了分辨率之外,我还将刷新率降低到了 30Hz,以减少网络传输上的压力。
需要注意的是,开启远程登录和远程管理前,一定要为你的 Mac 设置强密码,否则极有可能密码被暴力破解。
通过远程连接,甚至可以在 iPad 上使用 Final Cut Pro。经过本人实际体验,在同城市通过互联网连接操控时,感觉不到明显卡顿,完全可用。需要注意的是,使用 Final Cut Pro 时屏幕宽度必须大于 1280px(HiDPI 时为 2560 个像素点)。可以使用 SwitchResX 根据应用程序自动切换分辨率。下面这张截图是在 11-inch iPad Pro 上缩放显示的,因此有些许模糊。
macOS 的文件共享功能可以直接将 Mac mini 变成一个 NAS。只需要打开系统偏好设置——共享,然后启用 “文件共享”,就可以实现 NAS 了。Mac 使用的是 SMB 协议。建议使用有线网络以确保稳定性。
注意,你可能需要进入高级选项,然后启用 “Windows 文件共享”,才能在某些客户端上连接 SMB。
如果你想允许访客访问,你不仅需要在用户里添加 “任何人”,还需要在高级选项里打开 “允许客人用户”。此外,还需要在系统偏好设置——用户与群组——客人用户中启用 “允许客人用户连接到共享文件夹”。这时候,可以以用户名 “Guest”,密码空的方式连接 SMB。
Mac mini 的雷电 3 和 USB Type-A 接口很适合用于连接外部硬盘,连接的外部硬盘也可以通过文件共享去分享,只需要在添加外部硬盘到 “共享文件夹” 中即可。
我为我的外部硬盘配置了 RAID 和 Fusion Drive。我使用了 4 个 3TB 3.5 英寸 HDD 和一个 1TB SSD。其中 4 个 HDD 是通过四盘位硬盘盒的方式使用 USB Type-A 口连接到 Mac mini,SSD 使用雷电 3/USB 4 硬盘盒连接到 Mac mini。我在硬盘盒上做了 RAID5,将 4 个 3TB HDD 变成了 9TB 的存储空间。然后在此之上又使用 Fusion Drive 将其与 SSD 融合,最终达到了 10TB 的容量。Fusion Drive 配置方法我参考的是这篇文章。
我选择使用 APFS 作为文件系统。主要是因为新版本 macOS 已经不支持新建 HFS+ 加密分区,而且由于有 SSD 的加持,并不是很担心性能下降。
同样是在高级选项中,打开 “共享为时间机器备份目的位置” 即可。在需要进行备份的 Mac 上,使用访达(Finder)菜单栏中的前往——连接服务器(⌘K)连接到这台 Mac,然后就可以在系统偏好设置中的 “时间机器” 里找到通过文件共享的文件夹了。
我目前是通过 Internet 的方式连接到 Mac mini 实现异地备份的,首次备份花了大约 6 小时,之后每次备份都能在半小时内完成。我还添加了一个通过 USB 连接的 HDD,系统会使用两个磁盘轮流备份,成功实现了一个异地备份、三个存储介质和三份拷贝,符合备份 3-2-1 原则。
为了更好的安全性,还可以对 NAS 上的数据进行备份。我选择使用 Mac mini 上安装的 Carbon Copy Cloner,将 NAS 上部分重要数据再次备份到本地局域网的 AirPort Time Capsule 上。我选择备份到 APFS 文件系统的 Sparse Bundle 上以实现快照和加密。
由于有了这个 10TB 的 NAS,我果断将我的 Adobe 订阅从 Lightroom (1TB) 换到了 Photography (20GB)。Photography (20GB) 相比 Lightroom (1TB) 多了 Photoshop CC 和 Lightroom Classic CC。其中 Lightroom Classic CC 使用的是本地的照片库,同时还可以与 Lightroom CC 进行同步。我在 Mac mini 上安装了 Lightroom Classic CC,并打开了同步功能,将之前所有的 Lightroom CC 图片均存储在了本地,然后在 Lightroom Classic CC 上对这些图片取消同步。很快,我的云空间就全部释放了。然后,我再将这些照片重新添加到同步文件夹中。此时,Lightroom Classic CC 只会上传这些照片的智能预览(就是相对低分辨率的 RAW 格式),这些照片不占用云端存储空间。以后,当 Lightroom CC 的空间再次不足时,我依然可以使用这个方法释放 Lightroom CC 的空间。
现在,我可以在我的任何安装了 Lightroom CC 的设备上对照片进行编辑。不过,如果需要导出原图,则仍需要在 Mac mini 上的 Lightroom Classic CC 操作。为了能够在其他桌面设备上导出原图,我需要在其他设备上拥有——1. 原图文件、2. 资料库。我选择使用 ChronoSync Express 对原图文件进行双向定时同步,使用 iCloud 云盘同步资料库(包括标准预览、1:1预览、智能预览)。经过我实际测试,发现 iCloud 是支持增量同步的,即每次修改资料库后只会同步资料库文件中改动的文件块。
需要注意的是,Lightroom Catalog*
文件必须在同一个目录下。如有必要,可以使用软链接的方式实现在不同位置存储它们的原始文件。我一般会将原始文件存储在外置硬盘中,这样可以节省本机空间。当外置硬盘不可用时,依然可以使用智能预览进行编辑。
我使用 Surge 这个软件的 DHCP 服务器实现旁路由。Surge 可以接管局域网设备上的请求,对其重写、抓包、解密、代理等,十分方便。需要关闭路由器/光猫上的 DHCP 服务器。
打开 Surge 的增强模式,然后在 DHCP 页面中右键选择设备,然后开启 “使用 Surge 作为网关”。将那台设备重新连接到网络,其流量就会被 Surge 接管。
同样是使用 Surge,在其配置文件中加入如下内容:
[Snell Server]interface = ::port = 6160psk = SOME_RANDOM_PASSWORDobfs = offipv6=true
然后,在其他设备上的 Surge 加入如下代理配置:
[Proxy]Mac mini = snell, mac-mini.sgddns, 6160, psk=SOME_RANDOM_PASSWORD, udp-relay=true, tfo=true[Rule]IP-CIDR, 192.168.1.0/24, Mac mini
需要更改 SOME_RANDOM_PASSWORD
为一段随机字符串,更改 192.168.1.0/24
为你的内网 IP 段。现在,就可以实现内网穿透了。
我推荐使用 qBittorrent 作为下载器。其内置的 Web UI 可以方便的在其他设备上控制 qBittorrent.
有些人可能觉得使用树莓派就行了。实际上,树莓派确实可以实现大多数功能,但是它却没有 macOS 环境,无法安装 Lightroom Classic CC、Final Cut Pro 等软件。
当然也可以使用 Intel® NUC 等 Windows 主机来代替 Mac mini,可以实现类似的效果。
]]>需要注意的是,该键盘使用专门的协议与 iPad 通信,不支持蓝牙。也就是说,只能给 iPad Pro 使用。
重量:论重量,该键盘重量远大于 Magic Keyboard for Mac 加上 Magic Trackpad for Mac 的重量。因此便携度还是 Mac 所配的键盘和触摸板更优。11-inch 键盘的重量为 600g 左右。作为参考,11-inch iPad Pro 重量为 471g;11-inch 智能键盘夹(Smart Keyboard Folio)为 300g 左右;Magic Keyboard for Mac 加上 Magic Trackpad for Mac 的重量为 231g + 231g = 462g,何况后者比 iPad 的触摸板还要大很多,并支持 Haptic Feedback。安装上该键盘会使设备增重一倍多,实在有点夸张。主要问题是双面保护的问题,如果能够省去背面的保护,重量应该能轻不少。
类别 | 型号 | 重量 |
---|---|---|
iPad 11-inch | Magic Keyboard | 593g |
机身 | 471g | |
Smart Keyboard Folio | 297g | |
机身 + Magic Keyboard | 1.06kg | |
iPad 12.9-inch | Magic Keyboard | 699g |
机身 | 641g | |
Smart Keyboard Folio | 407g | |
机身 + Magic Keyboard | 1.34kg | |
Mac | Magic Keyboard | 231g |
Magic Trackpad | 231g | |
MacBook | 13-inch Air | 1.29kg |
13-inch Pro | 1.37kg | |
16-inch Pro | 2.0kg |
* Magic Keyboard for iPad Pro 和 Smart Keyboard Folio 的重量均不是官方数据
我的触摸板默认没有开启三指切换多任务的手势。需要进入设置、主屏幕与程序坞、多任务中找到 “手势” 开关开启。开启后在屏幕上四指也会出发多任务。
若开启指针动画,当移动到按钮上方时,指针会消失,取而代之的是按钮高亮的吸附效果。此功能可以关闭,关闭后更接近在 macOS 上的使用体验。
同样的,默认 iPadOS 会开启触摸板惯性,关闭此功能会更接近在 macOS 上的使用体验。
类似 Mac,iPad 也推出了辅助点按功能,可以代替 Haptic Touch,非常好用。
两指按下辅助点按
根据我的个人体验以及网上的说法,该触摸板明显比第三方的好用,效果与 Magic Trackpad for Mac 相当。似乎苹果目前对第三方触摸板在多点触控以及移动光标的流畅度上有 Bug(也可能是有意而为)。
该键盘使用最新的的剪刀式结构,介于最新的 16-inch MacBook Pro 和 Magic Keyboard for Mac 的手感。相比智能键盘夹(Smart Keyboard Folio)打字体验好太多。
尽管触摸板不支持 Haptic Feedback,但整个触摸板均可物理按压,不存在某一个角不好用一说。
两个角度控制的地方阻尼足够,无论什么角度放置,仅凭借 iPad 自身重量均无法使其自己转动。可放在腿部使用。
总体使用体验尚可,唯一缺点就是太重且两个面都很厚(背面由于支持充电和角度调整,也远大于普通双面夹)。此外就是似乎本次外壳材质较上一代没有变化,使用久了会严重变质。
可以前往 Apple Store 实体店或者在线商店购买。使用教育优惠可以便宜 ¥200,学生教师均可使用。购买时注意选择键盘样式,我购买的是美式英语。国内实体店可能只有简体拼音版。
]]>通过使用 PowerDNS,你可以在自己的服务器上搭建支持分区解析(精细到国家、城市、ASN、自定义 IP 段)、EDNS-Client-Subnet、DNSSEC、IPv6 的 DNS 服务器。
本文面向域名所有者和站长,讲述的是权威 DNS 服务器而非 DNS 缓存服务器。如果你想要了解更多的关于 DNS 的知识,请参考 DNS 域名解析系统详解——基础篇 以及 DNSSEC 简介,签名的工作原理。
本文是对自建 PowerDNS 智能解析服务器的更新。自建 DNS 的优缺点、配置 DNSSEC 以及分布式 DNS 服务在之前的那篇文章有所描述,本文将其省略。本文主要更新以下内容:
考虑到操作系统软件源默认版本不一,建议前往 PowerDNS repositories 重新为 PowerDNS Authoritative Server 配置软件源(请添加 4.2 或以上版本)。同样你也可以配置 dnsdist 的软件源(请添加 1.2 或以上版本)。
添加软件源后,更新软件列表并安装 pdns-server
和 pdns-backend-geoip
即可。在 Debian/Ubuntu 下:
sudo apt-get install pdns-server pdns-backend-geoip
需要注意的是,在 Ubuntu 18.04 LTS 后可能默认包含了 systemd-resolved
服务,这个服务占用了 loopback 地址的的 53 端口,这与 PowerDNS 所需要使用的端口(0.0.0.0:53
)冲突。你可以:1. 禁用这个服务,2. 修改 PowerDNS 的 local-address 和 local-ipv6 配置仅监听外网 IP 地址,3. 修改 local-port 为非 53 端口,并使用 dnsdist 进行转发(详见后文)。
如果你想要配置用户侧 IP 访问速率,请安装 dnsdist:
sudo apt-get install dnsdist
如果你选择禁用 systemd-resolved
,可以执行以下代码:
sudo systemctl disable systemd-resolved.service sudo systemctl stop systemd-resolved
为了实现分区解析,我们需要 GeoIP 数据库。最新版的 PowerDNS GeoIP Backend(4.2.0)已经支持了 GeoIP2 的 mmdb 格式,同时也支持 dat 格式。而老板的只支持 dat 格式的数据库。由于 MaxMind 已经停止维护免费的 dat 格式数据库,因此强烈建议使用 4.2 版本及以上的 PowerDNS 并换用 mmdb 格式的 IP 数据库。
首先建立配置文件,创建 /etc/GeoIP.conf
为如下内容(包含了 IPv4 和 IPv6 的国家、城市、ASN 数据):
ProductIds GeoLite2-Country GeoLite2-City GeoLite2-ASN DatabaseDirectory /usr/share/GeoIP
建议安装 geoipupdate,在 Ubuntu 下可以这样安装:
sudo add-apt-repository ppa:maxmind/ppa sudo apt update sudo apt install geoipupdate
然后下载/更新 GeoIP2:
sudo geoipupdate -v
All done!
同时建议配置 Crontab 定期执行上面指令更新数据库文件(并重载 PowerDNS 服务),以更新 GeoIP 数据库。
PowerDNS(下简称 pdns)的配置文件位于 /etc/powerdns
,首先删除 PowerDNS 原本的 demo 配置,然后建立文件夹以存储 DNSSEC 的密钥文件:
sudo rm /etc/powerdns/pdns.d/*sudo mkdir /etc/powerdns/keys
然后创建文件,创建 /etc/powerdns/pdns.d/geoip.conf
为如下内容:
launch=geoip geoip-database-files=/usr/share/GeoIP/GeoLite2-Country.mmdb /usr/share/GeoIP/GeoLite2-City.mmdb /usr/share/GeoIP/GeoLite2-ASN.mmdb geoip-zones-file=/etc/powerdns/zones.yaml geoip-dnssec-keydir=/etc/powerdns/key
在 geoip-database
选项中,你可以按照需要设置自己所需要的一个或多个 GeoIP 数据库。
你可以建立文件 /etc/powerdns/zones.yaml
以配置 DNS 记录。具体格式参见 Zonefile format。
需要注意的是,若使用 mmdb,则 %re
是 ISO3166 的两位区域缩写。若使用 dat,则是 GeoIP 的区域代码。
由于 PowerDNS GeoIP Backend 仅支持按域名配置分区解析,而不支持按记录配置按记录配置分区解析,所以若要配置根域名分区解析,可以参考如下配置(YAML 格式,下同):
domains:- domain: example.com ttl: 300 records: unknown.cn.example.com: - soa: &soa ns1.example.com hostmaster.example.com 2014090125 7200 3600 1209600 3600 - ns: &ns1 content: ns1.example.com ttl: 600 - ns: &ns2 ns2.example.com - mx: &mx 10 mx.example.com - a: 10.1.1.1 bj.cn.example.com: - soa: *soa - ns: *ns1 - ns: *ns2 - mx: *mx - a: 10.1.2.1 unknown.unknown.example.com: - soa: *soa - ns: *ns1 - ns: *ns2 - mx: *mx - a: 10.1.3.1 ns1.example.com: - a: 10.0.1.1 - aaaa: ::1 ns2.example.com: - a: 10.0.2.1 services: example.com: [ '%ci.%cc.service.geo.example.com', 'unknown.%cc.service.geo.example.com', 'unknown.unknown.service.geo.example.com']
可以看到,为了配置跟域名分区域解析,我们需要为每个区域配置所有类型的记录。而根域名通常有很多记录类型,所以配置起来相对繁琐。上述 YAML 写法使用了变量,这样可以减少配置重复的记录。(&variable
设置变量,*variable
使用变量)
你可以通过配置如下记录进行调试:
debug.tlo.xyz: - a: "%ip4" - aaaa: "%ip6" - txt: "co: %co; cc: %cc; cn: %cn; af: %af; re: %re; na: %na; as: %as; ci: %ci; ip: %ip"
在客户端通过类似下方的指令进行测试(替换 10.11.12.13
为服务所监听的 IP 地址),有如下结果:
$ dig @10.11.12.13 debug.example.com debug.example.com. 3600 IN TXT "co: us; cc: us; cn: na; af: v4; re: ca; na: quadranet enterprises llc; as: 8100; ci: los angeles; ip: 10.11.12.13" debug.example.com. 3600 IN A 10.11.12.13
这样你就可以看到每一个变量的具体值了。
在 PowerDNS 4.2 中,新增了 Lua 记录功能。其 Lua 记录的最主要的功能是可以配置宕机自动切换记录。
由于 Lua 记录可以使用 Lua 编程语言执行任意代码,相对危险,所以 PowerDNS 默认关闭了这个功能,需要在配置文件中开启:
enable-lua-records=yes
配置如下记录,将返回动态的可用 A 记录。如果两个 IP 的端口都可用(这里是 443 端口),则随机返回一个 IP 地址,若有一个不可用,则只返回可用 IP 的地址,否则同时返回两个 IP:
sub.example.com: - lua: A "ifportup(443, {'192.0.2.1', '192.0.2.2'})"
配置如下记录,就可以自动对指定 URL 进行状态检查,默认返回第一组 IP 地址,若第一组 IP 地址不可用,则返回第二组:
sub.example.com: - lua: A "ifurlup('https://sub.example.com/', {{'192.0.2.1', '192.0.2.2'}, {'198.51.100.1'}})"
Lua 记录可以与 GeoIP 功能共同使用,且可以与其他类型的记录共存。另外,状态检查并非与请求同步,而是在后台周期性的检查是否可用,所以使用状态检查不会增加 DNS 请求的延迟。
截止到现在,你的 DNS 服务器应该已经可以工作了。下面将介绍配置 dnsdist。
dnsdist 相当于在 pdns 之上加了一层代理,可以为其配置访问速率的限制,起到抗 DOS 的作用。正常情况下,安装完成 dnsdist 后,其服务就自动启动了。
在这个样例中,将 pdns 的主程序监听改为 127.0.0.1:8053
。创建或修改文件 /etc/dnsdist/dnsdist.conf
为以下内容:
newServer{address="127.0.0.1:8053",useClientSubnet=true}setLocal("10.0.1.1")setACL({'0.0.0.0/0', '::/0'})setECSSourcePrefixV4(32)setECSSourcePrefixV6(128)addAction(MaxQPSIPRule(10, 32, 56), TCAction())addAction(MaxQPSIPRule(20, 32, 56), DropAction())addAction(MaxQPSIPRule(40, 24, 48), TCAction())addAction(MaxQPSIPRule(80, 24, 48), DropAction())addAction(MaxQPSIPRule(160, 16, 40), TCAction())addAction(MaxQPSIPRule(320, 16, 40), DropAction())
newServer
语句设置了 dnsdist 所代理的服务器,也就是 pdns 所监听的 IP 地址和端口号。setLocal
设置了 dnsdist 的监听 ip 地址。setACL
设置了允许的 IP 地址,这里允许了所有的 IPv6 和 IPv4 访问。setECSSourcePrefixV4
和 setECSSourcePrefixV6
设置了 EDNS Client Subnet Client 功能传输 IP 地址的比特数,这里为 IPv4 设置了 32 位,IPv6 设置了 128 位,也就是保留了 IP 地址的完整长度。实际生产中也可以设置比这个更小的值。
后几行 addAction
和 MaxQPSIPRule
定义了访问速率限制。其中 MaxQPSIPRule
拥有三个参数。第一个参数是 qps,即 queries per second,每秒钟请求数。第二个参数是 IPv4 的 CIDR 值,默认为 32,第三个参数是 IPv6 的 CIDR 值,默认为 64。TCAction
代表要求客户端使用 TCP 请求,DropAction
代表拒绝请求。普通的客户端在收到 DNS 服务器要求使用 TCP 时,会使用 TCP 进行 DNS 请求,这样不影响普通用户的使用。而 DOS 一般不会对 TCP DNS 服务进行攻击。
举例,下面语句的意思是:
addAction(MaxQPSIPRule(40, 24, 48), TCAction())
限制 /24 的 IPv4 地址(256 个)和 /48 的 IPv6 地址(2^80 个)的 qps 为 40,若超出则要求客户端使用 TCP 请求。
除了 TCAction 和 DropAction,还可以使用 DelayAction(一个整数参数,代表为延迟的毫秒数)和 NoRecurseAction(专门用于限制标记了递归((RD))的请求)。
因此,将 dnsdist 与 pdns 配合使用,就可以使 DNS 服务有一定的抗 DOS 能力。
]]>TL;DR:固态硬盘(SSD)的性能比机械硬盘(HDD)高 10 倍左右,体积与重量也明显小于 HDD,但单位容量的价格也高了近 10 倍。
固态硬盘(SSD)已经成为了一个比较流行的概念。通常,固态硬盘的各个性能要好于传统机械硬盘(HDD),包括但不限于读写速度、IOPS 等指标。一个普通的机械硬盘的读写速度大概在 100Mbyte/s 左右,而固态硬盘则能达到 1000Mbyte/s 以上,速度比移动硬盘快了近 10 倍。SSD 的 IOPS 性能相比 HDD 可以提升近 100 倍。这些性能提升体现在各个方面:拷贝文件、打开存储在硬盘上的文档和软件软件、启动系统等,最高能有十几倍的速度提升(如果瓶颈是在硬盘读写的话)。当然 SSD 的价格也能比 HDD 高近 10 倍。此外,HDD 相比 SSD 噪音要大很多,SSD 基本是无声的。
市面上销售的移动硬盘多数都是低速的 HDD,因为普通消费者最常关心的是容量和价格,HDD 的每 GB 价格更低,SSD 则贵很多,所以 SSD 的销量也相对的低很多。花 300 块可以买到一个 1TB 的 HDD,而 1TB 的 SSD 可能需要 3000 块。
我是否需要 SSD?要看是否有高性能需求。比如,操作系统和软件就适合安装在 SSD 上,这样启动时间会大大缩短。一些文档、图片和视频等数据则可能不是那么需要 SSD。如果你是图像/视频工作者,需要存储高画质的图像/视频,那么 SSD 就会很有用,它可以大大缩短文件的加载时间;当然很多软件也为低性能设备做了优化,比如 Lightroom Classic CC 可以生成预览(Preview)以减少文件大小;Final Cut Pro 和 Premiere CC 可以为原始素材生成代理(Proxy)以减少文件大小,你可以将预览或代理存储在 SSD 上,原始文件存储在 HDD 上以节省成本。此外,一些访问频率很低的数据也可以存储在 HDD 上以节省成本,如数据备份、监控视频、日志等。
此外,SSD 能有更轻的重量,更小的体积,以至于 SSD 可以做成 U 盘大小。而 HDD 就会大很多。以现在常用的最小的 2.5英寸 HDD 为例,其长度为 10cm,宽度为 7cm,这还不包含外壳部分。上图所示的 SSD 的长宽高仅有 3.0cm * 2.7cm * 0.4cm,重量也不到 40g。其长度不到 HDD 的三分之一。
SSD 也可以做到很大的容量,比如 15英寸 MacBook Pro 甚至可以选择高达 4TB 容量的 SSD。但由于 SSD 的价格过于昂贵,导致大容量的 SSD 并不流行。
SSD 外设有着如此之高的读写速度,以至于只有使用 5Gbps 的 USB3.0 和 USB3.1 Gen1,或者 10Gbps USB3.1 Gen2 才能体现出它的性能,这些接口的速度对于 SATA SSD 已经够了。然而,若要发挥出其全部性能,则需要使用 20Gbps Thunderbolt 2 或者 40Gbps Thunderbolt 3 接口,因为多数的 NVMe SSD 读写性能大于 10Gbps 而不超过 20Gbps。使用 480Mbps USB2.0 的 SSD 几乎是无意义的,所以你也很难找到这种产品。不同接口的 SSD 外设价格也区分的很明确,使用的接口越高端就越贵。使用 Thunderbolt 接口的移动 SSD 价格会比使用 USB 接口的贵 23 倍(速度快 24 倍)。
Thunderbolt3 接口的外形与 USB Type-C 外形完全一样,有些移动硬盘使用了 Type-C 接口,但不代表它就是 Thunderbolt3。你可能需要通过观察其是否有 Thunderbolt 的 ⚡️标志来判断是否支持 Thunderbolt。此外,使用 Thunderbolt3 接口的移动硬盘未必支持 USB 协议,例如我购买的 HP P800 移动硬盘,就不支持 USB 协议,且不能转接成 USB,同时也不能转接成 Thunderbolt2,所以其兼容性就大打折扣。而 USB3.x 的设备通常兼容 USB2.0,且 USB Type-A 与 Type-C 也能相互转接,所以 USB 设备有着更好的兼容性。
SSD 移动硬盘类似与普通的移动硬盘(基于 HDD),但有着更高的性能。通常,SSD 移动硬盘的体积也会更小。
SSD U盘相当于更小的 SSD 移动硬盘,其体积可能和普通的 U 盘相近。由于体积的减小,SSD U盘读写性能与散热性能通常不如 SSD 移动硬盘。且更少有支持 Thunderbolt 的 U 盘。
HP P800 SSD | CHIPFANCIER SSD | |
---|---|---|
接口 | Thunderbolt3 | USB3.1 Gen2 Type-C |
类型 | 移动硬盘 | U 盘 |
大小(毫米) | 141x72x19 | 72x18x9 |
读取速度 | 2400Mbyte/s | |
约 500Mbyte/s | ||
写入速度 | 1200Mbyte/s | 约 450Mbyte/s |
容量 | 256GB/512GB/1TB/2TB | |
(2TB 版本尚未发布) | 128GB/256GB/512GB/1TB |
通常硬盘需要格式化后再使用。在格式化硬盘时,你就需要选择磁盘格式。在这里比较一下四种格式:APFS、NTFS、exFAT 和 FAT32。(某些软件和文档只能安装或存储到特定的磁盘格式中,就不再表里列举了)
APFS | NTFS (v3.1) | exFAT | FAT32 | |
---|---|---|---|---|
发布年份 | 2017 | 2001 | 2006 | 1977 |
适用介质 | 建议 SSD | |||
不限 | 不限 | 不限 | ||
Windows 兼容 | – | 支持 | 7+**** | |
支持 | ||||
macOS 兼容 | 10.12+ | |||
(Sierra) | 支持* | 支持 | 支持 | |
Linux 兼容 | – | 支持* | – | 支持 |
移动兼容 | – | – | 支持 | 支持 |
快照 | Snapshots | Shadow Copy** | – | – |
加密 | FileVault | BitLocker** | – | – |
Copy-on-Write | 支持 | – | – | – |
空间共享 | 支持 | – | – | – |
最大文件大小*** | ∞ | ∞ | ∞ | 4GB |
最大分区大小*** | ∞ | ∞ | ∞ | 32GB |
关于操作系统兼容,若该操作系统绝大多数主流版本都支持,则算作 “支持”。_移动兼容_只要同时兼容 iOS 和安卓就算 “支持”。
关于 iOS,目前 iOS 系统仅支持导入外置存储的图片和视频,且外置存储的图片和视频必须按照相机文件结构命名;尽管 iOS 内置存储使用的是 APFS,但还不支持基于 APFS 的外部存储。
磁盘格式对硬盘性能影响不大,主要看其兼容性与功能。但兼容性好的功能少,功能多的兼容性差。
通过使用 SSD 外设,可以在保证较高的性能的同时扩展电脑的储存。然而,你甚至可以把电脑操作系统安装在 U 盘上,这样你不用分区也能使用目标操作系统开机。如果你将操作系统安装到 HDD 移动硬盘上,其启动速度就会很慢;如果安装到普通 U盘上,其启动速度几乎是不能忍受的。因此建议将操作系统安装到 SSD 外设上。
macOS、Windows 和 Linux 都可以被安装在 U盘或者移动硬盘上。但 Windows 对各种硬件兼容的最好,如果你需要在 PC 机上使用,那么只推荐 Windows 系统。Windows 10 企业版支持 Windows To Go 功能,专门为安装在 U 盘或移动硬盘上时进行了优化。
要安装 Windows To Go(WTG) 需要有 Windows 环境,可以是安装 Windows 的 PC、使用 BootCamp 的 Mac,或者是运行有 Windows 的虚拟机。如果你恰好使用 Windows 10 企业版,那么你可以使用系统控制面板中的 WTG 工具(然而我用系统自带的工具安装失败了)。否则你只能使用第三方工具安装 WTG。这里推荐这个 WTG 辅助工具。
安装成功后,你可以在电脑启动时选择从 U 盘启动,或者在虚拟机里从 U 盘启动。这里展示一下在 Mac 上启动 WTG 以及 macOS 上的 VMware Fusion 中启动 WTG。
以上视频是在 Mac 上开机直接进入 WTG。如果你的 Mac 配备了 T2 安全芯片,那么你需要关闭启动安全性检查(无安全性、允许从外部介质启动)才能够从外部设备启动 Windows。你可以考虑开启固件密码以继续保证安全性(没有 T2 芯片的 Mac 也可以开启固件密码)。提示:请牢记固件密码,固件密码一旦忘记只能返厂修。
刚安装完的 Windows 可能没有 Mac 的鼠标和触摸板的驱动。你需要通过 USB 鼠标和触摸板来完成安装工作(Magic Keyboard 2 和 Magic Trackpad 2 连线后也可作为 USB 外设)。
你需要为 Windows 安装 Mac 的驱动。在 Mac 的 “启动转换”(Boot Camp)软件中的 “操作” 菜单里可以手动 “下载 Windows 支持软件”(驱动)。注意,不同型号的 Mac 的驱动不同,建议使用系统的软件下载。如果你需要在多个 Mac 上使用一个 WTG,你需要安装多个驱动。启动转换助理是帮助用户在 Mac 本地硬盘上安装 Windows 双系统的,不能用来安装 Windows To Go,这里只是用它安装驱动。
建议将驱动保存在另一个 Windows 可以识别的 U盘上(见本文的 “磁盘格式的选择”)。然后再次开机进入 WTG 后就能安装了。
如果你有虚拟机,你也可以在虚拟机里从 U 盘启动。
如果不启用 BitLocker,那么 U盘上所有用户文档都是明文存储的,也就是说只要有了你的 U盘,就能读取所有的用户数据。若启用了 BitLocker,那么磁盘数据安全性就能得到保证。然而 Mac 没有 BitLocker 的相关硬件支持,默认无法启动 WTG 中的 BitLocker,需要修改 Windows 下的配置文件。
启用 BitLocker 后会些许增加系统的 CPU 占用,略微降低磁盘性能。此外,启动了 BitLocker 的磁盘 macOS 无法识别,意味着在 macOS 系统上无法读取开启了 BitLocker 的 Windows 分区。建议谨慎开启。
将 Windows 安装到 U盘不但节省了电脑内的磁盘空间,还有了一个可以随身携带的操作系统,可以在 Mac 和 PC 机上使用。我没有开启 BitLocker。我在 macOS 上开启了 NTFS 读写,所以其 Windows 分区还可以被当作 U盘共享数据使用。
我在 WTG 上安装了一些常用软件,在其他 PC 机上未必需要进入 WTG 系统以使用这些软件,而直接进入 WTG 根目录下 Program Files 文件夹里访问这些软件就行了。
我将 Windows 安装到了 CHIPFANCIER 出的 SSD U盘上,其特色是使用了 USB3.1 Gen2 Type-C 接口,这样不需要转接就能够在新 Mac 上使用。然后我又购买了绿联的 Type-C 转 Type-A 的转接头(USB 3.0),可以将此 U 盘转接到 Type-A 设备上。
]]>这次的 5.0 是一个大版本更新,而不像之前的 4.9、4.8 更新那样,这从版本号就可以看出。
这个新的块编辑器(Gutenberg Editor)给人的第一感受就是更加简洁了,这个新的编辑器有着更大的留白。初次使用编辑器的时候会感觉有些不适应,这是因为新的编辑器中没有我们熟悉的工具条了。取而代之的是一个简单的添加块(Add Block)按钮和其他的一些基本操作。
在新版的编辑器中,每一个自然段、图片、副标题、引用等都是一个 “块”。你可以为每个块进行自定义操作,如为每个自然段设置不同的字体大小、字体颜色,甚至是背景色和自定义 CSS。而这一切都是通过右侧的 “组件” 工具可视化的实现的。
你可以直接拖移块,以实现拖移自然段等效果。
新版编辑器兼容老板编辑器。要想使用老款的编辑模式,可以通过插入一个或多个经典块(Classic Block)来实现。这个经典块与新编辑器中的其他块(如自然段块、副标题块等)同等级别。经典块中能包含一个或多个自然段、副标题,对于简单的排版,它可以代替最新的块编辑器。在使用经典块时,你依然能够看到你所熟悉的工具条。
经典块截图
在编辑以前发布的文章与页面时,默认依然使用原有的编辑模式,即在新的编辑器中包含一个经典块。
原有的块都是与 HTML 标签对应的,功能相对少一些。经典块用于兼容上一代编辑器。要想使用新特性,你需要学习使用这些新的块。
<p>
<h1>
~ <h6>
标题。<ul>
或 <ol>
列表。<!--more-->
。<img>
。<blockquote>
。新版的应用块支持了引文(Citation)。video
Shortcode。<hr>
。<pre>
。<pre>
和 <code>
组合。新版本中新增了很多块,通过使用这些块,你可以直接可视化地插入一些你想要的内容,而不用编辑源代码或者是使用插件。
<pre>
实现的。可以实现英文字符的等宽显示。以下内容原本可以作为 Widgets 在网页菜单中添加。现在还可以作为块在文章中直接添加。
除此之外,现在还有了嵌入(Embed)功能,可以直接嵌入第三方内容了,如 Twitter、YouTube、SoundCloud 等。
为了更好的配合新的编辑器的所有排版功能,WordPress 同时推出了全新的 2019 默认主题。详情
正如以往的默认主题一样,新的 WordPress 主题也是十分通用的。然而我感觉新的 2019 主题不如上一个 2017 主题(即本 Blog 正在使用的主题)简洁。
WordPress 不保证老版本继续提供安全性更新,所以你应该升级到最新的 5.0 版本。然而实际上,从 WordPress 的版本历史可以看出,目前 WordPress 仍在维护 3.7(发布于 2013-10-24)及之后的所有版本。所以即使你不更新 5.0 版本,你也可能继续收到安全性更新。
需要注意的是,每次更新 WordPress 版本,尤其是大版本更新,其源代码中的一些函数功能会有所改变,这意味着并不保证你的插件能够在新的 WordPress 中正确运行。你应当检查一下你所启用的插件是否能够在最新版本上正确运行,或者已经发布了适配新版本的更新。如果你是插件开发者,你应该有安装测试版 WordPress 的站点,并早该让你的插件适配最新的版本。
在升级前,请务必备份你的站点。对于 WordPress 而言,你需要备份 WordPress 的代码目录以及数据库内容。
]]>本文包括 Azure DNS、NS1、Constellix 的全面对比。
这次推荐的三家 DNS 均是海外的支持 GeoDNS 的服务商,并都支持 Anycast。其中的 Azure DNS 和 NS1 在国内的速度都非常好,是直接走的香港/亚洲线路,平均延迟能够在 50ms 以内,不输国内 DNS 服务商。而这三家的海外速度都是极快的,可以秒杀 DNSPod、CloudXNS、阿里云解析等国内提供商。
关于 GeoDNS,精细度最好的是 Constellix:支持国家、省、市(包括中国的省、市),甚至是 AS 号(可以实现分运营商解析)、IP 段。NS1 支持国家、美国的州,也支持 AS 号、IP 段。至于 Azure DNS,通过使用 Traffic Manager,可以支持国家、部分国家的州、IP 段。由于都支持 IP 段,所以理论上支持任意精度的 GeoDNS 了。
至于价格,NS1 提供了免费额度(每月 500k 请求),对于小流量网站而言是够用的,可一旦超出这个免费额度,那么收费是很高的:**$8/百万个请求**。相比而言,Azure DNS 和 Constellix 的价格都很便宜了,其中 Constellix 有 $5/月 的起价。
同时使用多家 DNS 服务商是可行的,只要使用服务商的 DNS 记录保持相同即可。这要求所使用的服务商能够配置主域名的 NS 记录(建议但不是必须)。这次介绍的 Azure DNS、NS1、Constellix 三家,以及以前介绍过的 Route 53、Google Cloud DNS、Rage4、阿里云解析均可配置主域名的 NS 记录(其中阿里云解析和 Azure DNS 只能额外添加第三方记录;其他几家可以完全自定义 NS 记录)。而 Cloudflare 以及国内的 DNSPod、CloudXNS、阿里云解析由于不能配置主域名下的 NS 记录,意味着你不能很好的进行 DNS 混用。
要使用多家 DNS,有两种实现方法:主服务商和从服务商方式以及两个主服务商方式。完成配置后,将多家的 NS 服务器配置到权威 NS 记录以及域名注册商下的 NS 列表。
使用两家服务商会增加配置难度,但可以提高 DNS 服务的稳定性。如最近的 DNSPod 宕机以及 2016 年的 Dyn 宕机所导致的众多网站无法访问,均是因为众多网站仅使用了一家 DNS 提供商。如果使用了多家 DNS 提供商,则网站仅会在所使用的所有服务商均发生宕机事故时才会无法访问,而这显然发生概率很小。
要想这样配置,需要从服务商支持使用 AXFR 从主服务商获取记录,还需要主服务商也支持 AXFR 传输。其中,NS1、Constellix 均可作为主服务商或从服务商,意味着你可以同时使用这两家,并选择任何一家作为主服务商,另一家作为从服务商。
你也可以使用两个主服务商,并保持所有的记录(包括主域名下的 NS 记录)相同(建议,但不是必须)。建议也将 SOA 的序列号同步。
github.com.
这个域名就同时使用了 Route 53 和 DYN 的服务。这可以使用 dig 工具验证。
$ dig github.com ns +short ns1.p16.dynect.net. ns2.p16.dynect.net. ns3.p16.dynect.net. ns4.p16.dynect.net. ns-1283.awsdns-32.org. ns-421.awsdns-52.com. ns-1707.awsdns-21.co.uk. ns-520.awsdns-01.net.
经检验,在两家 DNS 服务商也配置了相同的记录。
$ dig @ns1.p16.dynect.net. github.com a +short 13.229.188.59 13.250.177.223 52.74.223.119 $ dig @ns-1283.awsdns-32.org. github.com a +short 13.229.188.59 13.250.177.223 52.74.223.119
下面逐个介绍一下这三家 DNS 提供商。
所有 DNS 测评一览(还包括 CloudXNS、Route 53、Cloudflare、Google Cloud DNS、Rage4 以及阿里云解析)
微软 Azure 产品线下的 DNS 服务。使用 Anycast 技术,并且国内能够直接连接到香港/亚洲节点,所以速度很快。
值得注意的是,类似 Route 53,Azure 所分配的四个服务器使用的是不同的网段、不同的线路,可能有更高的可用性。
注意:Azure 的 DNS 的分区解析可能不兼容 IPv6,这意味的解析结果可能会被 Fallback 到默认线路。
NS1 也使用了 Anycast 技术,并且国内能够直接连接到香港/亚洲节点,所以速度很快。
此 DNS 以 GeoDNS 优势著称,使用了 Anycast 保证最低的延迟。
Constellix 三组有六个 DNS 服务器,每一组使用了不太相同的线路。
对于新用户而言,要清楚获得 Mac 软件的两种正确方式:从 App Store 下载/通过互联网下载。从 App Store 下载软件最为安全,因为所有上架 App Store 的软件均通过了苹果的审核;从互联网下载的软件要小心一些,因为它可能是恶意软件,详情请看本文的 “Mac 系统安全” 一节。
US$10/月两台 Mac 或 $15/月两台 Mac + 五个子账户。合买家庭版约每年 CN¥200。 Setapp 相当于另一个 Mac App Store。不同的是,Setapp 是订阅制的,相比买断软件,你只需要每月花固定的钱订阅 Setapp,然后就能够免费地下载与 Setapp 合作的所有软件,并享受后续更新,而这些软件原本都是需要付费买断(或者需要额外订阅/内购)的。 Setapp 的价格是 US$10/月,可以在两台 Mac 上使用,额外的 Mac 每台 $5/月。而最近新出的家庭版仅需要 $15/月,可以额外添加五个子账户(子账户仅限在一台 Mac 上使用)。所以如果组团合买家庭版的话会非常实惠,价格大约在每年 CN¥200 左右。 本文介绍的很多软件都是包含在 Setapp 中的,如果已经订阅了 Setapp 就无需额外购买,这些软件已经标注。
付费软件,可以通过 Setapp 下载 该软件可以自定义 Mac 触摸板和鼠标手势,充分发挥多点触控的功能。此外,通过使用其内置的 Window snapping 功能,可以实现类似 Windows 的 “移动窗口到屏幕边缘迅速调整窗口大小的功能”。我现在用 BetterTouchTool 主要就是在用其 Window snapping 功能。
免费软件 内容拦截器。通过使用此浏览器插件,可以屏蔽掉网页上烦人的广告,还给你清净的浏览体验。同时还能够达到省电的效果。
免费软件 解压缩软件。可以解压缩 Mac 系统不支持的 RAR 等压缩格式。
付费软件,可以通过 Setapp 下载 可以选择性的隐藏 Mac 菜单栏图标。当安装第三方软件越来越多的时候,菜单栏会越来越满。通过使用 Bartender,可以隐藏/折叠显示一些菜单栏图标。同时还可以配置使得在菜单图标有更新的时候再自动显示。
免费 + 内购软件,可以通过 Setapp 下载并解锁内购 可以通过图片或文字自动生成多种样式的图标,并应用到文件/文件夹/磁盘上。可以帮助你生成个性化的、漂亮的文件/文件夹/磁盘图标。
付费软件,$39.99 买断 Carbon Copy Cloner(CCC)是一个功能齐全的备份管理软件。相比 Mac 自带的 Time Machine(时间机器),它可以备份外部磁盘、选择目录备份,还可以备份系统到 APFS 格式的硬盘,并创建可启动的外部磁盘。这个软件全面支持了 APFS 下的快照(Snapshot)功能,并有可视化界面去管理这些快照(支持挂载、恢复、删除等操作)。 个人建议:对于 Time Machine 能够适用的场景,优先使用 Time Machine,否则使用 CCC。
付费软件,可以通过 Setapp 下载 CleanMyMac 可以帮助用户清理系统垃圾文件、卸载软件、管理开机启动项、实现基本的系统监控。
个人建议:除非系统空间不足,否则不要频繁清理系统垃圾,尤其是用户缓存文件和系统缓存文件,清理他们可能反而导致程序运行变慢。
付费软件,可以通过 Setapp 下载 它可以查找磁盘中的重复项目或相似项目,并可选择删除这些文件,为你的 Mac 腾出更多的磁盘空间。
免费 + 内购软件,可以通过 Setapp 下载并解锁内购 Mac 上的磁盘恢复软件。如果误删除了重要文件,并且没有任何备份,可以尝试使用此软件恢复文件。强烈建议做好文件备份,这样你就不需要使用这类软件了。然而关键情况下使用这个软件救急还是不错的。
订阅软件,可以通过 Setapp 解锁订阅 除了系统自带的备忘录、Pages,以及微软的 Word,这里额外推荐一个 Ulysses,基于 Markdown 的纯文本编辑器。特点就是简洁易用。
付费软件,可以通过 Setapp 下载 可以代替 iTunes 完成备份/恢复备份/重新安装系统/升级系统等操作,并有着比 iTunes 更多的功能。比如说它可以可以访问备份中的具体数据,包括每个程序的软件存档等。还可以管理应用程序,通过 .ipa 文件安装上一版本的软件或者已经下架的软件,管理手机铃声等。 当然,在 Mac 上管理 iOS App 更推荐使用 Apple Configurator 2。
付费软件,可订阅或买断 相比浏览器(如 Safari、Chrome)自带的密码管理功能,1Password 可以支持更多的浏览器,并且是跨平台的。它能够选择密码生成的公式,通过 Watchtower(瞭望塔)能够自动检查不安全的密码、已泄漏的密码等,同时还能够保存更多类型的资料,如信用卡、身份证、驾照、数据库、无线路由器资料等。 通过使用 1Password,你可以养成为每个网站设置不同的、安全的随机密码的习惯,保障互联网账户的安全。
除了 Apple 的 Xcode,这里罗列一些开发的工具供大家参考:
免费软件 界面简洁漂亮,支持很多格式的视频播放,并且适配 Touch Bar。
付费软件,可以通过 Setapp 下载 跨平台的 RSS 阅读器(iOS 端需要单独购买),可以通过 iCloud 同步。
订阅软件,可以通过 Setapp 解锁订阅 Mac 上的记账软件,功能齐全,可以添加各种类型的账户,并且可以生成多种格式的报表。
付费软件,有学生优惠 苹果推出的专业视频制作软件,相当于 iMovie 的升级版,可以进行更多的自定义设置,拥有摄影机录制的 RAW 视频的处理能力,可以制作 360 度的视频等。相比 Adobe Premiere Pro CC,它会更加易用一些,价格也相对便宜。
订阅软件,港区 Photography Plan,包含最新版的 Lightroom Classic CC、Lightroom CC、Photoshop CC 以及 20GB 的云端存储空间。 苹果曾开发的图像处理软件,iPhoto 已经整合到了 Photos(图片)软件中,专业软件 Aperture 也停止了维护。而 Photos 软件虽然很好用,足以处理绝大多数的照片,但对于 RAW 格式的照片的处理能力依然很弱。而且其云同步是同步库中的所有照片和视频,这对于无损图片而言是不不经济的。 Lightroom 系列软件和 Photos、iPhoto、Aperture 功能类似,也是用于管理照片的。目前的两个版本:Classic CC,只有桌面端,适用于将所有图片的原始文件存储在本地;CC,有桌面端、移动端、Web 端,适用于将所有图片的原始文件存在云端。 个人倾向于在桌面端使用 Classic CC,移动端使用 CC。因为经常要处理到的 RAW 格式或者是 TIFF 格式的无损图片都很大,将原图上传到云端并不经济。而且我处理图像主要在桌面端进行,CC 的桌面端感觉是为了迁就其他平台而在桌面端使用并不是那么方便。并且,Classic CC 也能够将压缩后的预览传输到云端,并也可以实现在其他平台上使用 CC 同步编辑。对于同步预览,Photography Plan 20GB 的空间已经足够了。 注意:中国区的 Creative Cloud 功能有所阉割,且没有优惠的套餐。建议购买港区(最便宜)。
和 Windows 系统一样,在 Mac 上从互联网上安装软件也需要多注意软件来源。这里强烈推荐在 Mac 设置中的 “安全性与隐私” 中选择 “App Store 和被任何的开发者”(默认),而非 “任何来源”。如果允许了任何来源,你的电脑将可以运行被篡改的软件,未经认证的软件以及恶意软件。
绝大多数的 Mac 软件均可以在这个安全级别上运行,上述推荐的所有软件均不需要启用 “任何来源”,除非你下载到的不是原始软件,而是被篡改过的。 如果你的 Mac 里这里的选项是 “任何来源”,请在终端中运行以下指令重新启用这个安全设定。
sudo spctl --master-enable
同时,也不建议关闭 SIP 功能,SIP 功能有助于保障 Mac 系统的完整性。查看 SIP 是否运行可以通过以下指令:
csrutil status
如果 SIP 已经启用(默认),会得到 System Integrity Protection status: enabled.
结果。
以上的数据丢失都给人们带来了巨大的损失,但倘若我们能够提前做好数据备份,那么就能够降低数据后的损失。
在进行备份的过程中,我们应该施行 321 原则,这样才能保证备份的可靠性与有效性。
此外也应该注意备份的时效性,如果可能,要尽量缩短备份周期。比如每分钟备份的时效性就强于每小时备份。在数据丢失时,前者只会丢失最近 1 分钟的工作,而后者会丢失最近 1 小时的工作。
通常,云端备份是非常可靠的。云端服务器都会帮你做好 321 原则,你只需要选择一家云存储服务商并将要备份的文件上传上去即可。
建议选择提供了自动化备份功能的服务商,这样可以省去手动选择文件上传的步骤。通常自动备份还会对文件进行增量备份,即每次备份只上传上一次备份后有改动的文件,这样能大大节省上传时间。
一个典型的云端备份的例子是 iOS 中的 iCloud 备份功能,开启该功能后,iOS 设备会自动将图片、通讯录、文档、聊天记录、软件存档等个人数据上传到云端。在购买新的 iOS 设备后,这些数据都能够从云端自动恢复到新设备上。
定期将服务器上的重要文件打包上传到对象存储,即可实现简单的备份。可以直接使用 Amazon S3、Google Cloud Storage、阿里云 OSS、腾讯云 COS 的对象存储,上述服务均提供 99.999999999% 的持久性,即文件一旦上传完毕,几乎不可能意外丢失。云服务中的对象存储通常是在一个区域内的多个可用区(通常至少三个)进行存储,每个可用区内也包含文件的多个副本。各个可用区之间有一定的距离,所以这实现了异地。关于区域和可用区,可以详细参考 AWS 的这篇文章。
云服务的对象存储一般都可以选择地区。通常选择地理位置最近的地区以获得最低的延迟。这些服务通常是按照使用量计费的,主要包括在一定时间内占用的存储空间以及传输数据所用的流量费用。比如你要备份 1GB 的数据,那么每月可能只需要几块钱或几毛钱,甚至是免费的。(不同服务商收费不一)
很多服务器上的软件已经集成了使用对象存储进行备份的功能:在服务提供商开通了对象存储后,只需要在软件中配置好授权密钥,就可以使用对象存储进行备份了。如果软件没有集成这种备份功能,那么也可以手动实现简单的备份。比如,使用 mysqldump
导出数据库文件,使用 gzip
、 tar
命令压缩、打包要备份的文件。通常对象存储的提供商也有提供命令行工具,使用这些工具可以简单的将文件上传到对象存储中。如 AWS 有 aws
,支持 S3 操作;Google Cloud Storage 有 gsutil
;阿里云 OSS 有 ossutil
;腾讯云有 tccli
,支持 COS 操作。
通常快照可以备份服务器磁盘上的所有数据。从快照中恢复也十分方便。这甚至都不需要服务器上的软件支持备份功能。不管是服务器磁盘损坏、系统文件丢失,还是文件删除,都可以从快照中恢复。
如果条件允许,建议同时使用对象存储备份和快照备份。
尽管云端备份简单、持久性高,但备份大容量的数据的速度与带宽成正比。何况备份所需要的是上行带宽,这通常是运营商所标称的下行带宽的几分之一。而仅仅是使用普通的机械硬盘进行备份,其速度就已经达到了千兆网络的速度,而千兆网络普及率低且价格极其昂贵。所以,遇到数据量大、带宽受限、备份/恢复时间有限等一种或几种情况时,本地备份也许更为合适。
在本地备份则需要自己做好 321 原则。你需要将数据备份到两个硬盘上(通过局域网或有线连接),并将其中一个硬盘存放在异地。很多桌面操作系统都支持了备份,你可以在最新的 Windows 系统的控制面板中找到备份功能,在 macOS 上使用时间机器(Time Machine)进行备份。建议配置好自动备份。
如果条件允许,建议在本地备份的同时,将较重要的文件再备份到云端。
我们应该保留文件的早期版本,以便不时之需。保留多个历史版本的文件使用增量备份有助于节省存储空间。如果条件允许,应保留尽可能多的历史版本。
早期的版本可以有相对更长的时间间隔,以便节省空间:像 macOS 中的时间机器(Time Machine),它会保留过去 24 小时的每小时备份、过去一个月内的每日备份、以及过去一个月以上的尽可能多的每周备份,直到磁盘空间填满。
一些网络存储会自动保留历史版本,比如 Dropbox、Google 云端磁盘、iCloud 等。一些软件也会在本地磁盘里保留历史版本。比如 Git 就会保留每一次提交的历史。
建议首先对重要文件保留历史版本,如果可能对所有文件保留历史版本。
通常对象存储提供多种存储类别,不同存储类别有不同的定价和使用场景,合理的使用多种存储类别可以节省支出。
按存储价格由高到低排序,持久性均为 99.999999999%,均为多个可用区。
大于 128kb 的且不经常访问的备份建议存储到 STANDARD_IA,几乎不会再访问的早期的历史版本可以存储到 GLACIER。
按存储价格由高到低排序,持久性均为 99.999999999%,均为多个可用区。
同样的,不经常访问的备份建议存储到 Nearline,几乎不会再访问的早期的历史版本可以存储到 Coldline。
按存储价格由高到低排序,持久性均为 99.999999999%,均为多个可用区。
同样的,不经常访问的备份建议存储到低频访问型,几乎不会再访问的早期的历史版本可以存储到归档型。
]]>从上一篇文章中已经知道,在你访问一个网站,比如 www.example.com
时,浏览器发送一个 DNS 消息到一个 DNS 缓存服务器上去查询,由于 DNS 系统的庞大,这中间还需要经过好几层 DNS 缓存服务器。想要正确访问到这个网站,就需要这所有的缓存服务器都要正确的响应。
DNS 查询是明文传输的,也就是说中间人可以在传输的过程中对其更改,甚至是去自动判断不同的域名然后去做特殊处理。即使是使用其他的 DNS 缓存服务器,如 Google 的 8.8.8.8
,中间人也可以直接截获 IP 包去伪造响应内容。由于我所在的国家就面临着这个问题,所以我可以轻松的给大家演示一下被中间人攻击之后是什么个情况:
$ dig +short @4.0.0.0 facebook.com243.185.187.39
向一个没有指向任何服务器的 IP 地址:4.0.0.0
发送一个 DNS 请求,应该得不到任何响应。可是实际上在我所处的国家却返回了一个结果,很明显数据包在传输过程中“被做了手脚”。所以如果没有中间人攻击,效果是这样的:
$ dig +short @4.0.0.0 facebook.com;; connection timed out; no servers could be reached
DNS 系统就是这么脆弱,和其他任何互联网服务一样,网络服务提供商、路由器管理员等均可以充当“中间人”的角色,来对客户端与服务器之间传送的数据包进行收集,甚至替换修改,从而导致客户端得到了不正确的信息。然而,通过一定的加密手段,可以防止中间人看到在互联网上传输的数据内容,或者可以知道原始的数据数据是否被中间人修改。
讲到 DNSSEC,就不得不讲到一些密码学的知识。这里从最基本的密码学开始讲起。 密码学主要分为三大类,这里也列出每一列常用的加密算法:
在 DNSSEC 中,主要使用到的是公钥密码学和数据完整性算法两种加密学。
公钥密码主要是与对称密码进行区分:对称密码的加密与解密使用相同的密钥;而公钥密码使用的加密密钥叫做公钥,解密密钥叫做私钥——两种密钥相对独立,不能替代对方的位置,而且知道公钥无法推出私钥。这两种密码学都必须是可逆的(所以解密算法可以看作加密算法的逆)。以函数的形式表达的话如下:
密文 = 加密算法(密钥, 原文)
原文 = 解密算法(密钥, 密文)
密文 = 加密算法(公钥, 原文)
原文 = 解密算法(私钥, 密文)
当然,如果私钥充当公钥,公钥充当私钥,那么就是这样的:
密文 = 加密算法(私钥, 原文)
原文 = 解密算法(公钥, 密文)
假如服务器要向客户端发送一段消息,服务器有私钥,客户端有公钥。服务器使用私钥对文本进行加密,然后传送给客户端,客户端使用公钥对其解密。由于只有服务器有私钥,所以只有服务器可以加密文本,因此加密后的文本可以认证是谁发的,并且能保证数据完整性,这样加密就相当于给记录增加了**数字签名**。但是需要注意的是,由于公钥是公开的,所以数据只是不能被篡改,但可以被监听。 此处的服务器如果是充当 DNS 服务器,那么就能给 DNS 服务带来这个特性,然而一个问题就出现了,如何传输公钥?如果公钥是使用明文传输,那么攻击者可以直接将公钥换成自己的,然后对数据篡改。
所以,一个解决的方法是使用一个被公认的公钥服务器,客户端的操作系统中在本地先存好这个公钥服务器自身的公钥。当与服务器通信时,客户端从这个被公认的公钥服务器通信,用户使用操作系统中内置的公钥来解密获得服务器的公钥,然后再与服务器通信。
然而 DNS 是一个庞大的系统,在这个系统中根域名服务器充当了被公认的公钥服务器,其中每一个一级域名服务器也是一个子公钥服务器。最后一张图,就是 DNSSEC 的基本雏形了。
在密码学中,还存在一种检查数据完整性的算法,其 “加密” 无须密钥,密文不可逆(或很难求逆),而且密文与原文不是一一对应的关系。而且,通过此算法算出的密文通常是一个固定长度的内容。通过此算法算出的密文叫做哈希值。在 DNSSEC 里所运用到它的特性是:原文一旦修改,密文就会发生变化。 公钥密码学存在的一个很重要的问题:加密和解密的速度相对于对称密码太慢了。所以想要提高性能,就需要减短需要加密和解密的文本。如果只是对文本的哈希值加密,由于长度的减短,加密速度就能大大提高。在服务器传送时,同时传送明文的文本和使用私钥加密的文本哈希值;客户端只需要先算出收到的明文文本的哈希值,然后再用公钥解密密文,验证两个值是否相等,依然能够防止篡改。 在 DNSSEC 中就运用了这种方法,无论是对密钥还是记录的加密。
DNSSEC 这一个扩展可以为 DNS 记录添加验证信息,于是缓存服务器和客户端上的软件能够验证所获得的数据,可以得到 DNS 结果是真是假的结论。上一篇文章讲到过 DNS 解析是从根域名服务器开始,再一级一级向下解析,这与 DNSSEC 的信任链完全相同。所以部署 DNSSEC 也必须从根域名服务器开始。本文也就从根域名服务器讲起。
DNSSEC 和 HTTPS 是两个完全不同的东西,但是这里只是对其加密方式对比。即 DNSSEC 的加密方式与 TLS 进行对比。
在配置 DNSSEC 的时候,如果与 HTTPS 比较,可以看出来:证书和私钥全部都是在自己的服务器上直接生成的,也就意味着这是 “自签名的”,不需要任何 “根证书颁发商”。二级域名所有者向一级域名注册商提交自己的公钥的哈希值,然后一级域名注册商就会给你的哈希值进行签名,从而也能形成一道信任链,远比 HTTPS 的信任链简单,操作系统也再不用内置那么多个 CA 证书,只需要一个根域名的 DS 记录即可。个人认为这是一个更先进的模式,但是它需要客户端一级一级的去依次解析,于是受到了速度的影响;HTTPS 则是直接由一个服务器返回整条证书链,与服务器进行 HTTPS 的连接时只需要与一个服务器通信。不过,DNS 记录是可以被缓存的,所以能够一定程度上的减少 DNSSEC 的延迟。
你发往 DNS 服务器的请求是明文的,DNS 服务器返回的请求是带签名的明文。这样 DNSSEC 只是保证了 DNS 不可被篡改,但是可以被监听,所以 DNS 不适合传输敏感信息,然而实际上的 DNS 记录几乎都不是敏感信息。HTTPS 的话会同时签名和双向加密,这样就能够传输敏感信息。 DNSSEC 的只签名,不加密主要是因为 DNSSEC 是 DNS 的一个子集,使用的是同一个端口,所以是为了兼容 DNS 而作出的东西,而 DNS 是不需要客户端与服务器建立连接的,只是客户端向服务器发一个请求,服务器再向客户端返回结果这么简单,所以 DNS 都可以使用 UDP 来传输,不需要 TCP 的握手,速度非常快。HTTPS 不是 HTTP 的子集,所以它使用的是另一个端口,为了做到加密,需要先与浏览器协商密钥,这之间进行了好几次的握手,延迟也上去了。
刚才所讲述的所有情况,都是在没有 DNS 缓存服务器的情况下。如果有 DNS 缓存服务器呢? 实际上,一些 DNS 缓存服务器就已经完成了 DNSSEC 验证,即使客户端不支持。在缓存服务器上验证失败,就直接不返回解析结果。在缓存服务器进行 DNSSEC 验证,几乎不会增加多少延迟。 但这也存在问题,如果缓存服务器到客户端之间的线路不安全呢?所以最安全的方法是在客户端上也进行一次验证,但这就会增加延迟了。
DNSSEC 相比 HTTPS 的一个特性就是 DNSSEC 是可以被缓存的,而且即使是缓存了也能验证信息的真实性,任何中间人也无法篡改。然而,既然能够缓存,就应该规定一个缓存的时长,并且这个时长也是无法篡改的。 签名是有时效性的,这样客户端才能够知道自己获得到的是最新的记录,而不是以前的记录。假如没有时效性,你的域名解析到的 IP 从 A 换到了 B,在更换之前任何人都可以轻易拿到 A 的签名。攻击者可以将 A 的签名保存下来,当你更换了 IP 后,攻击者可以继续篡改响应的 IP 为 A,并继续使用原本 A 的签名,客户端也不会察觉,这并不是所期望的。 然而在实际的 RRSIG 签名中,会包含一个时间戳(并非 UNIX 时间戳,而是一个便于阅读的时间戳),比如 20170215044626,就代表着 UTC 2017-02-15 04:46:26,这个时间戳是指这个记录的失效时间,这意味着在这个时间之后,这个签名就是无效的了。时间戳会被加进加密内容中去参与签名的计算,这样攻击者就无法更改这个时间戳。由于时间戳的存在,就限制了一个 DNS 响应可以被缓存的时长(时长就是失效时间戳减去当前时间戳)。然而,在有 DNSSEC 之前,控制缓存时长是由 TTL 决定的,所以为了确保兼容性,这两个时长应该是完全一样的。 通过这样做,即能够兼容现有的 DNS 协议,有能够保证安全,还能够利用缓存资源加快客户端的请求速度,是一个比较完美的解决方案。
其实,即使完全不了解,或者没看懂上面的内容,也不影响你去部署 DNSSEC,只不过你应当非常仔细的对待它,稍有不慎可能导致用户无法解析的情况。
由于是使用第三方的 DNS,部署 DNSSEC 就必须需要第三方支持。常见的支持 DNSSEC 的第三方 DNS 有 Cloudflare、Rage4、Google Cloud DNS(需要申请)、DynDNS 等。开启 DNSSEC 前首先需要在第三方服务上激活 DNSSEC,这样第三方 DNS 才会返回关于 DNSSEC 的记录。 在第三方的 DNS 上激活了 DNSSEC 之后,第三方会给你一个 DS 记录,大概长这样:
tlo.xyz. 3600 IN DS 2371 13 2 913f95fd6716594b19e68352d6a76002fdfa595bb6df5caae7e671ee028ef346
此时,你就需要前往域名注册商,给你的域名提供这个 DS 记录(有些域名注册商可能不支持添加 DS 记录,此时你可以考虑转移到本站的域名注册商或者其他支持 DS 记录的注册商。此外,一些域名后缀也不支持添加 DS 记录,建议你使用主流后缀,如 .com 等,此处就以本站的域名注册商为例):
添加然后保存,一切就 OK 了。注意关键标签(Key Tag)就是 DS 记录里的第一项(此处对应的是 2371),算法(Algorithm)就是第二项(此处对应的是 13),算法类型(Digest Type)就是第三项(此处对应的是 2),整理分类(Digest)就是最后一项。剩下的内容不需要填写。 有的第三方 DNS(比如 Rage4)会给你一下子提供多个 DS 记录(相同的关键标签但是不同的算法和算法类型),然而你不需要都填写上。我建议只填写使用算法 13 与类型 2 或者算法 8 类型与类型 2 的 DS。这两个分别是 Cloudflare 推荐的参数和根域名目前所使用的参数。填写多个 DS 记录不会给你带来多少的安全性提升,但可能会增大客户端的计算量。
使用自建 DNS 首先需要先生成一对密钥对,然后将其添加到 DNS 服务中去。我已经介绍了关于 PowerDNS 的添加 DNSSEC 的方法。 在此之后,你需要生成 DS 记录,通常你生成 DS 记录也是很多个,和第三方 DNS 一样,我建议只向域名注册商提交使用算法 13 与类型 2 或者算法 8 类型与类型 2 的 DS。
在 DNS 中,有一些是安全性相关的记录,比如 DS、TLSA、CAA、SSHFP、IPSEC、以及一些通过 TXT 记录来实现的记录等。安全性相关的记录类型十分建议包含签名,也就是说安全性相关的记录应该使用 DNSSEC。此外,当一个域名下不包含这种记录类型时,也必须返回 NSEC 记录并签名。之前一篇文章中所介绍的 DS 就是一个例子。除了 DS 外,还有这些记录类型:
DANE 可以用于绑定某个域名下的某个服务的证书,也就是说可以让一些原本被客户端信任的证书不被信任,证书颁发商未经网站管理人授权签发的证书可以不被信任,可以实现和 Certificate Transparency 类似的效果。这容易与 HPKP Pin 混淆。HPKP Pin 后者只能使用于 HTTPS 服务,且只有成功且没有劫持的访问过才有效果(所以为了使 HPKP Pin 达到真正安全,必须需要建立一个受信任的中央服务器去 Preload 这些记录,类似 HSTS);DANE 即使是在第一次访问也无法被劫持,而且可以用于 Mail 等域名相关的 SSL 服务,不只限于 HTTPS。 我认为 DANE 的真正有意思的地方是在于它可以让客户端去有选择的信任自签名的证书,也就是说可以让一些原本不被客户端信任的证书被信任:通过 DNS 的方式向浏览器告知这个网站自签名证书的公钥,由于包含了签名,浏览器就能够知道这是域名所有者的公钥,就能够在这个域名下信任这个自签名的证书。这打破了目前常用的 CA 机制,网站管理者也再也不用去向 CA 花钱或者是不花钱的申请证书,而是直接使用自签名证书甚至是自己管理的 CA 签发的证书,操作系统也不再需要选择去信任哪些根证书,也能避免传统证书签发商系统存在结构性缺陷(比如证书签发商通过自己签发证书来进行 HTTPS 中间人等)。然而实现这一步首先需要客户端的支持,已经开始有程序开始支持,然而却还没有看到浏览器去支持的迹象。 使用了自签名证书的 HTTPS 且配合了 DANE 的站点与常规 HTTPS 站点的信任链对比:
注:域名 tloxygen.com 只是在本地环境中进行的测试,公网无法访问
实现 DANE 的方式主要是通过 TLSA 记录: TLSA 记录包含了证书的哈希值,或者是某一个中间证书的哈希值(或者也可以是完整的证书)。同时,它可以针对不同的协议和端口配置不同的 TLSA 记录。我认为,TLSA 是最安全的一种 DANE 的方式。 你可以在这个网站生成一个 TLSA 记录,我的 dane-trusted-ca.tloxygen.com 站点绑定了 Let’s Encrypt 的中间证书,设置的 TLSA 记录是这样的:
_443._tcp.dane-trusted-ca.tloxygen.com. 604800 IN TLSA 0 0 1 25847D668EB4F04FDD40B12B6B0740C567DA7D024308EB6C2C96FE41D9DE218D
这里记录中的第一项(这里是 0)代表着 PKIX-TA,TA 意味着这个根证书或是中间证书必须在这个域名所使用的证书链中,也就是说这个域名只能使用某一个证书颁发商颁发的证书。如果第一项填写 1,代表着 PKIX-EE,EE 意味着这个证书必须是域名所使用的证书,也就是说每次更换证书后都得修改这个记录。PKIX 意味着这个证书链是受操作系统信任的,在使用证书颁发商颁发的证书时(如 Let’s Encrypt),应该使用 PKIX。 当第一项为 2 和 3 时,一切就变的有意思多了,2 代表着 DANE-TA,代表着绑定一个自签名的根证书,我的 dane-self-ca.tloxygen.com 站点就绑定了一个自签名的 Root,设置的 TLSA 是这样的:
_443._tcp.dane-trusted-ca.tloxygen.com. 604800 IN TLSA 0 0 1 25847D668EB4F04FDD40B12B6B0740C567DA7D024308EB6C2C96FE41D9DE218D
所以如果客户端支持了 DANE,那么这个自签名的根证书在这个域名下就是被信任的。 当第一项为 3 时,代表着 DANE-EE,这可以直接绑定域名证书,意味着不但可以使用自签名的证书,连证书链都免去了,我的 dane-self-signed.tloxygen.com 就直接使用了一个自签名的证书,设置的 TLSA 是这样的:
_443._tcp.dane-self-signed.tloxygen.com. 604800 IN TLSA 3 0 1 BF617DDCC4F39BD0C9228FC0C1EAD5E96252F36FB3FB5AB0CBB9B9B09C3CFE21
你可以在这个网站找到更多的不同种类的支持 TLSA 的网站。 那么问题就来了,为什么现有的浏览器都不支持 TLSA 呢?我认为主要原因如下:
然而我认为这些都不是什么问题。为了解决 DNS 的问题,可以使用 Google DNS-over-HTTPS,这样的话就能避免很多 DNS 污染的问题,而且由于 DNSSEC 本身包含签名,Google 是无法对返回内容篡改的。那么直至现在,TLSA 就只存在最后一个问题:为了获取 TLSA 记录而增加的加载延迟。而这也可以完美解决,OCSP 就是一个例子,现在传统的 CA 为了实现吊销机制,也都有 OCSP:
OCSP(Online Certificate Status Protocol,在线证书状态协议)是用来检验证书合法性的在线查询服务,一般由证书所属 CA 提供。为了真正的安全,客户端会在 TLS 握手阶段进一步协商时,实时查询 OCSP 接口,并在获得结果前阻塞后续流程。OCSP 查询本质是一次完整的 HTTP 请求,导致最终建立 TLS 连接时间变得更长。
- ——JerryQu
这样,在开始正式开始加载页面,客户端也需要进行一次 HTTP 请求去查询 OCSP。OCSP 也会十分影响页面加载速度,也同样会增加加载页面出错的可能。而 OCSP 有了 OCSP Stapling,这样的话 Web 服务器会预先从 CA 获取好 OCSP 的内容,在与 Web 服务器进行 HTTPS 连接时,这个内容直接返回给客户端。由于 OCSP 内容包含了签名,Web 服务器是无法造假的,所以这一整个过程是安全的。同理,TLSA 记录也可以被预存储在 Web 服务器中,在 TLS 握手阶段直接发送给客户端。这就是 DNSSEC/DANE Chain Stapling,这个想法已经被很多人提出,然而直至现在还未被列入规范。也许浏览器未来会支持 TLSA,但至少还需要很长一段时间。
传统的证书配合了现在的 Certificate Transparency,即使不需要 TLSA 记录,也能一定程度上保证了证书签发的可靠性。此外,传统证书也可以使用 TLSA,其本身的安全性不比 DANE 自签名差。 此外,传统 CA 签发的证书还有自签名证书做不到的地方:
CAA 比较简单,它相当于是公开声明这个域名允许了哪些证书颁发商颁发的证书。CAA 不需要 DNSSEC,写在这里只是和 TLSA 区分一下,但开启 DNSSEC 无疑能够使 CAA 更可信。 比如在域名添加了如下记录,就相当于限制了仅允许 Let’s Encrypt 签发证书,其他证书签发商则不再给这个域名签发证书。在 CAA 记录刚推出时受到以下因素限制:
但是从 2017 年底开始,所有证书颁发商被强制要求遵守域名的 CAA 记录。来源 CAA 的副作用最小,你也可以添加多个 CAA 记录来允许多个证书颁发商去签发,以增加灵活性。 google.com 就使用了 CAA(但是没有开启 DNSSEC):
$ dig google.com caa;; ANSWER SECTION:google.com.86399INCAA0 issue "symantec.com"
如果要将一个域名绑定在某个证书颁发商下,建议同时使用 TLSA 和 CAA。如果是长期的绑定,可以考虑一下 HPKP Pin。
在使用 SSH 首次连接一个主机时,SSH 通常会询问是否信任服务器的指纹(fingerprint):
$ ssh guozeyu.comThe authenticity of host 'guozeyu.com (104.199.138.99)' can't be established.ECDSA key fingerprint is SHA256:TDDVGvTLUIYr6NTZQbXITcr7mjI5eGCpqWFpXjJLUkA.Are you sure you want to continue connecting (yes/no)?
这个指纹告诉你了你连接到的是这个服务器,而不是别的服务器。你需要确认这个指纹与自己所要连接到的服务器匹配时,才应该进行连接,不然你就会连接到别的服务器(攻击者可以让服务器允许任何来源的 SSH,于是你就成功登陆到了攻击者的服务器。这样你所执行的代码,甚至是通过 SSH 提交的 Git,都能被获取到)。 那些允许公开的 SSH 连接的服务器,如 GitHub,会在网站上公开自己的指纹,用户需到在它们的官方文档中找到指纹。而 SSHFP 则是一种更简单且通用的的公开这个指纹的方式,这个功能甚至都集成到了 SSH 中去,当检测到指纹匹配时就会自动登陆,跳过询问指纹的步骤。 然而,假如攻击者同时控制了网络中的 DNS 和 SSH,那么 SSHFP 反而是更加不安全的。所以客户端仅应该信任使用了 DNSSEC 的 SSHFP 记录。 编辑 ~/.ssh/config
,添加这一行即可实现验证 SSHFP 记录:
VerifyHostKeyDNS=ask
如果将 ask
换为 yes
,那么会默认信任 SSHFP 记录。
前面我们介绍了 DNSSEC 的基本原理,这一篇文章中将会介绍给你 DNSSEC 的具体实现方法,我来使用 dig 程序为大家分析 DNSSEC 的实现过程
我有一个域名 tlo.xyz
长期部署了 DNSSEC,所以本文就拿这个域名作为例子讲解。首先,需要明确的是如何让 dig
程序去显示关于 DNSSEC 的资源类型,幸运的是这很简单,只需要加上 +dnssec
参数即可。 在之前的文章中,我们已经知道了根域名公开了 13 个服务器的 IP 地址。此外,其实根域名还公开了一组 DS 记录,这段记录可以在这里获得。
.172800INDS19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5.172800INDS20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D
第二条记录是 2016 年 10 月份生成,并在 2018 年 10 月完成切换。 现在我们利用这个地址查询根域名自身,结果如下(部分无关内容已经被删掉):
$ dig @a.root-servers.net. . any +dnssec;; ANSWER SECTION:.518400INNSa.root-servers.net.;; 这里省略剩下 12 个根域名服务器.518400INRRSIGNS 8 0 518400 20170227170000 20170214160000 61045 . HnSVXyC8UZuXnpOsZOv1/GP2byJFG9Y9ch4q0eUw/6CMEJ403spJ67Oo JiAGhdiE6xlONAMQN0Q7LpA7/bgCf29mmVJDcG76b/qaVnmRjKErBwep 68K831Uph2V+Rixcw8mx5XYWuMDyKDiRWlrPyY/bT0a7Us7dTnhkNJ+D g25E0lqXNKY9XgroVoTlwc5tCIe6L8GhoDU+LTLtBySBgQa3kEAI7WUQ CT4l47BCu3zzh8sJtdKGEXnXD0e22pB4ZaYF80iVWL1cRgghn2HphlN0 1kFJr3WuuIKP9r4vZFIjKiinV1KJdBBW2fciGAx+nZbP5sSUlOdiz/56 BZKM3g==.86400INNSECaaa. NS SOA RRSIG NSEC DNSKEY.86400INRRSIGNSEC 8 0 86400 20170227170000 20170214160000 61045 . JQQEDSGFolKu38MmdvvDj7Zi2AstqZc2cwhPQE+RRwTBVl3SWQOQ4FaS Wta+CdbhbaRAKQ9dUiOif95LLarewJDF9e4O2zTDsLt5MlgXLGZr3xd4 9HhDkEzjRk4Zro2qquvWmsHUjn+fbru4FsO6sZyS/FWjfh0XImlIYfh4 D50IplgRwv6awu4mO2RzJ0VL94l4WMMnV42vPSfWiNpL+9g7PHmaWkwe EqH7RamPDzw/M3bmts5yWp+cEI4IzE25kmZAHwN9EQHNNtDL3qKtAzrY wj6e8VVw0rI/XJ3DMI5aRk3xB+ac13dQv8cWtQZRImw76A5/N6clBXJS ZpmT+w==.172800INDNSKEY256 3 8 AwEAAYvgWbYkpeGgdPKaKTJU3Us4YSTRgy7+dzvfArIhi2tKoZ/WR1Df w883SOU6Uw7tpVRkLarN0oIMK/xbOBD1DcXnyfElBwKsz4sVVWmfyr/x +igD/UjrcJ5zEBUrUmVtHyjar7ccaVc1/3ntkhZjI1hcungAlOhPhHlk MeX+5Azx6GdX//An5OgrdyH3o/JmOPMDX1mt806JI/hf0EwAp1pBwo5e 8SrSuR1tD3sgNjr6IzCdrKSgqi92z49zcdis3EaY199WFW60DCS7ydu+ +T5Xa+GyOw1quagwf/JUC/mEpeBQYWrnpkBbpDB3sy4+P2i8iCvavehb RyVm9U0MlIc=.172800INDNSKEY257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq QxA+Uk1ihz0=.172800INRRSIGDNSKEY 8 0 172800 20170303000000 20170210000000 19036 . KHz7GVvg5DxUv70bUhSjRy1JO5soL+h6M08g8bSKecd+4NmZI87Sn20p uZNRuiASbnG63i89Z2S45NBAR8KtqB6N5CrRhLhfxZcRo5k3Ts6zsC1E J58upPKzFtu/sJBsPDjcRJJKbXlB4hLukQwVhn/MbsXxZdZGI57WoLFx bbR49NlFJrlrbTi2gieRR1SCLfT9aiBGsJA3T4jXap9FIsikNf1DJA8H cnQTW7hFi8l/O2ni2hbjsIE4S3GRTMypqDR/s7piy/qukfWwSknk6YZT bzld6ZgbZK+oOhRgj/W6XW78bJl0onov0F1wD0NQsec+sk2P+JNMc4xg vQmn9g==.86400INSOAa.root-servers.net. nstld.verisign-grs.com. 2017021401 1800 900 604800 86400.86400INRRSIGSOA 8 0 86400 20170227170000 20170214160000 61045 . A5CqIucYyfFTzp03EuajDjp5Vw6dd3Oxip60AI7MCs/2xfBu1red4ZvF GfIEGHstG61iAxf7S3WlycHX9xKyfIOUPmMxuvkI9/NXMUHuvjUjv9KW TTkc1HV6PuUB1sv9gsuQ6GFnHCXAgMKXZs9YofRDlBi2jxAvJVc5U7nG sd8UqQs4WcinMHNvFV9+gwfax0Cr9KFDmDUbS+S2wYmNs+SGOn+CbFrD 8gs34GiYao8i0QGw7RVGTVJiuVOuUkeYe4iSXnJjNjeIlm8liq6PRXgM nI+ndPDogA/a8JATfyzQ97VDRwe/FucoTbe5qd2cHxqh1ZxxPkA3K3Fj 8Jv3kg==;; ADDITIONAL SECTION:a.root-servers.net.518400INA198.41.0.4a.root-servers.net.518400INAAAA2001:503:ba3e::2:30;; 这里省略剩下 12 个根域名服务器
可以看到,此时没有再返回 DS 记录,因为 DS 记录总是由一个区域的上一级区域的权威服务器返回,之后还会再次提到这个问题。此处的 DNSKEY、RRSIG、NSEC 是三个关于 DNSSEC 的记录类型:
可以看到,上方查询的 DNSKEY 记录有两条,这两条的内容的第一项分别是 256 和 257。256 是 ZSK(zone-signing keys),257 是 KSK(key-signing keys)。其中 KSK 是专门用于签名 DNSKEY 记录集(就是 ZSK 与 KSK),而 ZSK 是用于签名该区域下的其他记录集。 仔细观察,就可以看出,每一种记录后面就对应着一个用于签名该种类记录的 RRSIG 记录,比如上面查询结果中的 NS、NSEC、DNSKEY、SOA 记录的后面都跟着一个 RRSIG 记录。 举个例子,客户端解析并验证根域名的 SOA 记录的方法大概如下:
但是值得注意的是,根域名服务器所返回的 Glue 记录却没有数字签名,那是因为这是不必要的。就算 Glue 记录被篡改成了别的服务器,那个服务器在解析根域名时也不能篡改任何权威记录(在 ANSWER SECTION 下)。
然后,我们来使用根域名服务器解析一级域名:
$ dig @a.root-servers.net. xyz. any +dnssec;; AUTHORITY SECTION:xyz.172800INNSx.nic.xyz.;; 这里省略剩下 3 个服务器xyz.86400INDS3599 8 2 B9733869BC84C86BB59D102BA5DA6B27B2088552332A39DCD54BC4E8 D66B0499xyz.86400INDS3599 8 1 3FA3B264F45DB5F38BEDEAF1A88B76AA318C2C7Fxyz.86400INRRSIGDS 8 1 86400 20170227170000 20170214160000 61045 . gXpaapTu67jlkfOeujL455lFDGLmLkFpnI+f8VNLMehozA7qWQD71oso SXJxkOB6o/ldXqoLGIo1khsYS8SMltOCMisJ6eA2cLokB7Ybzsaw8GWZ rkx64u2JbELWMbwGnY3PnZHGlBT77oAt49KNDfpxhgm3k1Yrcrua25D8 PL4fz6IQYQIMXWiHM/V2jH6E2Vu1Ynrjiu0lPEMf0TnGsK/URnCGE9uZ caT41mNz9kri/wkuQR11XtHjsN/qZgmcxZK+Tf4VQfOOdcfey4wAa1CM HRQ3Pm4mLo4LQwiESeMuqFyriizdMG4piNP7NLuI54GqWCGNSyDYbOdL X0n2Aw==;; ADDITIONAL SECTION:x.nic.xyz.172800INA194.169.218.42x.nic.xyz.172800INAAAA2001:67c:13cc::1:42;; 这里省略剩下 3 个服务器
这里返回的 DS 记录,虽然是两个,但是其 Key Tag(即第一项,为 3599)是相同的,后面两项算法有所不同,这其实就是同一个 KSK 的两种不同的哈希值算法,这个是为了提高兼容性和有限的安全性。这与刚才根域名的情况不一样,根域名下面的是完全两个不同的 KSK 的不同的 DS。 此时我们发现了不仅是 Glue 记录,NS 记录下也没有签名,这是因为这里返回的 NS 记录是属于委托记录(在 AUTHORITY SECTION 下),也不需要签名,xyz.
下 NS 记录的签名应该有 xyz.
的解析服务器来完成(而 DS 记录是例外)。我们来使用一级域名服务器来解析其自身:
$ dig @x.nic.xyz. xyz. any +dnssec;; ANSWER SECTION:xyz.172800INNSx.nic.xyz.xyz.172800INNSy.nic.xyz.xyz.172800INNSz.nic.xyz.xyz.172800INNSgenerationxyz.nic.xyz.xyz.172800INRRSIGNS 8 1 172800 20170525152637 20170425162314 47496 xyz. p57paKPWMyhwmz5IkkbZOMC/dIfxyANZ6QzRbEBiOff5JXnrdpKEX4YT zPMzF4SSNHPuK53uuJTtt2E4W3Xd2VjGVUx7V2mP7Hxs0nQblCDbQa51 zr6kYoXEOcdwVx23GyLe0baPELtEkQZHeKx5eWyZTUDCri4DBCZZv9m+ Lbk=xyz.3600INSOAns0.centralnic.net. hostmaster.centralnic.net. 3000288446 900 1800 6048000 3600xyz.3600INRRSIGSOA 8 1 3600 20170606000517 20170506113911 47496 xyz. oanexcZRLZ+NEPvSGhl0qyi6LH/3ubP+0JWjlNvcduZWUp7oQt4VWfy/ w0T2Y2/610u7mvcxRty2p6cZq1arVMLOci7ZzMpPHkNDxXHcNRxlMNL1 6mwLgKzOlxp0acEGhqQBhj/XQ2icScf8PMChC7uRsFOz9nqAxelcgJgY D9I=xyz.3600INDNSKEY257 3 8 AwEAAbYRTzkgLg4oxcFb/+oFQMvluEut45siTtLiNL7t5Fim/ZnYhkxa l6TiCUywnfgiycJyneNmtC/3eoTcz5dlrlRB5dwDehcqiZoFiqjaXGHc ykHGFBDynD0/sRcEAQL+bLMv2qA+o2L7pDPHbCGJVXlUq57oTWfS4esb GDIa+1Bs8gDVMGUZcbRmeeKkc/MH2Oq1ApE5EKjH0ZRvYWS6afsWyvlX D2NXDthS5LltVKqqjhi6dy2O02stOt41z1qwfRlU89b3HXfDghlJ/L33 DE+OcTyK0yRJ+ay4WpBgQJL8GDFKz1hnR2lOjYXLttJD7aHfcYyVO6zY sx2aeHI0OYM=xyz.3600INDNSKEY256 3 8 AwEAAaAxrInKa1BlzuJsfT/gWfrUUH5OP7IJquNOLRU7LVbKwJEv655b kBBbW53wVXmnWJfPxykrMme8a91FFqXTYepvVN5vJe9QuCfiW/C64jSo 0HNXhbSUkV1ZDcy+zgAmMriPm8g5ki7KJ7KRs+YRoL2NwCm5fJVsAchr WalFB4z3xyz.3600INDNSKEY256 3 8 AwEAAdNAEAD8rebFpKuiLr0BwTNQoECMnfJjiZ54ZCCke208h9eX7ui7 WFFz9hjmvAgIFavN5vVhR5SnDTRvD5iDsMKvefXbnz4Qeu4GILwJuTqC QAcqw6RUp1+U1KEkwRP/noqA4fSkmnInbQwW+Yq+bxohGQVatZiAiO/G ppSggZX3xyz.3600INRRSIGDNSKEY 8 1 3600 20170520002252 20170419140553 3599 xyz. h5TV5pu/QAAUal72x8Dm8tgqBzRvDSznaDrRqV0Fu8ponhfXQFjdG3p1 2/IVdkNLtLZq4I2aUMwJeTZcyq5gRcWOror0V6uChW5fgIkH7abj1CYL tSRv3M7mVBduGNIzMuITJu5Pn1BVXiF9FsTw1ks+wDjdPn2OLe5BKRmj d+6GgwwBhg4V2efFcb+peRBCRpk+i3S1dlMyILCCgAvnAaGbh3k+vaKN 2wb528jSvH0QVIXP8PTAxLw86IfFlvLm8Lxo1e8hweI+4hgECNX7UzeG epXE+LpOiZwkhf7JncytOcxw6YzSAQETYJfcK1MlMcH5zNzjhFTNoMV3 M4QTLQ==;; ADDITIONAL SECTION:x.nic.xyz.172800INA194.169.218.42y.nic.xyz.172800INA185.24.64.42z.nic.xyz.172800INA212.18.248.42generationxyz.nic.xyz.172800INA212.18.249.42x.nic.xyz.172800INAAAA2001:67c:13cc::1:42y.nic.xyz.172800INAAAA2a04:2b00:13cc::1:42z.nic.xyz.172800INAAAA2a04:2b00:13ee::42generationxyz.nic.xyz.172800INAAAA2a04:2b00:13ff::42
可以看到, xyz.
下的解析服务器就返回了 NS 记录的签名。 然而,xyz.
下却有两个 ZSK,这大概是因为 xyz.
下有两个私钥,这样的话每一个签名可以使用两个私钥中的任何一个签,灵活性更高。此外,我们也看出来了区分 KSK 和 ZSK 的意义:KSK 和 ZSK 的数量可以不相等。 然后,我们来使用一级域名的服务器来解析我的二级域名:
$ dig @x.nic.xyz. tlo.xyz. any +dnssec;; AUTHORITY SECTION:tlo.xyz.3600INNSkami.ns.cloudflare.com.tlo.xyz.3600INNSgordon.ns.cloudflare.com.tlo.xyz.3600INDS2371 13 2 913F95FD6716594B19E68352D6A76002FDFA595BB6DF5CAAE7E671EE 028EF346tlo.xyz.3600INRRSIGDS 8 2 3600 20170303035908 20170201045318 7558 xyz. b69lhRaZM8lWN44qaQCCm4+479ATwt+OlRWD770jmLJnai2ob/0CWPEZ pFQ+y/k6n/X8VPZa2IVwxB6qUTtirtOolBHVA4gmPQffXiYiTbP1dDT9 G7BwNMdOCGkH0bySW9rFpi3zKYvOieNQLlV/i61ox78AgxQeX4k800QN gEE=
由于 NS 记录属于委托记录,所以 NS 下也没有签名。 由于这个域名使用的 NS 是 kami.ns.cloudflare.com.
,不属于 xyz.
之下,所以没有任何 Glue 记录,于是这需要再按照流程再重头解析一遍 kami.ns.cloudflare.com.
,这里就省略了。 最后,我们来使用我二级域名服务器来解析二级域名自身:
$ dig @kami.ns.cloudflare.com. tlo.xyz. any +dnssec;; ANSWER SECTION:tlo.xyz.60INA52.84.21.12tlo.xyz.60INA52.84.21.243tlo.xyz.60INA52.84.21.67tlo.xyz.60INA52.84.21.107tlo.xyz.60INA52.84.21.4tlo.xyz.60INA52.84.21.46tlo.xyz.60INA52.84.21.29tlo.xyz.60INA52.84.21.224tlo.xyz.60INRRSIGA 13 2 60 20170507145606 20170505125606 35273 tlo.xyz. tcMNEbUGrnCoTK1Z7Xmo15k+pLyZJ+m28nKt/o5s+/ezrcMsgFv1C0bY ABs9M8cqjw+0Ld8DTtAwTQVwpAUe+g==tlo.xyz.60INAAAA2600:9000:203a:1000:b:fe0:fc00:93a1tlo.xyz.60INAAAA2600:9000:203a:7e00:b:fe0:fc00:93a1tlo.xyz.60INAAAA2600:9000:203a:e400:b:fe0:fc00:93a1tlo.xyz.60INAAAA2600:9000:203a:a200:b:fe0:fc00:93a1tlo.xyz.60INAAAA2600:9000:203a:4800:b:fe0:fc00:93a1tlo.xyz.60INAAAA2600:9000:203a:3000:b:fe0:fc00:93a1tlo.xyz.60INAAAA2600:9000:203a:1a00:b:fe0:fc00:93a1tlo.xyz.60INAAAA2600:9000:203a:a000:b:fe0:fc00:93a1tlo.xyz.60INRRSIGAAAA 13 2 60 20170507145630 20170505125630 35273 tlo.xyz. QV5gEUO9NK3W2G4aF/dTZrmsGURyVAiU3eyyuR4lp4YJ7jxGjmCQArPB 4CYz6laN+V6Kd78gi7v50gaf+WCeDQ==tlo.xyz.3600INSOAgordon.ns.cloudflare.com. dns.cloudflare.com. 2024522030 10000 2400 604800 3600tlo.xyz.3600INRRSIGSOA 13 2 3600 20170507145653 20170505125653 35273 tlo.xyz. KnJkiBfvb0xhw3mAjKxnWPSMptc+eoN7Qh50HJQYnmycvV1K9ADFKYyq RwhKzWEOFHXtsn8Pxh+d/EY0x4EVEw==tlo.xyz.86400INNSgordon.ns.cloudflare.com.tlo.xyz.86400INNSkami.ns.cloudflare.com.tlo.xyz.86400INRRSIGNS 13 2 86400 20170507145712 20170505125712 35273 tlo.xyz. vQDzeIteIeVdbPS7nxNXCVeGD97+ePvEHdPK263oocoDPY59tVOG6V+a s7k8GHSFJ8KKu8edoWcUayi3aNFY7g==tlo.xyz.86400INTXT"v=spf1 include:email.freshdesk.com include:\_spf.myorderbox.com include:amazonses.com -all"tlo.xyz.86400INRRSIGTXT 13 2 86400 20170507145729 20170505125729 35273 tlo.xyz. NDFDF9PHFSSvQu7oF17cNWIrQUrfaPA/019i6hCvj7JJiA21DWp0w5J3 BlxDEN6wIGq4Nzb4IVE0uf+zmdTb0w==tlo.xyz.3600INDNSKEY257 3 13 mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+ KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==tlo.xyz.3600INDNSKEY256 3 13 koPbw9wmYZ7ggcjnQ6ayHyhHaDNMYELKTqT+qRGrZpWSccr/lBcrm10Z 1PuQHB3Azhii+sb0PYFkH1ruxLhe5g==tlo.xyz.3600INRRSIGDNSKEY 13 2 3600 20170529092807 20170330092807 2371 tlo.xyz. SDm3eGWVamR+GIZ8TEcYDeik73gMUVyX6TGGtkir6A6TIY+2zvXwtfrN HEvkygTfiOuEn+/Ipj08o8+NyZeAZw==
下面总结一下解析并验证 tlo.xyz.
下的全部 A 记录的方法,DNS 在实际解析过程中会尝试尽可能跳过不必要的请求:
tlo.xyz.
,返回的是 xyz.
下的 NS 和 DS 记录,包含了签名xyz.
的 DS 记录xyz.
服务器解析 xyz.
下的 DNSKEY 记录,并要求签名xyz.
的 DS 记录验证 xyz.
的 KSKxyz.
的 KSK 及其签名验证 DNSKEY 记录集xyz.
服务器解析 tlo.xyz. 下的 NS 和 DS 记录,并要求签名xyz.
的 ZSK 和 DS 的签名验证 tlo.xyz.
的 DS 记录tlo.xyz.
服务器解析 tlo.xyz.
下的 DNSKEY 和 A 记录,并要求签名tlo.xyz.
的 DS 记录验证 tlo.xyz.
的 KSKtlo.xyz.
的 ZSK 和 A 的签名验证 tlo.xyz.
的 A 记录为了做区分,我把解析分为了两类,验证分为了三类:
NSEC 记录比较特殊,所以单独的讲一下。 在全面普及 DNSSEC 之前,仍然有不少域名并不支持 DNSSEC,此时如何让已经支持 DNSSEC 的网站进行签名认证,拒绝解析签名错误的请求,又同时让没有 DNSSEC 的域名无视签名正常解析呢?HTTPS 的推进是区分了协议:以 https://
开头的网站进行签名认证,以 http://
开头的网站不进行签名认证,在 HSTS Preload 里的域名则强制进行签名验证。而实际上,HTTP 和 HTTPS 是两种不同的协议,而支持 DNSSEC 的 DNS 与普通的 DNS 是同一种协议,前者是后者的子集。只有域名下有 DS 记录时,才会进行签名认证,否则还是按照普通的处理。 那么试想,攻击人可以在解析 tlo.xyz.
时的第九步做手脚:删除 DS 记录以及 DS 的签名,这样不就相当于移除了这个域名的 DNSSEC 了吗?(有些类似于 HTTPS 降级攻击),或者直接删除某个域名下的 A 记录,客户端能知道这个域名下是真的没有 A 记录还是被恶意删除了?实际上这样做手脚是没用的,当开启了 DNSSEC 的权威服务器收到了一个不存在的记录的请求时(这可以是不存在的子域名,也可以是某个域名下不存在的一些记录类型),不是返回空的内容,而是返回一个 NSEC 记录去声明这个域名下没有这种记录,同时也将这个记录签名。综上所述,开启了 DNSSEC 后对于该区域下的所有的 DNS 请求都会签名,从来不会返回空的内容。 根据这里公开的数据,我们来尝试一下解析第一个不支持 DNSSEC 的一级域名:ae.
的 DS 记录的结果
$ dig @a.root-servers.net. ae. ds +dnssec;; AUTHORITY SECTION:.86400INSOAa.root-servers.net. nstld.verisign-grs.com. 2017021401 1800 900 604800 86400.86400INRRSIGSOA 8 0 86400 20170227170000 20170214160000 61045 . A5CqIucYyfFTzp03EuajDjp5Vw6dd3Oxip60AI7MCs/2xfBu1red4ZvF GfIEGHstG61iAxf7S3WlycHX9xKyfIOUPmMxuvkI9/NXMUHuvjUjv9KW TTkc1HV6PuUB1sv9gsuQ6GFnHCXAgMKXZs9YofRDlBi2jxAvJVc5U7nG sd8UqQs4WcinMHNvFV9+gwfax0Cr9KFDmDUbS+S2wYmNs+SGOn+CbFrD 8gs34GiYao8i0QGw7RVGTVJiuVOuUkeYe4iSXnJjNjeIlm8liq6PRXgM nI+ndPDogA/a8JATfyzQ97VDRwe/FucoTbe5qd2cHxqh1ZxxPkA3K3Fj 8Jv3kg==ae.86400INNSECaeg. NS RRSIG NSECae.86400INRRSIGNSEC 8 1 86400 20170227170000 20170214160000 61045 . B03J+aJuEA5r5Va8QiecBHZUucisWgdC8b14Q4MU5oGSdgmK9PmHLKMS mUiGj/OzH51P1l0G6zxG6bxU56tZ4gSME+rcpIntdKyiWU4QLpkiPa32 aApHFmu0pzugGSDWnQUmNDmCig7jJ2J61xlOzx19ni0eJazAthRtGWuK WI9bCVt9Yb7Bd21AedC0gugQWY+LKj7HR3zRhZ5dywpcTQUc78BrJDvh P8UxWprUJozcMYdVDqA5TvSlRHz8aLOnkD/olVsE5cU6qSvCX32E7WuQ IeFfhf1J940hly/3f960Dvm5kwX8l6CkNW083yLCnG8e7zArEUBRthvA a90SJw==
注意新增的 NSEC 记录,这个记录首先声明了一级域名 ae.
下只有 NS RRSIG NSEC 这三种记录,也就是说没有 DS 记录。此外,它还说明了 ae.
之后的一个一级域名是 aeg.
,所以通过这个记录,可以轻松的证明不存在 aea.
、aeb.
、aec.
…… 这些一级域名。 那么,如果请求 aea.
这个不存在的一级域名,会发生什么情况?
$ dig @a.root-servers.net. aea. any +dnssec;; AUTHORITY SECTION:ae.86400INNSECaeg. NS RRSIG NSECae.86400INRRSIGNSEC 8 1 86400 20170228050000 20170215040000 61045 . U2e52sVPmIup4pSfWzg7hupPZb63NdYdsiNEqr2ygDBQrgOQ6rT2SZkP xZVvHc7ZtfggUV1iT6kels8+d3beURz0Vf58x6up+PUF6svaFOmx2Bpu 42owq6wYQH6ll8GLOKiIC/35omIXja0VFj4ueG1HsbHbWVxUcL5bsDrt UWRUU9Hp1ySp36+H7M5NE+YPNk8soH2xyANe+STkymH661m8jJqXbG2X atbCEEOtuXuplvS7Rm/YRS+UEtsamC3A9bDBnus/OiL3KS1ztuvrxQfS 6a1z45UtL0PBBQ5DzNiVd9QHHhSpsaxFUqg0iw21CB6MZaK10EB7EJCQ EWkRkg==.86400INNSECaaa. NS SOA RRSIG NSEC DNSKEY.86400INRRSIGNSEC 8 0 86400 20170228050000 20170215040000 61045 . fnA/PW3QvSzI4MXZ+ylGhv/Z+F+u6YdAWnSz1DfbwSZkcpzwZoO1/uiY QtYhYU5GF/dbTk7oGEjStA0dWVzyyf+7opW+DS1+R9pn5N/LynyqZ6Et Swk85MQl04gu5LxLrnn6Nind2ozRMha4Nn7tNlYG59GLH3hXkaQ6xYmE hD0Ya+UE6h2vcQ8Y8m3ccifDO2rBukdsUJ13dZLAScNAVJU6/2YxlyyX fYY7G0Ktqu5Tq10YvfJazZ5VraBzw+bkEzM8UEPGNNfX9FTB7zxhjyhU h1u87Z/nKMoIznzVu6Xk9AC5JM1lU/OIHyYHCp+XzMGuUdjwNZH706ND MGq/rQ==.86400INSOAa.root-servers.net. nstld.verisign-grs.com. 2017021500 1800 900 604800 86400.86400INRRSIGSOA 8 0 86400 20170228050000 20170215040000 61045 . Nj7xEVPJ5DtBFRP9Zy0GCIwY/ax3v9n9JV0EsKyAeHPYDw4PBMpXQRxa banAl7DVyytO+xLz1NxY3iYTSPtyFjbAzkipC5BJT0EFovbQJ7VJOS4P nZBFaVltjGnzzrC8+hWESyhcwn2DdsNw94JqlkVPEtbT+u6vgXbIv5lD 1/YJMRcvWR74FzBC/bYyk+s0WWVNWDenioI2F7NCRgKSYm1+6qXK4on7 MFAmJE9TYYyZFFRiQurS1wH+d3/xQTtjd93GYOhpWVND0NyN/t4nkxhT spHrofo9GvzTIcGTcwT4Pp1bdBXL6dS0P+JIDXTKQN7u/3RwoJj/6jPm FOSEKw==
通过请求 aea.
,从请求的结果可以得出两个结论:
ae.
和 aeg.
是两个相邻的一级域名(这也就相当于声明了不存在 aea.
这个一级域名),此外也说明了 ae.
下只有 NS SOA RRSIG NSEC DNSKEY 这些记录。aaa.
,此外也说明了根域名下只有 NS SOA RRSIG NSEC DNSKEY 这些记录。注意,相邻的域名排序是包含该区域所有子域名的,也就是说所有的子域名都参加到了排序,刚才得出的 “ae.
和 aeg.
是两个相邻的一级域名” 其实并不准确,而应该是根域名区域下 ae.
和 aeg.
是两个相邻的子域名,因为 NSEC 结果还相当于说明了 a.ae.
这样的二级域名在根域名区域下也不存在。 如果 NSEC 是最后一个记录,那么它的下一个就又是区域自身了。 然而,可以发现,通过这个方法可以轻松的获得已经存在的记录:比如我只是试了一下 aea. 这个一级域名,却一下子就知道了根域名下还有 aaa.
、ae.
和 aeg.
三个一级域名,通过这样一直往下遍历,就能搜索到一个区域下的所有子域名。 知道所有的一级域名对于根域名服务器无所谓,因为一级域名的列表本来就是公开的。可是,这个功能也许不是我们所期望的,有的时候,想要在自己的域名下放置一些只有自己知道的子域名,这些子域名也许就是自己源站服务器的 IP,如果 DNSSEC 就这样实现的话,这就让其他人很容易就能遍历出来你所有的子域名。所以,在 DNSSEC 中,响应记录不存在的话还有两种解决方案,一种是对 NSEC 的 Hack,还有一种是 NSEC3:
Cloudflare 上就使用了对于 NSEC 的 Hack,这样就能避免其他人遍历你的所有子域名。举个例子,正常的 NSEC 去解析 a.tlo.xyz
可能是这个结果(假如我只有 www
这一个子域名):
$ dig @kami.ns.cloudflare.com. x.tlo.xyz. +dnssec;; AUTHORITY SECTION:tlo.xyz.3600INNSECwww.tlo.xyz. A MX TXT AAAA DNSKEY RRSIG NSEC; 省略一个 RRSIG 记录www.tlo.xyz.3600INNSECtlo.xyz. CNAME RRSIG NSEC; 省略一个 RRSIG 记录; 还省略了一个 SOA 以及 SOA 的 RRSIG 记录
通过观察 NSEC 记录,就可以直接看出这个域名下只有 www
一个子域名。 然而 Cloudflare 实际返回的结果是这样的:
$ dig @kami.ns.cloudflare.com. x.tlo.xyz. +dnssec;; AUTHORITY SECTION:tlo.xyz.3600INSOAgordon.ns.cloudflare.com. dns.cloudflare.com. 2023791623 10000 2400 604800 3600tlo.xyz.3600INRRSIGSOA 13 2 3600 20170216150135 20170214130135 35273 tlo.xyz. ARUYgesljY5azg1RqFgoKbTN6OOmAQUqTsLiQyTBXAMO4P/CecFGwTKY f1cVTI/s4euNahfGOvc0MnDb2R55TQ==x.tlo.xyz.3600INNSEC\\000.x.tlo.xyz. RRSIG NSECx.tlo.xyz.3600INRRSIGNSEC 13 3 3600 20170216150135 20170214130135 35273 tlo.xyz. y4g0Of3Ir/DqcbRT1ND5kwdGXlW++Zb+c9Cx0z60UAzbI+cpW2DDOmBB 4MMKi4zV9xEBg5Jq/8hwBGVo4ytDDg==
Cloudflare 这样则是告知了 x.tlo.xyz.
是存在的,但是只有 RRSIG 和 NSEC 记录,即相当于这个域名下没有任何记录。x.tlo.xyz.
之后的下一个域名是 \000.x.tlo.xyz.
,而实际上那个域名也是不存在的。这其实相当于 Cloudflare 撒了一个谎,并没有直接告知你这个域名的下一个域名。这虽然解决了问题,但是并不符合规范。
NSEC3 使用了在区域内的下一个记录内容的哈希值(按照哈希值的顺序排序)代替了原本的记录内容。从哈希值反推记录内容本身有一定的难度,于是就能够避免其他人遍历出所有的记录内容。(guozeyu.com
没有在生产环境中开启 DNSSEC,以下内容仅为测试结果)
$ dig @a.ns.guozeyu.com. ns.guozeyu.com +dnssec;; AUTHORITY SECTION:guozeyu.com.3600INSOAa.ns.guozeyu.com. ze3kr.icloud.com. 1 21600 3600 1209600 3600guozeyu.com.3600INRRSIGSOA 8 2 21600 20170411191942 20170403191942 52311 guozeyu.com. bHSh4a0zcaFEwS5dNEj/JT9Aosuy8Wdh+U2WaPou95iywqG6VhH85BXT EhYnjmeph/CABF5HC2OvUf9HhcnxjPF9NAQ2cfPTr6Ael9aNBGLFSejI 5VmCdp4Q1sYD6hS51k5BY22bJRyu9v8zWHNLYDRJSFBk4kR0RSV5n0CK 4pA=67uromrbachidk57be8035jf9gqnhmn1.guozeyu.com. 300IN NSEC3 1 0 1 F327CFB1FFD107F1 ENPCB7U0K7KFHLSCEOTOB7RAHS4TCH3V67uromrbachidk57be8035jf9gqnhmn1.guozeyu.com. 300IN RRSIG NSEC3 8 3 300 20170411191942 20170403191942 52311 guozeyu.com. MpV+6foWp+XQpwJnNCiIE0dqGigqX+2Z7XWuCFAd/TUS1sBHwnTRKmB5 Rl8Wf23ZMMfZh/oRHQbm4vE1RecMd78ZuvQM61iOmwAOmjIhJJh+LPSg 5KXMmYimTmtyd7/N437XYqmBREbz9EQ66ZqGucOahncPfxX2jhErvICN KDc=
标准的 NSEC 会暴露所有的子域名,而 NSEC3 不会,看起来 NSEC3 的优势明显。然而标准的 NSEC 相比 NSEC3 又有好处:子(Slave)DNS 服务器不需要拥有 DNS 的私钥,这样配置 Slave DNS 后就方便多了,和常规的 Slave 一样,只需要传送(Transer)整个区域即可,也能够正确的响应不存在的子域名。因为在标准的 NSEC 下 NSEC 和 RRSIG 的数量是有限的。而 NSEC3 或者 Hacked NSEC 都会根据不同的子域名返回不同的 NSEC(3) 记录,NSEC(3) 和 RRSIG 记录都是无限的。 举个例子,比如你现在可以下载到签名过的根域名的区域。其中包含了所有的 NSEC 记录,这样 RRSIG 可以在一台机器上生成,并将签名过的整个区域传送给其它子的根域名服务器上,这样能够有效的确保私钥安全。而用 NSEC3 或者 Hacked NSEC 的话,每一个子 DNS 服务器都需要有私钥。根域名服务器的数量众多,也由各种不同的组织管理着,所以很有必要保护好私钥。所以对于这种不怕被遍历到所有子域名的区域来说,使用标准的 NSEC 也未尝不可。
]]>Cloudflare 的节点很多,但是节点太多有时不是一件好事——大多数 CDN 之间的节点是相对独立的。首先要先明白 CDN 的工作原理,CDN 通常不会预先缓存内容,而是在访客访问时充当代理的同时对可缓存的内容缓存。就拿本站来说,本站用的是香港虚拟主机,如果有英国伦敦的访客访问了我的网站,那么由于我的网站是可被缓存的,他就会连接到伦敦的节点并被缓存在这个节点。那么如果是英国曼彻斯特的访客访问了呢?由于 CDN 在曼彻斯特另有节点,访客会直接连接到曼彻斯特节点,然而曼彻斯特上并没有缓存,所以该节点会回源到香港。而显然的是,如果曼彻斯特回源到伦敦,使用伦敦的缓存会更快。 综上,如果能选择性的从其他节点上获取资源,TTFB 会更低,缓存命中率也会相应提高。但是一般的 CDN 不会去这样做,因为节点相互独立,节点之间并不知道对方是否已经缓存。一般的解决方法是节点与源站之间先经过为数不多的几个节点,这几个节点可能只是分布在几个州,比如整个欧洲就只有一个这种节点。这样的话,伦敦的访客访问后,同时也被欧洲的那个节点缓存。这样,当再有欧洲其他地区的访客连接到一个没有缓存的节点时,这些节点会直接提供欧洲的那个节点的缓存。CloudFront 和 KeyCDN 就利用了这样的技术。 Cloudflare 是如何实现的他们官方没有详细说明。然而在实际测试时,并没有观察到缓存率上有明显提升,远比不过 CloudFront 的效果。下图是通过这些节点测试的 TTFB,请求是逐个发起的。
通常情况下,节点与源站的连接是直接的,这之间的网络很大程度上取决于主机的网络接入。然而,有了 Argo Smart Routing,Cloudflare 会使用自己的线路。图片来自 Cloudflare.com。
国外请求测试地址,其中的 via 字段就是 Cloudflare 与本站建立的连接的 IP 地址。通过 GeoIP 服务查询,发现是香港的 IP。Cloudflare 将自己的节点之间都建立了长连接,并在离源站最近的服务器上与源站也提前建立了连接。这样,就能大大降低首次连接所需要的时间。如果回源是 HTTPS 的,那么效果更明显。我的另一个测试地址是没有开启这个功能的,用来对比,它的回源与本站建立的 IP 就不是香港的。
速度的确有一定的提升,但是不是特别明显,而且似乎开启了之后一些节点反而更不稳定——原本都是比较稳定的一个速度,开了这个之后一些节点反而忽快忽慢。看来提速的最佳方法还是半程加密。
Railgun 是 Cloudflare 专门为 Business 和 Enterprise 企业级客户提供的终极加速方案。要使用它,先需要升级网站套餐为 Business 或 Enterprise,然后还需要在服务器上安装必要软件并在 Cloudflare 上完成配置。这相当于是一个双边加速的软件,其实现原理是让服务器与 Cloudflare 建立一个长久的 TCP 加密连接,使用 Railgun 独有协议而不是 HTTP 协议,这样显然能减少连接延迟。此外,它还会对动态页面缓存:考虑到大多动态页面都包含了大量相同的 HTML 信息,在用户请求一个新的页面时,服务器将只发送那些变化了的内容。这相当于一种多次的 Gzip 压缩。
官方宣称,使用 Railgun 能够实现 99.6% 的压缩率,并实现两倍的速度。实际体验也确实如此:
Railgun 的加速效果还是非常之明显的,明显强于 Argo。
Argo 并没有想象中的那么好用,而且 $5/mo 的起步价和 $0.10/GB 的流量并不便宜。当然也有可能需要一段时间 Argo 去分析线路延迟才能更好的进行优化。本文预计将在一个月后补充更新。 Railgun 效果还是极其显著的,但是它需要企业版套餐才能够使用,并不亲民。
延迟:Google Cloud CDN 延迟最低,Cloudflare Railgun 仅次。 流量:对于普通的动态 CMS,Cloudflare Railgun 大约能节省 10 倍以上流量,Google Cloud CDN 是做不到的。 我在国内外几家全站 CDN 对比中测试 Google Cloud CDN 时,其极低的 TTFB 令我惊讶,仔细研究后发现节点是与主机之间建立长连接,而且会保持很长一段时间,此外所有网络都走 Google 内网,本质上与 Argo 和 Railgun 类似。所以目前服务动态内容最快的应该还属 Google Cloud CDN 了,Railgun 基本与之相当。
CloudFront 自带的 Regional Edge Caches 在缓存静态内容和提高缓存命中率上要比 Argo Tiered Cache 和 Railgun 好,但是 Argo Smart Routing 在服务于动态的不可缓存的内容上更显出优势。Railgun 和 Google Cloud CDN 除了会在边缘节点缓存之外没有其他专门的优化。
本站的解析没有使用 Cloudflare 而是 自建的 DNS,因为我的 Cloudflare 域名是通过 CNAME 接入的。Cloudflare 分配的 IP 在很长时间内都不会变动,所以我直接把其 IP 设置为了海外线路。使用自建的DNS是为了在备案后,为国内分区解析配置 CDN 线路。 PS: 大家应该都知道启用这个功能后并不会提升国内连接 Cloudflare 的速度,如果想要用 Cloudflare 并且希望国内快一点,源站最好就用美国西岸的。
]]>StatusCake 同时提供免费和付费的监控服务。免费版本可以创建无限多个 HTTP(s)、TCP、DNS、SMTP、SSH、Ping 和 Push 的协议监控,监控周期最短为 5 分钟,提醒主要支持 E-mail 和 Webhook 两种方式。免费版本不支持监控服务器配置信息,所以也无需在服务器上安装任何软件。
此外,StatusCake 支持 Public Reporting,你可以利用 StatusCake 建立一个监控页面。它还支持将在线率图像及网页嵌入在你自己的网页中,十分方便。
UptimeRobot 也提供免费的监控服务,支持 HTTP(s)、端口检测、Ping,监控周期最短为 5 分钟。同样不支持监控服务器配置信息,所以也无需在服务器上安装任何软件。最多只能创建 50 个监控,支持 E-mail 提醒。
相比 StatusCake,它的监控功能要少,但是 Public Reporting 的页面要漂亮一些。由于 StatusCake 所多的那些功能个人站长也几乎用不到,所以 UptimeRobot 也是 StatusCake 的一个良好的替代。
监控宝是一家国内的监控服务,长期提供的免费版可以创建 6 个 HTTP(s)、Ping、DNS、FTP、TCP、UDP、SMTP 甚至是使用 SNMP 对服务器性能监控(需要软件),监控周期最短为 15 分钟。如果你需要检测国内到你的主机的速度,或者你的主机在国内,监控宝是一个不错的选择。它的免费监控是从中国内 3 个位置同时监控。它支持 E-mail 和手机短信告警。它不支持 Public Reporting,但是可以给分享网站的 SLA 证书。功能相当齐全,就是网站的界面设计比较欠缺。
最后,就要介绍我最近开始使用的强大的 Stackdriver。Stackdriver 是 Google Cloud Platform(下文简称 GCP)旗下的服务器监控服务,支持监控、调试、跟踪、日志。其中的 Uptime Check 支持 HTTP(s) 和 TCP,监控周期最短为 1 分钟。它支持 E-mail 、手机短信和 APP 内告警。它的 Uptime Check 是从全球 6 个地区同时监控,可以看到每一个地区的延迟。用来检测 CDN 的速度肯定会很不错。
如果你正在使用 Google Compute Engine(下文简称 GCE) 或者其他 GCP 的服务,那么这个服务还可以帮你记录服务器日志,每月有 5 GB 额度,超出后每 $0.5/GB。此外,它还能进行服务器性能监控,监控服务器各项指标。虽然原本 GCE 面板也能提供 CPU 等信息,但是这个是需要在服务器上安装 Agent,于是就能提供更丰富更准确的信息。安装过程如下:
curl -O https://repo.stackdriver.com/stack-install.shsudo bash stack-install.sh --write-gcmcurl -sSO https://dl.google.com/cloudagents/install-logging-agent.shsudo bash install-logging-agent.sh # 谨慎安装,见下文
毕竟是 Google 自家的服务,安装不需要任何登陆等操作。安装完毕后就会自动采集数据。它分为两个部分,Stack Monitoring 用于监控服务器指标,包括硬盘存储空间、内存占用(包括 Used、Buffered)等 GCE 默认无法监控到的数据。还有就是 Logging,它可以自动同步日志到 Google 的云端,你可以集中的执行搜索等操作。然而 Logging 这个进程会大概占用 100M 内存,小内存实例谨慎使用。需要注意的是,只有 Logging 是免费的,Monitoring 是收费的,每月 $8。 然后,你还可以为某一项指标建立告警,比如我创建了一个当磁盘空间高于 90% 的时候给我发邮件。 它可以创建公开页面分享服务器指标和 Uptime Check 延迟的图标,但是却不能显示在线率,实在是一个奇怪的设计。
Observium 通过 snmp 可以用来监控服务器的各项指标,包括内存、储存、网卡等。它可以免费安装在自己的服务器上,需要 MySQL 和 PHP 环境。官网给的是 Apache 的范例,如果你用 Nginx 就不需要安装 Apache。
它通过在服务端生成 PNG 来显示图表,所以图表很漂亮精致,但是由于不是矢量图,所以很难做到实时增量更新而且不能精细看到某一个时刻的数值。 Observium 可以轻松的管理许多个服务器。你可以体验在线 Demo。
]]>就算不缓存任何内容,全站 CDN 也是有他的优点的:
CloudFront 有 Amazon 自建的网络,单价较高但是 0 元起步,适合中小客户。本文将重点介绍 CloudFront 和 WordPress 配合实现动静分离,缓存 HTML 页面。之后将对比其他的一些 CDN。
CloudFront 作为全站 CDN 的特性:
先去 CloudFront 控制面板,点击 “Create Distribution”,选择 “Web”,然后进行类似如下的配置。源站配置注意 Origin Domain Name 必须是完整域名,而且如果用了 HTTPS,那么那个域名下必须有配置有效证书。
缓存配置,我把 Host 加入了 Header 白名单,Cookie 要添加 wordpress*
和 wp*
到白名单。
然后前端配置,证书点 “Request or Import a Certificate with ACM” 就能申请 Amazon 颁发的证书了。CNAMEs 下填写你的网站的域名。
注意,创建后可能要等不到一小时才能被访问到。 为了根域名和 CloudFront 配合使用,我还得换 Route 53 这个 DNS 解析。由于这是精度非常高的 GeoDNS,是需要将解析服务器向各大 DNS 缓存服务器去提交,让这些缓存服务器去针对你的 DNS 缓存服务器加入到启用 EDNS Client Subnet 的白名单中。还好 Route 53 是最流行的 GeoDNS 之一,所以如果你用它给的 NS 记录,而不去自定义,就不用操心这个了。在配置根域名时,直接选择 A 记录,然后开启 Alias,填写 CloudFront 域名就行。如果想要支持 IPv6,那就再建一个 AAAA 记录即可。这样的话如果你从外部解析,你会直接解析到 A 记录和 AAAA 记录,而不是 CNAME 了!
此时,CloudFront 就配置完了。现在 CloudFront 会自动缓存页面约一周的时间,所以需要配置文章更新时清理缓存。我写了一个插件,可以在有文章更新/主题修改/内核更新时清理所有缓存,新评论时清理文章页面,控制刷新频率为 10 分钟(这是由于 CloudFront 刷新缓存的速度是出奇的慢,而且刷新缓存只有前一千次免费)。欢迎使用我制作的插件。 不过,CloudFront 在国内的访问速度还不如我之前用的 GCE,这可怎么办?没关系,Route 53 可以 GeoDNS,我把中国和台湾还是解析到了原本的 GCE 上,这样速度其实只提不减。注意,若要这样做,原本的服务器也要有有效证书(同理,你要是域名已经备案,则可以设置为国内的 CDN 的 IP,达到国内外 CDN 混用的效果)。CloudFront 会影响 Let’s Encrypt 的签发,所以需要通过设置 Behaviors 和多个源站服务器,来继续实现 80 端口的文件认证。实际测试 Route 53 为中国解析的 IPv4 识别率为 100%,IPv6 的识别率欠佳。
国内解析情况:
$ dig @8.8.8.8 +short guozeyu.com a104.199.138.99$ dig @8.8.8.8 +short guozeyu.com aaaa2600:9000:2029:3c00:9:c41:b0c0:93a12600:9000:2029:9600:9:c41:b0c0:93a12600:9000:2029:2a00:9:c41:b0c0:93a12600:9000:2029:1600:9:c41:b0c0:93a12600:9000:2029:c00:9:c41:b0c0:93a12600:9000:2029:ce00:9:c41:b0c0:93a12600:9000:2029:6400:9:c41:b0c0:93a12600:9000:2029:ac00:9:c41:b0c0:93a1
国外解析情况:
$ dig @8.8.8.8 +short guozeyu.com a52.222.238.23652.222.238.22752.222.238.20752.222.238.10752.222.238.20852.222.238.7152.222.238.6852.222.238.67$ dig @8.8.8.8 +short guozeyu.com aaaa2600:9000:202d:5c00:9:c41:b0c0:93a12600:9000:202d:ec00:9:c41:b0c0:93a12600:9000:202d:7c00:9:c41:b0c0:93a12600:9000:202d:2a00:9:c41:b0c0:93a12600:9000:202d:9400:9:c41:b0c0:93a12600:9000:202d:c600:9:c41:b0c0:93a12600:9000:202d:f600:9:c41:b0c0:93a12600:9000:202d:6200:9:c41:b0c0:93a1
没错,CloudFront 分配给的 IP 数量就是多,让别人看了会感觉很厉害。
这里只对比国外的速度
这里也是只对比国外的速度
启动 CDN 后的 TTFB 几乎全面绿色,建立 TCP 和 TLS 的时间显著降低。
CloudFront 免费签发的 SSL 证书是多域名通配符证书(Wildcard SAN),并且主要名称是自定的,要比 Cloudflare 的共享证书高级。此类证书在 Cloudflare 上需要花费每月 10 美元。此类证书在市面上很难买到,而且价格取决于域名数量,在一年几千到几万不等。 然而,这个证书只能在 AWS 的 CloudFront 和负载均衡器上使用。
CloudFront 的证书链较长,会影响 TLS 时间,不过由于它同时也是 CDN,这样 TLS 时间几乎减少到了可以忽略不计的程度。主要还是因为 macOS 上还没有直接信任 Amazon Root CA,如果直接信任了,就用不着这样了。
以下列出的所有提供商(或某一提供商的某些版本),均符合以下条件,如果不符合则单独列出:
有自建的网络,最快的速度、最低廉的价格,主要提供网站安全防护,当然还附带了 CDN。其提供的 NS 服务也是(国外)业界第一的速度。本站国外使用了 Cloudflare,欢迎直接测试本站国外的速度。
Cloudflare 作为全站 CDN 的特性:
有一点不同的是,Cloudflare 签发的是共享证书,证书样式如下:
我觉得 Cloudflare 签发共享证书有两个原因,一是历史遗留问题:Cloudflare 专业版的 SSL 证书服务是支持无 SNI 的客户端的,而为了支持无 SNI 的客户端,一个 IP 就只能配置一个证书,所以就使用了共享证书节约 IP 资源。而现在免费版也有了 SSL,虽然免费版使用了 SNI 技术,但是证书总不能比付费版本还要高级吧,于是还是使用了共享 SSL 证书;二是为了增加更多的增值服务,现在 Cloudflare 上可以购买 Dedicated SSL Certificates,实现独立的证书(如果是付费版本启用,不支持 SNI 的客户端仍然 Fall back 到共享证书,所以仍然兼容不支持 SNI 的设备)。
简介同上,此版本适合大客户,流量越大越适合用。百度云加速是和 Cloudflare 深度整合的,其实基础设施完全一样,但百度云加速没有提供 API 接口。
Cloudflare 企业版作为全站 CDN 的特性:
使用自己管理的机房,网络有些受限于中国的环境,单价业界最低。
UPYUN 作为全站 CDN 的特性:
UPYUN 和下面的 KeyCDN 签发的都是 Let’s Encrypt 的独立证书,但都是单域名证书,甚至有 www 和无 www 的都要单独申请。
有全球最密集的网络集群,最快的速度、较低的单价,主要提供负载均衡,SSL 卸载,当然还附带了 CDN。由于缓存命中率低,需要超大型访问量的网站才有效。正是因为这一点,Google 自己只是将用户量极大的搜索服务用上了这个 CDN 系统,其余的很多 CDN 用的是 Cloudflare 和 Fastly 的。Google 的网络和 Cloudflare 和 Fastly 的网络有内网链接。详细介绍看本站的这篇文章
Google Cloud CDN 作为全站 CDN 的特性:
他们是租用别人的独立服务器,提供一体化 CDN 服务,单价业界最低。
KeyCDN 作为全站 CDN 的特性:
我为他写了一个插件可以实现完美清理缓存,详情见此
WordPress 可以分别设置 Site URL 和 Home URL,对于 https://example.com 这个网站,这两栏就可以这样设置:
然后,直接给 Home URL 上 CDN,在 CDN 或者源站上配置忽略 Cookie 信息。Site URL 回源,用作 WordPress 后台管理即可。
]]>HTTPS 是加密了的 HTTP 协议,网址以 https://
开头,就代表是使用了这个协议。 HTTPS 相比 HTTP,拥有全部的以下特性:
由于 HTTPS 要完成身份验证,所以若需要配置 HTTPS,就必须要取得被公认的证书颁发商颁发的证书。
部署 HTTPS 必须要拥有 SSL 证书,而 SSL 证书的价格区间在每年几百甚至上万元不等,高昂的证书价格成为了部署 HTTPS 的一个重大负担。2015 年末,Let’s Encrypt 正式开始公测,可以免费签发多域名的证书,此类证书原先的价格在百元到千元左右。即使是在测试阶段,仅仅 3 个月时间就签发了 100 多万张证书! Let’s Encrypt 的证书使用自动化部署,验证、签发过程均通过 API 自动实现,大大缩短了申请证书所需要的时间;同时各种服务提供商也纷纷提供了自动签发 Let’s Encrypt 证书的渠道。由于 Let’s Encrypt 的出现,确实大大加快了 HTTPS 的普及。
在 2015 年初,HTTP/2 正式成为标准,紧接着各大浏览器和操作系统纷纷支持:Firefox 36、Chrome 41、iOS 9 & macOS 10.11(Safari 9)、Windows 10(IE 11 & Edge)。紧接着,Cloudflare、CloudFront、UPYUN 这些 CDN 提供商也纷纷支持了 HTTP/2,HTTP 服务器 Nginx 和 Apache 也对其做了支持。 HTTP/2 的出现是为了取代 HTTP 1.1 和 SPDY。HTTP/2 主要是支持了多路传输,原本需要合并 CSS 和 JS 文件、为众多的图片准备多个域名的做法,使用了 HTTPS/2 之后就没什么必要了。相比 HTTP 1.1 的每一个数据需要单独的一个连接,HTTPS/2 中网站的所有数据只需要一个连接。
由于浏览器会限制连接数量,这就会导致在 HTTP 1.1 中,每次只能同时下载几个文件。多路传输可以让这些文件一块儿传输,大大减少加载时间。
然而,这些浏览器里只是针对 HTTPS 站点做了 HTTP/2 的实现。于是想到让网站提高加载速度,又不得不用 HTTPS。所以,HTTP/2 的出现也推进了 HTTPS 的发展。
现在,Chrome 已经开始对使用了 HTTPS 的网站显示 “安全” 字样(EV 证书这个地方则显示企业名称):
在未来的某一个版本中,对于无 HTTPS 的网站,最终将会这样显示(对于所有 HTTP 网站,未来不同的版本显示的过程是:灰色叹号、红色警报叹号、红色警报叹号 + “不安全字样”;有信用卡或密码提交的会先进行这类显示。下图是最终的第三阶段):
你也可以在 Chrome 设置页面将其调整为 “一律将 HTTP 网页标为不安全”。我推荐所有人都这样设置,因为 HTTP 确实是毫无安全可言! 相信没有公司愿意让用户看到自己的网站被标记为 “不安全” 吧?浏览器的推进起到至关重要的作用。
在最新的 Chrome 58 版本里,非 HTTPS 的密码输入处已经显示这样的信息(此处为 weibo.com 的网站登陆窗口):
经测试,只要主站是 HTTP,即使表单是提交到 HTTPS 页面,也会显示此信息。
2015 年末的时候,苹果就开始实施 ATS,然而开发者仍能找到选项去关闭这个功能。而在 2017 年或之后某个时刻后(具体 deadline 苹果尚未明确给出,不过可以确定的是不开 ATS 审核会逐渐变严格,并要求提供更多的理由),所有新提交的 APP 必须开启 ATS,也就是说新提交的 APP 必须全部使用 HTTPS 内容了。这促使着众多国内厂商去做 HTTPS 支持。
本站特别推荐的虚拟主机提供商 TlOxygen 现在就支持申请免费 SSL 证书了。整个过程十分简单,并且会自动续签!实现方式:自动为虚拟主机安装 acme.sh 软件,然后自动执行安装流程。此外,TlOxygen 的虚拟主机支持 SSH 访问,所以你也可以自行使用 acme.sh 或者任何其他工具操作。
]]>一般的,建站所需要购买的服务也是属于这三种服务之间的。从 SaaS、Paas 到 IaaS,依次从使用简便到复杂,从可拓展性低到高。了解这三种服务类型有助于选择合适的服务。
一些可能需要的特性:基于要实现的不同功能,可能需要在以下方面有要求,在选择服务的时候需要优先考虑。
排列的顺序只是与添加在这个列表里的时间有关,新添加的会被放在后面。此处添加的服务商全是个人的推荐的,以后还会持续更新。 标注列表:
以下 CDN 都支持 HTTPS 与 IPv6
SaaS 还有很多,太多的东西都是 SaaS 了,所以这里只能算举几个例子。
或者说是分布式的虚拟主机,但是有独立的 CPU 和内存资源。
标注列表:
(U):独享 CPU³
(C):基于云端的技术,高可用性
(S):关机后不计费
Vultr (6、D⁶)
OVH (6²、D、C⁴)
Google Compute Engine (D⁵、C、U、S)
Linode (6)
DigitalOcean (6)
AWS EC2 (S)
QingCloud/青云 (S)
example.com
)的核心组成部分。绝大多数与域名相关的东西,都离不开它。比如:https://www.example.com
)@
后面是主机名,而主机名通常是个域名(如 webmaster@example.com
)整个 DNS 具有复杂的层次,这对刚开始购买域名的人有很大的疑惑。本文将详尽的介绍 DNS 的工作原理,有助于更深刻的理解。本文将介绍:
同时还包含:
先从本地的 DNS 开始讲起。
本地的 DNS 相对于全球 DNS 要简单的多。所以先从本地 DNS 开始讲起。 127.0.0.1
常被用作环回 IP,也就可以作为本机用来访问自身的 IP 地址。通常,这个 IP 地址都对应着一个域名,叫 localhost
。这是一个一级域名(也是顶级域名),所以和 com
同级。系统是如何实现将 localhost
对应到 127.0.0.1
的呢?其实就是通过 DNS。在操作系统中,通常存在一个 hosts
文件,这个文件定义了一组域名到 IP 的映射。常见的 hosts 文件内容如下:
127.0.0.1 localhost::1 localhost
它就定义了 localhost
域名对应 127.0.0.1
这个 IP(第二行是 IPv6 地址)。这样,当你从浏览器里访问这个域名,或者是在终端中执行 Ping 的时候,会自动的查询这个 hosts
文件,就从文件中得到了这个 IP 地址。此外,hosts
文件还可以控制其他域名所对应的 IP 地址,并可以 override 其在全球 DNS 或本地网络 DNS 中的值。但是,hosts
文件只能控制本地的域名解析。hosts
文件出现的时候,还没有 DNS,但它可以说是 DNS 的前身。 如果需要在一个网络中,公用同一个 DNS,那么就需要使用 IP 数据包向某个服务器去获取 DNS 记录。 在一个网络里(此处主要指本地的网络,比如家庭里一个路由器下连接的所有设备和这个路由器组成的网络),会有很多主机。在与这些主机通信的时候,使用域名会更加的方便。通常,连接到同一个路由器的设备会被设置到路由器自己的一个 DNS 服务器上。这样,解析域名就不仅可以从 hosts 去获取,还可以从这个服务器上去获取。从另一个 IP 上去获取 DNS 记录通过 DNS 查询,DNS 查询通常基于 UDP 或者 TCP 这种 IP 数据包,来实现远程的查询。我的个人电脑的网络配置如下,这是在我的电脑连接了路由器之后自动就设置上的:
重点是在路由器和搜索域上。 我的电脑的主机名(也是电脑名)设置的是 ze3kr
,这个内容在连接路由器时也被路由器知道了,于是路由器就给我的主机分配了一个域名 ze3kr.local
,local
这个一级域名专门供本地使用。在这个网络内所有主机通过访问 ze3kr.local
这个域名时,路由器(10.0.1.1
)就会告知这个域名对应的 IP 地址,于是这些主机够获得到我的电脑的 IP 地址。至于搜索域的作用,其实是可以省去输入完整的域名,比如:
$ ping ze3krPING ze3kr.local (10.0.1.201): 56 data bytes64 bytes from 10.0.1.201: icmp_seq=0 ttl=64 time=0.053 ms--- ze3kr.local ping statistics ---1 packets transmitted, 1 packets received, 0.0% packet lossround-trip min/avg/max/stddev = 0.053/0.053/0.053/0.000 ms
当设置了搜索域时,当你去解析 ze3kr
这个一级域名时,便会先尝试去解析 ze3kr.local
,当发现 ze3kr.local
存在对应的解析时,便停止进一步解析,直接使用 ze3kr.local
的地址。 现在你已经了解了本地 DNS 的工作方式。DNS 的基本工作方式就是:获取域名对应 IP,然后与这个 IP 进行通信。 当在本地去获取一个完整域名(FQDN)时(执行 getaddrbyhost
),通常也是通过路由器自己提供的 DNS 进行解析的。当路由器收到一个完整域名请求且没有缓存时,会继续向下一级缓存 DNS 服务器(例如运营商提供的,或者是组织提供的,如 8.8.8.8)查询,下一级缓存 DNS 服务器也没有缓存时,就会通过全球 DNS 进行查询。具体的查询方式,在 “全球 DNS” 中有所介绍。
在本地,先读取本地缓存查找记录,再读取 Hosts 文件,然后在搜索域中查找域名,最后再向路由器请求 DNS 记录。
在全球 DNS 中,一个完整域名通常包含多级,比如 example.com.
就是个二级域名, www.example.com.
就是个三级域名。通常我们常见到的域名都是完整的域名。
一级域名被分为以下三个部分:
arpa
域:用于将 IP 地址转换为对应的域名的根域。我们通常所见到的域名都是普通域和国家域,而 arpa
域用作 IP 到域名的反向解析。 在本地 DNS 中,只存在域名对应 IP 这种映射关系。然而,在全球 DNS 中,有着更多的资源记录种类(RR),不只是域名对应 IP 的关系,下面将分别介绍一些最基本的资源记录种类:
先从根域名开始,未命名根也可以作为 .
。你在接下来的部分所看到的很多域名都以 .
结尾,以 .
结尾的域名是特指的是根域名下的完整域名,然而不以 .
结尾的域名大都也是完整域名,实际使用时域名末尾的 .
也常常省略。在本文中,我使用 dig 这一个常用的 DNS 软件来进行查询,我的电脑也已经连接到了互联网。 假设目前这个计算机能与互联网上的 IP 通信,但是完全没有 DNS 服务器。此时你需要知道根 DNS 服务器,以便自己获取某个域名的 IP 地址。根 DNS 服务器列表可以在这里下载到。文件内容如下:
; This file holds the information on root name servers needed to; initialize cache of Internet domain name servers; (e.g. reference this file in the "cache . <file>"; configuration file of BIND domain name servers).;; This file is made available by InterNIC; under anonymous FTP as; file /domain/named.cache; on server FTP.INTERNIC.NET; -OR- RS.INTERNIC.NET;; last update: October 20, 2016; related version of root zone: 2016102001;; formerly NS.INTERNIC.NET;. 3600000 NS A.ROOT-SERVERS.NET.A.ROOT-SERVERS.NET. 3600000 A 198.41.0.4A.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:ba3e::2:30;; FORMERLY NS1.ISI.EDU;. 3600000 NS B.ROOT-SERVERS.NET.B.ROOT-SERVERS.NET. 3600000 A 192.228.79.201B.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:84::b;; FORMERLY C.PSI.NET;. 3600000 NS C.ROOT-SERVERS.NET.C.ROOT-SERVERS.NET. 3600000 A 192.33.4.12C.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2::c;; FORMERLY TERP.UMD.EDU;. 3600000 NS D.ROOT-SERVERS.NET.D.ROOT-SERVERS.NET. 3600000 A 199.7.91.13D.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2d::d;; FORMERLY NS.NASA.GOV;. 3600000 NS E.ROOT-SERVERS.NET.E.ROOT-SERVERS.NET. 3600000 A 192.203.230.10E.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:a8::e;; FORMERLY NS.ISC.ORG;. 3600000 NS F.ROOT-SERVERS.NET.F.ROOT-SERVERS.NET. 3600000 A 192.5.5.241F.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2f::f;; FORMERLY NS.NIC.DDN.MIL;. 3600000 NS G.ROOT-SERVERS.NET.G.ROOT-SERVERS.NET. 3600000 A 192.112.36.4G.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:12::d0d;; FORMERLY AOS.ARL.ARMY.MIL;. 3600000 NS H.ROOT-SERVERS.NET.H.ROOT-SERVERS.NET. 3600000 A 198.97.190.53H.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:1::53;; FORMERLY NIC.NORDU.NET;. 3600000 NS I.ROOT-SERVERS.NET.I.ROOT-SERVERS.NET. 3600000 A 192.36.148.17I.ROOT-SERVERS.NET. 3600000 AAAA 2001:7fe::53;; OPERATED BY VERISIGN, INC.;. 3600000 NS J.ROOT-SERVERS.NET.J.ROOT-SERVERS.NET. 3600000 A 192.58.128.30J.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:c27::2:30;; OPERATED BY RIPE NCC;. 3600000 NS K.ROOT-SERVERS.NET.K.ROOT-SERVERS.NET. 3600000 A 193.0.14.129K.ROOT-SERVERS.NET. 3600000 AAAA 2001:7fd::1;; OPERATED BY ICANN;. 3600000 NS L.ROOT-SERVERS.NET.L.ROOT-SERVERS.NET. 3600000 A 199.7.83.42L.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:9f::42;; OPERATED BY WIDE;. 3600000 NS M.ROOT-SERVERS.NET.M.ROOT-SERVERS.NET. 3600000 A 202.12.27.33M.ROOT-SERVERS.NET. 3600000 AAAA 2001:dc3::35; End of file
这个文件中每一行分为 4 列,分别是完整域名、资源类型、生存时间(TTL,也就是可以缓存的时间)以及资源数据。通过这个文件就可以知道根域名所对应的 13 个根域名服务器的完整域名,还能知道这 13 个完整域名所对应的 IP 地址。这是因为 NS 记录只能设置为完整域名,所以为了告知 NS 所对应的 IP,还需要额外的数据去说明这 13 个完整域名对应的 IP(这些额外的数据叫做 Glue 记录)。这 13 个根域名服务器都是独立的且冗余的(但是所返回的内容应该是相同的),这样当其中的某个或某些服务器发生故障时,不会影响到解析。一旦无法解析根域名,那么所有的域名都将无法访问。
Glue 记录:如果 NS 记录对应的某个完整域名包含在那个域名之中,那么就需要添加一个 Glue 记录,来指定那个完整域名所对应的 IP。实际上任何完整域名都属于根域名之中,所以根域名就必须对这些 NS 记录设置对应的 IP 地址。Glue 记录实质上就是 A(或 AAAA)记录。(RFC 1033)
我们假设你已经通过某种方法成功获取到了这个文件,那么下一步,就是使用这里的服务器对根域名以及一级域名进行解析。对根域名的解析实际上是不必要的,但是我们还是对其进行解析以便进一步分析,获得在互联网上最新、最全的数据。 在根域名上的记录,以从根域名服务器中所解析其根域名的数据为准,而不是刚才的那个文件中的内容。刚才的文件内容只是告知根域名服务器的列表,也就是只有 NS 记录和 NS 记录对应的完整域名的 IP 记录,而不是根域名下的所有记录。 我们先向 198.41.0.4
这个 IP 发送查询根域名的所有记录,any 代表显示任何类型的记录,为了看起来方便,一些无关的响应已经删除(如果只是解析根域名,这一步不能跳过。如果需要直接解析一级域名,那么这一步就可以跳过)。
$ dig @198.41.0.4 . any;; QUESTION SECTION:;.INANY;; ANSWER SECTION:.518400INNSa.root-servers.net..518400INNSb.root-servers.net..518400INNSc.root-servers.net..518400INNSd.root-servers.net..518400INNSe.root-servers.net..518400INNSf.root-servers.net..518400INNSg.root-servers.net..518400INNSh.root-servers.net..518400INNSi.root-servers.net..518400INNSj.root-servers.net..518400INNSk.root-servers.net..518400INNSl.root-servers.net..518400INNSm.root-servers.net..86400INSOAa.root-servers.net. nstld.verisign-grs.com. 2016122400 1800 900 604800 86400;; ADDITIONAL SECTION:a.root-servers.net.518400INA198.41.0.4b.root-servers.net.518400INA192.228.79.201c.root-servers.net.518400INA192.33.4.12d.root-servers.net.518400INA199.7.91.13e.root-servers.net.518400INA192.203.230.10f.root-servers.net.518400INA192.5.5.241g.root-servers.net.518400INA192.112.36.4h.root-servers.net.518400INA198.97.190.53i.root-servers.net.518400INA192.36.148.17j.root-servers.net.518400INA192.58.128.30k.root-servers.net.518400INA193.0.14.129l.root-servers.net.518400INA199.7.83.42m.root-servers.net.518400INA202.12.27.33a.root-servers.net.518400INAAAA2001:503:ba3e::2:30b.root-servers.net.518400INAAAA2001:500:84::bc.root-servers.net.518400INAAAA2001:500:2::cd.root-servers.net.518400INAAAA2001:500:2d::de.root-servers.net.518400INAAAA2001:500:a8::ef.root-servers.net.518400INAAAA2001:500:2f::fg.root-servers.net.518400INAAAA2001:500:12::d0dh.root-servers.net.518400INAAAA2001:500:1::53i.root-servers.net.518400INAAAA2001:7fe::53j.root-servers.net.518400INAAAA2001:503:c27::2:30k.root-servers.net.518400INAAAA2001:7fd::1l.root-servers.net.518400INAAAA2001:500:9f::42m.root-servers.net.518400INAAAA2001:dc3::35
其中,可以看到 TTL 与刚才文件中的内容不一样,此外还多了一个 SOA 记录,所以实际上是以这里的结果为准。这里还有一个 SOA 记录,SOA 记录是普遍存在的,具体请参考文档,在这里不做过多说明。
SOA 记录:指定有关 _DNS 区域_的权威性信息,包含主要名称服务器、域名管理员的电邮地址、域名的流水式编号、和几个有关刷新区域的定时器。(RFC 1035)
_DNS 区域_:对于根域名来说,DNS 区域就是空的,也就是说它负责这互联网下所有的域名。而对于我的网站,DNS 区域就是 guozeyu.com.
,管理着 guozeyu.com.
本身及其子域名的记录。
此处的 ADDITIONAL SECTION 其实就包含了 Glue 记录。
根域名自身的 DNS 服务器服务器除了被用于解析根自身之外,还用于解析所有在互联网上的一级域名。你会发现,几乎所有的 DNS 服务器,无论是否是根 DNS 服务器,都会解析其自身以及其下级域名。 从之前的解析结果中可以看出,根域名没有指定到任何 IP 地址,但是却给出了 NS 记录,于是我们就需要用这些 NS 记录来解析其下级的一级域名。下面,用所得到的根 NS 记录中的服务器其中之一来解析一个一级域名 com.
。
$ dig @198.41.0.4 com any;; QUESTION SECTION:;com.INANY;; AUTHORITY SECTION:com.172800INNSa.gtld-servers.net.com.172800INNSb.gtld-servers.net.com.172800INNSc.gtld-servers.net.com.172800INNSd.gtld-servers.net.com.172800INNSe.gtld-servers.net.com.172800INNSf.gtld-servers.net.com.172800INNSg.gtld-servers.net.com.172800INNSh.gtld-servers.net.com.172800INNSi.gtld-servers.net.com.172800INNSj.gtld-servers.net.com.172800INNSk.gtld-servers.net.com.172800INNSl.gtld-servers.net.com.172800INNSm.gtld-servers.net.;; ADDITIONAL SECTION:a.gtld-servers.net.172800INA192.5.6.30b.gtld-servers.net.172800INA192.33.14.30c.gtld-servers.net.172800INA192.26.92.30d.gtld-servers.net.172800INA192.31.80.30e.gtld-servers.net.172800INA192.12.94.30f.gtld-servers.net.172800INA192.35.51.30g.gtld-servers.net.172800INA192.42.93.30h.gtld-servers.net.172800INA192.54.112.30i.gtld-servers.net.172800INA192.43.172.30j.gtld-servers.net.172800INA192.48.79.30k.gtld-servers.net.172800INA192.52.178.30l.gtld-servers.net.172800INA192.41.162.30m.gtld-servers.net.172800INA192.55.83.30a.gtld-servers.net.172800INAAAA2001:503:a83e::2:30b.gtld-servers.net.172800INAAAA2001:503:231d::2:30
可以看到解析的结果和解析根域名的类似,com.
下也设置了 13 个域名服务器,但是这 13 个域名服务器与根域服务器完全不同。
此处也存在 ADDITIONAL SECTION 包含的 Glue 记录,然而 gtld-servers.net.
却并不包含在 com.
下。然而实际上,com.
和 net.
域名都是属于同一个所有者(Verisign),所以这样设置是可以的。
和根域名类似,此时解析到的内容只是 com.
的域名服务器,而并不是 com.
本身的记录,在 com.
上的记录,以从 com.
的域名服务器中所解析其 com.
域名的数据为准。 所以,下面再使用 com.
的域名服务器来解析 com.
自身,看情况如何(如果只是解析一级域名,这一步不能跳过。如果需要直接解析二级域名,那么这一步就可以跳过):
$ dig @192.5.6.30 com any;; QUESTION SECTION:;com.INANY;; ANSWER SECTION:com.900INSOAa.gtld-servers.net. nstld.verisign-grs.com. 1482571852 1800 900 604800 86400com.172800INNSe.gtld-servers.net.com.172800INNSm.gtld-servers.net.com.172800INNSi.gtld-servers.net.com.172800INNSk.gtld-servers.net.com.172800INNSb.gtld-servers.net.com.172800INNSj.gtld-servers.net.com.172800INNSa.gtld-servers.net.com.172800INNSd.gtld-servers.net.com.172800INNSg.gtld-servers.net.com.172800INNSc.gtld-servers.net.com.172800INNSh.gtld-servers.net.com.172800INNSf.gtld-servers.net.com.172800INNSl.gtld-servers.net.;; ADDITIONAL SECTION:e.gtld-servers.net.172800INA192.12.94.30m.gtld-servers.net.172800INA192.55.83.30i.gtld-servers.net.172800INA192.43.172.30k.gtld-servers.net.172800INA192.52.178.30b.gtld-servers.net.172800INA192.33.14.30b.gtld-servers.net.172800INAAAA2001:503:231d::2:30j.gtld-servers.net.172800INA192.48.79.30a.gtld-servers.net.172800INA192.5.6.30a.gtld-servers.net.172800INAAAA2001:503:a83e::2:30d.gtld-servers.net.172800INA192.31.80.30g.gtld-servers.net.172800INA192.42.93.30c.gtld-servers.net.172800INA192.26.92.30h.gtld-servers.net.172800INA192.54.112.30f.gtld-servers.net.172800INA192.35.51.30l.gtld-servers.net.172800INA192.41.162.30
也和根域名解析的情况类似,此时多了一个 SOA 类型的记录。
和解析一级域名 com.
时类似,继续使用 com.
的域名服务器解析 guozeyu.com.
。
$ dig @192.5.6.30 guozeyu.com any;; QUESTION SECTION:;guozeyu.com.INANY;; AUTHORITY SECTION:guozeyu.com.172800INNSa.ns.guozeyu.com.guozeyu.com.172800INNSb.ns.guozeyu.com.guozeyu.com.172800INNSc.ns.guozeyu.com.;; ADDITIONAL SECTION:a.ns.guozeyu.com.172800INAAAA2001:4860:4802:38::6ca.ns.guozeyu.com.172800INA216.239.38.108b.ns.guozeyu.com.172800INAAAA2001:4860:4802:36::6cb.ns.guozeyu.com.172800INA216.239.36.108c.ns.guozeyu.com.172800INAAAA2001:4860:4802:34::6cc.ns.guozeyu.com.172800INA216.239.34.108
此处也存在 ADDITIONAL SECTION 包含的 Glue 记录,是因为 ns.guozeyu.com.
在 guozeyu.com.
之下。 同样的,在 guozeyu.com.
上的记录,以从 guozeyu.com.
的域名服务器中所解析其 guozeyu.com.
域名的数据为准。此时这种解析就尤为必要了,因为 guozeyu.com.
上不只有 SOA 记录,同时也有 A 记录和其他重要的记录。 现在使用 guozeyu.com.
的域名服务器来解析 guozeyu.com.
(如果只是解析二级域名,这一步不能跳过。如果需要解析三级域名,那么这一步可以跳过):
$ dig @216.239.38.108 guozeyu.com any;; QUESTION SECTION:;guozeyu.com.INANY;; ANSWER SECTION:guozeyu.com.21600INA104.199.138.99guozeyu.com.172800INNSa.ns.guozeyu.com.guozeyu.com.172800INNSb.ns.guozeyu.com.guozeyu.com.172800INNSc.ns.guozeyu.com.guozeyu.com.21600INSOAa.ns.guozeyu.com. support.tlo.xyz. 1 21600 3600 259200 300guozeyu.com.172800INMX100 us2.mx1.mailhostbox.com.guozeyu.com.172800INMX100 us2.mx2.mailhostbox.com.guozeyu.com.172800INMX100 us2.mx3.mailhostbox.com.;; ADDITIONAL SECTION:a.ns.guozeyu.com.604800INA216.239.38.108a.ns.guozeyu.com.604800INAAAA2001:4860:4802:38::6cb.ns.guozeyu.com.604800INA216.239.36.108b.ns.guozeyu.com.604800INAAAA2001:4860:4802:36::6cc.ns.guozeyu.com.604800INA216.239.34.108c.ns.guozeyu.com.604800INAAAA2001:4860:4802:34::6c
可以发现增加了 A、SOA 和 MX 记录。
正是因为 MX 记录的存在,所以发往 username@guozeyu.com
的邮件不是指向 guozeyu.com.
对应的 IP 地址,而是使用 mailhostbox.com.
下的服务器。 当然,由于我是 guozeyu.com.
的所有者,所以我也可以控制 guozeyu.com.
下的三级或更高级的域名。比如 www.guozeyu.com.
:
$ dig @216.239.38.108 www.guozeyu.com any;; QUESTION SECTION:;guozeyu.com.INANY;; ANSWER SECTION:www.guozeyu.com.172800INCNAMEguozeyu.com.guozeyu.com.21600INA104.199.138.99guozeyu.com.172800INNSa.ns.guozeyu.com.guozeyu.com.172800INNSb.ns.guozeyu.com.guozeyu.com.172800INNSc.ns.guozeyu.com.guozeyu.com.21600INSOAa.ns.guozeyu.com. support.tlo.xyz. 1 21600 3600 259200 300guozeyu.com.172800INMX100 us2.mx1.mailhostbox.com.guozeyu.com.172800INMX100 us2.mx2.mailhostbox.com.guozeyu.com.172800INMX100 us2.mx3.mailhostbox.com.;; ADDITIONAL SECTION:a.ns.guozeyu.com.604800INA216.239.38.108a.ns.guozeyu.com.604800INAAAA2001:4860:4802:38::6cb.ns.guozeyu.com.604800INA216.239.36.108b.ns.guozeyu.com.604800INAAAA2001:4860:4802:36::6cc.ns.guozeyu.com.604800INA216.239.34.108c.ns.guozeyu.com.604800INAAAA2001:4860:4802:34::6c
我的三级域名 www.guozeyu.com.
使用 CNAME 记录指向了 guozeyu.com.
,这代表着 guozeyu.com.
下所有资源类型均与 guozeyu.com.
相同。这也是为什么 CNAME 不能和其他任何记录连用的原因,CNAME 的存在会取代任何其他的记录。由于主域名下常常也存在 SOA、NS 以及 MX 记录,所以主域名下不能使用 CNAME 解析。此外,我也可以设置在 guozeyu.com.
下的三级域名指向一个 NS 记录,这样我就可以把我的三级域名再给别人使用。
通常,凡是解析过的记录,都会被解析服务器、路由器、客户端、软件缓存。这样可以大大减少请求次数。凡是被缓存的记录,其在 TTL 规定的时间内都不会再次去解析,而是直接从高速缓存中读取。正常情况下,服务器、路由器等都不应该扩大 TTL 值。被缓存的内容,TTL 值要在每秒减 1 。
$ dig guozeyu.com;; QUESTION SECTION:;guozeyu.com.INA;; ANSWER SECTION:guozeyu.com.21599INA104.199.138.99;; Query time: 514 msec;; SERVER: 10.0.1.1#53(10.0.1.1);; WHEN: Sat Dec 24 20:00:29 2016;; MSG SIZE rcvd: 43$ dig guozeyu.com;; QUESTION SECTION:;guozeyu.com.INA;; ANSWER SECTION:guozeyu.com.21598INA104.199.138.99;; Query time: 45 msec;; SERVER: 10.0.1.1#53(10.0.1.1);; WHEN: Sat Dec 24 20:00:30 2016
这是我连续两次在我的电脑上直接通过路由器解析 guozeyu.com.
的结果。显然第一次解析没有命中高速缓存,路由器向运营商的 DNS 服务器查询,运营商的 DNS 再从根域名逐级解析 guozeyu.com.
,总耗时 514 毫秒。然后 guozeyu.com.
就会同时在运营商的服务器上和路由器的 DNS 服务器上进行缓存。在第二次请求 guozeyu.com.
时,就命中了在路由器上的缓存,于是由路由器直接返回解析记录,总耗时 45 毫秒。两次查询时间相隔一秒,所以 TTL 值也被减去 1 。
arpa
反向解析反向解析用于:给定一个 IP 地址,返回与该地址对应的域名。函数 gethostbyaddr
正是使用了这种方法获取 IP 对应的域名。 一级域名 arpa. 用于设置反向解析,对于我的网站的 IPv4 地址 104.199.138.99
,其所对应的 arpa
完整域名是:99.138.199.104.in-addr.arpa.
,通过获取这个域名的 PTR 记录,就可以得到这个域名所对应的完整域名域名。
$ host 104.199.138.9999.138.199.104.in-addr.arpa domain name pointer 99.138.199.104.bc.googleusercontent.com.$ dig 99.138.199.104.in-addr.arpa. ptr +short99.138.199.104.bc.googleusercontent.com.
可以看到,使用 host
命令获得 IP 地址的域名与使用 dig
获取的相同,均为 99.138.199.104.bc.googleusercontent.com.
。可以看出,这个 IP 是属于 Google 的。此外,需要注意的是 in-addr.arpa. 下的字域名正好与原 IPv4 地址排列相反。 这个记录通常可以由 IP 的所有者进行设置。然而,IP 的所有者可以将这项记录设置为任何域名,包括别人的域名。所以通过这种方法所判断其属于 Google 并不准确,所以,我们还需要对其验证:
$ dig 99.138.199.104.bc.googleusercontent.com a +short104.199.138.99
可以看到,这个域名又被解析到了原本的 IP,此时验证完毕,确认了这个 IP 属于 Google。所以,通过 gethostbyaddr
之后,还要继续 getaddrbyhost
验证。 然而,进行这种解析时解析服务器是由谁提供的呢?我们来看看 99.138.199.104.in-addr.arpa.
的上一级域名的解析记录:
$ dig 138.199.104.in-addr.arpa. any;; QUESTION SECTION:;138.199.104.in-addr.arpa.INANY;; ANSWER SECTION:138.199.104.in-addr.arpa. 21583INNSns-gce-public1.googledomains.com.138.199.104.in-addr.arpa. 21583INNSns-gce-public2.googledomains.com.138.199.104.in-addr.arpa. 21583INNSns-gce-public3.googledomains.com.138.199.104.in-addr.arpa. 21583INNSns-gce-public4.googledomains.com.138.199.104.in-addr.arpa. 21583INSOAns-gce-public1.googledomains.com. cloud-dns-hostmaster.google.com. 1 21600 3600 259200 300
可以看到,上一级 138.199.104.in-addr.arpa.
下配置了 Google 的域名服务器,所以 104.199.138.0/24
(104.196.123.0 - 104.196.123.255
)都是属于 Google 的。然而,既然这个域名下的域名服务器可以设置为 Google 自己的,所以这个域名下就可以设置任何记录,不只是 PTR,所以也可以添加 A 记录把 arpa 域名当作网站! 我虽然没有那么大块的 IPv4 地址,但是我有这个 IPv6 地址:2001:470:f913::/48
并且能够设置在 arpa.
下的 NS 记录。这个 /48
的 IPv6 地址对应着 arpa.
反向解析的完整域名是 3.1.9.f.0.7.4.0.1.0.0.2.ip6.arpa.
,可以看到 IPv6 的反向解析在另一个二级域名 ip6.arpa.
下,此外其地址是将 IPv6 的每一个十六进制为拆开为一个字域并反向排列的。 我已把这个地址设置为了我自己可以控制的 NS,然后配置了 A 记录,瞬间这个反向解析域名就可以当作正常的解析使用了!
3.1.9.f.0.7.4.0.1.0.0.2.ip6.arpa
ze3kr.3.1.9.f.0.7.4.0.1.0.0.2.ip6.arpa
如果你试图用浏览器访问这两个域名,会收到证书错误的报告,因为我还没给这个域名签发证书。
]]>html[lang^="zh-"] body,html[lang^="zh-"] button,html[lang^="zh-"] input,html[lang^="zh-"] select,html[lang^="zh-"] textarea { font-family: "PingFang TC", "Helvetica Neue", Helvetica, STHeitiTC-Light, Arial, sans-serif;}
看来这是 WordPress 的 Bug,已经提交并修复。在官方修复前,可以在外观的 “自定义” 里面添加以下 CSS 解决此问题:
html[lang="zh-CN"] body,html[lang="zh-CN"] button,html[lang="zh-CN"] input,html[lang="zh-CN"] select,html[lang="zh-CN"] textarea { font-family: "PingFang SC", "Helvetica Neue", Helvetica, STHeitiSC-Light, Arial, sans-serif}
为什么这次 WordPress 要为每个语言单独指定系统字体呢?因为如果将字体设置为 -apple-system
后,在 Safari 下能够正确显示苹方字体,但是在 Chrome 下显示的还是老的字体。但如果特定指明字体种类,就能正确显示了。
AMP HTML 也是一种 HTML,一个符合标准的 AMP 页面只能使用有限的标签,而且很多标签都并非 HTML 标准,如 <amp-img>
、<amp-video>
等。 一个 Hello, AMPs 的例子:
<!doctype html><html amp lang="en"> <head> <meta charset="utf-8"> <script async src="https://cdn.ampproject.org/v0.js"></script> <title>Hello, AMPs</title> <link rel="canonical" href="http://example.ampproject.org/article-metadata.html" /> <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1"> <script type="application/ld+json"> { "@context": "http://schema.org", "@type": "NewsArticle", "headline": "Open-source framework for publishing content", "datePublished": "2015-10-07T12:02:41Z", "image": [ "logo.jpg" ] } </script> <style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript> </head> <body> <h1>Welcome to the mobile web</h1> </body></html>
此代码可以在主流浏览器中直接运行,和普通的 HTML 相比,它有以下区别:
<html>
中增加了 amp 属性,来标记这是个 AMP 页面<head>
中必须引用一个 JS:<script async src="https://cdn.ampproject.org/v0.js"></script>
amp-boilerplate
属性的 style,其中一个在 <noscript>
中。<head>
中需要有一个 <script type="application/ld+json">
去标记文档的 metadata。在 AMP HTML 中插入一个图片的例子:
<amp-img src="450px.jpg" srcset="450px.jpg 450w, 1200px.jpg 1200w"></amp-img>
会发现其实这和普通的 img 标签的语法没有什么区别,只是换了一个名字,实际上通过这样引入图片,AMP Runtime(就是在头部所引用的 v0.js
) 就会自动地解析这个 AMP Components,并会根据设备的分辨率去选择一张图片加载(原理只不过是通过 js 再创建一个 img 标签去让浏览器识别),甚至都不需要浏览器去支持 srcset 属性;而且还能够自动的延迟加载图片。插入视频和音频同样也需要使用 AMP 特定的方法去做。如果浏览器禁用了 JS,那么网页上的所有图片和视频等使用非标准 HTML 标签的内容都无法显示。
AMP 中禁止使用任何自己的 JS,这样做只是为了保证 JS 的加载速度——因为移动设备的性能不高,尽量减少 JS 或避免使用低质量 JS 的使用能够提高用户体验。所以,如果想使用更多的交互,那么必须通过 AMP HTML Extensions 的功能来实现,所以只能使用有限的交互功能。或者可以通过纯 CSS 来实现各种复杂的功能。
在这个网站上可以在线对 AMP 页面进行验证
你其实会发现,网页中可能会阻碍加载的内容只有一个外部的 JS(也就是 AMP Runtime),而且这个 JS 还被标记上了异步加载。所有的 CSS 都是 Inline 的。
AMP 所必须要引用的 AMP Runtime 这个核心 JS 必须要使用 Google 提供的那个特定的域名,现在 Google 已经针对中国解析到了中国服务器,中国访问还挺快! 现在,我发往微信公众号上的文章就使用了 AMP 技术,直接推送 AMP 版本的网页,放弃使用微信素材库,实际测试加载速度比微信素材库的文章还要快。并且由于 AMP 页面适合缓存,我也针对中国进行了缓存的优化。
为了支持 AMP,需要让每个文章拥有两个页面:一个正常版本的页面,一个符合 AMP 标准的 AMP 页面。当然,也可以通过直接修改页面本身让其符合 AMP 规范,只不过这种方法做的改动会比较大。最简单实现 AMP 的方式就是通过插件的方式去实现,尤其是如果你正在使用 WordPress 的话:
Automattic(其实就是 WordPress 官方)制作了一个 AMP 插件,安装并激活这个插件之后,无需任何配置——这是我喜欢这个插件的原因之一,就能够激活 AMP 功能了。这个插件会自动生成每个文章的对应页面,并会相应的在原始页面添加 AMP 的 metadata。安装后表面上没有任何变化,但是当在一个文章页面后添加上 /amp/
或者 ?amp=1
后,就能看到文章对应的 AMP 页面了。 这个插件之所以免去任何配置,是因为它实际上所提供的功能只是一个框架。用户(实际上是开发者)可以自己开发一个插件对其进行自定义。官方已经给出了具体的介绍,我列举一些我所自定义的东西:
这个插件默认使用了一个衬线字体,然而对于中文的使用引用外部字体毫无作用,甚至还会导致中英文字体错乱的问题。 下载这个 CSS,找到:
font-family: 'Merriweather', 'Times New Roman', Times, Serif;
替换为:
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen-Sans", "Ubuntu", "Cantarell", "Helvetica Neue", sans-serif;
把修改后的文件保存在你制作的插件的文件夹中的 templates
目录(如果没有,就创建一个)下的 my-amp-style.php
。 在插件中添加下面代码:
add_filter( 'amp_post_template_file', 'tlo_amp_set_custom_template', 10, 3 );function tlo_amp_set_custom_template( $file, $type, $post ) { if ( 'style' === $type ) { // Use stystem font $file = dirname( __FILE__ ) . '/templates/amp-style.php'; } return $file;}add_action( 'amp_post_template_head', 'tlo_remove_fonts', 2 );function tlo_remove_fonts(){ remove_action( 'amp_post_template_head', 'amp_post_template_add_fonts' ); // Remove Google fonts.}
这将使用系统默认的无衬线字体,在苹果设备上中文字体就是苹方,同时还会移除页面上的 Google 字体。
AMP 本来就支持 Google Analytics,但是如果需要添加自己的统计,虽不能通过 JS 的方法,但是最简单的方式是通过添加一个空的 Gif:
add_action( 'amp_post_template_footer', 'tlo_amp_add_pixel' );function tlo_amp_add_pixel( $amp_template ) { //$post_id = $amp_template->get( 'post_id' ); $piwik_id = $GLOBALS\['wp-piwik'\]->getOption( 'site_id' ); ?> <amp-pixel src="https://piwik.example.com/piwik.php?idsite=<?php echo $piwik_id; ?>&rec=1&action_name=TITLE&urlref=DOCUMENT_REFERRER&url=CANONICAL_URL&rand=RANDOM"></amp-pixel> <?php}
这是一个使用 Piwik 工具进行统计的例子,与 WP-Piwik 插件配合,可以自动获取站点 ID(需要手动替换域名)。
在激活了 AMP 一段时间后,使用移动设备在 Google 上搜索网站的内容,就可以从 AMP 中显著获益了,视频右侧包含了资源列表,使用的是 iOS 10 自带的 Safari 浏览器(不要眨眼!):
可以看到,还在停留在搜索结果的时候,AMP Runtime 等 AMP 内容就已经开始下载了,同时开始下载的还有我网站上的 Logo 以及网页中的第一张图片。 在点击第一条搜索结果时,页面没有任何重新加载的迹象,直接通过类似 ajax 的方式呈现出来,此时整个页面已经预加载完毕,所以加载时间几乎为零(由于使用的是 iOS 模拟器,配置较低,实际真机测试白屏时间更短,可以说是毫无感知)。页面顶部可以看到网址域名。在滚动页面时,可以看到之后的几张图片是延迟加载的,延迟加载的时间恰到好处,几乎很难感受到是在延迟加载。 值得注意的是,这个页面的所有内容几乎都是由 Google 的服务器提供的,包括 HTML 和图像在内(经测试,视频资源依然回源),只有我的统计代码没有被 Google 代理。如果此时分享 URL,那么分享出去的域名仍是 Google 的,在打开时(或者刷新一次页面之后)左上角的关闭将不再有,其余都完全一样。如果这个网址在非移动设备上打开,那么会跳转到原始文章(不是 AMP 的)页面。 点击左上角的关闭按钮之后,就又返回到搜索结果页面了,整个过程十分顺滑。如果搜索结果有多个 AMP 页面,那么进入这些其他的页面也同样秒开。 可以想到,之所以 AMP 做这么多限制,很大一部分原因是为了防止在 google.com 上呈现 AMP 页面时网站所有者 “作恶”,即使浏览器不是 Google 可控的(如 Safari)。
Google 的 AMP 功能非常类似于 Facebook 的 Instant Article,只不过后者甚至都不需要自己去托管服务器。AMP 中大量的 CSS 仍能自己控制,这相比国内绝大多数搜索引擎的转码页面的效果还是要好不少。网页中仍能自己投放广告内容,这也是 AMP 能被接受的那么快的原因。它在各种不开放的限制中也保留了众多开放的东西。 启用 AMP 不仅能在 Google 搜索结果页面中载入获益,AMP 页面本身其实还可以作为专门给移动设备适配的页面——如果网站本身没有移动版页面,那么移动版页面可以直接拿 AMP 做,然后自动跳转。 当然,就像之前说的,网页可以通过直接修改页面本身让其符合 AMP 规范,或者在制作之初就按照 AMP 的规范作,AMP 官网就是一个典型的例子。然而这种做法未免过于激进,兼容性也不是很好(比如其对于 JS 的强烈依赖),使用前应该做好充分考虑。
百度从 AMP 借鉴了很多技术并做了 MIP,其与 AMP 十分类似。 经过简单的实验,我发现 AMP 可以很轻松的变为 MIP,只需要将 AMP 页面做以下内容的替换或删除即可:
<html amp
替换为 <html mip
<script src="https://cdn.ampproject.org/v0.js" async></script>
替换为 <link rel="stylesheet" type="text/css" href="https://mipcache.bdstatic.com/static/v1/mip.css">
amp-pixel
替换为 mip-pix
amp-
替换为 mip-
</body>
替换为 <script src="https://mipcache.bdstatic.com/static/v1/mip.js"></script></body>
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
修改完的 AMP 页面可以直接通过 MIP 测试,这相当于不需要二次开发就能够同时兼容 AMP 和 MIP,多方便!启用了 MIP 的网站在百度搜索结果上也会预加载,于是就能实现秒开的效果。
MIP 自带的 CSS 竟然声明了这个样式:
* { margin: 0; padding: 0}
由于它的存在,会导致很多地方的排版出现问题,并会覆盖掉浏览器的默认样式(例如 h1、h2 这些标签),所以你可能还要为百度单独添加一些样式。
经测试,<mip-video>
标签不能够支持 <source>
标签,使用了这种标签的视频无法加载。
GCE 上所实现的这个功能是基于第七层的网络代理,所以其拓扑图是这样的: 用户 —> 边缘服务器 —> 实例
不论配置了几个位置的实例,边缘服务器都是使用 Google 全部的边缘服务器。 启用这个功能后,就会得到另一个 Anycast 的 IP 地址,这是个独享的 IP 地址。
什么是 Anycast?Anycast 能够让多个主机使用一个 IP 地址,当用户连接这个 IP 地址的时候,连接到的只是这多个主机中的其中之一,通常会选择最快的线路,能有效的降低延迟,所以很多 DNS/CDN 提供商都使用了 Anycast。
此外,目前使用负载均衡是唯一能让其原生支持 IPv6 的方法。具体可以参见其文档:IPv6 Termination for HTTP(S), SSL Proxy, and TCP Proxy Load Balancing
首先,需要前往到 GCE 后台,建立至少两个不同地区的实例,我专门为测试 Anycast 功能建立了两个新的实例:
每个地区也可以建立多个实例以提高可用性,而我只给每个地区建立了一个实例,这两个实例分别叫 anycast-asia 和 anycast-us。
然后,需要给每个地区的实例建立一个实例组:
需要注意的是,实例组配置页面中位置里的 “多地区(Multi-zone)” 是指同一个地区(Region)的不同可用区域(Zone),而不是多个不同的地区,所以这实际上是翻译的错误,应该叫做 “多可用区域” 才对。
刚接触云服务的人可能不理解可用区域的概念,可以参考 AWS 的这篇文章来理解。简单点说,地区这个概念就是指离得很远的地区(比如城市之间,如北京和上海),所有在北京的服务器都算北京地区,所有在上海的服务器都算上海地区。但是为了能达到更高的可用性,通常还会在同一个地区设立多个数据中心,也就是可用区域。这些可用区域虽在一个地区中,其之间的距离可能相隔几十甚至几百公里,但这些可用区域之间的距离和不同地区之间的距离相比起来要小得多,所以这些可用区域之间的网络延迟也很低。
设立多个可用区域的意义是:可以能加更高的可用性(主要是为了避免外界因素:比如说火灾等),虽然是异地分布,但是可用区域之间的距离并不远,所以网络延迟可以忽略。
我只给每个地区建立了一个实例,所以我只需要选择 “单地区(Single-zone)”。每个地区都需要建立一个实例组,所以一共需要建立两个(或更多的)实例组。我配置了两个实例组,分别叫 asia-group 和 us-group。
完成前两步之后,就需要建立负载均衡的规则了,需要选择 “HTTP(S) 负载平衡” 来实现 Anycast 的功能。
在负载均衡的配置界面,把这两个实例组都添加到 “后端” 中。 该功能还需要创建一个运行状态检查(相当于监控功能),当主机宕机后能实现切换。
创建成功后,可以看到如下界面,其中的 IP 地址就是 Anycast IP 了。
这里的配置只是为了方便调试,实际使用不用额外修改 Nginx 的配置。 在这两个主机上都安装 Nginx,然后稍微改动默认的配置文件:增加两个 Header,然后 Reload。
add_header X-Tlo-Hostname $hostname always;add_header Cache-Control "max-age=36000, public";
在测试 Anycast 之前,先测试这两个主机是否存在问题。为了方便阅读,我将 curl 的 IP 地址换为主机名,并省略两个主机都相同的 Header 字段
$ curl anycast-us -IHTTP/1.1 200 OK…ETag: "57ef2cb9-264"X-Tlo-Hostname: **anycast-us**$ curl anycast-asia -IHTTP/1.1 200 OK…ETag: "57ef2b3b-264"X-Tlo-Hostname: anycast-asia
可以看到这两个主机都没有什么问题。然后,我用我的电脑去测试那个 Anycast IP:
$ curl anycast-ip -IHTTP/1.1 200 OK…ETag: "57ef2b3b-264"X-Tlo-Hostname: anycast-asiaAccept-Ranges: bytesVia: 1.1 google
可以看到,这是 anycast-asia 主机响应的。现在我使用另一个在美国的主机继续测试这个 Anycast IP:
$ curl anycast-ip -IHTTP/1.1 200 OK…ETag: "57ef2cb9-264"X-Tlo-Hostname: anycast-usAccept-Ranges: bytesVia: 1.1 google
此时就是 anycast-us 主机响应的,是因为客户端离这个服务器更近。 当通过 Anycast IP 访问时,就可以看到 HTTP Header 中的 Via: 1.1 google
字段。
Ping 测试发现速度很快,看来反代的操作是放在 Google 的边缘服务器上了。速度堪比 Google 啊!
中国的速度那更是一流的快,Google 有香港的边缘节点,所以基本上是直接走的香港节点,比原本的连接台湾可用区快不少。(只有部分 IP 段是完全直连的)
在开启 CDN 功能之前,负载均衡器是不会对任何内容缓存的,所以会发现 Connect 的速度很快,但是 TTFB 延迟还是有不少。
可以预测,如果启用了 HTTPS 功能,其 TLS 所需要的等待时间也会很短,TTFB 时间不变,总时长不会延长太多。
当将 CDN 开启后,负载均衡器就会自动地对静态资源做缓存了,当缓存命中后会显示 Age 字段,这个字段是表示自缓存命中了,后面的数字代表这是多少秒之前缓存的内容。
curl anycast-ip -I
HTTP/1.1 200 OK
…
Via: 1.1 google
Age: 10
经过多次执行这个指令,会发现有一定几率 Age 字段消失,这可能是流量指到了同一个地区的不同可用区上。但总之,是缓存命中率不高,即使之前曾访问过了。
多次运行测试确保有缓存之后,发现速度似乎并没有太多明显的提升。能够明显的看出改善的是:巴黎和阿姆斯特丹的 TTFB 延迟从 200ms 减少到了 100ms,然而还是不尽人意。可能的原因是:Google 并没有将内容缓存到离访客最近的边缘节点上,而是别的节点上。 CDN 缓存服务器的位置列表
开启了 Load Balancing 后,就会自动在 Google Cloud Platform 下记录一些信息了。
在网页后台的 Network,Load balancing,advanced menu 的 Backend service 下,可以查看实时的流量情况:
在网页后台的 Stackdriver,Trace 下,可以看到延迟日志:
这里的延迟包含了网络延迟和服务器响应延迟
GCE 所能实现的 Anycast 功能,只能通过 HTTP 代理(第七层)的方式实现,所以只能代理 HTTP 请求,其他功能(如 DNS)无法实现。所以很多功能受限于负载均衡器的功能(比如证书和 HTTP2 都需要在负载均衡器上配置),然而由于 TLS 加解密过程是在边缘服务器上实现,而且其本身也带有 CDN 功能,所以会比单纯的 Anycast(比如基于 IP 层,或是 TCP/UDP 层)的更快一些。
前五个 Rules $18/月,流量费用相比 GCE 不变,已经被缓存的内容的流量有一点优惠。
通过使用 Cloudflare 所提供的服务也能实现 Anycast,也是基于第七层的,即将也能实现 Cross-Region Load Balancing 的功能。虽然它还不能根据主机的 CPU 占用率去调整权重(毕竟它拿不到这些数据),却有强大的 Page Rules 功能以及 WAF 功能。 CloudFlare 并不提供独立 IP 地址,不过这不是什么大问题。 由于它属于第三方服务,不受服务提供商的限制,于是就可以给多种不同的服务提供商去做 Anycast 功能;而且无论服务商是否支持,都能够使用。 连接速度上,GCE 的在中国连接速度有明显的优势。
BuyVM 是一家 VPS 提供商,却提供免费的 Anycast 功能,其 Anycast 功能是直接基于 IP 层的 Anycast,所以可以配置 HTTP 之外的各种服务。BuyVM 没有所谓的边缘服务器一说,只能有三个节点,Ping 的结果不像前两家那么快,而且 TLS 过程也是在原本的主机(这三个主机中里用户最近的一个)上进行,也会有一定延迟。 BuyVM 并不提供任何亚洲的主机,所以中国的连接速度也没有比 Cloudflare 快多少,整个亚洲的速度也不是很快。
]]>Load Balancing 支持更加高级的负载均衡功能,并终于支持了大家很需要的跨区域负载均衡功能;Rate Limiting 支持了高级的访问次数限制功能。越来越多的原本需要在服务器上配置的功能,现在在 Cloudflare 上也能进行配置了。(目前这两个功能还属于 Beta 阶段,需要认证用户才能使用)
此功能可以把 Cloudflare 当作负载均衡器使用,而不需要再在主机提供商上配置负载均衡,官网介绍。目前此功能仅向 Enterprise 账户和部分有资格的用户开放。该功能有两种实现方式,分别如下:
负载均衡的功能是在 Cloudflare 的边缘服务器上实现,是通过第 7 层反代的方式实现,其实很类似于原本的 CDN 功能,不过回源可以高度定制。源站可以配置多个地区(需手动设置服务器的位置),每个地区也可以配置多个服务器,可以将这些众多服务器设置为一个 Group。将域名指向这个 Group,然后 Cloudflare 的边缘服务器的回源可以根据服务器的地区来自动选择最近的源站服务器。这样可以非常有效的降低首字节的延迟,对动态资源速度的提升会有很大的帮助。
此外,Cloudflare 还自带了 Health Check 功能,可以当服务器宕机后能够自动更改回源。虽然通过 DNS 的方式也可以实现宕机后切换,但是 DNS 方式毕竟会收到缓存时长影响,若使用 CDN 切换,则可以实现秒级切换。 我的一个 WordPress 站点 tlo.xyz 就使用了这个功能,默认是美国东部和亚洲东部跨区域负载均衡,两者有一者宕机自动切换。如果全部宕机,则 fallback 到 Google Cloud Storage 上的静态页面。你可以观察 https://tlo.xyz 上的 TLO-Hostname 的 Header 来判断是哪一个服务器做的响应。
使用此功能不需要开启它的 CDN 功能,故访客是直接连接源站的。同上一种方式也是配置一个 Group,只是不开启 CDN 功能,然后 Cloudflare 会只作为 DNS 服务器的功能。它会自动进行 GeoDNS,给访客返回最近的服务器的 IP 地址,同样也支持 Health Check 功能,当服务器宕机后会自动切换解析。 不同于其他的 DNS 解析商,Cloudflare 真正做到了智能,只需要配置一个 Group 即可,剩下的 Cloudflare 会自动搞定,而不是去手动地选择哪一个地区解析到哪一个服务器。 此功能已经被我测试,目前的测试期间,GeoDNS 的定位功能是根据请求最终抵达的 CloudFlare 的服务器来决定的,也就是说是依靠 Anycast 系统来决定的。然而中国用户绝大多数会被运营商定向到 CloudFlare 的美国西部服务器,于是就会被 GeoDNS 系统解析道美国西部位置所对应的结果。所以此功能还是十分有限,不适合国内使用。
Cloudflare 终于可以限制 IP 的请求速率,此功能能够相当有效的过滤 CC 攻击,而且对于普通访客几乎没有影响(以前只能通过 I’m under attack 功能实现,然而这个功能会让所有用户等 5 秒才能载入)。它可以根据不同的路径配置不同的请求速率,能够实现防止暴力破解密码、防止 API 接口滥用等功能。
]]>具体价格请参见官方价格表。(由于有持续使用折扣,每月实际价格比按照每小时更低) GCE 的价格比较亲民,最低配 (f1-micro) 1 共享核-0.6 GB 内存-10GB HDD 每月只需要不到 5 美元,而且由于 CPU、内存大小和磁盘大小都是可调的,所以可以根据自己的需要去购买最适合的,能省去不必要的开销。 而且对于北美的部分机房而言,账户首个最低配 (f1-micro) 实例可以享受到永久免费配额,对于建站而言 (再配合 Cloudflare 使用) 还是很划算的。流量的话对于所有的可用区,连中国大陆 $0.23/Gbyte、美欧地区 $0.12/Gbyte,流量的价格有些小贵,但是如果是连接 Google 自己的服务的话(包括但不限于 Gmail、YouTube),流量不计费(但是流量是双向的,所以是本地通过 GCE 上传完全免费,下载还是原价)。 GCE 还有一点比较特殊的是它是按分钟计费的,当服务处于终止状态(相当于关机,磁盘数据保留)时,不收取费用(除了少量的磁盘使用费用)。每次计算 Uptime 时,如果不到 10 分钟则一律按十分钟算,超过 10 分钟后才是真正的按分钟计费,不过还是很划算了。
f1-micro(0.6 GB)和 g1-small(1.7GB)这两个版本使用的是共享核心(其余配置都是独立核心),根据 Google 的说明,0.60GB 是 0.2 vCPU,1.70GB 是 0.5 vCPU。但是却支持 Bursting,也就是短时间内最高能使用到 1.0 vCPU。 那么 1.0 vCPU 是多少呢?查 cpuinfo,是 Intel(R) Xeon(R) CPU @ 2.50GHz。也就是说这两个版本最高能占用到 2.5GHz。但是假如长时间占用,速度就会压缩到 0.5GHz 和 1.75 GHz。
我的 f1-micro 装了监控软件,对比 GCE 给的 CPU 占用率(深蓝色)和系统自己监控到的占用率(浅蓝色),发现 GCE 图表上统计的 CPU 占用率正好是本地统计的 5 倍,也就是说如果本地看到的 CPU 占用是 20%,GCE 图表上显示的就正好是 100%,本地为 20100%,GCE 图表上就是 100500%,这时就算作 Bursting 了。 和其他 VPS 对比,其他的 VPS 也几乎都是共享核心,但你却无从判断是否超售。比如有 10 个用户共用一个核心,如果那 10 个人都在不停的占用 CPU,那么你的 CPU 速度会低于单核的十分之一。而 Google 的共享核心,保证了一个最低的速度(0.2 vCPU 和 0.5 vCPU),就算其他用户用的再狠,也能给你保证一定的速度。
首先需要前往创建实例的页面,然后进行配置
GCE 默认开启了防火墙且不能关闭,只能允许你自己指定的协议和端口的流量;经过我自己的实际测试,GCE 能够自动过滤相当的 DDOS 攻击流量。 由于防火墙不能关闭,所以不能配置类似 IPv6 Tunnel 的服务,所以导致目前的 GCE 是不能够支持 IPv6 的,不过相信以后 Google 还是会启用 IPv6 支持。 在 “网络” 里,可以找到防火墙规则,然后可以添加防火墙规则。 默认已经允许了 SSH 和 ICMP 等(以 default 开头的)
我只需要另一个主机去访问 SNMP 监控,不需要将其公开到互联网上,所以限制了 IP。
有的 DNS 请求是通过 TCP 发送的,所以需要同样启用 TCP 请求。 如果配置了目标标记,那么就不是默认应用到所有实例的防火墙规则,还需要在实例上配置好同样的标记才可以。
由于 GCE 是 Google 的,其网络其实也是 Google 的 AS15169,于是不用想也知道连接 Google 旗下的服务会很快,但是实际使用后发现远比我想象的快,GCE 连接 Google 的服务简直就像内网一样。
$ ping google.comPING google.com (74.125.203.102) 56(84) bytes of data.64 bytes from th-in-f102.1e100.net (74.125.203.102): icmp_seq=1 ttl=53 time=0.631 ms64 bytes from th-in-f102.1e100.net (74.125.203.102): icmp_seq=2 ttl=53 time=0.433 ms64 bytes from th-in-f102.1e100.net (74.125.203.102): icmp_seq=3 ttl=53 time=0.330 ms64 bytes from th-in-f102.1e100.net (74.125.203.102): icmp_seq=4 ttl=53 time=0.378 ms64 bytes from th-in-f102.1e100.net (74.125.203.102): icmp_seq=5 ttl=53 time=0.413 ms^C--- google.com ping statistics ---5 packets transmitted, 5 received, 0% packet loss, time 3999msrtt min/avg/max/mdev = 0.330/0.437/0.631/0.103 ms
要是 traceroute 的话就更神奇了:
$ traceroute google.comtraceroute to google.com (64.233.189.113), 64 hops max 1 64.233.189.113 0.826ms 0.313ms 0.435ms
中国目前连接 GCE 亚洲区的速度还算不错,按流量计费,实际测试能够超过 100M 带宽。亚洲区的位置在台湾,中国连接通常会绕香港,然后从香港到台湾这条路线走的是 Google 自己的骨干网,所以最终的结果只是比香港服务器慢了十几毫秒而已。
其他国家连接的话优势就更明显了,Google 的网络实在太强大,无论是亚洲还是欧美,几乎还没有出这个城市/国家就立即跳进 Google 的骨干网络里了,然后 Google 自身的骨干网的选路通常要比运营商的选路要好一些,几乎不会出现绕路的情况。
详细内容已在下一篇文章中介绍,通过 Load Balancing 可以分配到一个独立的 IPv4 地址,还能够有原生的 IPv6,支持 CDN 和 HTTPS。Google 的 Anycast 有多快?和 Google 一样快。
每个实例都有其对应的内网 IP,方便两个主机间建立直接的连接,这个内网 IP 的神奇之处在于:它可以跨可用区使用,包括跨大洲。经过实际测试,使用内网 IP 建立的连接速度会稍快,而且收取的价格(如果是跨州的话)也有优惠。
在 GCE 的后台,能够显示长达 30 天的 CPU 利用率、磁盘字节数、磁盘操作字节数、网络字节数、网络数据包量等数据,都能够精确到分钟级别的记录,而且是实时更新的。
你可以为主机增加快照,方便在其他实例中恢复快照,或者用做备份功能。GCE 的快照是增量备份,这意味着如果有两个快照,第二份快照只备份与第一份快照的差异部分。使用这个脚本可以实现自动备份,并且能够实现到期自动删除老备份。
你可以轻松的添加任意(大于 10 GB)大小的硬盘,有多种磁盘种类可供选择。经过我的测试,如果执行长时间的高 I/O 操作,硬盘读写速度会明显地降低。而且并不一定 SSD 就比 HDD 快,硬盘的大小与吞吐量限制和随机 IOPS 限制呈正相关,也就是说 40G 的 HDD 的速度相当于 10G 的 SSD。
低配置的版本用来建站或者是当 “梯子” 都很不错,每月 5 美元的价格还是很吸引人的(做 “梯子” 的一定要注意流量价格!)。已经相当完善的 Web 控制页面可以大大降低使用和学习的门槛。高配置的版本拥有独立 CPU,而且可伸缩性很大。与 Google Cloud 各种功能配合使用,可以搭建大型网站或者游戏服务器。
下面来讲一讲它的一些坑,尤其是从传统 VPS 转到 GCE 会遇到的一些问题。由于 GCE 是基于云端的,所以有很多东西都不太一样。
GCE 虽然是提供独立 IP 的,但是当你执行 ifconfig -a
时,你会看到默认分配的 IP 是一个内网的保留 IP(形如 10.123.0.1),这是为了方便 instance 里之间互相连接的 IP。当你配置一些需要外网的服务要 bind 到指定 IP 时,你只需要 bind 到这个 IP 即可,所分配给你的外网 IP 会自动将流量转发到这个 IP 上。而且,你的主机并不知道那个外网 IP 就是主机本身,所以所有发向主机对应的外网 IP 的流量都会经过一个路由器,然后再由路由器返回,并且会应用防火墙策略。所以,如果需要本地的通讯,建议尽量多使用环回地址(如 127.0.0.1,::1)或那个内网地址。
不能关闭的防火墙对于初次接触的人来说可能有些不适,不过一旦习惯后便会爱上这个功能,这个基于在路由器上的防火墙功能要比在 iptables 里做限制更方便。强烈建议利用好防火墙功能,不要默认允许所有端口。比如你的网站流量全部经过 Cloudflare,那么就可以通过防火墙来只允许 Cloudflare 的 IP 与你的主机连接。
GCE 上不能通过加钱的方式去购买多个 IPv4 地址,所以一个实例只能有一个 IPv4 地址,需要多个 IPv4 需求的可以尝试多个实例(或者可以通过 Load Balancing 来实现多个 IP 地址)。 同时,GCE 目前不支持 IPv6,这实在是很可惜的。目前已经可以通过负载均衡器来实现 IPv6。
]]>我开发的这个功能特点是:当评论者被回复时,邮件标题是 “Re: [文章标题]”,这样评论者的一个留言被多个人回复时,会被自动在本地邮件客户端上归为一类;而且评论者收到邮件后可以直接回复邮件,会直接给回复的发出者发邮件(不会显示在网站上,我也无法看到,这将是两人的私聊)。
邮件内容简洁,无额外无用的东西,不会被认定为 Spam。
所有代码已经放到 GitHub Gist 上。
<?phpfunction tlo_comment_mail_notify($comment_id) { global $comment_author; $comment = get_comment($comment_id); $parent_id = $comment->comment_parent ? $comment->comment_parent : ''; $spam_confirmed = $comment->comment_approved; $from = $comment->comment_author_email; $to = get_comment($parent_id)->comment_author_email; if (($parent_id != '') && ($spam_confirmed != 'spam') && $from != $to && $to != get_bloginfo('admin_email') ) { $blog_name = get_option('blogname'); $blog_url = site_url(); $post_url = get_permalink( $comment->comment_post_ID ); $comment_author = $comment->comment_author; $subject = 'Re: '.html_entity_decode(get_the_title($comment->comment_post_ID)); $headers[] = 'Reply-To: '.$comment_author.' <'.$comment->comment_author_email.'>'; $comment_parent = get_comment($parent_id); $comment_parent_date = tlo_get_comment_date( $comment_parent ); $comment_parent_time = tlo_get_comment_time( $comment_parent ); $message = <<<HTML<!DOCTYPE html><html lang="zh"> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <title>$blog_name</title> </head> <body> <style type="text/css"> img { max-width: 100%; height: auto; } </style> <div class="content"> <div> <p>$comment->comment_content</p> </div> </div> <div class="footer" style="margin-top: 10px"> <p style="color: #777; font-size: small"> — <br> Reply to this email to communicate with replier directly, or <a href="$post_url#comment-$comment_id">view it on $blog_name</a>. <br> You're receiving this email because of your comment got replied. </p> </div> <blockquote type="cite"> <div>On {$comment_parent_date}, {$comment_parent_time},$comment_parent->comment_author <<a href="mailto: $comment_parent->comment_author_email">$comment_parent->comment_author_email</a>> wrote:</div> <br> <div class="content"> <div> <p>$comment_parent->comment_content</p> </div> </div> </blockquote> </body></html>HTML; add_filter( 'wp_mail_content_type', 'tlo_mail_content_type' ); add_filter( 'wp_mail_from_name', 'tlo_mail_from_name' ); wp_mail( $to, $subject, $message, $headers ); }}add_action('tlo_comment_post_async', 'tlo_comment_mail_notify');function tlo_comment_mail_notify_async($comment_id) { wp_schedule_single_event( time(), 'tlo_comment_post_async', [$comment_id] );}add_action('comment_post', 'tlo_comment_mail_notify_async');// add_action('comment_post', 'tlo_comment_mail_notify');function tlo_mail_content_type() { return 'text/html';}function tlo_mail_from_name() { global $comment_author; return $comment_author;}function tlo_get_comment_time( $comment ) { $date = mysql2date(get_option('time_format'), $comment->comment_date, true); return apply_filters( 'tlo_get_comment_time', $date, $comment );}function tlo_get_comment_date( $comment ) { $date = mysql2date(get_option('date_format'), $comment->comment_date); return apply_filters( 'tlo_get_comment_date', $date, $comment );}
]]>关于双证书,仅建议使用独立 IP 的人去使用,如果没有独立 IP,那么就需要启用 SNI 功能——然而几乎所有支持 SNI 功能的浏览器也都支持了 ECC 证书,所以可以跳过升级步骤,直接换 Let’s Encrypt 的 ECC 证书,不使用 RSA 证书。 我有不止一个服务器,如果都使用自己编译的 Nginx,那么太麻烦了,于是我决定使用添加软件源的方法,通过 apt
升级,方法如下: 首先需要先添加 Nginx mainline 的软件源:
$ sudo add-apt-repository ppa:nginx/stable # sudo apt install software-properties-common$ sudo apt update
然后移除现有 Nginx 并安装新版本:
$ sudo apt remove nginx nginx-common nginx-core$ sudo apt install nginx
安装时可能会询问是否替换原来默认的配置文件,选择 N 即可。 此时安装的 Nginx 已经包含了几乎所有的必要和常用模块,比如包括但不限于 GeoIP Module、HTTP Substitutions Filter Module、HTTP Echo Module。我安装的 Nginx 的 OpenSSL 版本是 1.0.2g-fips,所以并不支持 CHACHA20,想要支持 CHACHA20 只能使用 CloudFlare 的 Patch 然后自己编译。安装完成后就可以验证 Nginx 版本了:
$ nginx -Vnginx version: nginx/1.12.0built with OpenSSL 1.0.2g 1 Mar 2016TLS SNI support enabledconfigure arguments: --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --with-mail=dynamic --with-mail_ssl_module --add-dynamic-module=/build/nginx-DYnRGx/nginx-1.12.0/debian/modules/nginx-auth-pam --add-dynamic-module=/build/nginx-DYnRGx/nginx-1.12.0/debian/modules/nginx-dav-ext-module --add-dynamic-module=/build/nginx-DYnRGx/nginx-1.12.0/debian/modules/nginx-echo --add-dynamic-module=/build/nginx-DYnRGx/nginx-1.12.0/debian/modules/nginx-upstream-fair --add-dynamic-module=/build/nginx-DYnRGx/nginx-1.12.0/debian/modules/ngx_http_substitutions_filter_module
此时,你的服务器就没有 Nginx 的 HTTP/2 bug 了,既然使用了最新版的 Nginx,那么就能够配置 ECDSA/RSA 双证书了。
在我升级的时候,遇到了 GeoIP 模块无法使用的问题,经研究发现是新版本将 GeoIP 改成动态调用模块的方式实现了,在 Nginx 的 http {}
配置中添加下方代码得以解决:
load_module "modules/ngx_http_geoip_module.so";
Let’s Encrypt 提供完全面为免费,并且是自动化签发的证书,一张证书最多能签 100 个域名,暂不支持通配。 为了配置双证书,你首先应该签发下来两张证书,以下以 acme.sh 为例,首先先建立目录(以下所有案例均使用 example.com
作为例子,实际使用需自行替换):
$ mkdir -p /etc/letsencrypt$ mkdir -p /etc/letsencrypt/rsa$ mkdir -p /etc/letsencrypt/ecdsa
然后修改 Nginx 配置文件,确保所有在监听 80 端口的都有 location ^~ /.well-known/acme-challenge/
区块,本配置文件是强制跳转 HTTPS 的案例,这是源站的配置:
server { listen 80 default_server; listen [::]:80 default_server; location ^~ /.well-known/acme-challenge/ { root /var/www/html; } location / { # Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response. return 301 https://$host$request_uri; }}
在签发之前,确保所有要签发的域名都指向了你自己的服务器! 然后签发 RSA 证书(如果需要多域名证书,只需要多个 -d
即可,下同,不过保存的文件目录以及证书显示名称均为第一个域名):
$ acme.sh –issue –reloadcmd “nginx -s reload” -w /var/www/html -d example.com –certhome /etc/letsencrypt/rsa
然后再签发 ECDSA 证书:
$ acme.sh –issue –reloadcmd “nginx -s reload” -w /var/www/html -d example.com -k ec-256 –certhome /etc/letsencrypt/ecdsa
卸载 acme.sh
自带的 cron,自己重新配置:
$ acme.sh –uninstallcronjob
$ vim /etc/cron.d/renew-letsencrypt
输入以下内容,注意替换 acme.sh
的路径为你安装的绝对路径:
15 02 * * * root /path/to/acme.sh --cron --certhome /etc/letsencrypt/rsa20 02 * * * root /path/to/acme.sh --cron --ecc --certhome /etc/letsencrypt/ecdsa
然后就完成了,证书会自动续签。
因为 Let’s Encrypt 使用的不是通配符域名,所以会经常遇到有新的子域的情况,此时就需要给证书添加域名,一张证书最多可以添加 100 个域名。最简单的添加方法如下: 首先,修改证书的配置文件,两个证书的配置文件都要修改:
$ vim /etc/letsencrypt/rsa/example.com/example.com.conf$ vim /etc/letsencrypt/ecdsa/example.com\_ecc/example.com.conf
找到 Le_Alt
一行,将新的域名添加进后面(每个域名用逗号隔开,总共不能超过 100 个)。然后开始重新签发这个证书,需要添加 -f
。
$ acme.sh --renew -d example.com --certhome /etc/letsencrypt/rsa -f$ acme.sh --renew -d example.com --ecc --certhome /etc/letsencrypt/ecdsa -f
要注意的一点是,目前 Let’s Encrypt 签发的 ECC 证书的中间证书和根证书暂且不是 ECC 证书,这将会在以后支持,详情见 Upcoming Features。
首先需要生成几个 Key:
$ openssl rand 48 > /etc/nginx/ticket.key$ openssl dhparam -out /etc/nginx/dhparam.pem 2048
然后添加以下内容进 Nginx,放在 http 或 server 区块下,虽然不支持 CHACHA20,但是添加进去也没影响。
### SSL Settings##ssl_certificate /etc/letsencrypt/rsa/example.com/fullchain.cer;ssl_certificate_key /etc/letsencrypt/rsa/tlo.xyz/example.com.key;ssl_certificate /etc/letsencrypt/ecdsa/example.com_ecc/fullchain.cer;ssl_certificate_key /etc/letsencrypt/ecdsa/example.com_ecc/example.com.key;ssl_session_timeout 1d;ssl_session_cache shared:SSL:50m;ssl_session_tickets off;ssl_dhparam dhparam.pem;ssl_protocols TLSv1 TLSv1.1 TLSv1.2;ssl_prefer_server_ciphers on;ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';ssl_stapling on;ssl_stapling_verify on;
最后不要忘了 nginx -s reload
,然后 前往 SSL Labs 检查配置,可以看到旧的浏览器使用了 RSA 证书(我的服务器有独立 IP,所以无 SNI 支持的也能访问):
至此,ECDSA/RSA 双证书配置完成,你可以在浏览器里查看到证书类型:
]]>什么是 IPv6-Only 网络 严格上来讲,IPv6-Only 网络下只能连接上 IPv6 地址,这也就意味着 DNS 缓存服务器也必须是 IPv6 地址,只能连接上支持 IPv6 的服务器。如果要解析一个域名,这个域名本身及其所属的根域名的 DNS 服务器也必须统统支持 IPv6。总之,在整个过程中不存在 IPv4。所以想要支持 IPv6-Only 网络,几乎需要在所有的环节下功夫。
为了支持 IPv6,首先你所使用的根域名必须支持 IPv6,好在大多数根域名都支持 IPv6 了。从这里可以看到已经有 98% 的根域名都支持了 IPv6。 一般大家还是喜欢使用第三方的 DNS 而不是去自建,那么这就需要给自己使用支持 IPv6 的 DNS 服务器。好在也有不少 DNS 服务器支持 IPv6 了,比如 CloudFlare、OVH、Vultr、DNSimple、Rage4 等等大多数国外 DNS 解析,哦,除了 Route53;国内目前就见到了百度云加速、sDNS 的 DNS 解析支持,其他常用的 CloudXNS、DNSPod、阿里云等等都不支持。 检测根域名或者是某个域名所使用的 DNS 服务器是否支持 IPv6,只需要执行指令,替换其中的 <domain>
为根域名(如 com)或者任意一级域名(如 example.com):
$ dig -t AAAA `dig <domain> ns +short` +short
然后查看输出的 IP 中是否全是 IPv6 地址,如果什么也没有输出,说明 DNS 服务器不支持 IPv6。 正确配置 IPv6 的例子:
如果想要自建 DNS 服务器,可以参考自建 PowerDNS 方法。 如果你的根域名不支持 IPv6,那么你可以联系根域名那里让他们去支持,或者换一个根域名。如果你的一级域名不支持 IPv6,那就联系 DNS 解析商让他们支持,或者直接换走。
也就是让你自己的服务器支持 IPv6,这需要联系你的服务器提供商,让他们给你分配一个 IPv6 地址,如果还是不支持 IPv6,那么可以使用 IPv6 Tunnel Broker,比如 Hurricane Electric 的免费 Tunnel Broker,这样通常没有服务商给你的原生的 IPv6 好,但是在服务商支持原生 IPv6 之前只能先用着。Tunnel Broker 相当于建立在网络层(第三层)上的代理,需要你的服务器的操作系统支持,而且服务器必须要有一个固定的 IPv4 地址。为了使用它你需要在系统里重新配置网卡(所以共享主机就没戏了),然后就能按照正常方法使用 IPv6 了,简直零成本支持 IPv6。注意,主机到 Tunnel Broker 传输是明文,不过只要应用程序都使用安全的协议(如 HTTPS、SMB、SFTP、SSH),这不是问题。
很可惜,我目前的两个服务器暂时都没有原生的 IPv6 可以用,于是只能用 Tunnel Broker 了,使用后发现虽然是免费的,但是效果也不错:下载时似乎没有限速,我 100M 的独享带宽在原生的 IPv4 上下载速度为 12Mbyte/s,在 IPv6 上还几乎是这个速度。Ping 延迟还是会有一些增加的,主要是因为 Tunnel Broker 的服务器连接到你的服务器会有一些延迟,它相当于一个代理,所以创建时一定要选择离你服务器最近的 Tunnel Broker(延迟最短的),而不是里用户最近的 Tunnel Broker。
注意,强烈不建议国内主机使用 HE 的 Tunnel Broker,原因是中国连接 HE 都会绕道美国,最终会给 IPv6 增加 500ms 的 Ping 延迟,1000ms 以上的 TCP 延迟和好几秒的 HTTPS 延迟。建议国内主机使用方案二。
在服务器支持了 IPv6 后,确保域名上也新设置了 AAAA 记录解析到了 IPv6 地址上。
刚才所介绍的方案是直接支持,或者使用 Tunnel Broker 建立在网络层的代理。当然还有另一种代理的方式,那就是建立在应用层(第七层)上的,建立在第七层上的其实就是 HTTP Proxy,不过大多数提供 HTTP Proxy 功能的地方都能够缓存静态内容,所以也就是 CDN。 最佳解决方案是直接使用免费的 CloudFlare,然后开启 CDN 功能,这需要更换 DNS 服务器,甚至还可以配置 IPv4 回源,仅使用 IPv6 CDN),不过这样的话连 DNS 在内的所有服务都能支持 IPv6 了,类似的还有 Akamai,它们在代理了之后都能给你 IPv6 支持。 但是如果使用这种方案,原先收集用户真实 IP 的功能就会失效,包括防火墙和 Web 应用程序在内。但只需要配置稍作一些修改,就又能收集访客 IP 了。
在做好了这些配置之后,网站就能够被 IPv6-Only 的网络访问了。然而这只是其中一步,别忘了网站上的 CDN 和域名上的邮件服务还没支持 IPv6 哦,最后,我来列一下:
注:CDN、VPS 中列出的那几家服务自己都提供了支持 IPv6 的 DNS,在此不再列出(其中 Linode 和 DigitalOcean 所提供的 DNS 服务实际上也是 CloudFlare 的)
当你配置好后,你可以在 IPv6 Test 上测试你的网站。
直至现在,支持 IPv6-Only 网络访问在生产中仍然不是必须的,因为实际上很少存在 IPv6-Only 的网络,一般都兼容 IPv4,很多大网站也完全不支持 IPv6。苹果所说的要求支持 IPv6-Only,只是程序内部要使用 IPv6 通信,程序中不能有 IPv4 地址,能够在只分配了 IPv6 地址的运营商使用(然而实际上这些运营商还是支持 IPv4 的)。
]]>本文的自建 DNS 是指的是权威 DNS,即给自己的域名配置的 DNS,而非在客户端配置的缓存 DNS。
首先,我先说用自建 DNS 服务器的致命坏处:
使用自建 DNS 服务器优点:
最终我还是选择了使用 PowerDNS 软件(这其实也是很多提供 DNS 服务的服务商所使用的),我安装它的最近才出的 4.0 版本,这个版本支持的一些特性:
等等,以上只是我想到的。同时 PowerDNS 支持超多的解析记录种类(至少是我目前见过最多的):A、AAAA、AFSDB、ALIAS(也是 ANAME)、CAA、CERT、CDNSKEY、CDS、CNAME、DNSKEY、DNAME、DS、HINFO、KEY、LOC、MX、NAPTR、NS、NSEC、NSEC3、NSEC3PARAM、OPENPGPKEY、PTR、RP、RRSIG、SOA、SPF、SSHFP、SRV、TKEY、TSIG、TLSA、TXT、URI 等,还有不常用的没有列出来,见所有支持的记录。说实话有一些冷门的记录很多解析商都不支持,但我又需要用,比如 LOC、SSHFP 和 TLSA。不知道这一堆记录是干什么的?请见维基百科。
详情安装方法见官方文档,需要先安装 pdns-server
,然后再安装 pdns-backend-$backend
。Backend 是你可以自己选的,常用的有 BIND
和 Generic MySQL
,需要 GEODNS 可以用 GEOIP
,所有列表见此。如果想做网页版控制后台,使用 MySQL 的可能比较方便。如果只是通过文件形式控制,那么 BIND 和 GEOIP 都可以。 我使用 GEOIP 版本的,GEOIP 版本可拓展性强,使用 YAML 文件,更灵活、优雅,本文就讲讲 GEOIP 版本: 在 Ubuntu 上安装(系统软件源里就有):
$ sudo apt install pdns-server
$ sudo apt install pdns-backend-geoip
然后修改配置文件:
$ rm /etc/powerdns/pdns.d/* # 删除 Example
很多特性,如 CAA 记录等,需要新版 PowerDNS。请前往官网配置软件源。
注意,你应该已经有 MaxMind GeoIP Lite 数据库,如果没有,通过如下方式安装:
重要更新⚠️:2018 年 4 月 1 日起已经无法通过软件自动下载到 DAT 格式的 GeoIP 数据库,请前往官网手动下载对应数据库。需要的是 Binary 格式的。
创建文件 /etc/GeoIP.conf
内容是:
# The following UserId and LicenseKey are required placeholders:UserId 999999LicenseKey 000000000000# Include one or more of the following ProductIds:# * GeoLite2-City - GeoLite 2 City# * GeoLite2-Country - GeoLite2 Country# * GeoLite-Legacy-IPv6-City - GeoLite Legacy IPv6 City# * GeoLite-Legacy-IPv6-Country - GeoLite Legacy IPv6 Country# * 506 - GeoLite Legacy Country# * 517 - GeoLite Legacy ASN# * 533 - GeoLite Legacy CityProductIds 506 GeoLite-Legacy-IPv6-CountryDatabaseDirectory /usr/share/GeoIP
然后安装 geoipupdate,执行 sudo apt install geoipupdate && mkdir -p /usr/share/GeoIP && geoipupdate -v
,你的数据库就已经下载完毕了。
创建文件 /etc/powerdns/pdns.d/geoip.conf
内容是:
launch=geoipgeoip-database-files=/usr/share/GeoIP/GeoLiteCountry.dat /usr/share/GeoIP/GeoIPv6.dat # 选择 IPv4 和 IPv6 国家模块geoip-database-cache=memorygeoip-zones-file=/share/zone.yaml # 你的 YAML 配置文件的位置,随便哪个地方都行geoip-dnssec-keydir=/etc/powerdns/key
创建那个 YAML 文件,然后开始写 Zone,这是一个例子(IPv6 不是必须的,所有 IP 应该都填写外部 IP,本文以精确到国家举例,并列内容的顺序无所谓):
# @see: https://doc.powerdns.com/md/authoritative/backend-geoip/domains:- domain: example.com ttl: 300 # 默认 TTL 时长 records:##### Default NS ns1.example.com: - a: # 你的服务器的第一个 IPv4 地址 content: 10.0.0.1 ttl: 86400 - aaaa: # 你的服务器的第一个 IPv6 地址 content: ::1 ttl: 86400 ns2.example.com: # 你的服务器的第二个 IPv4 地址(如果没有就和上面一样) - a: content: 10.0.0.2 ttl: 86400 - aaaa: # 你的服务器的第二个 IPv6 地址(如果没有就和上面一样) content: ::2 ttl: 86400##### Root domain example.com: # 根域名下的记录 - soa: content: ns1.example.com. admin.example.com. 1 86400 3600 604800 10800 ttl: 7200 - ns: content: ns1.example.com. ttl: 86400 - ns: content: ns2.example.com. ttl: 86400 - mx: content: 100 mx1.example.com. # 权重 [空格] 主机名 ttl: 7200 - mx: content: 100 mx2.example.com. ttl: 7200 - mx: content: 100 mx3.example.com. ttl: 7200 - a: 103.41.133.70 # 如果想使用默认 TTL,那就不用区分 content 和 ttl 字段 - aaaa: 2001:470:fa6b::1##### Servers list 你的服务器列表 beijing-server.example.com: &beijing - a: 10.0.1.1 - aaaa: ::1:1 newyork-server.example.com: &newyork - a: 10.0.2.1 - aaaa: ::2:1 japan-server.example.com: &japan - a: 10.0.3.1 - aaaa: ::3:1 london-server.example.com: &uk - a: 10.0.4.1 - aaaa: ::4:1 france-server.example.com: &france - a: 10.0.5.1 - aaaa: ::5:1##### GEODNS 分区解析 # @see: https://php.net/manual/en/function.geoip-continent-code-by-name.php # @see: https://en.wikipedia.org/wiki/ISO\_3166-1\_alpha-3 # unknown also is default # %co.%cn.geo.example.com # 默认 unknown.unknown.geo.example.com: *newyork # 默认解析到美国 # 洲 unknown.as.geo.example.com: *japan # 亚洲解析到日本 unknown.oc.geo.example.com: *japan # 大洋洲解析到日本 unknown.eu.geo.example.com: *france # 欧洲解析到法国 unknown.af.geo.example.com: *france # 非洲解析到法国 # 国家 chn.as.geo.example.com: *beijing # 中国解析北京 gbr.eu.geo.example.com: *uk # 英国解析到英国 services: # GEODNS www.example.com: [ '%co.%cn.geo.example.com', 'unknown.%cn.geo.example.com', 'unknown.unknown.geo.example.com']
这个配置,就相当于把 www.example.com 给分区解析,由于目前这个解析存在一些问题,导致不能同时在根域名和子域名下设置 GEODNS,这个 Bug 我已经提交反馈了。 如果你想只把解析精度设在洲级别,那么就直接 %cn.geo.example.com 这样少写一级就行了。如果你需要精确到城市,那么多写一级就行,但是需要在配置文件中添加 GeoIP 城市的数据库。然而免费的城市数据库的城市版本并不精准,你还需要去购买商业数据库,这又是一个额外开销。
前往你的域名注册商,进入后台修改设置,给域名添加上子域名服务器记录,如图:
由于要设置的 NS 是在自己服务器下的,所以务必要在域名注册商上向上级域名(如 .com)注册你的 NS 服务器 IP 地址,这样上级域名就能解析道 NS 的 IP,自建 DNS 才能使用,比如 icann.org 下就有一个属于自己的 NS:
$ dig icann.org ns +shorta.iana-servers.net.b.iana-servers.net.c.iana-servers.net.ns.icann.org.
然后再看它的上级域名 org:
$ dig org ns +shorta2.org.afilias-nst.info.b0.org.afilias-nst.org.d0.org.afilias-nst.org.c0.org.afilias-nst.info.a0.org.afilias-nst.info.b2.org.afilias-nst.org.
随便找一个服务器,查询权威记录(我就不用 +short 了):
$ dig @a0.org.afilias-nst.info icann.org ns;; QUESTION SECTION:;icann.org.INNS;; AUTHORITY SECTION:icann.org.86400INNSc.iana-servers.net.icann.org.86400INNSa.iana-servers.net.icann.org.86400INNSns.icann.org.icann.org.86400INNSb.iana-servers.net.;; ADDITIONAL SECTION:ns.icann.org.86400INA199.4.138.53ns.icann.org.86400INAAAA2001:500:89::53
可以看到,在这个 org 的 NS 服务器就已经把 ns.icann.org. 的记录返回来了,这也就是你需要在域名注册商填写 IP 地址的原因。然而你最好在你域名下的 DNS 服务器上也返回相同的 NS 和相同的 IP。 最后,不要忘了改域名的 NS 记录。
我刚才的 YAML 中其实就已经用到了 YAML 的高级写法,就是 &variable
设置变量,*variable
使用变量,这很像 CloudXNS 下的 LINK 记录,比如在 CloudXNS 下你可以这么写:
www.example.com 600 IN A 10.0.0.1www.example.com 600 IN A 10.0.0.2www.example.com 600 IN AAAA ::1www.example.com 600 IN AAAA ::2sub.example.com 600 IN LINK www.example.com
然后在你的 YAML 记录里就可以这么写:
www.example.com: &www - a: 10.0.0.1 - a: 10.0.0.2 - aaaa: ::1 - aaaa: ::2sub.example.com: *www
这就是 YAML 的一种高级写法,不需要其他额外支持。
详情可以参考文档,运行以下指令:
$ mkdir /etc/powerdns/key$ pdnsutil secure-zone example.com$ pdnsutil show-zone example.com
最后一个指令所返回的结果就是你需要在域名注册商设置的记录,不推荐都设置,只设置 ECDSAP256SHA256 - SHA256 digest 就行了。 最后在线检查设置即可 测试地址1 测试地址2,可能有几天缓存时间。 我的检查结果
你可以在 YAML 里写上这个,为了方便你调试:
"*.ip.example.com": - txt: content: "IP%af: %ip, Continent: %cn, Country: %co, ASn: %as, Region: %re, Organisation: %na, City: %ci" ttl: 0
这些变量都能作为你 GEODNS 的标准,也可以检查你的 GEOIP 数据库情况。 然后,正确检查的姿势:
$ random=`head -200 /dev/urandom md5` ; dig ${random}.ip.example txt +short"IPv4: 42.83.200.23, Continent: as, Country: chn, ASn: unknown, Region: unknown, Organisation: unknown, City: unknown"
IP 地址就是 DNS 缓存服务器地址(如果你开启了 EDNS Client Subnet,且缓存服务器支持,那么就是自己的 IP,但是如果使用 8.8.8.8,那么会看到自己的 IP 最后一位是 0),如果你在本地指定了从你自己的服务器查,那就直接返回你自己的 IP 地址。由于我只安装了国家数据库,所以除了洲和国家之外其余都是 Unknown。
一般情况下,是一个 Master 和一个 Slave 的 DNS 解析服务器,但是这样的话对 DNSSEC 可能有问题,于是我就建立了两个 Master 服务器,自动同步记录,并设置了相同的 DNSSEC Private Key,好像并没有什么错误发生(毕竟包括 SOA 在内的所有记录也都是完全一样的),我的服务器目前的配置
$ dig @a.gtld-servers.net guozeyu.com;; QUESTION SECTION:;guozeyu.com.INA;; AUTHORITY SECTION:guozeyu.com.172800INNSa.geo.ns.tloxygen.net.guozeyu.com.172800INNSc.geo.ns.tloxygen.net.;; ADDITIONAL SECTION:a.geo.ns.tloxygen.net.172800INA198.251.90.65a.geo.ns.tloxygen.net.172800INAAAA2605:6400:10:6a9::2c.geo.ns.tloxygen.net.172800INA104.196.241.116c.geo.ns.tloxygen.net.172800INAAAA2605:6400:20:b5e::2
其中是两个 IPv4 两个 IPv6,其中 a.geo.ns.tloxygen.net. 是使用了 Anycast 技术的 IP 地址,其背后由三台服务器提供。c.geo.ns.tloxygen.net. 属于另一家服务商的主机,这样一个挂了之后还有备份,更加稳定。
像我这种分布式的 DNS,其实是 Unicast 和 Anycast 的组合,这样存在的一个问题就是在一个地方连接其中一个会比较快,但是另一个会比较慢。只有在用支持异步查询,或者是带 GeoIP 的 DNS 缓存服务器,才有可能连接到最快的 DNS 权威服务器,其他情况下则是随机连接,而且如果一个服务器挂掉了,那么服务器对应的 IP 就废了。 Anycast 是一个 IP 对应多个主机,然而我却没有条件用,这个对于个人来说也许成本会比较高,要么你自己有 AS 号然后让主机商给你接入,要么你的主机商提供跨区域的 Load Balancing IP。我的 VPS 在两个不同的主机商,也没有 AS,就不能用 Anycast 了。我觉得 DNS 服务如果可能还是要用 Anycast,因为 DNS 服务器对应的 IP 不能 GEODNS(因为这是根域名给你解析的),使用 Anycast 后就基本能保障最快的连接速率,并且一个服务器挂了 IP 还能用。此外,DNS 必须要同时转发 TCP 和 UDP 的 53 端口。
如何实现宕机自动切换?实现这个的流程是: 监控服务发现宕机 -> 向服务器发送已经宕机的请求 -> 服务器对宕机处理,解析到备用 IP/暂停解析 监控服务发现服务正常 -> 向服务器发送服务正常的请求 -> 服务器对服务正常处理,恢复解析 可以建立两个 YAML file,一个是默认使用,一个是服务器宕机时使用的,当监控服务发现服务器宕机后,重新加载另一个 YAML file,然后这就是宕机模式了。
]]>.gitlab-ci.yml
文件实现自动 Build,实时同步镜像到 GitHub。能够 Host 在自己的服务器上的软件/服务其实有很多,比如 GitHub Enterprise,Bitbucket Server。不过再此还是推荐完全开源、免费、由社区维护的 GitLab Community Edition,没有任何限制,只是相比 Enterprise Edition 少了些本来也用不着的功能。
具体安装方法见文档,目前官方推荐的系统环境是 Ubuntu 16.04 LTS,安装起来非常简便,整个 Web 环境都会配置好。安装后的更多配置请参见文档。如果你的主机上跑了不只一个 Web 程序,那就需要对现有的 Web 软件做修改,需要参见官方的 Nginx 的配置文档。我的代码中使用了 sub_filter
来实现替换默认的标题,实现更好的 SEO,更加品牌化。 然后为了能达到更好的使用效果,还应该配置 SMTP 发件服务器,我使用的是 AWS SES;然后还需要一个支持 IMAP 的收件服务器实现 Reply by email,我使用的是 Gmail,收邮件的限制总比发邮件的限制少吧~这些的具体设置方法官方文档里都有。 安装后默认是允许注册的,如果你不想让外人注册,你需要直接去 Web 后台禁用。如果你想要开放注册,那么最好先想好新注册用户能干什么,比如和我一样:只允许新用户创建 Issues 和 Snippets,那就在 Web 后台将 Default projects limit 设置为 0
,然后编辑后台的配置文件,禁止新用户创建 Group。同时建议在 Web 后台启用 reCAPTCHA 和 Akismet,防止恶意注册和恶意发 Issues。既然允许注册,那么也建议使用 OmniAuth 来支持第三方 OAuth 的方式登陆。
GitLab Runner 十分强大,但是并不是内置的,它可以极其方便的实现自动部署等非常有用的功能。安装配置好 Runner 后,在项目根目录下添加一个名为 .gitlab-ci.yml
的文件,以 master 分支为例,为了实现每次 commit 到 master 都将文件部署到 /var/gitlab/myapp
,那么文件内容应该是这样的:
pages:stage: deployscript:- mkdir -p /var/gitlab/myapp- git --work-tree=/var/gitlab/myapp checkout -fonly:- master
注意,你需要先创建 /var/gitlab
文件夹,并设置这个文件夹的用户组为 gitlab-runner:gitlab-runner
$ sudo chown -R gitlab-runner:gitlab-runner /var/gitlab
.gitlab-ci.yml
核心的部分就是 script:
,这里的脚本都是由用户 gitlab-runner
执行的,你可以根据需要修改,后文中也给了几种范例。 然后 commit,去设置页面里里激活这个项目的 Runner。建议在设置里设置 Builds 为 git clone
而不是 git fetch
,因为后者常常出现奇奇怪怪的问题,前者的速度瓶颈主要在于网络传输。
官方的文档里强烈不推荐把 Runner 部署在同一个主机上,其实这种说法并不正确。官方不推荐这样做是因为一些 build 会花费很长时间,占用很多的 CPU 和内存资源。但是如果你执行的 build 脚本并不会这样,那么安装在同一个主机上也未尝不可。
这几种部署是我比较常用的,大家可以当作范例,具体根据自己的需要弄各种不同的部署。 以下几种 Web 的部署方式所消耗的系统资源都不多,而且由于使用了 nice
,并不会阻塞其他任务,可以部署在同一台主机上。
修改之前那个 .gitlab-ci.yml
文件的 git checkout
一行,替换为:
jekyll build --incremental -d /var/gitlab/myapp
也是添加以下代码到 .gitlab-ci.yml
即可自动检查所有 PHP 文件的编译错误,编译通过的文件不会显示,只会显示编译错误的:
if find . -type f -name "*.php" -exec nice php -l {} \; grep -v "No syntax errors"; then false; else echo "No syntax errors"; fi
以下过程需要 root 权限登陆到主机,或者在每行命令前添加 sudo
。 首先,需要先给 gitlab-runner
用户一个单独的 SSH Key:
$ ssh-keygen -f /home/gitlab-runner/.ssh/id_rsa
然后,创建 /home/gitlab-runner/.ssh/known_hosts
,内容是:
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
之后,获取 /home/gitlab-runner/.ssh/id_rsa.pub
文件内容,在 GitHub 上添加这个 SSH Key。 由于是使用 root 帐号,弄完了之后不要忘了修改用户组:
$ sudo chown -R gitlab-runner:gitlab-runner /home/gitlab-runner/.ssh
然后,同样是通过 .gitlab-ci.yml
实现自动同步:
git push --force --mirror git@github.com:[Organization]/[Project].git
修改 [Organization]
和 [Project]
为你自己的名称即可。
文件都存储在自己的服务器里,安全性比较有保障,自己有最高权限,不会遇到项目被删的情况。部署时延迟极低,可靠性也高,不会遇到自己服务器没问题但是第三方服务宕机导致无法部署的窘况。 可以根据情况部署到离自己最近的服务器,或者是内部服务器,像 GitHub 的服务器就在美国东岸,亚洲这边连接并不快,国内也不稳定。 最关键的是,如果你本来就有个 VPS 什么的,也有很大的空闲,那么相当于你可以免费获得私有存放处,但是要注意性能需求,没有足够的空闲还是不要启用。 由于能够配置好实时同步镜像到 GitHub,GitLab 还有那么多 GitHub 没有的功能,其实已经可以完全使用 GitLab 作为主要的版本控制工具,GitHub 只是存一份镜像备用。
]]>WordPress 是一个动态的系统,如果不配置缓存,每次请求都需要服务器去读取数据库,生成页面内容,对于不同性能的主机,这可能就需要 20ms~1000ms 甚至更慢。如果能够正确配置缓存,就可以明显的加速,并且减少主机的运算资源。
使用插件来配置缓存是最简单的方法。在此推荐 WP Super Cache,这是 WordPress.com 出品的缓存插件,就页面缓存来说,功能非常全面,它支持多种缓存模式,包括 mod_rewrite
,如果你使用 Nginx,那么可以使用我这个配置文件,这样可以直接跳过 PHP 而直接服务静态文件,页面相应速度有显著提升。 同时,为浏览器返回正确的 Cache-Control
也是十分有必要的,尤其是 CSS 和 JS 文件。
对象缓存比页面缓存更灵活,使用范围更广,但速度肯定不如页面缓存。在此推荐 APCu 缓存系统。在 Ubuntu/Debian 安装方法如下:
$ apt install php-apcu
然后重启 Web server,安装 APCu Object Cache Backend 即可。 Redis、Memcached 等都算此类型的缓存,不过 APCu 配置最为简单,速度也很快。
比如我的网站使用北美东岸(主要)和亚洲的 VPS,主服务器配置了 Nginx,PHP 和 MySQL;亚洲的服务器只配置了 Nginx。在这些服务器上都配置好缓存,并用 lsyncd 同步缓存内容。每次访问时 Nginx 检查缓存,仅当没有缓存时代理,这样可以大大减少首页面的延迟。
使用全站 CDN,可以免去在自己的服务器上配置缓存的问题,还可以为服务器增加 HTTPS、HTTP/2 等功能,同时还能过滤非法流量,防御 DDOS(前提是你的 IP 没有被暴露,或者你设置好了白名单)。 除此之外,使用 CDN 后还能更加明显的提高网站加载速度,让访客从中受益。
CloudFlare 是可以免费使用的,使用 CloudFlare 前需要更改 DNS 服务商,然后无需额外配置就能使用了。但是它只会缓存 CSS、JS 和多媒体文件,不会缓存 HTML 页面,也就是说用户每次访问时还是会返回到原始服务器,页面本身的速度不会有明显提高,在原始服务器上配置缓存也是必要的。
KeyCDN 是一个按流量使用付费的 CDN 提供商,使用我制作的插件 Full Site Cache for KeyCDN 可以简单的对其配置,这个插件会自动刷新缓存。 KeyCDN 相比 CloudFlare,可以缓存 HTML 页面,大大减少源服务器的压力,同时在刷新缓存时可以通过 Tag 方式刷新,避免不必要的刷新。 在网站访问量较大时,使用 KeyCDN 就能明显的提高速度,缓存命中率也会有很大的提高。
你可以配置另一个域名,在那个域名上使用 CDN,然后通过插件重写页面地址实现部分 CDN。上文提到的 WP Super Cache 就能配置 CDN,或者使用 CDN Enabler 也能实现部分 CDN 功能。至于 CDN 的选择无所谓,只要支持 Origin Pull(也就是请求回源)就行。
提高服务器本身的性能是最简单的方法,使用更大的内存,更多核心的 CPU 能明显提速。除此之外,提高服务器上应用的性能也很重要:
PHP 脚本的处理速度是 WordPress 的一大瓶颈,使用最新版本的 PHP,可以获得更高的性能,例如 7.0 就比 5.6 快了 3 倍。
其次,少用插件能减少 PHP 需要执行的脚本,因为在加载每一个页面时,WordPress 都会加载一遍所有的插件。少量的插件(10个以下)对 WordPress 速度的影响不大,当然也取决于插件本身。
数据库是 WordPress 性能的瓶颈之一,在数据库上优化能提高一定的速度。 一般情况下,如果正确的使用 WordPress,并不需要清理数据库。但可能会有某些插件可能在数据库中创建了太多没用的表,这时服务器的响应速度就会大大降低(约 1~3 倍),推荐使用 WP-Optimize 进行清理。 不是太多的文章数量,是不太会的影响加载速度(1 万篇文章以下速度其实都还能接受,不过你写那么多文章干嘛,质量比数量更重要嘛)。
图片占据着网页中很大一部分的大小,同时也关系着用户体验。
对图片压缩不仅可以提高访问时图片加载速度,还能减少服务器带宽 推荐使用免费的 EWWW Image Optimizer,可以在服务器上对图片进行处理。如果你的服务器性能有限,可以使用 Optimus 在线处理,免费版功能十分有限。
对于不同的设备加载不同的图片,比如在手机上加载的图片,就可以比视网膜屏幕的电脑上要加载的图片小的多。使用本站曾经提到过的 srcset 技术可以最简单的实现这个功能,只要你的主题支持就可以了(官方的最新默认主题已经支持),如果主题本身不支持,也可以通过插件实现。
WordPress 中有一些自带的服务你可能并不需要,禁用它们可以减少页面所需要加载的资源以及服务器需要做的事情。
WordPress 支持 Emoji 表情符号,但会因此在页面中引入额外的 CSS,使用这个脚本可以禁用它(如果你不需要的话)。
Google Font 在国内加载非常慢,而且加载完成之前页面会一直白屏。你可以专门安装 Disable Google Fonts 的插件,或者在下文要提到的 Autoptimize 插件中的设置里禁用它。
进入 设置 => 讨论 中可以禁用 “尝试通知文章中链接的博客” 和 “允许其他博客发送链接通知(pingback和trackback)到新文章” 功能(如果你不需要的话)。 此功能并不影响页面加载时间。
减少请求数在也一些情况下也能提高加载速度,减少页面大小能缩短下载页面所需要的时间。推荐使用 Autoptimize,它可以 minify CSS、JS 和 HTML,还能 combine CSS 和 JS 以减少请求数。
然而,如果你的博客启用了 HTTP/2 协议,那么减少请求数就没什么必要了,不过为了启用 HTTP/2,必须要使用 HTTPS,所以最终下来是快是慢也不好说。不过还是强烈推荐使用 HTTPS,为了安全,牺牲点速度算什么。
做到上面几点,就能有效提速了,我的网站做到以上几点,在国内无缓存的 Wi-Fi 情况下本网站的时间线如下:
]]>备注:CloudXNS 不支持 TCP。
国内免费 DNS 中最好用的,作为 DNS 服务来说其功能也算齐全。CloudXNS 的服务器国内有不少,但没有使用 Anycast 技术,所以谈任何国外的服务器都是白搭。
CloudXNS 通过 GeoDNS 对其 NS 服务器的域名进行分区解析,国内的解析到国内服务器,国外的解析到国外服务器。然而其根域名的 Glue Record 中的四个仍是国内的四个服务器,实际解析中会优先使用 Glue Record,所以并不会用上任何国外的服务器。
为什么不将这些国外服务器也添加到 Glue Record 上?因为 Glue Record 并不支持 GeoDNS,所以解析器将会随机选择服务器,所以如果这样的话会导致国内的一部分请求也走到美国服务器,反而减速。
国外相当流行的 DNS 服务,必要的那些功能也算齐全。服务器都遍布全球,使用了 Anycast 保证最低的延迟。
国外占有量相当大的免费 DNS,服务器都遍布全球,使用了 Anycast 保证最低的延迟。
价格低廉,提供 100% 的 SLA,使用了 Anycast 保证最低的延迟。
同时支持 DNSSEC 和分区解析,使用了 Anycast 保证最低的延迟。
阿里云旗下产品,解析服务器全部使用阿里云机房,有速度保障。按照使用功能而非解析量收费。服务器国内有不少,但没有使用 Anycast 技术,所以国外速度很差。 测速基准:
ns1.alidns.com. 106.11.141.111
阿里云付费版与免费版线路有所不同,付费版含有海外线路,但由于没有 Anycast,所以最终线路是随机选择的,所以付费版与免费版相比,其在国外的响应时间稍短,在国内的解析时间稍长。 备注:阿里云 DNS 不支持 TCP。
虽然桥上有路灯,但是已经有一半都坏了。当地的孩子说,这些灯很久以前就坏掉了,也从来没人修过。走着走着,路灯彻底没有了,月光映出我们的影子。把我们的影子拉得长长的,说不出的孤寂,好像也在和我们告别着。
无论是白天还是夜晚,这里都非常安静。路上很难看到汽车,人们也普遍不走人行道而走马路上。红绿灯?这里一个都没有。夜空中的星星非常多,足以百计,当地的孩子不屑地告诉我:“这算什么!要是赶上晴天,星星要多好几倍!”
这里的景确实很美,据说即将也会开发成旅游景区,人们可以在这里享受清新的空气、享受钓鱼的乐趣、在湖中划船。从好的方面说,这的确能迅速发展这里的经济,但是也会吞噬这个沙州镇这一片净土。
不知不觉,我们已经走回住宿的地方,今天的情景还是挥之不去。明天,将是最后一个完整的日子了。晚自习的时候,我们组的三个人都留下了联系方式,也说了一些惜别的话,同学们都表达了自己不忍分别的情感,我们都非常感动。
再见!沙州镇!我会想念这个地方!想念这里的学生!还有那些留给我的珍贵回忆!
写下此文留作纪念。
]]>背景介绍:2016 年 4 月 9 日(周六),我所在的学校开展了青川社会实践活动,经历 1 天多的路途,来到了青川。这次活动共要教授 4 个课时的课程。我们班级所被分配到的是沙州初等中学。青川位于四川,是 2008 年四川地震的重灾区之一。
每天早上,我一般会在 05:45 时起床,在简单的准备后,就出发了。此时,虽然太阳还没有升起(日出时间大约为 06:30),却已经有微微曙光了。大多数星星已经变得不再可见,但是此时的路仍然很
难看清。路上可以听见鸟鸣和鸡叫,我们就一直向北走着。路过桥时,右侧已经可以看到金黄色的曙光,天就逐渐亮了起来,直到到了学校后,就开始准备跑步了,跑步之前也不需要什么准备活动,直接开始沿着操场跑。
操场虽不算很大,却足以容得下这个学校所有的班级。第一天(周一),我所任教的八年级二班由于多数同学都去县里踢足球赛了,直到周二才能回来。所以在这期间,这个班级只有自习课,我便只能到其他班级里听课。这里的老师讲课注重基础(文科),一堂课所涉及到的知识点不会很多,老师课堂提问和学生回答占据了课程中很大的比例。
在这一天的下午,我成功要到了一节数学课。在这一节课的前半部分,我讲了二元一次方程组(的第一课时),后半部分我给他们上习题课。上习题课的时候,我注意到他们其实并没有真正理解数学中的一些概念。比如我在课上复习实数的分类的时候,我把其中的有理数分成了整数和分数,还特意强调了零是包含在整数里面的,然后同学们就说我讲的不对,要有零,因为书中把有理数分为了正有理数、零和负有理数(在此就不吐糟人教版奇葩的分类了)……所以我得重复很多遍这之间的区别他们才能够理解。后面的题我还是讲得比较细致,最终我在下课铃响后 40 秒才完成讲课,我们的学校老师告诉我这是严重的教学事故。(由于学校的表比我的表快了 2 分钟,在此之后这样的 “严重教学事故” 依然频频发生……)
上完这一次的数学课后,老师所给我的反馈是:讲二元一次方程组的时候比较快。课后我想到,确实是这样。这是他们第一次见到这样的方程,理解其中的含义还是需要一段时间的,我讲得确实比较快。但是从各方面反映的结果来看,我的习题部分讲的还是非常好的。
一天的教学任务就这样结束了,我对自己所做的还算比较满意。
]]>用 MP4 封装的 H.264 + AAC 格式是目前兼容性最强的格式,能够在绝大多数的设备上播放,但是它不是一个开源的格式,在一些只用开源软件的客户端或者服务器上就不能使用这个格式。典型的例子就是维基百科背后的媒体资源站 Wikimedia Commons 就没有使用 MP4 格式,导致了在维基百科上的视频在一些浏览器上根本无法播放。不过对于大多数情况来说,使用 MP4 封装的 H.264 + AAC 格式就足够了。 其次,需要将视频展示出来,在 21 世纪来说,这已经不是什么难事了。如果你想在网页上展示,一个好消息是:所有的主流浏览器都遵循着一套统一的规范(HTML5),只要你也使用这套规范,那么就可以在主流的浏览器上嵌入视频了(虽然它们遵循同一套规范,但是支持的编码有所不同。就好比说现在用户的信箱都是统一的规格,你可以将你要寄的书放到这些信箱里。但是你的书是用中文写的,那么不懂中文的人就无法知道书中的内容。)。
同一个视频,在互联网上流播的版本是与在本地播放的质量是有所不同的。为了能够让视频在互联网上流畅播放,会降低视频的画质。很多视频网站也会准备一个视频的不同画质的多个版本,方便在不同网络环境下播放更好的画质的版本。
其实写本文的目的,还是想说说中国的视频网站与国外的差距。有些是不能避免的因素,但是有一些是这些网站本应该做,却没有做。 国外的 YouTube 视频画面分辨率能到 7680×4320@60FPS,就这也不敢称作为 “超清”,然而国内普遍将 1280×720@30FPS 甚至更低的分辨率,就叫 “超清”,这比前者低了将近 100 倍(从像素的信息量上来说)。而且,同等分辨率下的画质也是有很大区别的,使用越低的画质越能节约钱(中国大陆很多视频网站都是很有钱的,但为什么还要节约钱呢?这就不得而知了~)。
更高的视频分辨率,意味着能够在更高分辨率的显示器上获得更好的效果。4K、8K 的电视以及显示器已经有很多了,而且能够录制 4K、8K 视频的相机/手机也越来越多。这些高画质内容正在走向低端消费市场,所以视频网站还是有支持的必要的。
但之前说的这些,我并不指望国内的视频网站能做到,因为它们都还想多赚钱呢。但是为什么还要使用一个漏洞百出,并且官方已经停止维护,需要通过额外安装插件的方法来播放视频呢?我说的就是 Flash(当然有少数网站已经不用它了),仅仅播放一个视频,用 HTML5 完全就够了,根本不需要这么一个复杂的东西。 想要让它们不用 Flash,首先得让 Flash 彻底地从客户端消失(如果浏览器能够主动屏蔽 Flash 就更好了,例如 Safari),渐渐的,它们会发现有大量的用户流失(这件事正在发生),然后终于有一天就能使用上新的技术了。 在国外,就比中国领先的多。从很多年前开始,主流的视频网站默认都不再使用 Flash 了。
视频在互联网上的流播实际上还有很多很多可以讲的,本文仅仅是粗略的谈一下而已。
]]>并没有什么全新的高级功能,都是以前就有的,或者是软件上的小升级。
然并卵,电脑后期都可以做的嘛
通过短片创意滤镜功能,可以拍摄得到添加了特殊滤镜效果的短片。这得益于影像处理器的不断进化。包括原有的微缩景观效果短片在内,还有回忆、梦幻、老电影以及黑白分明共5种滤镜效果可供选择。
就是拍摄多张照片并自动合成视频。据我的理解,应该每次快门都是电子快门,这样可以大大节约快门寿命和电池续航。并且由于自动合成的是 1080p 视频,所以也很省空间,这个功能应该是支持手动模式的。
将按照一定间隔拍摄的静止图像拼接在一起并进行快放的短片形式就是延时短片。可以充分发挥EOS 80D静止图像的画质优势,得到高质量的MOV全高清短片(约30p、25p)。适合拍摄云朵的流动或天空中繁星的运动等,与普通短片相比,被摄体的变化被浓缩在短时间内,效果更加令人印象深刻。拍摄时间间隔的设置范围为从1秒到99小时59分59秒,拍摄张数的设置范围为2张到3600张。
然而这是在逗我吗?为什么合成的短片是全高清而不是 4K 呢? 不得不说,以上两个功能只是软件上的升级而已,将来可能通过软件升级的形式让其它 EOS 相机也具有这些功能。而下面的其它功能中所列的,才是硬件上的升级。
这些功能已经在其他的 EOS 相机中有了,但却是曾经 70D 没有的功能。
全新用了 45 点全十字对焦,这相比 70D 的 19 点已经提高了不少了,但是从数字上来看,似乎并不如原先发布的 7D Mark II 上的 65 点全十字对焦,然而实际真的如此吗?
全45点十字型自动对焦感应器,是能够对应F2.8、F4、F5.6光束的自动对焦系统,部分自动对焦点能够兼容F8光束。当使用最大光圈为F5.6及更明亮的大光圈的镜头时,最多可使用45个十字型自动对焦点进行对焦。根据所搭配镜头最大光圈大小,自动对焦点的性质也将随之产生变化。搭配不同镜头或设置不同长宽比时,可使用的对焦点数及对焦方式会有所不同。
经过我一番研究,发现一个惊人的新特性:在 F8 下也能有 27 个自动对焦点(其中 9 个是十字对焦),这是 EOS 系列中在 F8 下拥有自动对焦点第二多的机身了(仅次于 1DX Mark II),这样的话即使是长焦配了增倍镜光圈变得非常小后,也能方便的对焦了。
在EF 100-400mm f/4.5-5.6L IS II USM上安装增倍镜 EF 1.4X III,远摄端最大光圈降为F8时也有27个对焦点可以使用。
对比一下不同对焦系统在 F8 下的对焦能力:
哇塞!80D 好厉害,不过有哪些镜头支持它的 G组的自动对焦呢?
额,感觉被忽悠了。那不支持的镜头在 F8 下有几个对焦点呢?
一个,只有一个,连辅助对焦点都没有,不过至少相比 70D 已经好了些了。 除此之外,全新的 45 点全十字对焦应该是各方面都不如 65 点全十字对焦了。
EOS 80D配备了佳能自主研发制造的新CMOS图像感应器,有效像素约2420万。CMOS半导体制造工程导入新的精细化工艺,并采用无间隙微透镜,缩短了微透镜与光电二极管的距离,提高了聚光率。且优化了像素结构,提高了信噪比。与DIGIC 6数字影像处理器联动,在暗光场景下也能得到高解像感,实现精细的表现。
这个像素在 APS-C 相机中已经算高的了,然而,这次并没有提升 ISO 的上线,如果不做像素上的升级,ISO 上线能翻一番,到 51200。 然而这块 CMOS 和 760D 的完全一样~ 为什么说它们是一样的?因为从这里可以看出似乎是一样的:
但是,有两点不同:
值得在意的是对焦系统,Hybrid CMOS AF III 只在 750/760D 上出现过,性能表现出色,或许就是限制了的 Dual Pixel CMOS AF。详情参考 YouTube 上的测试
佳能在EOS的2位数机型上首次配备了视野率约为100%的光学取景器,这个功能还是很重要的。而且 80D 取景器里也多了些新元素,我称其为 “(伪)电子水准仪”
为什么是伪呢?因为它的能力有限:
正版是这样的,看见正上方的水准仪了吗?双轴的。
看到这个模式我就呵呵了,再一次印证了 80D 不会是专业或准专业水准的相机。
特殊场景模式中汇集了一些有代表性的拍摄场景,相机可以配合具体场景进行相应拍摄设置。可选场景有手持夜景、烛光、儿童等共10种。拍摄时操作简便,只要像使用智能手机一样,通过在液晶监视器上滑动手指,触摸选择图标,相机就可以根据被摄体及拍摄环境的特点找到合适的设置拍出好照片。
如果你是非专业人士,在 7D Mark II 和 80D 之间选择的话,我推荐 80D,它有触摸屏和 Wi-Fi,确实方便了不少。7D Mark II 在对焦、连拍、耐久度都优于 80D,但是其它方面不一定比它强多少,像素还低一些。 如果是在 5D Mark III、6D 和 80D 之间选择,你的预算不高,并且有录制视频的需求,还是推荐 80D,它的对焦和快门速度都要好于前两者。至于全画幅还是 APS-C,那就是另一个值得讨论的问题了。关于 80D 的更多信息,可参考佳能官方新闻稿
]]>无损及有损压缩 JPEG 和 PNG 图像,支持压缩已有的图像,可以加快访问者加载图片的速度。同时支持 JPEG 的渐进式加载。正常情况下,网速低时,图片是一点点从上往下加载,而使用渐进式加载,则是先加载这个图片的低分辨率版本,然后逐渐变得清晰。我已经成为这个插件的付费用户,能够进一步有损压缩 PNG 和 JPEG 格式图片、降低服务器 CPU 占用(否则每上传一张图片,CPU 都消耗很多)。不过最近使用了 Cloudflare 的 Polish 功能,就没有再在服务器上安装同类软件了。
这个插件能够自动的合并 CSS 和 JS,并对其压缩,非常的方便。而且一些主题会有大量的 inline CSS,当开启了合并 CSS 后,这些 inline CSS 会自动添加到文件中。 我在这个插件中的一些配置,分享出来:
functions.js,player,mediaelement,sparkline,toolbar,admin,akismet,themes
admin,mediaelement,wordfence,piwik,toolbar,dashicons,crayon-syntax-highlighter/themes,crayon-syntax-highlighter/fonts
<head>
**:能提前加载 JS插件作者是:Automattic ,为 Google 优化,搜索结果中展示超快的 AMP 页面。详情:使用 AMP 构建超快的移动页面
二部认证器(需要配合同名手机客户端,或者 1Password 专业版)。你可曾听说过 Heart Bleed 漏洞?有了二部认证,就算再有 Heart Bleed 漏洞,都无需害怕。 原理:手机生成器上扫描二维码保存密钥,然后生成器根据时间变量生成6位数字。这6位数字有有效期,并且只能用一次。安全性甚至大于短信验证码
更换 IP 后需要重新登录,就算使用 HTTP 也可以一定程度上避免 Cookie 泄漏的风险
WordPress #1 的安全防御插件,可限制密码尝试次数防止暴力破解,可为你的 WordPress 增加 WAF 功能,查看实时访问。通过查看它的日志我才发现,原来我的 WordPress 一直在被恶意的暴力破解,有时一天几千次,几乎天天都有。不过还好只要尝试 3 次错误密码,IP 会直接被屏蔽掉,这也是 Failed Logins 数量不多的原因。 像这种是基于应用层面的防御,并不是 Cloudflare 等云加速,抗 DDOS 服务所能防御的。
这个插件能够让 WordPress 上展示自动高亮的源代码,有多种主题可以选择,支持多种编程语言。
这是 Jetpack 的简化版,没有 Jetpack 那一堆没用的特性,不需要登录到 wordpress.com,功能齐全,使用起来也非常简便。
这个插件能够自动生成网站的 sitemap.xml
和 robots.txt
,你可以直接将 sitemap.xml
提交到百度和 Google,这样搜索引擎就不会漏掉你的网站上的每一篇文章了。 这个插件支持 WordPress 的多站点,不需要任何配置,推荐在整个网络上启用。
这个插件能够让你的整个网站拥有统计功能,支持 WordPress 的多站点,推荐在整个网络上启用。关于 Piwik 配合 WordPress,请参见这篇文章:Piwik 与 WordPress 配合使用,建立强大统计系统。
这个插件能够让你的 WordPress 生成一个 Podcast Feed,让你有一个播客平台,你也可以把这个 Feed 直接提交到 iTunes 等地方。
这个插件可以让你将图片的 Exif 信息插入到图片的说明中,缺点是需要上传图片后手动添加,但是它可以批量添加,还算方便。将 Exif 信息插入到图片的说明后,再将这个图片插入到文章中,Exif 信息就能够显示在文章中。
]]>前往设置中的地理位置页面,在页面左下角选择下载一个 GeoIP 数据库。下载了之后,你就可以使用 GeoIP (Php) 了,然而这个比较慢。我推荐你使用 GeoIP (PECL),如果你使用的是 cPanel,那么你可以直接在 Select PHP Version 页面中开启 GeoIP 模块,然后再去 php.ini
中加入或编辑这一行:
geoip.custom_directory = /Matomo/misc
然后就 OK 了,选择 GeoIP (PECL) 即可!
如果你的语言设置的是中文,那么你的图像报表中会出现乱码。请 下载字体文件,然后解压放到 plugins/ImageGraph/fonts/
下即可。
首先,需要在 WordPress 下安装 Matomo Analytics(完美支持多站点),之后前往设置。如果你的 WordPress 和 Matomo 都安装在一个站点下了,那么就选择 PHP API,否则选择 HTTP API。填写 Matomo 路径和 Auth Token(可在 Matomo 的后台中找到)即可,然后打开 Enable Tracking,选择默认跟踪即可。在 Show Statistics 里可以选择在哪些地方显示哪些统计,非常方便。
当你选择了 Show per post stats 后,你可以在每一个文章的编辑页面都能看到这个文章的访客信息,非常赞。
首先,为了能够正确的识别用户 IP,你需要在 config/config.ini.php
中添加下面这行代码。
proxy_client_headers[] = "HTTP_CF_CONNECTING_IP"
如果你的 CloudFlare 启用了 IP Geolocation 功能,那么你其实不需要在主机上开启 GeoIP。只需要根目录下创建 .htaccess
文件,添加下面这几行代码:
RewriteEngine OnRewriteBase /RewriteRule ^ - [E=GEOIP_COUNTRY_CODE:%{HTTP:CF-IPCountry}]
然后前往 Matomo 统计的地理位置选项,现在,你的地理位置选项就可以选第三个了 GeoIP (Apache),这个是速度最快的。
]]>其实,在 TL-PA500 的说明书中,写明了它的网线端口为 10/100Mbps 端口,也就是说它根本无法达到 100M 以上的速度…… 其实我并不相信这个电力猫真的能达到 500M 的速度,于是我对其进行了测试,在连接另一个 AirPort 基站(无线)的情况下,拷贝一个 3 GB 的文件到 AirPort Time Capsule。并在直接连接 AirPort Time Capsule (无线)情况下拷贝,对比时间,两个基站距离约 15m。 特别要注意的是,另一个基站(AirPort Extreme)是不支持 802.11ac 的,而 AirPort Time Capsule 是支持的。二者都支持 5GHz 频段,拷贝时都使用了它。 经过了电力猫之后,传输这个 3GB 的文件消耗了 8 分钟,大约达到了 50M 的速度,没有达到 802.11n 在 5GHz 下的极限。 直接传输,消耗了 2 分 20 秒,大约是 170M。 所以,经过了电力猫之后,传输速度被限制在了 50M 左右(但或许是用了网线也是这个速度),这个速度还是可以接受的,因为中国地区普遍的网速都没有达到这个极限,用来部署互联网还是完全可行的。 然而最终还是重新走了暗线,全家局域网终于达到 1000M,可算是够用了。
]]>通常,你并不需要将文件上传到 CDN,你只需要将域名解析到对应的服务器。当用户访问你的网站时,就相当于访问到了这个服务器。这个服务器会检查是否有缓存,若有,那么会直接从这个缓存返回给你;如果没有,则会去从原始服务器上下载下来,然后再返回给用户。此后(再次在这个位置的)用户访问时, 就会直接从 CDN 上缓存的文件下载,速度大大提升。 访问你网站的用户越多,这个速度提升就越明显。如果大多数的请求都没有缓存,那么几乎就没有什么速度提升。除此之外,最好将 CDN 的域名放在一个没有 Cookie 的根域名下。 关于 CDN 的推荐,已经在新的一篇文章里总结概括
又拍云是一个使用起来非常方便的 CDN 服务器,价格极低,按需付费。在国内 CDN 节点覆盖良好,并且还有实时统计等功能。同时支持绑定自定义域名,免费自定义 SSL 服务。 又拍云同时支持静态加速和动态加速两种,适合全站 CDN 加速。
KeyCDN 使用起来也非常方便,节点覆盖全球,价格极低,按需付费。它也有实时的日志。同时支持绑定自定义域名,免费自定义 SSL 服务,同时提供免费的 SSL 证书(Let’s Encrypt)。KeyCDN 只支持静态资源的加速,
为了使用 CloudFlare,你需要更改你域名的 NS 解析提供商,仅此而已,无需其他设置。CloudFlare 默认是动态资源加速。同时提供免费的 SSL 证书(Comodo Positive SSL Wildcard),而且 CloudFlare 是有免费版的。
]]>.html
文件。 首先这里存在一个误区,一些人认为静态网页是不能很方便更新的,实际上静态网页是可以很方便更新的,借助静态网页生成器,更新它并不复杂。当它需要更新一篇文章时,需要重新生成主页和这篇文章,还好这一切一般不到一分钟就能完成。 如果博客要使用动态网页呢?这样做当然是可以的,现在有很多成熟的软件,比如 WordPress,运行在 PHP 环境中,需要 MySQL 数据库。每次访问网页时,需要服务器读取数据库的内容(或从缓存中读取),再处理成有一定样式的 HTML 返回给用户。当然动态网页能够实现一切静态网页的功能,当然还能有更多的功能,比如图片上传,定时发布等。 既然动态网页能实现一切静态网页的功能,那么静态网页有什么优势呢?经过大量的 DDOS 攻击测试,我发现静态网页相比动态网页难攻击很多,甚至难一个到几个数量级。每次访问动态网页时,需要解析 PHP,读取数据库或缓存,需要远大于静态网页的计算量。所以 DDOS 攻击基本上效果不明显,甚至速度都不会慢。
静态网页根本不需要数据库,它本身只是一个文件,所以根本不存在数据库注入等问题。漏洞什么的更是少之又少。
静态网页上 CDN 极其简单,全站缓存即可。每一个页面都可以直接被缓存,网页有更新时清除所有缓存。有了 CDN 之后,那就更不怕 DDOS 了,攻击对方几个甚至 GB 都不算事,人家只不过需要为此付几毛钱流量费而已。
静态网页根本不需要数据库,它只需要一个能上传文件并外链的服务器,比如 Amazon S3 都能放它。大多数服务器都能部署它。
基本上只要会 HTML、CSS 和 JavaScript,就会写静态网页了,再利用一些静态网页生成器直接生成出来所有的页面。
如果使用了静态网页生成器,那么就一定存在着延迟,延迟大小取决于网页生成的速度。有两种生成方式可供选择,一是在本地生成,二是在服务器生成。
这些功能一般只能在动态网页中实现,因为他们都需要数据库。但是静态网页可以选择第三方的服务,比如评论可以用 Disqus,统计可以用 Google Analytics,或者你可以自己建一个动态服务器专门来做这些事,安装上 Piwik。
拿静态网页做博客是没有任何问题的,而且也是我所推荐的(打脸,现在其实已经转用 WordPress 了)。它方便且简单,也没有什么硬伤。
]]>https://
开头,就代表是使用了这个协议。 苹果最新发布的移动端操作系统 iOS 9,除了带来了许多新的功能之外,还提升了整个系统安全性,正如iOS 开发者资源所说If you’re developing a new app, you should use HTTPS exclusively. If you have an existing app, you should use HTTPS as much as you can right now, and create a plan for migrating the rest of your app as soon as possible. In addition, your communication through higher-level APIs needs to be encrypted using TLS version 1.2 with forward secrecy. If you try to make a connection that doesn’t follow this requirement, an error is thrown. 如果你正在开发一个新的程序,你仅应该使用 HTTPS。如果你已经有一个程序,你现在就应该尽可能多的使用 HTTPS,并准备好对剩下部分迁移的计划。另外,如果你的程序使用更高层级的 API 进行通信,则需要使用 TLS 1.2 或以上的版本。如果你试图建立一个不遵守这些需求的通信,就会引发错误。
没错,从 iOS 9 开始,将逐步禁用非 HTTPS 请求! 即使现在已有的程序在 iOS 9 中仍可以在非 HTTPS 情况下工作。但是相信在不久的将来,所有程序都会使用 HTTPS,而且 HTTP 将会完全淘汰。 那么为什么要使用 HTTPS?那些情况下要使用HTTPS呢?
HTTPS 能够加密数据传输,防止中间人截取或是修改。能够实现加密用户信息和网站内容。 比如使用大众所说的 “不安全的免费 Wi-Fi”,如果用户访问的网页全部是 HTTPS 的,那么这个 Wi-Fi 对用户没有任何影响。也就是说,媒体报道的 “免费 Wi-Fi 不安全” 纯属造谣,没有任何道理。当启用了 HTTPS 和 HSTS 后,免费 Wi-Fi 完全不能截获到用户密码等任何信息,用户可以安心的进行付款等操作。显然央视 315 没有任何专业知识及解释就在骗大家 “免费 Wi-Fi 不安全”,完全就是恐吓观众。之所以微信朋友圈所有照片都能被获取,是因为微信朋友圈的上传是明文的,这分明是微信自己的问题,显然并不是所有的软件都存在这样的问题。随着 iOS 9 的发布以及强制 HTTPS 措施,这一类问题将不复存在了。 其次,使用 HTTPS 不仅仅是为了防止信息被盗窃,还可以防止信息被中途修改。比如中国联通和中国移动会修改网站内容,投放自己的广告让用户升级产品,而这些广告并不是网站主准备的,网站主事先也不知道。虽然它们这样做就是没有行业道德底线,但是我们仅需要使用 HTTPS,这些运营商就统统无能为力了。 包括小米路由器的 “404错误页面优化” 也是利用了同样的原理,对非 HTTPS 页面进行篡改,给用户提供自己的广告从而谋取利益。其本身就是劫持,绝没有夸大之言。除此之外,有的用户还发现就算是正常页面,也有小米通过劫持网页代码注入而加入的广告信息。但当 HTTPS 普及之后,这一切都会无影无踪。然而在 HTTPS 普及之前,一些不支持 HTTPS 的网站主只能忍受被运营商、路由器的劫持了。
我认为,所有的网页以及程序都有必要全部且强制的使用 HTTPS,可以避免上述情况的发生。包括个人网站在内,也应该全面启用 HTTPS,防止因为被篡改植入的广告而流失读者。 使用 HTTPS 并不会增加太多的成本,还可以让页面速度变得更快。SPDY 协议可以最小化网络延迟,提升网络速度,优化用户的网络使用体验,然而 SPDY 协议只支持 HTTPS。 随着现在的趋势,越来越多的站长会主动或被迫的使用 HTTPS,HTTPS 即将成为主流。中国是 HTTPS 普及程度最小的国家,但是随着百度全站 HTTPS 以及 UPYUN 支持自定义域名的 HTTPS,将推动整个行业 HTTPS 的发展。
如果一个网页没有使用 HTTPS,那么就意味着页面上的内容,你正在搜索的关键词,甚至是用户名和密码都没有加密,“中间人”可以进行读取、篡改这些没有加密的内容。比如说你连接的免费 Wi-Fi、运营商等都可能会对网页内容进行修改。这些中间人会在你未经允许的情况下在网页上添加他们的广告、修改 404 页面样式、读取你微信朋友圈的图片。 但当这个网页启用了 HTTPS 之后,页面的数据就会被加密,正常情况下中间人就不能获取到你的数据,但是如果中间人替换掉了原有的 HTTPS 后,攻击依然是可能的,所以 HTTPS 站点必须包含一个证书用于验证。
由于 HTTPS 站点必须包含一个证书用于验证,那么就可以验证这个服务器是否被域名所有者许可(以防止连接到中间人的服务器)。通常浏览器都会检验这个证书,如果证书错误会警告用户正在访问的网站有问题。假如用户的 DNS 服务被污染,那么就可能伪造身份,到另一个主机(IP 地址),这个甚至比中间人攻击更可怕,能做到更多的事。当用户使用 HTTPS 访问时,浏览器会验证这个网站的证书,如果证书报错则会警告,甚至无法访问。 但是假如用户访问的时候使用的是 HTTP,那么就不会对服务器进行验证。只有网站进行强制 HTTPS (也就是禁用 HTTP 链接)并启用了 HSTS,那么才能够进行全面的认证。一旦启用 HSTS,那么这个域名的所有页面在设定的有效期内就只能通过 HTTPS 访问。
对于站点下所有资源都使用 HTTPS 协议的页面,很多浏览器都会有加密提示,以告知用户这个站点是加密的,让整个网站更高大上。不过我想在此提醒用户,并不是所有使用 HTTPS 的页面就是安全的,任何网站都能轻易申请到 SSL 证书,所以仍然需要辨别域名本身。但是对于直接显示其公司名称的 HTTPS 站点就更值得被信任,因为这种证书是需要纸质证明材料的验证的。下方为使用 Mac 版 Chrome 访问一些 HTTPS 站点的加密提示,Chrome 的加密提示菜单中分为两部分,前一部分验证,后一部分是加密,通常可以分为以下 4 种:
其中第一种和第二种情况代表使用了足够安全的加密方式(但是第二种没有提供任何 Certificate Transparency 信息),只是证书的签名等级不同,与加密方式以及验证的安全性无关,这两种情况下都能保证证书不是伪造的。
第三种情况是包含不安全资源,网站的外观可能会被改变,但 HTML 文本本身是可靠的。
第四种情况是使用了 SHA-1 签名的证书,由于 SHA-1 不是足够的安全,也就是说验证的安全性不够,由于这种证书伪造的成本越来越低,所以可能不安全。这种站点的加密仍然是足够的。
第五种情况代表当前可能正在被中间人攻击(因为没有提供任何 Certificate Transparency 信息,而且还使用了 SHA-1)。
第六种情况表示这个网站使用不被信任的根证书签发的证书(或者证书中不包含当前域名)。 关于 Chrome 的加密提示 无论如何,我都不推荐你使用 SHA-1 签名的证书,值得注意的是最新版 Safari 也可以选择不信任 SHA-1 签名的证书了,SHA-1 即将淘汰。
Google 对 HTTPS 站点的抓取很友好,官方说使用 HTTPS 还会提高排名。Google 也支持使用 SNI 协议的 HTTPS 站点。 百度近期支持了对 HTTPS 站点的抓取,并会相应提高排名,经测试并不是所有证书都支持,但是也支持 SNI 协议。
不得不说使用 HTTPS 的确会增大延迟,这种延迟主要体现在加载首个页面,进入下一个页面就会快很多了。在我这里测试启用 HTTPS 后会多出 2~5 倍的延迟。如果还有资源在别的域,那么这些资源也会多出这么多的延迟。
SNI 协议已经被大量的使用,但是仍然有一些设备是不兼容的,比如 Windows XP 的 IE8 及以前的浏览器都不兼容。截止到目前,中国支持 SNI 的浏览器使用率已经达到了 95%。
有些搜索引擎对 HTTPS 很好,但是也有一些搜索引擎不支持它。不过目前越来越多的搜索引擎都在逐步支持 HTTPS,我觉得不必担心。
使用 HTTPS 必须需要得到一个证书。现在已经有越来越多的免费 SSL 证书了,总体来说实现 HTTPS 的成本越来越低了。但是随着证书颁发的成本越来越低,HTTPS 作为验证的功能将会变的更小,但是作为加密的功能还是存在的。
HTTPS 只能在一定程度上防止篡改,但是并不能抵制一些强大的网络封锁。 目前一些“流氓”浏览器竟然不验证证书,大大减弱安全性。如果不验证证书,虽然还有加密的效果,但是如果 DNS 被污染,中间人攻击依然可行。 如果 DNS 被污染,但仍需要使用 HTTPS,那么就将无法访问站点。所以 DNS 也是十分需要加密的。如果能早日支持 DNSSEC 或者是 “HTTPS DNS”(即使用 HTTPS 协议解析 DNS),那么 HTTPS 作为验证则显得不那么重要,完全没有中间人攻击的日子指日可待(但是没有网络封锁还是不可能的)。 或许以后的浏览器只能访问 HTTPS 站点,就像 iOS 9 大力推动 HTTPS 一样,这样就能大大提高安全性,抵制中间人攻击。
下方为在 Apache 里的 .htaccess
中配置
RewriteEngine onRewriteCond %{HTTP:X-Forwarded-Proto} =httpRewriteRule ^ https://%{HTTP\_HOST}%{REQUEST\_URI} \[L,R=301\] # 禁用 HTTP 协议
HSTS(HTTP Strict Transport Security, HTTP 严格传输安全)是一种让浏览器强制 HTTPS 的方法,当用户访问 HTTPS 站点时,由服务器返回一个 Header,告知浏览器在这个域名下必须强制 HTTPS,在有效期内,浏览器访问此域名将只使用 HTTPS,下方为在 Apache 里的 .htaccess
中配置。
Header set Strict-Transport-Security "max-age=315360000; preload; includeSubDomains" env=HTTPS
比如首次访问 http://tlo.xyz
时,浏览器会被 301 跳转到 https://tlo.xyz
下,然后就会收到这个 Header,在 10 年内,tlo.xyz 下所有的域名都只会使用 HTTPS,包括二级域名 ze3kr.tlo.xyz
。 但这一切还没有结束,假如浏览器第一次访问时,网站就已经被 HTTPS 劫持攻击了,那么这样做是毫无意义的,所以需要在启动 HSTS 后,包含 preload
参数,然后去提交,注意好要求。 当你提交了之后,一段时间后就能在各大浏览器的源码里看到你的域名了。
前往 SSL Server Test,就能给你的服务器的 SSL 配置给出一个评分。 哎,这差距
Activité Pop 可以自动的检测走路、跑步、游泳以及睡眠。你根本不需要去进行任何设置,他就能正确的识别出当前的运动类型,包括睡眠记录也是如此。 它可以记录运动时长、步行/跑步距离、运动中消耗的卡路里,还有睡眠总时长、醒来的次数、深睡眠时长、浅睡眠时长。这一切都是自动的。
Activité Pop 有震动闹钟功能,不仅如此,它还拥有智能唤醒功能,当即将到已经设定的时间,并且它检测到你已经醒来后或者进入浅睡眠时就提前唤醒你。
续航时间长达 8 个月,使用标准纽扣电池。
4K 屏幕通常是指分辨率为 1080p 的 4 倍(即宽和高分别是两倍)的显示器。论 4K 屏幕和 1080p 清晰度的差别,就相当于 iPhone 4 与其上一代的差别,用过的人都知道,iPhone 4 的 Retina 屏幕与非 Retina 屏幕差距十分明显。特别是在显示文字是变得更加清晰、锐利。然而由于显示器要比手机大很多,如果大于 19 英寸的显示器也要做到 Retina 的效果,那就需要 4K 的超高分辨率。
经过实际使用,4K 的屏幕果然没有让我失望,特别是文字和图片的展现十分出色。
这算是一款中端的 4K 显示器,作图、处理照片等均能胜任。16:9 的宽屏幕、60 Hz 的刷新率以及最低 6 ms 延迟,使其也适合当做游戏屏幕,功能十分广泛。
如果在这个显示器上使用 HDMI 接口,最高只能到 3840 x 2160 @ 30 Hz,只有拥有 DisplayPort 接口的电脑,才有可能支持 3840 x 2160 @ 60 Hz。随设备会附赠一条 MiniDP 到 DisplayPort 的线。 Mac 下所有系列的最新款都能够支持 3840 x 2160 @ 30 Hz,配备 Retina 屏幕的 MacBook Pro 的最新机型、Mac Pro 和 5K iMac 都能支持 3840 x 2160 @ 60 Hz(需要启用此款显示器的 MST 功能)。 为了达到 Retina 效果,需要放大显示。Mac 下支持的很好,几乎所有第三方 App 都能支持 Retina。PC 上 Windows 8.1 及更新的版本也支持放大显示,可惜并不是很多第三方 App 支持 Retina,对于这些 App 则会有锯齿效果,显得不那么清晰。 特别是如果你正在使用视网膜的 Mac,那么这个显示器若作为扩展屏幕则不会让你感到与原本显示器的太大差距。但假如你使用视网膜的 Mac,但却配的是 1080p 的屏幕,那么你会明显感觉到在 1080p 的屏幕上文字十分模糊。
这个显示器能够当作 USB Hub 使用,具体使用方法是将电脑上的一个 USB 输出口连到显示器上,显示器上有 4 个 USB 3.0 的输出口连接任何基于 USB 设备,于是电脑就能与这些设备建立连接。如:硬盘、手机、鼠标、键盘、网卡等等,就相当于直接连到电脑上,可以省一个 USB Hub。随设备会附赠一个 USB 3.0 - Type A 到显示器上的 USB 输入的线。本人的 Mac 在实际使用中没有遇到任何问题,也不用安装任何驱动程序。 当然显示器上的口也能给任何 USB 设备充电,更神奇的是——当电脑处于关闭状态或者显示器没有连接电脑的 USB 口,且显示器开启或处于待机状态时,显示器上的 4 个 USB 口依然能够给设备充电。(默认当显示器待机时不给设备供电,可在设置里启用这个功能)
参数名称 | 对应值 |
---|---|
屏幕对角线尺寸 | 60.47 cm (23.80”) |
宽高比 | 宽屏幕 (16:9) |
面板种类 | IPS |
最佳分辨率 | 3840 x 2160 @ 60 Hz |
亮度 | 最高 300 cd/㎡ |
响应时间 | 最低 6 ms |
颜色 | 10.7 亿色 |
我认为 24 英寸附近的 4K 屏幕的像素密度是基本接近于配备 Retina 屏幕的 Mac 的,相比之下我更推荐 24 英寸的 4K 显示器。而 27 英寸就需要 5K 或更高了。而目前能够传输 5K 分辨率的接口很少,所以 24 英寸 4K 是最合适的选择。
但是,它们官方并没有明确的提出如何不让好搜给网站重新排版,说白了就是 “绑架” 站长,我好搜就给你的网站重新排版,就做无视著作权的事情,钻大陆法律空子。
首先能做的事情就是屏蔽它,我特意看了它们的文档 然后我发现了啥?好搜竟然不支持使用 robots.txt
文件协议单独屏蔽它,好搜跪着求我:“不要屏蔽我,我还想那你的内容赚钱,你要非要屏蔽就把所有的都屏蔽了吧!” 当然,我是不怕这些的,我直接屏蔽你的 User Agent 不就好了。于是我在 .htaccess
文件下加入了如下内容:
RewriteEngine onSetEnvIfNoCase User-Agent "360Spider" bad_bot # 屏蔽垃圾搜索引擎SetEnvIfNoCase User-Agent "HaoSouSpider" bad_bot # 屏蔽垃圾搜索引擎SetEnvIfNoCase User-Agent "360Spider-Image" bad_bot # 屏蔽垃圾搜索引擎SetEnvIfNoCase User-Agent "360Spider-Video" bad_bot # 屏蔽垃圾搜索引擎Deny from env=bad_bot
然后我竟然发现了就算这样也依然没有效果!看来好搜为了不想让别的网站屏蔽可是下了功夫啊,没关系,我还有方法。
嗯,很成功,图片加载不了了,但是并没有完全屏蔽它。
于是,我发现好搜并不支持抓取 HTTPS 站点,那好,我强制 HTTPS。好搜终于怂了。
]]>此处指的确定宽度照片,是指样式属性宽度设置为一个确定了多少 px 的照片。 随着越来越多的高设备像素比(指 device pixel ratio,下同)显示器出现,网站需要更高像素的照片来适配这些显示器。 比如有一张照片显示宽度为 200px,它在@1x(即设备像素比为 1 的显示器,下同) 的显示器上,是占了 200 个物理像素(即实际所占的像素,下同);它在 @2x 的显示器上,实际上是占了 400 个物理像素;在 @3x 的显示器上,实际上是占了 600 个物理像素;同样的,在 @4x 的显示器上就是占了 800 个物理像素。 如果这个照片只提供 200 像素的版本,那么在 @2x~@4x 的显示器上看起来就很模糊。如果只提供 800 像素的版本,那么在 @1x~@3x 的设备上会加载不必要的内容,也就意味着更长的不必要时间(尤其是在手机上)。 此时,就需要使用响应式图片这个方法,最简单高效的方式是使用 srcset 来解决。比如现在提供了 4 个宽度分别为 200、400、600、800 像素的照片,通过 srcset 属性,能够实现在 @1x~@4x 设备像素比的显示器上分别显示这 4 张照片,这样在每个显示器上都能显示最适合它的照片。这四张图片的文件名分别为 200px.png, 400px.png, 600px.png, 800px.png。 总结一下,就是确定宽度的照片所占物理的像素只与设备像素比有关,所以只需要 srcset 属性的 x 标识符。
<img src="200px.png" srcset="400px.png 2x, 600px.png 3x, 800px.png 4x">
这样加上 srcset 属性,浏览器就会根据自己的设备像素比来加载不同的照片,不支持 srcset 属性的浏览器就默认加载 200px.png 这张照片。这个方法是向下兼容的。
此处指的不确定宽度的照片,是指样式属性宽度设置为一个确定了多少百分比的照片。 如果是不确定宽度的照片的话(或者是手机上不确定图片宽度,电脑上确定宽度等),也可以通过 srcset 解决。由于像素是不能确定的,所以很难达到照片本身和照片所占物理像素是一样的,因为用户的窗口大小是不确定的。 如果只准备 5 张照片,宽度分别是 400~3200 像素,文件名是400px.png, 800px.png, 1600px, 2400px, 3200px。通常,如果没有对应图像所占的物理像素的照片的话,则会加载比所占的物理像素稍大一些的图片。例如照片占屏幕的 500 个物理像素,那么就应该选择加载 800px.png。这样加载稍大的照片仍然可以达到最佳的显示效果,同时最大限度的节省网络资源。 总结一下,就是不确定宽度的照片所占物理的像素与设备像素比和所占宽度有关,然而使用了 srcset 属性的 w 标识符后,你只需要指定宽度,浏览器会自动根据设备像素比来选择最优图片。 如果这个图片占整个窗口的 100% 大小(即 100vw 宽,下同),那么只需要这样设置 srcset 就能达到效果。 抛开设备像素比的概念吧,这个全新的 srcset 属性的 w 标识符能够让浏览器自己适应所要加载的照片。
<img src="800px.png" srcset="400px.png 400w, 800px.png 800w, 1600px.png 1600w, 2400px.png 2400w, 3200px.png 3200w" alt="" />
不过此时还有一个小问题,浏览器比较笨,它会认为图片宽度始终是整个窗口的 100% 宽,如果图片不是占整个窗口的 100%,两边留有边框怎么办呢?此时就需要使用 size 属性。 sizes 属性里制定图片的宽度,不能使用百分比单位,但可以使用 vw、px 等单位(100vw 就是整个窗口的宽度),也可以使用 calc 运算,同时支持媒体查询。要保证使用 sizes 里计算出来的宽度始终是图片所占屏幕宽度,剩下的事情都只需要浏览器完成了。 以下几种典型案例示范:
如果图片两侧边框(指图片边缘到窗口边缘长度)始终是占屏幕的一定的百分比时,那么图片总会有一个相对于整个窗口的百分比。比如图片两侧边框始终是整个窗口的 10%,那么 size 属性就可以如下设置:
sizes="80vw"
如果图片已经在一个宽度是整个窗口的 70% 的元素下,而且元素内图片两侧还留有 10% 的边框,那么 size 属性就可以如下设置:
sizes="50vw"
比如图片两侧边框始终是 10px,那么 size 属性就可以如下设置:
sizes="calc( 100vw - 10px )"
如果图片已经在一个宽度是整个窗口的 70% 的元素下,而且元素内图片两侧边框始终是 10p,那么 size 属性就可以如下设置:
sizes="calc( 70vw - 10px )"
比如图片两侧边框始终是 10px,但是图片最大只能是 1000px,那么 size 属性就可以如下设置:
sizes="(min-width: 1020px) 1000px, calc( 100vw - 10px )"
其中 (min-width: 1020px) 1000px
代表当屏幕像素宽度大于 1020px 时,图片宽度为 1000px。
此处以我的网站为例,我的网站图片边框适中是 1.875rem,这个图片本身就是在一个元素下,这个元素默认宽度是整个窗口的 100%,但在屏幕宽度大于 40.063rem 的情况下,这个元素占整个窗口的 50%,并且这个元素有最大尺寸 500px,现在把 size 属性和用 w 标识符的 srcset 属性放在一起,就完美解决了。
<img src="800px.png" sizes="(min-width: 1000px) calc( 500px - 1.875rem ), (min-width: 40.063rem) calc( 50vw - 1.875rem ), calc( 100vw - 1.875rem )" srcset="400px.png 400w, 800px.png 800w, 1600px.png 1600w, 2400px.png 2400w, 3200px.png 3200w" alt="" />
然后你就可以在浏览器中测试了,达到了适配所有屏幕尺寸,所有设备像素比的效果。
通常情况下,srcset 属性的 x 标识符支持的比 w 标识符更好,因为 w 标识符是一个新的属性。不过好消息是 Chrome 38+、Firefox 38+、Safari 9+、Opera 30+、Android 5.0+、iOS 9+(没错,IE/Edge、Windows Phone 截止到写文章之日都不支持) 都纷纷支持了 w 标识符,所以我认为现在很适合换用 srcset 属性的 w 标识符来做响应式图片了。而且这个方法是完美向下兼容的,即使不支持也没关系。 你也可以在 CanIUse.com 上查询关于 secset 属性的完整的兼容性列表
]]>兼容绝大多数能安装 SD 卡的相机 比如佳能 5D Mark III、7D Mark II 等机型都不带 Wi-Fi 功能,但是都是 CF/SD 双卡槽,可以将照片同时存进两张卡中。考虑到 Eyefi Mobi 卡的速度以及容量不及 CF 卡。所以我设置在 Eyefi Mobi 卡中存储 JPEG 格式,在 CF 卡中存储 RAW 格式,JPEG 格式更适合手机分享到社交网络,RAW 格式适合后期编辑,十分方便。我在佳能相机中每拍下一张照片都会同时存储 JPEG 和 RAW 格式的照片至两张卡(相机中设置为“同时记录”即可),即使是使用 7D Mark II 的每秒十张连拍也没有丝毫问题,可见这张卡在专业相机上当作副卡是表现不错的,可以快速从手机分享刚刚拍摄的照片。 除此之外,Eyefi Mobi 卡还适合仅有 SD 卡的入门级机型,这些相机没有很快的连拍,这张卡能达到日常需要,也很适合喜欢分享照片的入门级用户。
兼容 Eyefi 联动功能的相机可以直接配置 Eyefi 卡的设置,同时还能够保证相机关闭后还能够继续传输文件,通过相机的显示屏显示传送进度,或在机器的菜单中直接看到Eyefi的运行情况。 以佳能相机为例,在安装了 Eyefi 卡后,相机设置中就会有一个新菜单选项:
Eyefi Mobi 卡首次使用时,只需要在手机上下载一个软件,在软件中输入这张卡的 ID,待配置完成后,将此卡装入相机中照一张照片,你就会发现手机上立刻就出现了这张照片,使用十分方便。在相机中可以查看此卡的传输状态,以及进度。通常这张卡仅在有新照片的时候无线功能才工作,当图片全部传输完成后,无线功能自动关闭,相机续航能力几乎没有什么变化。
域名通常对应着一个 IP 地址,浏览器只有在知道了这个 IP 地址后才能与服务器通讯。为了解析域名,客户端会向 DNS 解析服务器发送一个关于这个域名的请求,就能查询到这个域名的 IP 地址。DNS 解析是存在 “TTL 生存时间” 的,也就是缓存时间,这个内容会被缓存在 DNS 解析服务器上、路由器和客户端上,按照缓存时间存储。DNS 解析服务器通常会由运营商提供,如果存在缓存,那么解析速度则是相当快的。(目前的 DNS 解析是以十分不安全的明文的方式传输的,任何中间人都能破坏或者是修改解析结果)
有了 IP 地址之后,浏览器会与服务器建立 TCP 链接,然后发出一个请求。请求中会包含需要访问网站的域名(得以使 IP 可以给多个域名提供不同内容)、请求方式、网址路径、所能接受的数据,压缩类型和编码方式、 Cookie 以及浏览器信息(能够判断你是否在手机上访问网站)。
浏览器开始下载页面本身,下载页面本身后又会开始下载页面中依赖的其他内容,包括 CSS 、JavaScript 、图片等。随着优先级不同,它们可能是在渲染之前或者之后下载。
浏览器会等待加载了最重要的依赖内容(也就是在 head
部分中的 CSS 和 JavaScript,之后会重点提到)加载完毕后,进行渲染。因为渲染时要依赖这些内容, CSS 也就是我们常说的样式表,这些样式表十分重要,比如百度这个网页:
没有 CSS 样式表后,整个网页的布局是 “失控” 的,页面不会以预期的方式被加载,这种体验十分糟糕。没有样式表与有样式表的网页通常是两种完全不同的样子。然而 JavaScript 通常与布局无关,可以放在之后加载,不影响页面样式。
网页中的每一个内容都要经历这样的过程,以被客户端得到。只有到了渲染页面这一步时,用户才能够看到页面的内容,在此之前,页面是一片空白。要知道如果一个页面在 3 秒之内都是一片空白,那么多半用户会退出。 移动优先会考虑高延迟移动网络下的用户体验,然而当到了桌面端则也能享受到移动有限带来的速度提升。为了提升速度,有以下几种常用方法:
如果 JavaScript 放在末尾,可以在页面被渲染后再加载,大大减少了页面空白的时间。这是最简单,且提升效果最明显的一条。
使用 CDN 的意思是尽可能把静态文件放在 CDN 服务器上,一个 CDN 包含很多个节点,用户下载 CDN 上的文件时会从物理位置最近或者是相同运营商的节点上下载,如果这个节点上已经有缓存则直接传给用户,如果没有缓存则从最近的数据中心下载并缓存,再传给用户。 我的做法是把网站上所有图片、视频、CSS 样式表和 JavaScript 放在 CDN 上,网站本身不在 CDN 上。这样做能大大减少加载时间,而且成本不大。无论是个人博客还是行业网站,使用 CDN 都很有必要。如果没有钱买自己的 CDN,没关系,你可以免费使用常用开源 CSS 和 JavaScript 的 CDN,官网地址地址:cdnjs.com。
将图片、CSS 样式表和 JavaScript 设置缓存。我习惯于设置相当长的时间(一周、一年等),有的人为了能够经常修改而把缓存期限调小。我在修改文件时会直接换文件目录,这样文件从能保持是最新的。利用好缓存,可以让用户在第二次访问时大大加速。
对于网站速度,既要注重首次启动速度,还要利用缓存提升下一次访问速度。而且应该注意在提升速度的同时也要注重用户体验。
]]>当你激活 Mac 的显示器后,你的手机会收到一条通知,向右滑动点击 “解锁” 然后按下指纹,你的电脑就已经被无线解锁了。除此之外,你还可以在手机上无线让电脑锁定,或者是播放歌曲等等,十分方便。 另外 MacID 的电脑客户端甚至可以通过声音检测你是否离开,然后自动锁定。如果你的电脑有 Muti-Touch 触控板的话,你还可以设定特定的手势来解锁 Mac,为了安全性,你可以设定仅当手机连接电脑后才可以使用手势解锁。 而且 MacID 不仅可以让你方便的解锁电脑,而且可以在手机和电脑上双向互相传送剪贴板的内容。对于经常同时使用两个设备的人来说,这个功能十分贴心。
MacID 还支持今日视图中的插件,更是可以随时随地解锁 Mac,方便至极。
一个手机可以无线控制很多台 Mac 解锁等功能,列表简洁美观。
你还可以使用 Apple Watch 无线控制 Mac 哦。
]]>这个软件内置自己的 HDR,完全不同于系统的 HDR 功能,它的 HDR 堪比在 PhotoShop 上合成后的效果,十分出彩。并且有多种 HDR 格式可供选择,而且可以进行手动 HDR,自己调整 HDR 的亮度,满足所有需求。(HDR 功能需要单独购买)
它支持手动对焦、手动曝光。不仅如此,它还可以调整快门速度、ISO 感光度、白平衡等等,均能实时显示,满足绝大多数照片需要。它的快门速度最高可以设置到 0.5 秒,可以轻松应对夜景(通常,系统的相机是自动曝光,然而它不会照出 0.5 秒长时间快门速度,所以噪点通常很多)。 除此之外,它还可以调整图像格式,它支持保存 JPEG 格式 (可调质量)、无压缩 TIFF 和无损压缩的 TIFF,得到无损的照片。 它可以实时手动调节画面的色温,达到最完美的白平衡。
通常情况下,系统的相机从来不提供长曝光,因为长曝光会因为手抖导致画面模糊。然而 ProCamera 可以允许 0.5~1 秒的曝光时间,如果有正确的持握方式,画面并不会模糊。长时间曝光可以让画面更明亮,或者同样亮度下有更少的噪点,大大提升夜景的画质。
此软件有丰富的后期处理的功能,甚至可以调节曝光曲线等参数,操作十分简便。
除此之外,它还有众多滤镜,甚至还能调节每一种滤镜的参数,十分强大。
这个软件有强大的定时器功能,非常适合高级的自拍或者间隔拍摄。通过后期制作,能够达到 800 万像素的间隔拍摄视频。此功能类似单反上的定时器,十分有用。你甚至不需要为了定时器去购买别的软件了。
购买此软件后,可以在 Apple Watch 上遥控 ProCamera 进行照相,同时还可以浏览已经拍摄的照片,充分利用 Apple Watch。如你已经拥有一个 Apple Watch,并正在寻找一个可以用 Apple Watch 遥控照相的第三方软件,那么这款软件正是你要找的。
虽说这个软件功能十分繁多,但是在使用时你丝毫不会觉得这个软件过于“沉重”,它的界面是十分简洁友好的,同时适合专业与非专业用户使用。这一款软件就可以完成全部的图片创作了。
我这里的截图可能提供的是英文版截图,但实际上这款软件是完全支持中文的,可放心购买。
]]>不过,直到 iPhone 的发布,这一切都得到了很大的改变。因为 iPhone 上的浏览器 —— Safari 是一个真正的且非常前沿的 Web 浏览器,而且它还支持 HTML5 标准。它配备有几乎和电脑一样的浏览器 —— 以至于它支持 CSS3 和 JavaScript。但是这一切,却是在一个宽度仅有 320 个像素的设备上显示。 然而当一个桌面浏览器宽度缩小到 320 个像素时,它就变的大不一样,当他访问一个没有对它优化的网页时,它就会将其缩放(宽度将缩放至 1/3),以百度新闻为例,若没有适配,则将现实电脑版网站,这样页面的字会很小,但是用户可以通过缩放就能够解决,所以并没有什么问题。然而,百度新闻做了一个专门为 iPhone 的版本,像这样:
它能够更好的适应触摸屏,并且没有了字体小的问题,也不需要缩放。但是请要注意,这个页面已经不是刚才的那个页面了,也就意味着百度需要专门重新设计一个为 iPhone 版本的网页,成本是很高的。 然而在 CSS 的帮助下,不需要准备两个网页就可以同时适配电脑和手机,它们加载到的页面相同,但是应用的样式表并不同。例如没有针对移动而优化的 Wikipedia 导航页,iPhone 上的 Safari 访问时将会缩放显示,布局就如同电脑访问一样:
然而通过增加的 CSS 样式表(当然还包括 head
中的 viewport
),这个页面在手机上就会完美的显示了,就像下图:
像 Wikipedia 导航页这样先根据电脑布局设计,再新增 CSS 使其支持移动设备的网页,就是桌面优先而不是移动优先。而移动优先则正好相反,页面根据手机而设计,然后再让它适配电脑,电脑与手机也是访问同一个页面,这就属于移动优先。由于移动优先的网站是根据手机设计,自 iPhone 发布之后,很多智能手机也使用了前沿的浏览器,所以移动优先的网站自然会使用 HTML5、CSS3 中的众多新特性,大大缩短了一个网页所需要的开发时间。而且移动优先的网站根据手机的高延迟网络而设计,减少了页面大小,无论身处什么网络环境,加载速度都有很大的提升。移动优先的优点众多,这就是导致其流行起来的原因。
]]>