1 điểm bởi GN⁺ 2024-09-18 | 2 bình luận | Chia sẻ qua WhatsApp
  • Little Snitch 6.1 có thể khiến mã hóa DNS thất bại trong một số tình huống, nhưng phạm vi đã được thu hẹp là vấn đề của chính phiên bản này chứ không phải lỗi trên toàn bộ macOS, và đã được sửa trong 6.1.1
  • Để hoạt động bình thường, các yêu cầu DNS của macOS phải được chuyển tới DNS proxy của Little Snitch, rồi proxy này thực hiện truy vấn đã mã hóa
  • Trong quá trình điều tra, đã quan sát thấy một số yêu cầu từ API legacy cấp thấp không tới được proxy mà gửi truy vấn UDP 53 không mã hóa tới nameserver mặc định của hệ thống
  • Cách tái hiện là bật mã hóa DNS trong Little Snitch, chạy Wireshark với bộ lọc port 53, rồi gọi getaddrinfo("dnsproxytest.com") trong Xcode playground
  • Các truy vấn dựa trên API cấp cao như Safari và Chrome ban đầu có vẻ không bị ảnh hưởng, còn Firefox có vẻ bị ảnh hưởng, nhưng phạm vi cuối cùng được xác định là DNS proxy của Little Snitch 6.1

Lỗi mã hóa DNS xảy ra trong Little Snitch 6.1

  • Tính năng mã hóa DNS của Little Snitch 6 định tuyến việc phân giải hostname qua Little Snitch để xử lý ở dạng mã hóa
  • Để làm được điều này, Little Snitch đăng ký một DNS proxy, và macOS phải gửi mọi yêu cầu DNS tới proxy đó
  • Đã phát hiện một số yêu cầu DNS, đặc biệt là các yêu cầu thông qua một số API legacy cấp thấp nhất định, không được proxy nhận
  • Các yêu cầu đó có thể được gửi ở dạng không mã hóa tới nameserver mặc định của hệ thống, và có thể xác nhận trong Wireshark dưới dạng lưu lượng UDP cổng 53
  • Little Snitch Network Monitor không hiển thị lưu lượng truy vấn đó vì các truy vấn đã bỏ qua hoàn toàn network filter

Quy trình tái hiện và diễn biến cập nhật

  • Quy trình tái hiện

    • Bật DNS encryption trong phần cài đặt của Little Snitch
    • Chạy Wireshark với bộ lọc bắt gói port 53
    • Thực thi truy vấn dnsproxytest.com bằng getaddrinfo trong Xcode playground
    • Truy vấn dnsproxytest.com có thể xuất hiện ở dạng không mã hóa trên UDP 53
  • Phạm vi ảnh hưởng ban đầu

    • Các truy vấn DNS thông qua API cấp cao có vẻ không bị ảnh hưởng
    • Duyệt web bằng Safari và Chrome có vẻ vẫn giữ được lợi ích của các truy vấn đã mã hóa
    • Firefox có vẻ bị ảnh hưởng
  • Lịch sử cập nhật

    • 2024-09-17 19:10: Đã xác nhận vấn đề này có thể đã tồn tại từ macOS 14.5 Sonoma, và không thể thử nghiệm trên các hệ thống 14.x cũ hơn
    • 2024-09-18 12:05: Đã kết luận đây không phải vấn đề DNS proxy chung của macOS mà chỉ ảnh hưởng tới DNS proxy của Little Snitch 6.1
    • 2024-09-18 15:52: Vấn đề đã được sửa trong Little Snitch 6.1.1

