Category Archives: Blog

Main blog category, I’m too lazy to manage multiple categories so this blog has only one category.

Install Zerotier One on UniFi Cloud Key

Run the following commands on your UniFi Cloud Key:

curl -s | bash


*** ZeroTier One Quick Install for Unix-like Systems

*** Tested distributions and architectures:
***   MacOS (10.7+) on x86_64 (just installs ZeroTier One.pkg)
***   Debian (7+) on x86_64, x86, arm, and arm64
***   RedHat/CentOS (6+) on x86_64 and x86
***   Fedora (16+) on x86_64 and x86
***   SuSE (12+) on x86_64 and x86
***   Mint (18+) on x86_64, x86, arm, and arm64

*** Please report problems to [email protected] and we will try to fix.

*** Detecting Linux Distribution

*** Found Debian "jessie" (or similar), creating /etc/apt/sources.list.d/zerotier.list

*** Installing zerotier-one package...
Hit jessie InRelease                                                                                                  
Hit jessie/main armhf Packages                                                                                                                                              
Get:1 jessie InRelease [20.9 kB]                                              
Ign jessie InRelease                                                                                
Get:2 jessie/updates InRelease [44.9 kB]                                                   
Hit cloudkey-stable InRelease                                           
Hit cloudkey-stable/ubiquiti armhf Packages                                                     
Hit jessie Release.gpg                                   
Get:3 jessie/main armhf Packages [2479 B]
Hit jessie Release                                          
Hit jessie/main armhf Packages                                                                                                                                             
Hit jessie/contrib armhf Packages                                                                                                                                          
Hit jessie/non-free armhf Packages                                                                                                                                         
Get:4 jessie/updates/main armhf Packages [695 kB]                                                                                                                           
Hit jessie/updates/contrib armhf Packages                                                                                                                                   
Hit jessie/updates/non-free armhf Packages                                                                                                                                  
Fetched 764 kB in 1s (764 KB/s)                                                                                                                                                                  
Reading package lists... Done
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following NEW packages will be installed:
0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
Need to get 763 kB of archives.
After this operation, 2366 kB of additional disk space will be used.
Get:1 jessie/main zerotier-one armhf 1.4.6 [763 kB]
Fetched 763 kB in 44s (17.3 kB/s)                                                                                                                                                                      
Selecting previously unselected package zerotier-one.
(Reading database ... 23329 files and directories currently installed.)
Preparing to unpack .../zerotier-one_1.4.6_armhf.deb ...
Unpacking zerotier-one (1.4.6) ...
Processing triggers for systemd (230-7~bpo8+2.ubnt+1) ...
Setting up zerotier-one (1.4.6) ...
Processing triggers for systemd (230-7~bpo8+2.ubnt+1) ...

*** Enabling and starting zerotier-one service...
Synchronizing state of zerotier-one.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable zerotier-one

*** Waiting for identity generation...

*** Success! You are ZeroTier address [ e50a7c7fc2 ].

Run zerotier-cli to see if everything works:

ZeroTier One version 1.4.6 build 0 (platform 1 arch 3)
Copyright (c) 2019 ZeroTier, Inc.
Licensed under the ZeroTier BSL 1.1 (see LICENSE.txt)
Usage: zerotier-cli [-switches] <command/path> [<args>]

Please note after upgrading the Cloud Key firmware, you need to reinstall the Zerotier One package. And if you got the following error when trying to reinstall the package:

*** Enabling and starting zerotier-one service...
Synchronizing state of zerotier-one.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable zerotier-one

*** Waiting for identity generation...

Press control – C and execute the following to restart the service and rejoin the Zerotier network:

systemctl restart zerotier-one
systemctl status zerotier-one
zerotier-cli info
200 info 8ade3af9ef 1.4.6 ONLINE
zerotier-cli join eda9f5dbfe94adbe
200 join OK
# ...then approve it in your Zerotier dashboard
# list network
zerotier-cli listnetworks -j

Fixing TXTRDATATooLong Errors for AWS Route 53

