MySQL 在不同種類 EBS 上的效能

Percona 的人寫了一篇關於 MySQL 跑在 AWS 上不同種類 EBS 的效能差異:「Performance of Various EBS Storage Types in AWS」,不過這篇的描述部份不是很專業,重點是直接看測試資料建立自己的理解。

他的方法是在 AWS 上建立了相同參數的 gp2gp3io1io2 空間,都是 1TB 與 3000 IOPS,但他提到這應該會一樣:

So, all the volumes are 1TB with 3000 iops, so in theory, they are the same.

但這在「Amazon EBS volume types」文件上其實都有提過了,先不管 durability 的部份,光是與效能有關的規格就不一樣了。

在 gp2 的部份直接有提到只有保證 99% 的時間可以達到宣稱的效能:

AWS designs gp2 volumes to deliver their provisioned performance 99% of the time.

而 gp3 則是只用行銷宣稱「consistent baseline rate」,連 99% 都不保證:

These volumes deliver a consistent baseline rate of 3,000 IOPS and 125 MiB/s, included with the price of storage.

io* 的部份則是保證 99.9%:

Provisioned IOPS SSD volumes use a consistent IOPS rate, which you specify when you create the volume, and Amazon EBS delivers the provisioned performance 99.9 percent of the time.

另外在測試中 gp2gp3 的 throughput 看起來也沒調整成一樣的數字。在 1TB 的 gp2 中會給 250MB/sec 的速度,1TB 的 gp3 則是給 125MB/sec,除非你有加買 throughput。

另外從這句也可以看出來他對 AWS 不熟:

The tests were only run in a single availability zone (eu-west-1a).

在「AZ IDs for your AWS resources」這邊有提過不同帳號之間,同樣代碼的 AZ 不一定是一樣的區域,需要看 AZ ID:

For example, the Availability Zone us-east-1a for your AWS account might not have the same location as us-east-1a for another AWS account.

To identify the location of your resources relative to your accounts, you must use the AZ ID, which is a unique and consistent identifier for an Availability Zone. For example, use1-az1 is an AZ ID for the us-east-1 Region and it is the same location in every AWS account.

在考慮到只有設定大小與 IOPS 的情況下,剩下的測試結果其實跟預期的差不多:io2 貴但是可以得到最好的效能,io1 的品質會差一些,gp3 在大多數的情況下其實很夠用,但要注意預設的 throughput 沒有 gp2 高。

Kaspersky Password Manager 的漏洞

Hacker News Daily 上看到「Kaspersky Password Manager: All your passwords are belong to us」這篇,講 Kaspersky Password Manager (KPM) 嚴重的安全漏洞,另外在 Hacker News 上的討論「Kaspersky Password Manager: All your passwords are belong to us (ledger.com)」也有提到一些有趣的東西。

標題的 All your passwords are belong to us 是出自「All your base are belong to us」這個梗的變形。

這包安全問題主要的原因是因為 KPM 沒有使用 CSPRNG,而且也沒有正確 seed,所以極為容易被猜出密碼本身。

KPM 的 Web 版使用了 Math.random(),在各家瀏覽器主要是用 xorshift128+ 實做 Math.random(),作者沒有針對這塊再花時間研究,但很明顯的 Math.random() 不是個 CSPRNG:

The underlying PRNG used by Chrome, Firefox and Safari for Math.random() is xorshift128+. It is very fast, but not suitable to generate cryptographic material. The security consequences in KPM has not been studied, but we advised Kaspersky to replace it with window.crypto.getRandomValues(), as recommended by the Mozilla documentation page previously mentioned.

Note: Math.random() does not provide cryptographically secure random numbers. Do not use them for anything related to security. Use the Web Crypto API instead, and more precisely the window.crypto.getRandomValues() method.

而桌機版則是用了 MT19937,理論上取得 624 bytes 的輸出後就可以重建整個 PRNG 的內部狀態 (於是就可以預測後續的 output),但這代表你要知道其他網站的密碼,這點其實有點困難。

但作者發現 KPM 在產生 MT19937 的 seed 只跟時間有關,超級容易被預測:

So the seed used to generate every password is the current system time, in seconds. It means every instance of Kaspersky Password Manager in the world will generate the exact same password at a given second.

於是可以直接暴力解出所有的可能性:

The consequences are obviously bad: every password could be bruteforced. For example, there are 315619200 seconds between 2010 and 2021, so KPM could generate at most 315619200 passwords for a given charset. Bruteforcing them takes a few minutes.

Hacker News 上有不少陰謀論的討論,像是:

Getting some DUAL_EC prng vibes.

