Hacker News Nổi bật (buzzing.cc bản dịch tiếng Trung)
85

Thủ thuật

Giải mã GitHub Copilot: Những bài học từ việc chặn lưu lượng qua MitM Proxy

(giờ Việt Nam)

Tóm tắt AI

Tác giả thực hiện phân tích ngược GitHub Copilot bằng cách chặn lưu lượng qua mitmproxy, từ đó hé lộ cách thức vận hành của các ứng dụng AI dựa trên nền tảng Electron và chia sẻ cách thiết lập proxy hiệu quả.

Bản dịch AI

How GitHub Copilot Works: Context, Memory and Network Traffic

Chào các bạn, tôi là Rafael đây. Hàng tuần, tôi đều chia sẻ những thách thức và sự phát triển thú vị mà tôi bắt gặp dưới góc nhìn của một kỹ sư đang xây dựng các hệ thống AI.

Hãy đăng ký để nhận các bản tin hàng tuần 👇

Trong vài năm trở lại đây, đã có một làn sóng các ứng dụng và tính năng tích hợp AI xuất hiện. Các tên tuổi lớn như Slack đã nhanh chóng bổ sung các tính năng AI vào danh mục của mình. Đối với những ứng dụng "AI-native" (thuần AI) như Cursor, Notion, ChatGPT Desktop và Claude Desktop, AI luôn là một phần trong lý do tồn tại của chúng.

Càng nhiều tính năng AI được các ứng dụng này tung ra, tôi càng có xu hướng muốn tìm hiểu cách thức hoạt động bên trong của chúng. Hy vọng rằng tôi có thể khám phá được phần nào những gì đang diễn ra "dưới nắp ca-pô"; ít nhất, tôi cũng sẽ học được một hoặc hai điều về phát triển ứng dụng desktop.

Tình cờ thay, tôi nhận thấy mình bắt đầu dùng hết hạn mức Copilot ngày càng sớm hơn mỗi tháng. Điều này thôi thúc tôi chọn ra một ứng cử viên chính cho các thử nghiệm của mình. Tôi quyết định đi sâu vào nghiên cứu VS Code và Copilot.

Điểm chung của tất cả các ứng dụng trên là chúng đều được xây dựng bằng Electron. Electron là một framework JavaScript giúp các nhà phát triển xây dựng và phân phối các ứng dụng desktop. Nói một cách dễ hiểu, nó hoạt động bằng cách đóng gói môi trường Node.js cùng với các thành phần HTML, CSS và JavaScript, sau đó được hiển thị thông qua Chromium.

Điều này loại bỏ nhu cầu phải duy trì nhiều cơ sở mã (codebase) bằng các ngôn ngữ gốc cho từng nền tảng khác nhau (ví dụ: C# cho Windows và Swift cho macOS), giúp các nhà phát triển dễ dàng xây dựng ứng dụng desktop chạy đa nền tảng từ một cơ sở mã duy nhất. (Các module gốc và một số bước đóng gói nhất định vẫn thường yêu cầu xử lý riêng cho từng nền tảng, nhưng phần lớn logic ứng dụng là dùng chung).

Vì cùng chia sẻ nền tảng Electron, chúng có kiến trúc khá tương đồng, nghĩa là bất cứ điều gì tôi học được khi khám phá ứng dụng này đều có thể áp dụng cho các ứng dụng khác.

Bản tin Lighthouse hoàn toàn miễn phí:) hãy ủng hộ công việc của tôi bằng cách chia sẻ nó với bạn bè và đồng nghiệp, những người có thể quan tâm 👇

Chia sẻ

Bản năng đầu tiên của tôi là chỉ lướt qua mã nguồn của VS Code để xem liệu nó có giải đáp được các câu hỏi của tôi hay không. Vấn đề là tôi vẫn chưa có một bộ câu hỏi đầy đủ - và việc tìm kiếm chúng trong hàng triệu dòng mã sẽ tiêu tốn của tôi quá nhiều thời gian hoặc quá nhiều token.

Mã nguồn cho bạn biết ứng dụng có thể làm gì; nhưng khám phá những gì nó thực sự thực hiện trong thời gian chạy (runtime) lại là một thách thức lớn hơn. Đặc biệt là khi bạn vẫn chưa biết mình đang tìm kiếm điều gì.

Có một vấn đề thứ hai. VS Code là một ngoại lệ trong số các ứng dụng tôi đã bắt đầu: mã nguồn của nó (hoặc ít nhất là phần lớn) là mã nguồn mở. Điều này không áp dụng cho Claude, ChatGPT, Codex, Notion và Slack.

Điều đó bắt đầu đẩy tôi đi theo con đường kỹ thuật đảo ngược (reverse engineering): trước tiên hãy quan sát lưu lượng truy cập một cách thụ động, để các yêu cầu (request) và phản hồi (response) cho tôi biết những câu hỏi nào đáng để đặt ra, và chỉ sau đó mới đi vào mã nguồn để xác nhận (hoặc bác bỏ) những gì tôi đang thấy.

Điều này đồng nghĩa với việc tôi phải bắt tay vào tìm hiểu kiến trúc và ngăn xếp mạng (network stack) của Electron - những kỹ năng mà sau này sẽ rất hữu ích.

Đến giờ chúng ta đều biết rằng các ứng dụng Electron được vận chuyển kèm với Chromium. Trình duyệt này cung cấp công cụ hiển thị (rendering engine) cho giao diện người dùng dựa trên web của ứng dụng, nhưng nó cũng cung cấp một ngăn xếp mạng mà các tiến trình renderer có thể sử dụng cho các kết nối HTTP và WebSocket.