RFC 4408 3.1.3 says

     IN TXT "v=spf1 .... first" "second string..."
   MUST be treated as equivalent to
      IN TXT "v=spf1 .... firstsecond string..."
   SPF or TXT records containing multiple strings are useful in
   constructing records that would exceed the 255-byte maximum length of
   a string within a single TXT or SPF RR record.

so if you are getting error “TXTRDATATooLong” a solution for you will be splitting it into multiple strings within the same record set. For example, instead of:

"v=DKIM1; k=rsa; g=*; s=email; h=sha1; t=s; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDx2zIlneFcE2skbzXjq5GudbHNntCGNN9A2RZGC/trRpTXzT/+oymxCytrEsmrwtvKdbTnkkWOxSEUcwU2cffGeaMxgZpONCu+qf5prxZCTMZcHm9p2CwCgFx3

you can pick a split point where each part is less than 255 characters long and put [double quote][space][double quote] 

for example I tried:

"v=DKIM1; k=rsa; g=*; s=email; h=sha1; t=s; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDx2zIlneFcE2skbzXjq5GudbHNntCGNN9A2RZGC/trRpTXzT/+oymxCytrEsmrwtvKdbTnkkWOxSEUcwU2cffGeaMxgZpONCu+qf5prxZCT" "MZcHm9p2CwCgFx3reSF+ZmoaOvvgVL5TKTzYZK7jRktQxPdTvk3/yj71NQqBGatLQIDAQAB;"

and as a result I’ve got:

dig -t TXT long.xxxxxx.yyyy
long.xxxxxxx.yyyy. 300    IN      TXT     "v=DKIM1\; k=rsa\; g=*\; s=email\; h=sha1\; t=s\; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDx2zIlneFcE2skbzXjq5GudbHNntCGNN9A2RZGC/trRpTXzT/+oymxCytrEsmrwtvKdbTnkkWOxSEUcwU2cffGeaMxgZpONCu+qf5prxZCT" "MZcHm9p2CwCgFx3reSF+ZmoaOvvgVL5TKTzYZK7jRktQxPdTvk3/yj71NQqBGatLQIDAQAB\;"

Note that returned TXT contains [double quote][space][double quote] , however the RFC above mandates that string to be treated as the same as concatenated one.

Note that your example does the same too on 128 character boundary

dig TXT                                                                                                                                      /workspace/stepany-HaasControlAPI-development
;; Truncated, retrying in TCP mode.
; <<>> DiG 9.4.2 <<>> TXT
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61356
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 5, ADDITIONAL: 5
;    IN      TXT
;; ANSWER SECTION: 61881 IN    TXT     "k=rsa\; t=y\; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuoWufgbWw58MczUGbMv176RaxdZGOMkQmn8OOJ/HGoQ6dalSMWiLaj8IMcHC1cubJx2gz" "iAPQHVPtFYayyLA4ayJUSNk10/uqfByiU8qiPCE4JSFrpxflhMIKV4bt+g1uHw7wLzguCf4YAoR6XxUKRsAoHuoF7M+v6bMZ/X1G+viWHkBl4UfgJQ6O8F1ckKKoZ5K" "qUkJH5pDaqbgs+F3PpyiAUQfB6EEzOA1KMPRWJGpzgPtKoukDcQuKUw9GAul7kSIyEcizqrbaUKNLGAmz0elkqRnzIsVpz6jdT1/YV5Ri6YUOQ5sN5bqNzZ8TxoQlkb" "VRy6eKOjUnoSSTmSAhwIDAQAB\; n=A 2048 bit key\;"

Google Fi、Google Voice、Google Hangouts 使用技巧与细节

最近国内 Lycamobile 翻车,政策改动导致大量在国内漫游的 Lyca 号无信号,只能购买 ¥19/m 的套餐才可以,但部分人反应即便买了套餐依然无任何信号,因此只能上 Google Fi 的车,然而 Google Fi 在 iOS 上依然有些问题,加上 Google Voice、Google Hangouts 产品迭代更替的混乱,使用起来有许多坑,在这里记录一下


  • 港版 iPhone Xs Max,iOS 12.3.1
  • 主卡槽(正面卡槽)为 Google Fi 实体卡,已激活
  • 副卡槽(背面卡槽)为普通联通 4G 卡
  • 系统上已安装 Google Fi、Google Hangouts、Google Voice 这几个 apps
  • Surge 全局代理,美国 IP 地址