Insert Kaspersky owned by Russia intelligence conspiracy here...

另外 Kaspersky 跟俄羅斯軍方的關係也是很知名,這些東西大概要到十來年後才會知道...

Dan Kaminsky 過世

Hacker News 首頁上看到震驚的消息,Dan Kaminsky 過世:「Dan Kaminsky has died (twitter.com/marcwrogers)」,目前還沒看到過世的原因...

Dan Kaminsky 最有名的「成果」應該是在 2008 年發現當時大多數的 DNS resolver 軟體實做有問題,可以被 DNS cache poisoning 攻擊,當年我有寫下來提到,但寫的很短:「DNS 伺服器安全性更新」。

攻擊手法是先發一個 DNS query 到 DNS resolver,然後馬上再送出一個偽造的 DNS response packet 給 DNS resolver 收,運氣好的話這個偽造的結果就會被 cache 起來。

記得當年的 168.95.1.1168.95.192.1 沒有太直接受到影響 (相較於其他的 DNS resolver),是因為這兩個 DNS resolver 後面有 server cluster 會打散流量,所以未必能猜對去查詢時用的 DNS server 所使用的 IP address,有點類似下面提到的緩解方案 (只是沒那麼有效)。

而記得後來的緩解方式是透過亂數化 source port (讓 DNS resolver 查詢時不要從 port 53 出去問),這個方式讓攻擊機率大幅下降 (大約降到 1/2^{16} 的機率)。

後來 DNS 加上 nonce 機制再繼續壓低攻擊成功的機率 (再降一次 1/2^{16},變成大約 1/2^{32}),最後則是 DNSSEC 的支援度逐漸普及,才解決掉這個問題。

資安領域的重大損失,尤其在 DNS 這塊...

用 SSD 的 I/O 暴力解

這篇「Achieving 11M IOPS & 66 GB/s IO on a Single ThreadRipper Workstation」用了 AMD 平台上的 PCI-e 4.0 硬幹出 4K 隨機讀取 11M IOPS 的速度,另外在大區塊讀取可以到 66GB/sec,後面這個速度應該是可以把 DDR4 記憶體頻寬吃滿...

硬體的部份,作者用了 8*1TB + 2*500GB 的 M.2 SSD 來建這組系統,然後接到卡上:

不過他好像沒提到這組機器的價錢 (雖然每個單品都查的到),大概算了一下 storage 的部份其實不怎麼貴,Samsung 980 Pro PCIe 4.0 M.2 SSD 的部份,1TB 每一條要 USD$160,500GB 要 USD$120,旁邊那些 CPU 與記憶體反而貴不少... 不過整台機器應該有機會在 USD$10000 搞定?

感覺拿來給剪片的人用很爽?至少在處理讀寫的時候應該是很順...

AT&T 網路的問題

Hacker News Daily 上看到個有趣的 troubleshooting 過程,AT&T 的線路會造成 random bit flipping 的問題,另外在 Hacker News 上的討論野蠻熱鬧的:「AT&T Fiber in the SF Bay Area is flipping bits (twitter.com/catfish_man)」。

有人生了一個 script 出來測試,這隻 script 會抓 www.example.com 的 HTTP 與 HTTPS 結果比較,從下面大家的留言回報,可以看出來有 random bit flipping 的問題:「bmastenbrook/example-test.sh」。

然後總算是解決了:

可惜看不到 AT&T 的回應,大家只能猜測是 memory 相關的問題,也許壞的部份有多個地方,造成 ECC 機制在某些情況下不夠用...

莎士比亞風格的 UUID

UUID 是個長 128 bits 的數字,轉成 16 進位也有 32 個字要記,對於人類記憶來說不太友善。

前幾天在 Hacker News 上看到的東西,把這 128 bits 的資訊轉成類莎士比亞的句子,相比前面 32 個 16 進位的數字來說好記不少:「uuid-readable」。

Generate Easy to Remember, Readable UUIDs, that are Shakespearean and Grammatically Correct Sentences

給的輸出範例包括了:

Loren Chariot Addy the Titbit of Cholame questioned Cele Garth Alda and 16 windy frogs

Drucill Hubert Lewse the Comer of Avera rejoices Fiann Craggy Florie and 5 hard trouts

Jacquette Brandt John the Pectus of Barnsdall doubted Glenn Gay Gregg and 12 noisy stoats

我不覺得有變簡單啊 XDDD 也許對於英文母語的人來說會簡單一些... 吧?

sysbench 的 RNG

Percona 的 blog 上看到了 sysbench 的 RNG (Random Number Generator) 跟想像中的不太一樣:「What You May Not Know About Random Number Generation in Sysbench」。