Đây là một lựa chọn phổ biến (và được khuyến nghị) để cho phép các ứng dụng giao tiếp với backend từ xa, nhưng không phải là lựa chọn duy nhất. Các ứng dụng cũng có thể thực hiện các yêu cầu HTTP bằng cách sử dụng http/https/fetch của Node. Việc xác định yêu cầu đi theo con đường nào trở nên quan trọng khi bạn cố gắng chặn (intercept) nó.

Trong một số trường hợp, như với VS Code, ứng dụng sẽ có kiến trúc tách rời, nơi có một nhóm các tiến trình riêng biệt đóng vai trò là host cho các extension. Điều này giúp duy trì ranh giới rõ ràng giữa các trách nhiệm riêng biệt; trong trường hợp của VS Code, đó là ranh giới rõ ràng giữa giao diện người dùng (UI), chức năng IDE và các plugin/extension.

Một trong những cách cổ điển để chặn lưu lượng mạng của ứng dụng là thiết lập một máy chủ proxy và cấu hình ứng dụng đó sử dụng proxy này.

Proxy đóng vai trò là "người đứng giữa" (man-in-the-middle - MITM): nó chặn các yêu cầu HTTP từ client, chuyển tiếp chúng đến máy chủ và chuyển tiếp các phản hồi từ máy chủ trở lại client.

Một sự thật thú vị: cách tiếp cận tương tự khá phổ biến trong môi trường mạng doanh nghiệp vì mục đích kiểm tra lưu lượng, đặc biệt là trong các ngành được quản lý chặt chẽ. Phù hợp thay, một trong những công cụ mã nguồn mở chính được sử dụng cho việc này có tên là mitmproxy, công cụ mà chúng ta sẽ sử dụng trong các bước tiếp theo.

Một chi tiết quan trọng là hầu hết lưu lượng mạng ngày nay đều diễn ra qua HTTP bảo mật (HTTPS). Điều này có nghĩa là lưu lượng được mã hóa bằng TLS.

Bằng cách tin tưởng vào cơ quan cấp chứng chỉ (CA) do mitmproxy tạo ra cục bộ, client có thể chấp nhận các chứng chỉ mà mitmproxy tạo ra ngay lập tức cho từng đích đến. Thay vì một kết nối mã hóa đầu-cuối duy nhất, bạn sẽ có hai kết nối: một giữa ứng dụng và mitmproxy, và một giữa mitmproxy và máy chủ đích.

Do đó, mitmproxy có thể giải mã yêu cầu, kiểm tra nó, thiết lập một kết nối TLS riêng biệt ở phía thượng nguồn (upstream) và chuyển tiếp phản hồi trở lại ứng dụng.

Nếu bạn không muốn làm theo các đoạn mã và chỉ muốn xem kết quả, bạn có thể bỏ qua phần này.

Trên macOS, cách đơn giản nhất là sử dụng brew:

Chúng ta cần thay đổi một số cài đặt trong VS Code để định tuyến lưu lượng truy cập của nó thông qua mitmproxy. Bạn có thể thay đổi các cài đặt này bằng cách sử dụng tổ hợp phím Cmd+Shift+P và tìm kiếm "User Settings". Sau đó, bạn cần đảm bảo rằng các cài đặt dưới đây có các giá trị sau:

Http Proxy: http://localhost:8080 (mitmproxy sẽ lắng nghe các kết nối tại cổng này)

Http Proxy Strict SSL: bỏ chọn (chúng ta muốn bỏ qua việc xác minh chứng chỉ của mitmproxy so với danh sách các CA)

Http: Proxy Support: override (buộc hỗ trợ proxy cho các extension)

Sau khi thực hiện các thay đổi này, hãy nhớ khởi động lại VS Code.

Bước cuối cùng trước khi bắt đầu là khởi chạy giao diện web của mitmproxy:

Hãy đợi vài giây và bạn sẽ bắt đầu thấy một số lưu lượng mạng từ VS Code truyền qua đó.

Bạn sẽ thấy một số trường văn bản ở trên cùng. Hiện tại bạn có thể bỏ qua hầu hết chúng; trường hữu ích nhất là trường đầu tiên, Search. Trường này cung cấp các khả năng tìm kiếm mạnh mẽ như tìm kiếm từ khóa, regex, v.v. Ví dụ, nếu chúng ta đặc biệt quan tâm đến các yêu cầu mà VS Code gửi đến API Extensions Marketplace của nó, chúng ta có thể chỉ cần sử dụng "marketplace" làm chuỗi lọc.

Điều này sẽ khớp với tất cả các yêu cầu gửi đến https://marketplace.visualstudio.com và tất cả các đường dẫn con của nó.

GitHub CopilotBảo mậtKỹ thuậtReverse EngineeringProxy
Đọc bài gốc

Bài viết được AI dịch và tổng hợp tự động từ Hacker News Nổi bật (buzzing.cc bản dịch tiếng Trung). Liên kết bài gốc ở phía trên. Dữ liệu đồng bộ qua API công khai được ghi nguồn tại AI HOT (canonical) ↗. AIHOT.vn luôn dẫn nguồn đầy đủ — nếu bạn thấy điểm cần chỉnh sửa, hãy gửi ý kiến tại trang phản hồi.