Google Fi

这个 app 做的总体还不错,但有几点需要注意:

  • 不要过于指望 Google Fi 中的 voicemail,因为根据使用观察 Google Fi 中的 voicemail 时效性非常差,延迟大概在 15 分钟之久,也就是说在对方给你留言完毕并挂断电话之后,你的 Google Fi app 不会马上出现对方的 voicemail,这就很坑爹了,在有紧急电话的时候会漏掉不少重要电话。为什么我要强调这个时效性,后面的 Hangouts 部分有更多说明
  • Google Fi app 你哪怕开了「后台应用程序刷新」,也无法收到 voicemail 的推送通知,也许跟第一条有关,也许是我个别现象,目前我必须打开 Google Fi app,切换到 Voicemail 标签,稍等几秒后才能刷新出来的新的 voicemail

Google Hangouts

这个 app 在一定程度上会对 Google Fi 用户造成迷惑,主要有以下几点:

  • 以下结论基于你默认开启 Hangouts 里的 Answer on lock screen 设置
  • 如果你开启了 Settings – Phone number – Incoming phone calls(该功能描述为:Ring Hangouts for incoming phone calls made to your Google Fi number.),那么在其他人打给你的 Fi 号码时,会优先显示 Hangouts 的接听界面,此时:
    • 如果你不接电话:
      • 在系统自带的电话 app 下,会出现两条未接,一条来自运营商本身,一条来自 Google Hangouts,标记为 Hangouts Audio
      • 如果你已经开启了 iOS 的 Continuity,即「在附近设备接听」功能,其他苹果设备上依然会收到运营商的来电提醒
      • 不论您是否开启 Incoming phone calls 选项,如果你同时开启了网页版的 Hangouts,网页版都会收到提示音
    • 如果你通过 Hangouts 的界面接听:
      • 可以提供更好的音质,起码优于目前运营商的音质
      • 在接听成功后的数秒内,你会看到系统电话界面闪一下,出现「挂断并接听/等待」的选项,然后数秒后又消失,应该是系统电话与 Hangouts 界面冲突所致
      • 接听完成后你会看到系统电话中 Hangouts Audio 的记录标记为已接听,运营商来电标记为未接听
    • 如果你通过运营商来电接听:
      • 如果你是苹果党,则可以方便的通过「在附近设备接听」功能在任意设备上接听
      • 接听完成后你会看到系统电话中 Hangouts Audio 的记录标记为未接听,运营商来电标记为已接听
    • 建议:对于电话送达率要求不高,或者 Fi 信号比较好的区域,不建议开启此选项,每次来电都出现两条记录还是比较烦的
  • 如果你开启了 Settings – Phone number – Messages(该功能描述为:Show SMS and voicemail in Hangouts Learn more),那么在别人:
    • 因你未接电话对方给你发 voicemail 时:
      • 不像我上面提到的 Google Fi app,voicemail 会在对方留言完毕挂掉电话后,几乎实时出现在 Hangouts 的聊天记录中
      • Voicemail 依然会同步到 Google Fi app 中
    • 给你 Fi 号码发送短信时:
      • 短信将直接出现在 Hangouts 中,包括网页版 Hangouts,多端同步
      • 短信将不再出现在系统自带的 Messages 中,导致 Continuity 功能(即 Text Message Forwarding)不可用,无法在 macOS 上接收短信,但你可以正常通过 iOS、macOS 自带的 Messages 给对方发短信
      • 如果对方是通过 Hangouts 给你发带图片的消息时,你同样可以在 Hangouts 中收到
    • 建议:如果是苹果全家桶的重度用户,此选项也不建议开启,开启此选项会丢掉不少便利性。但在关键时刻,比如信号不好但必须接一个重要的短信时,可以临时开启此选项

