- Mullvad đặt nhiều IP thoát trên mỗi máy chủ, nhưng việc gán được quyết định một cách tất định dựa trên khóa WireGuard nên không thay đổi ngẫu nhiên sau mỗi lần kết nối
- 3.650 điểm dữ liệu thu thập được từ 9 máy chủ bằng cách thay đổi lặp lại pubkey chỉ được gán vào 284 tổ hợp, trong khi về lý thuyết có thể có hơn 8,2 nghìn tỷ tổ hợp
- IP thoát của từng máy chủ nằm ở vị trí phần trăm tương tự nhau trong pool, và một tổ hợp thường khớp quanh mức phần trăm thứ 81 trên nhiều máy chủ
- Nguyên nhân có vẻ là cấu trúc chọn chỉ số IP thoát bằng RNG dựa trên seed, dùng pubkey hoặc địa chỉ tunnel làm seed và kích thước pool làm giới hạn trên
- Khi các khoảng float của log IP chồng lấp nhau, việc tương quan giữa các tài khoản vẫn có thể thực hiện được ngay cả khi dùng các máy chủ Mullvad khác nhau, làm tăng rủi ro ẩn danh
Cấu trúc khiến IP thoát của Mullvad trở thành một vector nhận diện
- Mullvad cung cấp nhiều IP thoát trên mỗi máy chủ, và hai người dùng kết nối vào cùng một máy chủ thường sẽ nhận các IP công khai khác nhau
- Số lượng máy chủ là 578, ít hơn 20.000 máy chủ của Proton VPN, nên cách mở rộng theo chiều dọc để tránh dồn người dùng vào cùng một IP có lợi cho việc né chặn IP quá mức và giới hạn tốc độ
- Tuy nhiên, mỗi lần kết nối vào máy chủ thì IP thoát không đổi ngẫu nhiên mà được chọn một cách tất định dựa trên khóa WireGuard
- Khóa WireGuard được xoay vòng mỗi 1~30 ngày, nhưng trên client bên thứ ba thì không xoay vòng
- Nếu mỗi máy chủ được gán một IP thoát cố định một cách độc lập, thì chỉ với tổ hợp IP của vài máy chủ cũng có thể phân biệt một người dùng với các người dùng Mullvad khác
Các tổ hợp IP thoát quan sát được trên 9 máy chủ
- Một script thu thập IP thoát của 9 máy chủ bằng cách thay đổi pubkey lặp lại đã được chạy qua đêm, thu được 3.650 điểm dữ liệu pubkey
- Dải IP thoát của từng máy chủ được quan sát như sau
| Hostname |
Start IP |
End IP |
# IPs |
| au-syd-wg-101 |
103.136.147.5 |
103.136.147.64 |
60 |
| cl-scl-wg-001 |
149.88.104.4 |
149.88.104.14 |
11 |
| de-ber-wg-007 |
193.32.248.245 |
193.32.248.252 |
8 |
| dk-cph-wg-002 |
45.129.56.196 |
45.129.56.226 |
31 |
| fi-hel-wg-201 |
185.65.133.10 |
185.65.133.75 |
66 |
| us-lax-wg-001 |
23.234.72.36 |
23.234.72.126 |
91 |
| us-nyc-wg-602 |
146.70.168.132 |
146.70.168.190 |
59 |
| us-sjc-wg-302 |
142.147.89.212 |
142.147.89.224 |
13 |
| za-jnb-wg-002 |
154.47.30.145 |
154.47.30.155 |
11 |
- Nhân kích thước pool của các máy chủ này lại thì có vẻ như có thể tạo ra hơn 8,2 nghìn tỷ tổ hợp IP thoát
- Nhưng toàn bộ pubkey được thử nghiệm thực tế chỉ rơi vào một trong 284 tổ hợp
- So với số tổ hợp khả dĩ, số tổ hợp quan sát được là cực ít, cho thấy việc chọn IP theo từng máy chủ không hề độc lập
Mẫu hình các IP khác nhau lại nằm ở cùng một bách phân vị
- Có thể tính vị trí số học của IP thoát bằng khoảng cách của nó so với IP đầu của pool
- Ví dụ, trên
au-syd-wg-101, 103.136.147.53 có chỉ số 1-based là 49 nếu đếm từ 103.136.147.5
- Khi chia vị trí IP trong các tổ hợp quan sát được cho kích thước pool của từng máy chủ, ta thấy gần như cùng một tỷ lệ xuất hiện trên các máy chủ khác nhau
| Server |
IP |
Position |
Pool size |
Ratio |
| au-syd-wg-101 |
103.136.147.53 |
49 |
60 |
0.816 |
| cl-scl-wg-001 |
149.88.104.12 |
9 |
11 |
0.818 |
| de-ber-wg-007 |
193.32.248.251 |
7 |
8 |
0.875 |
| dk-cph-wg-002 |
45.129.56.220 |
25 |
31 |
0.806 |
| fi-hel-wg-201 |
185.65.133.63 |
54 |
66 |
0.818 |
| us-lax-wg-001 |
23.234.72.109 |
74 |
91 |
0.813 |
| us-nyc-wg-602 |
146.70.168.179 |
48 |
59 |
0.813 |
| us-sjc-wg-302 |
142.147.89.222 |
11 |
13 |
0.846 |
| za-jnb-wg-002 |
154.47.30.153 |
9 |
11 |
0.818 |
- Mỗi IP đều nằm ở bách phân vị tương tự trong pool tương ứng, và ví dụ trên nhìn chung rơi vào bách phân vị thứ 81
- Vì mẫu hình này, Mullvad trông như đang chỉ gán các IP thoát ở những vị trí lân cận nhau trên mọi máy chủ
Nguyên nhân có vẻ là chọn ngẫu nhiên dựa trên seed
cl-scl-wg-001 và za-jnb-wg-002 luôn chia sẻ cùng một chỉ số IP trong toàn bộ 284 tổ hợp IP đã quan sát
- Điểm chung của hai máy chủ này là kích thước pool 11, phù hợp với cấu trúc mà một lời gọi số ngẫu nhiên có cùng seed và cùng bounds sẽ cho ra cùng kết quả
- Nếu khởi tạo RNG bằng một seed tĩnh rồi rút số ngẫu nhiên trong cùng một khoảng, kết quả giống nhau sẽ lặp lại
- Có vẻ Mullvad chọn chỉ số IP thoát bằng RNG dựa trên seed, dùng pubkey hoặc địa chỉ tunnel làm seed và dùng kích thước pool làm giá trị giới hạn trên
- Dù bounds thay đổi, entropy pool của RNG dường như không bị ảnh hưởng, và trong Rust điều này khớp với cách cùng một float được tạo ở lần gọi đầu tiên rồi nhân với bounds
- Hành vi này có thể được hình dung đơn giản như
min + round((max - min) * float), dù đây có thể là cách diễn đạt đã lược giản khá nhiều
- Vì đặc tính này, dù kích thước pool khác nhau thì float tạo ra từ cùng một seed vẫn được ánh xạ tới các điểm có tỷ lệ tương tự trong pool của từng máy chủ
- Client Mullvad được viết bằng Rust, nên backend cũng có thể dùng Rust, nhưng đây chỉ là suy đoán dựa trên triển khai phía client
- Rất khó dự đoán chính xác
random_range hoạt động thế nào khi bounds thay đổi; người ta dễ nghĩ việc tăng bounds sẽ trộn với entropy để tạo ra số khác, nhưng quan sát thực tế lại không như vậy
Rủi ro ẩn danh phát sinh từ tương quan log IP
- Một công cụ ước tính giá trị float nhỏ nhất và lớn nhất ứng với một tổ hợp IP cụ thể được cung cấp tại mullvad-seed-estimator
- Tập IP cụ thể trong ảnh chụp màn hình được diễn giải là giá trị float nằm trong khoảng 0.2909~0.2943, với độ chênh 0.0034
- Điều này có nghĩa là 0,34% người dùng Mullvad sẽ chia sẻ các IP đó, tương đương khoảng 340 người nếu ước tính thô có 100.000 người dùng đang hoạt động
- Mức độ duy nhất không cao như dự đoán ban đầu, nhưng độ chính xác trên 99% vẫn không hề thấp
- Ví dụ, khi quản trị viên diễn đàn kiểm tra một tài khoản mới bị nghi là sockpuppet của người dùng đã bị cấm từ hôm trước, nếu log IP của hai tài khoản có các khoảng float chồng lấp như
0.4334 - 0.4428 và 0.4358 - 0.4423, thì ngay cả khi hai tài khoản dùng các máy chủ Mullvad khác nhau, xác suất là cùng một người vẫn vượt 99%
- Nếu áp dụng cùng cách tương quan này vào log IP thu được từ rò rỉ dữ liệu hoặc thủ tục pháp lý, người dùng đứng sau VPN có thể mất tính ẩn danh
Cách bảo vệ
- Khuyến nghị không đổi máy chủ quá một lần với mỗi pubkey
- Có thể đăng xuất khỏi ứng dụng Mullvad để buộc xoay vòng pubkey
1 bình luận
Ý kiến trên Hacker News
Tôi là đồng CEO kiêm đồng sáng lập đang làm việc tại Mullvad. Một phần hành vi được nêu trong bài là có chủ đích, một phần thì không, và nguyên nhân cũng không hoàn toàn đúng như phần giải thích trong bài blog
Về biện pháp giảm thiểu, chúng tôi đã thử nghiệm bản vá cho hành vi ngoài ý muốn trên một phần hạ tầng, nên nếu thử tái hiện hôm nay thì kết quả có thể gây nhầm lẫn
Chúng tôi cũng sẽ đánh giá lại xem hành vi có chủ đích đó có còn chấp nhận được hay không; ở đây có sự đánh đổi giữa nhiều yếu tố quyền riêng tư và trải nghiệm người dùng
Đây là đánh giá hiện tại của tôi sau khi biết chuyện này một giờ trước, trao đổi ngay với đội vận hành và sắp xếp lại suy nghĩ trong lúc viết bình luận này, nên có thể sẽ thay đổi
Tôi mong những người làm nghiên cứu bảo mật, khi phát hiện vấn đề bảo mật hoặc quyền riêng tư, hãy báo trước cho quản trị viên hoặc nhà cung cấp ngay cả khi dự định công khai ngay sau đó
Có thể kiểm tra bằng
mullvad tunnel getvà thay đổi bằngmullvad tunnel set rotation-interval; đây cũng là cách giảm thiểu mà bài viết ưa dùngCá nhân tôi không thấy IP bán cố định là vấn đề lớn. Mục tiêu là ngăn ISP và giám sát ở cấp độ mạng của chính phủ, và một số bên thậm chí còn bán IPv4 cố định như một tính năng
Với VPN chú trọng quyền riêng tư, không gian IP càng nhỏ thì càng có nhiều người dùng trộn lẫn phía sau một IP nhìn từ bên ngoài, nên cũng có lợi. Khi kết hợp công nghệ bơm lưu lượng giả vào đường hầm như DAITA với điểm vào multi-hop, tôi cho rằng điều đó thực sự có thể khiến kẻ giám sát ngồi xem netflow cả ngày khó khăn hơn
Phát hiện cốt lõi là tương quan vị trí trong pool IP giữa các máy chủ có vẻ thực sự bao gồm hành vi ngoài ý muốn. Theo kinh nghiệm từng làm việc với đội Mullvad, tôi nghĩ họ sẽ xử lý sớm thôi
Nếu muốn có các “danh tính” khác nhau, bạn phải xoay khóa WireGuard hoặc dùng các khóa khác nhau
Bài viết nói rằng “mỗi lần kết nối tới máy chủ, IP thoát không được chọn ngẫu nhiên mà được chọn một cách quyết định dựa trên khóa WireGuard, và khóa này được xoay mỗi 1~30 ngày. Nếu dùng client bên thứ ba thì sẽ không xoay” nhưng WireGuard theo thiết kế là giao thức không kết nối, nên không có khái niệm kết nối; chỉ có bắt tay rekey mỗi 2~3 phút khi có lưu lượng chạy qua
Nếu ngay cả với cùng một khóa WireGuard mà IP thoát lại đổi mỗi lần “kết nối”, chẳng hạn mỗi lần bắt tay rekey hoặc mỗi 15 phút, thì ở tầng truyền tải gần như mọi kết nối bên trong đường hầm trừ QUIC sẽ bị ngắt và phải thiết lập lại; ở tầng ứng dụng, các dịch vụ nghi ngờ “cùng cookie, IP mới” sẽ đăng xuất người dùng, hiện CAPTCHA hoặc tăng điểm rủi ro
Cả hai đều cho trải nghiệm người dùng tệ, và tệ hơn nữa là có thể khiến người dùng bị tạo dấu vân tay độc nhất hơn, kiểu “người này cứ kết nối lại từ IP khác nên chắc là người dùng Mullvad”
Ví dụ “quản trị viên diễn đàn nghi một tài khoản mới là tài khoản phụ của người dùng bị chặn hôm trước, kiểm tra log IP thì thấy dù dùng các máy chủ Mullvad khác nhau nhưng hai tài khoản được ánh xạ vào các khoảng số thực chồng lấp 0.4334~0.4428 và 0.4358~0.4423, nên có thể xem là cùng một người với xác suất hơn 99%” tạo cảm giác nếu cơ quan tình báo thiết kế VPN thì chắc sẽ làm như vậy
Hơn nữa cách này còn phụ thuộc vào việc người dùng chọn các máy chủ khác nhau, nên lại càng không có lý do để làm vậy
Theo tiêu chuẩn của tôi thì đây là vấn đề lớn, và nó cho phép phân tích tương quan giữa nhiều nút thoát VPN, nhưng cũng chỉ đến thế. Nó không tự động cho phép nhận diện người dùng
Tuy vậy nó làm giảm mạnh độ khó của việc nhận diện, còn điều kiện cần thì vẫn cao. Hy vọng sẽ sớm được sửa
Tôi không thể tin kiểu sai lầm “hãy tạo từ giá trị nhạy cảm như hash” vẫn còn xảy ra, mà lại ở Mullvad. Sao không đơn giản là ngẫu nhiên hóa nhỉ
Dĩ nhiên còn các cơ quan khác, nhưng nơi đáng lo nhất là bên đó. Hoặc họ trực tiếp vận hành, hoặc biết ý tưởng như vậy và làm theo, hoặc có quyền truy cập vào dịch vụ do cơ quan đối tác vận hành. Nếu không thì hẳn không phải mối đe dọa với tôi
Ngoài ra cũng không có trường hợp công khai nào người dùng Mullvad bị phi ẩn danh hóa thông qua chính VPN; thay vào đó chỉ có các trường hợp bị phát hiện vì thất bại opsec khác. Nếu cơ quan tình báo có khả năng này, thì khó tin là họ đã giữ dữ liệu gần 20 năm mà không dùng đến
Tôi không hiểu chỉ từ các con số trong bài mà làm sao ra được “xác suất hơn 99%”. Ngay cả khi giả định mạnh rằng seed của IP bị chặn thứ nhất và seed thứ hai đều nằm trong khoảng 0.4423~0.4358, thì điều đó cũng chỉ có nghĩa khoảng này bao phủ 0.65% toàn bộ người dùng Mullvad
Nếu có 100.000 người dùng thì là 650 người; tức là đã loại trừ hơn 99% “nghi phạm”, chứ không phải nhận diện một cá nhân qua nhiều IP thoát với độ chính xác trên 99%
Theo kiểu Bayes, việc các seed tiềm năng chồng lên nhau là bằng chứng mạnh rằng hai IP thuộc cùng một người, hoặc ít nhất là cùng một tài khoản Mullvad, nhưng có vẻ tác giả không nói theo nghĩa đó
Với đa số website nhỏ thì đó là bằng chứng khá mạnh
Mục đích của VPN không bao gồm việc ẩn danh người dùng đối với website họ truy cập, nên không có gì đáng ngạc nhiên khi Mullvad không ép dùng IP thoát độc nhất. Người dùng muốn ẩn danh nên dùng mạng như Tor
Nếu dùng VPN công cộng, bạn muốn không ai biết ai gửi yêu cầu, kể cả IP đầu cuối
Theo logic đó thì VPN không nên dùng cho torrent. Vì như vậy có nghĩa nó không được phép ẩn danh hóa đối với IP đầu cuối. Nhưng trên thực tế nó lại hoạt động rất tốt cho torrent
Nếu bạn đang nói tới VPN riêng thì Mullvad không phải loại đó
Tôi đã dùng Mullvad từ lâu và sẽ tiếp tục mua, sử dụng dịch vụ Mullvad VPN bằng thẻ tín dụng đứng tên tôi miễn là điều đó còn hợp pháp ở nước tôi
VPN không ẩn danh 100%, và cũng không được thiết kế để làm thế. Thay vào đó nó nhằm cung cấp một mức độ riêng tư nhất định cho người lớn tuân thủ pháp luật
Phần lớn mọi người sẽ thấy ngượng nếu đồng nghiệp hay hàng xóm biết đời tư, sở thích, thứ họ mua và việc họ làm. Vì vậy đa số nên dùng VPN để bảo vệ quyền riêng tư
Theo định nghĩa, “đa số mọi người” không muốn hay kỳ vọng ẩn danh 100% trên mạng; họ chỉ muốn một chút riêng tư trong đời sống cá nhân và các mối quan hệ
VPN không bảo vệ tội phạm muốn phạm tội trực tuyến rồi được ẩn danh 100% trước chính phủ, và cũng không có ý định như vậy. Sự phân biệt này rất quan trọng. “Đa số mọi người” không phải tội phạm và không đặt kỳ vọng phi thực tế như thế lên Mullvad hay các nhà cung cấp VPN khác
Không thể chỉ dùng lập luận trên để bác bỏ báo cáo. Phát hiện đó vẫn có giá trị
Có điều gì đó còn thiếu. Tôi muốn biết liệu họ đã liên hệ Mullvad chưa. Nếu có cả cách đội bảo mật phản ứng thì càng thú vị
Sau đó tôi thấy hối hận vì đã viết bình luận này. Không cần thiết, nhưng nếu giờ xóa đi thì có vẻ kỳ quặc
Tôi thấy khá ngạc nhiên khi mọi người kỳ vọng VPN sẽ giống Tor
Diễn giải ra như vậy thì nghe không hợp lý, và cũng cần nhớ rằng nếu kiểm soát được nút thoát thì ngay cả người dùng Tor cũng có thể bị phi ẩn danh hóa
Đoạn “IP thoát không được ngẫu nhiên hóa mỗi lần kết nối mà được chọn một cách quyết định dựa trên khóa WireGuard, và khóa này được xoay mỗi 1~30 ngày. Nếu dùng client bên thứ ba thì sẽ không bao giờ xoay” hơi khó hiểu
Nếu kho mã có mô tả chi tiết cách làm, tôi không rõ điều gì ngăn bên thứ ba thực hiện xoay khóa giống như client ứng dụng mặc định
Tác giả phát hiện ra điều này rất tốt, và tôi hoàn toàn tin đây là sai sót của Mullvad. Khá sốc khi thứ đơn giản như vậy lại lọt qua, nhưng có lẽ tôi cũng có thể đã bỏ sót
Nếu bỏ qua tương quan IP giữa nhiều máy chủ, ban đầu tôi cũng tự hỏi vì sao họ lại giữ IP người dùng ổn định trên một máy chủ. Nhưng lời giải thích của tác giả rằng như vậy là để bắt chước các VPN khác vốn thường chỉ có một IP cho mỗi máy chủ thì nghe hợp lý
Khi người dùng tìm được một máy chủ có thể truy cập dịch vụ nào đó, việc kết nối lại máy chủ đó và nhận cùng IP để tiếp tục hoạt động có lợi thế nhất định
Tuy vậy tương quan IP giữa nhiều máy chủ thì nên được sửa kiểu
rand.seed(user_pub_key + server_id)Tôi làm ở IPinfo. Chúng tôi kinh doanh phát hiện VPN, nhưng thành thật mà nói tôi muốn diễn giải theo hướng thiện chí với Mullvad
Mullvad là một trong ba nhà cung cấp VPN không cố nộp dữ liệu vị trí địa lý sai cho nhà cung cấp địa lý IP như chúng tôi. Tôi tin họ cũng sẽ sửa vấn đề này