預設是 Special:

而不是直覺的 Uniform (也有提供):

另外還提供三種:

翻了翻可以翻到其他四個的理論基礎,但就是不知道 Special 的設計理論在哪裡...

利用 Sensor 校正資訊產生 Device Fingerprint 的隱私攻擊

看到「Fingerprinting iPhones」這篇提出的攻擊,標題雖然是提到 iPhone,但實際上攻擊包括了 Android 的手機:

You are affected by this fingerprinting attack if you are using any iOS devices with the iOS version below 12.2, including the latest iPhone XS, iPhone XS Max, and iPhone XR. You are also likely to be affected if you are using a Pixel 2/3 device, although we hypothesise the generated fingerprint has less entropy and is unlikely to be globally unique. A SensorID can be generated by both apps and mobile websites and requires no user interaction.

目前 iPhone 升級到 12.2 之後可以緩解這個問題,Android 看起來還不清楚...

攻擊的方式是透過手機在出場前會使用外部的校正工具,找出手機內 sensor 所偵測到的值與實際值的差異,然後把這些資訊燒到韌體裡,當呼叫 API 時就可以修正給出比較正確的值。

而因為這些校正資訊幾乎每一隻手機都不一樣,而且不會因為重裝而變更 (即使 factory reset),加上還可以跨 app 與 web 追蹤,就成為這次攻擊的目標:

In the context of mobile devices, the main benefit of per-device calibration is that it allows more accurate attitude estimation.

資訊量其實相當大,透過 app 分析可以得到 67 bits entropy,透過網頁也有 42 bits entropy,而且不怎麼會變:

In general, it is difficult to create a unique fingerprint for iOS devices due to strict sandboxing and device homogeneity. However, we demonstrated that our approach can produce globally unique fingerprints for iOS devices from an installed app -- around 67 bits of entropy for the iPhone 6S. Calibration fingerprints generated by a website are less unique (~42 bits of entropy for the iPhone 6S), but they are orthogonal to existing fingerprinting techniques and together they are likely to form a globally unique fingerprint for iOS devices.

We have not observed any change in the SensorID of our test devices in the past half year. Our dataset includes devices running iOS 9/10/11/12. We have tested compass calibration, factory reset, and updating iOS (up until iOS 12.1); the SensorID always stays the same. We have also tried measuring the sensor data at different locations and under different temperatures; we confirm that these factors do not change the SensorID either.

目前提出來的解法是加入隨機值的噪音 (iOS 的作法),不過作者有建議預設應該要關閉 js 存取 sensor 的權限:

To mitigate this calibration fingerprint attack, vendors can add uniformly distributed random noise to ADC outputs before calibration is applied. Alternatively, vendors could round the sensor outputs to the nearest multiple of the nominal gain. Please refer to our paper for more details. In addition, we recommend privacy-focused mobile browsers add an option to disable the access to motion sensors via JavaScript. This could help protect Android devices and iOS devices that no longer receive updates from Apple.

不過當初這群人怎麼會注意到的...

AWS 提供模擬 Amazon Aurora 異常的測試功能...

Twitter 上看到 Jeff Barr 提到了在 Amazon Aurora 上的模擬 (這邊應該是講 MySQL):

指到的頁面是文件「Managing Amazon Aurora MySQL - Amazon Relational Database Service」,翻了一下 Wayback Machine,看起來之前就有了,只是現在拿出來再宣傳一下:「Managing Amazon Aurora MySQL - Amazon Relational Database Service」。

透過主動觸發 Amazon Aurora 異常,可以測試整個系統的後續反應:

  • A crash of the master instance or an Aurora Replica
  • A failure of an Aurora Replica
  • A disk failure
  • Disk congestion

前面三種都屬於 Aurora 本身的故障測試,第四種除了有可能是 Aurora 本身的問題外,也可以測壓力過大時的情境 (i.e. 前面透過 auto scaling 撐住了,但後面的資料庫可能沒有足夠的能力支撐)。

Googlebot 的 Math.random()

Hacker News Daily 上看到「Googlebot’s Javascript random() function is deterministic」這則有趣的發現。作者發現 Googlebot 的 Math.random() 並不隨機,甚至是固定的:

The first time Googlebot calls Math.random() the result will always be 0.14881141134537756, the second call will always be 0.19426893815398216. The script I linked to above simply uses this fact but obfuscates it a little and ‘seed’ it with something that doesn’t look too arbitrary.

需要無法預測的 random number (有安全性需求的) 應該用 RandomSource.getRandomValues() 這類函數,而不是用 Math.random(),所以這點倒是還好...