Google Voice

  • 当你激活了 Google Fi 后,iOS 上的 Google Voice 将不再可用,打开后会出现一行提示告诉你请去 Google Fi 上操作。但如果你打开电脑版的,在左下角依然可以进入老版本的 Google Voice 网页版
  • 但此时你可以选择切换账户,用另外一个有 Google Voice 号码但没开启 Google Fi 的 Google 账户继续使用 Google Voice app
  • 根据上面 Google Fi 部分的说明,如果 voicemail 对你很重要,建议用电脑打开旧版本的 Google Voice 页面,去 Settings – Voicemail & Text 下勾选 Alert me when I have new voicemails 的邮件通知,邮件通知基本是在对方留言完毕挂电话后实时推送的,此选项不像上面的 Hangouts 那样有副作用,因此有需求的人这个选项强烈建议开启



  • 当主卡(正面插槽)为联通,副卡(背面插槽)为 Google Fi 的情况下,双卡信号都非常差,在信号不强的区域经常会双双无信号
  • 因此在原手机号为联通的情况下,建议主卡 Google Fi,副卡联通,此时不管是用哪张卡当流量卡/通话卡,都可以获得「较好」的信号
  • 为什么是「较好」的信号呢?因为这代 iPhone 基带的问题,如果你只装单张卡,会获得「更好」的信号
  • 目前我只知道只有 Pixel 可以原生支持 Google Fi 的 Wi-Fi Calling,因此不介意用 Android 的情况下,可以考虑买个 Pixel 专门跑 Google Fi,也可以避免上面 Hangouts 各种诡异的问题,但代价是不能用 iOS 的 Continuity 特性了

Receive a User’s UPN, Email, First and Last Name via Azure Active Directory Custom Manifest

In May 2019 Microsoft has made the new and improved App Registration portal generally available. For some time this new portal has been available under the Azure Active Directory > App registration (preview) menu in the Azure Portal. The old App Registration is still available under Azure Active Directory > App registration (legacy) but most likely it will be discontinued soon.

The ID token does no longer by default contains fields such as user principal name (UPN), email, first and last name, most likely to ensure that personal data is handled with more consideration. As a result, you must manually update the app registration’s manifest to ensure that ID tokens include the UPN, email, first and last name by adding these optional claims.

  1. Go to Azure Portal > Azure Active Directory > App registrations
  2. Find your application registration (you may click on the All applications tab)
  3. Click Manifest
  4. Update the Manifest and change the optionalClaims node as shown below
"optionalClaims": {
	"idToken": [{
			"name": "family_name",
			"source": null,
			"essential": false,
			"additionalProperties": []
		}, {
			"name": "given_name",
			"source": null,
			"essential": false,
			"additionalProperties": []
		}, {
			"name": "upn",
			"source": null,
			"essential": false,
			"additionalProperties": []
		}, {
			"name": "email",
			"source": null,
			"essential": false,
			"additionalProperties": []
	"accessToken": [],
	"saml2Token": []

Ubiquiti UniFi Account/User Credentials Cheatsheet

If your brand-new network is set up by UniFi Network iOS app. and using existing Ubiquiti account [email protected] for sync (the option Enable Local Login with UBNT Account will be enabled automatically if you login your Ubiquiti account during the setup), there’s what you will get:

Router, Security Gateway aka. USG

  • Web login:
    • User: admin or custom defined
    • Password: Random-generated during your first setup via iOS app. You need to checked “Enable SSH authentication” in order to change your USG username and password at the time of writing (UI version: It can be found in UniFi Controller Web UI (under Settings – Site – Device Authentication, then click the eye-shaped icon to reveal the password)
  • SSH login:
    • User: admin or custom defined
    • Password: same as USG login credentials

Switch, aka. USW

  • SSH login:
    • User: admin
    • Password: same as USG login credentials

UniFi Cloud Key, aka. UCK

  • UniFi Controller Web UI:
  • UniFi Cloud Key Web UI:
  • SSH login:
    • User: root
    • Password: Your UniFi Cloud password