2 bình luận

 
GN⁺ 2024-09-18
Ý kiến trên Hacker News
  • Việc getaddrinfo() bị xem là một “API cũ cấp thấp” khiến tôi thấy hơi lạ
    Trên macOS tình hình có thể rất khác, nhưng trên Linux và có lẽ cả *BSD, đây là cách tiêu chuẩn dùng để phân giải tên
    Có lẽ phần lớn ứng dụng macOS dùng các framework kiểu Foundation hoặc NetworkKit cho truy vấn DNS, nhưng cũng bất ngờ là bên trong chúng rốt cuộc lại không hạ xuống xử lý bằng các lời gọi như getaddrinfo()
    Vì GAI là blocking, có lẽ có một lời gọi bất đồng bộ cấp thấp khác

    • Đúng vậy. CFNetwork là mã nguồn mở nên có thể kiểm tra cách triển khai, và tôi nhớ lần xem trước đây nó dùng một biến thể như getaddrinfo_async
      Tuy nhiên Apple không muốn người dùng cuối tự phân giải IP trực tiếp bằng getaddrinfo hoặc biến thể bất đồng bộ mà CF phơi ra rồi connect() tới IP đó
      Nhìn chung, họ hướng tới việc kết nối bằng hostname, nhờ vậy Apple có thể xử lý nội bộ phần triển khai happy-eyeballs
      Có thể xem vì sao Apple không ưa mô hình getaddrinfo() tại https://www.ietf.org/proceedings/72/slides/plenaryw-6.pdf. Bên dưới mỗi slide cũng có ghi chú của diễn giả
    • Tôi không nghĩ getaddrinfo() được xem là legacy. Có vẻ bài blog đó viết sai ở phần này
      Còn có phải “cấp thấp” hay không thì tùy góc nhìn
    • getaddrinfo() không phải thứ liên quan riêng đến Linux, mà chỉ là một hàm glibc
      Mọi người giả định glibc là cách tiêu chuẩn trong user space của Linux, nhưng không nhất thiết phải như vậy
      Ví dụ systemd đã tạo cơ chế resolved riêng, và hóa ra tốt hơn nhiều so với phía glibc
      Tôi cũng đang làm phần mềm độc lập nhắm tới Linux, nên rất có thể một ngày nào đó sẽ tự làm thứ tương tự
    • Trên OpenBSD, ít nhất các hàm DNS truyền thống/tiêu chuẩn như getaddrinfo/gethostbyname đều là wrapper của triển khai OpenBSD libc asr do Eric Faurot viết
      https://man.openbsd.org/man3/asr_run.3
      https://github.com/openbsd/src/tree/master/lib/libc/asr
    • Tôi không biết trường hợp này có đúng là như vậy không, nhưng ngay cả các hàm hệ thống cùng tên thì phần triển khai bên trong cũng có thể khác nhau đáng kể giữa *Linux/BSD/macOS
      Giữa các *BSD với nhau cũng có khác biệt
      Trên một hệ thống, một lời gọi hàm có thể được duy trì nhiều năm và là “chuẩn mực”, nhưng trên hệ thống khác thì thực sự có thể đã cũ và không còn hữu ích
  • Vấn đề được đề cập ở đây hóa ra không phải vấn đề chung của macOS mà chỉ áp dụng cho Little Snitch 6.1, và dự kiến sẽ được sửa bằng bản cập nhật Little Snitch vào cuối ngày hôm nay

    • Nếu tiêu đề cũng có thể được cập nhật để phản ánh nội dung này thì tốt
  • Điều tra thêm cho thấy lỗi này đã tồn tại ít nhất từ macOS 14.5 Sonoma
    Có thể đã có từ trước nữa, nhưng hiện không có quyền truy cập vào hệ thống 14.x cũ hơn để kiểm thử

    • Tôi thắc mắc liệu họ đã từng kiểm thử xem nó có thực sự hoạt động với getaddrinfo hay chưa
      Hay là chỉ thấy nó hoạt động một lần với CFNetwork rồi thôi, sau đó đăng bài blog nói rằng nó bị hỏng
    • Việc các nhà phát triển vẫn phải giữ riêng các phiên bản OS cũ để kiểm thử thật vô lý
      Gần như không có lý do kỹ thuật nào khiến Apple không thể cho phép downgrade
    • Xét việc họ đang bán sản phẩm và OS mới vừa ra hôm qua, chuyện này cũng khá kỳ quặc
  • Sequoia còn làm hỏng khả năng dùng DNS của ứng dụng, và có lẽ cả các chức năng dựa trên UDP nói chung, nếu firewall của macOS đang bật và ứng dụng được đăng ký là “chặn kết nối đến”
    https://waclaw.blog/macos-firewall-blocking-web-browsing-aft...

    • Tôi không tái hiện được. Một số người nói nó liên quan đến ESET: https://www.reddit.com/r/MacOS/comments/1fievr5/updating_mad...
    • Trước Sequoia, ngay cả khi dùng OpenDNS trong VPN thì iMessage và các ứng dụng khác vẫn tiếp tục hoạt động khi đang kết nối VPN; sau Sequoia, trong lúc kết nối VPN thì tin nhắn iMessage và các thứ tương tự không còn hoạt động nữa
      Ngắt VPN thì tất cả đều đi qua
      Không biết có liên quan đến chuyện này không. Firewall macOS đang bật, nhưng không chặn tất cả kết nối đến
    • Sau khi nâng cấp lên Sequoia, tôi không thể duyệt web bằng Safari hay Mozilla
      Vào phần thiết lập DNS của kết nối Wi-Fi và thêm các máy chủ DNS của Google là 8.8.8.88.8.4.4 thì được giải quyết, thay thế các máy chủ DNS trước đó được tự động điền vào
    • Thành thật mà nói, tôi thấy hành vi như vậy là ổn. Ứng dụng không nên tự phân giải DNS ngoài những gì được chỉ định trong cài đặt
      Lý do các ứng dụng làm như vậy là để người dùng không thể chặn những thứ như telemetry
      Đây là máy tính của tôi, nên tôi phải là người có quyền quyết định cuối cùng về những gì được gửi ra ngoài
  • Tiêu đề ám chỉ rằng việc này là có chủ đích hoặc được áp dụng đặc quyền cho Apple, nhưng thực tế trông có vẻ gần với một bug đơn thuần hơn
    Khi nói rằng đã báo cáo nội dung như thế này, sẽ tốt hơn nếu đăng kèm cả số FB và chi tiết báo cáo

    • Ở góc nhìn “luật sư của quỷ”, họ cũng có thể cố tình làm như vậy để tránh phản ứng dữ dội và khiến nó trông như một bug chưa được sửa
      Miễn đạt được mục tiêu thì cách triển khai có thể linh hoạt thế nào cũng được
    • Nếu là cố ý, có lẽ đó sẽ là một URL được hard-code và mã hóa
      Một số thiết bị đã bắt đầu dùng cách đó để vượt qua chặn quảng cáo
  • Có thể tôi nhầm, nhưng mỗi lần iOS hay Mac có bản phát hành mới, tôi lại có cảm giác déjà vu rằng các vấn đề DNS phát sinh và ảnh hưởng đến những thứ như Little Snitch, Mullvad
    Nếu đúng vậy thì thật sự không hiểu Apple làm gì trong suốt nhiều tháng thử nghiệm developer/beta

  • Nhắc đến Little Snitch làm tôi hơi rối, nhưng đọc thêm thì có vẻ là một bug của LS chỉ xảy ra trong một số trường hợp nhất định
    Nếu đây là blog của LS, câu hỏi duy nhất là tại sao nó lại được mô tả như bug của macOS
    Không có ý nói họ sai, và đó là lĩnh vực của họ chứ không phải của tôi, nhưng chỉ dựa vào bài viết thì lý do biện minh có vẻ chưa thuyết phục lắm

    • Nếu OS cho phép đăng ký proxy DNS nhưng một số lời gọi lại đi vòng qua proxy đó, thì rõ ràng đó là bug của OS
  • Tôi nhớ Apple từng deprecate việc các nhà phát triển bên thứ ba dùng một network API nhất định
    Nhưng các ứng dụng của chính Apple, ví dụ App Store, lại không chịu cùng hạn chế đó
    Vì vậy, khi cố lọc lưu lượng mạng qua tường lửa ứng dụng bằng API mới, việc đó thất bại vì App Store dùng API legacy
    Có thể đây là một phần của bug cũ mà tôi tưởng đã được sửa từ trước

    • getaddrinfo() không phải API legacy, mà là API chuẩn đa nền tảng để truy vấn DNS
  • Những thông báo kiểu “Phát hiện bug trong bản phát hành OS mới! Chỉnh sửa: thật ra đó là bug đã tồn tại từ khá lâu rồi!” lúc nào cũng thú vị

  • Tôi đang dùng routedns [0] làm trình phân giải stub cục bộ để tự chọn yêu cầu nào gửi đi đâu và dùng phương thức truyền tải nào
    Nó cũng hỗ trợ danh sách chặn, rewrite, cache, cân bằng tải và xử lý yêu cầu thay thế, nên có rất nhiều quyền kiểm soát
    Với các yêu cầu cục bộ, tôi dùng stub listener tại localhost:53, còn phần lớn yêu cầu được chuyển tiếp tới 1.1.1.1 của Cloudflare qua UDP QUIC, tức TLS 0-RTT, kèm cache
    Nhanh và khá an toàn
    [0] https://github.com/folbricht/routedns

 
nearfall 2024-09-18

Cảm ơn vì thông tin quan trọng.
Trước mắt, thật may khi có thể yên tâm rằng Safari và Chrome vẫn an toàn.