Httptap - Xem được các yêu cầu HTTP/HTTPS của mọi chương trình Linux
(github.com/monasticacademy)- httptap là công cụ chạy một chương trình Linux theo dạng
httptap -- <command>và hiển thị trong terminal phần tóm tắt các yêu cầu/phản hồi HTTP/HTTPS mà chương trình đó tạo ra - Hoạt động mà không cần quyền root, daemon, thay đổi toàn hệ thống, quy tắc
iptableshay thay đổi bảng định tuyến; file thực thi là binary Go tĩnh không có phụ thuộc - Hiện chỉ dành cho Linux, và cho biết khó port sang hệ điều hành khác vì sử dụng các system call riêng của Linux như network namespace
- Lưu lượng HTTPS được giải mã bằng cách tạo nhanh một cơ quan chứng thực khi chạy rồi inject vào môi trường subprocess; hoạt động theo kiểu transparent TCP proxy xử lý các gói IP/TCP/UDP thô
- Trên Ubuntu 23.10 trở lên hoặc các bản phân phối mặc định tắt unprivileged user namespace, có thể cần cấu hình
sysctl; cũng có các hạn chế như nhận kết nối đến và truy cập/dev/net/tun
httptap làm gì
- httptap bọc và chạy một lệnh Linux bất kỳ, đồng thời hiển thị các yêu cầu HTTP/HTTPS mà lệnh đó tạo ra
- Cách dùng cơ bản là
httptap -- <command> - Ví dụ khi chạy
curl https://monasticacademy.org, nó hiển thị yêu cầuGET https://monasticacademy.org/và phản hồi308
- Cách dùng cơ bản là
- Trong ví dụ Python
requests.get('https://monasticacademy.org'), nó theo các redirect và hiển thị hai yêu cầu- Yêu cầu đầu tiên là
308chohttps://monasticacademy.org/ - Yêu cầu tiếp theo là
200chohttps://www.monasticacademy.org/
- Yêu cầu đầu tiên là
Cài đặt và điều kiện chạy
- Có thể cài binary dựng sẵn bằng cách tải tarball của bản phát hành mới nhất
- Có thể xem tất cả phiên bản và kiến trúc CPU tại releases
- Cũng cung cấp cách cài bằng Go
go install github.com/monasticacademy/httptap@latest
- Thông thường khi chạy không cần quyền root, cũng không cần daemon hay cấu hình toàn hệ thống
- Không tạo quy tắc
iptables - Không thay đổi bảng định tuyến
- Nhìn chung không ảnh hưởng đến các tiến trình khác trên cùng hệ thống
- Không tạo quy tắc
- Trên Ubuntu 23.10 trở lên cần các thiết lập sau
sudo sysctl -w kernel.apparmor_restrict_unprivileged_unconfined=0sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
- Thiết lập này vô hiệu hóa tính năng kernel gần đây vốn hạn chế user namespace không đặc quyền
- Cũng có thể cần trên các bản phân phối khác mặc định tắt unprivileged user namespace
- Đang nghiên cứu cách cung cấp kèm AppArmor profile cho httptap để loại bỏ nhu cầu này
Ví dụ sử dụng
- Ví dụ chạy
curl -s https://buddhismforai.sutra.co -o /dev/nullcho thấy máy chủ trả về redirect302 - Nếu cho phép theo redirect như
curl -sL, các yêu cầu bổ sung cũng được hiển thị- Yêu cầu đầu tiên là
302 - Yêu cầu thứ hai là
200cho URL đích của redirect
- Yêu cầu đầu tiên là
- Trong ví dụ
gcloud compute instances list, có thể kiểm tra các HTTP endpoint mà Google Cloud CLI dùng nội bộPOST https://oauth2.googleapis.com/tokenGET https://compute.googleapis.com/compute/v1/.../aggregated/instances?...- Output thông thường của
gcloudxuất hiện cùng log yêu cầu của httptap
- Ví dụ
kubectl get allhiển thị yêu cầu đến Kubernetes API server--https 443 6443khiến các kết nối TCP tới cổng 443 và 6443 được xử lý như HTTPS--insecure-skip-tls-verifylà cần thiết vì kubectl không dùng cơ quan chứng thực do httptap tạo ra
- Ví dụ
curl --doh-url https://cloudflare-dns.com/dns-querycho thấy luồng DNS-over-HTTP- Hai yêu cầu đầu tiên là truy vấn DNS
- Hai yêu cầu tiếp theo là các yêu cầu HTTP thông thường tới trang đích
- Khi dùng cùng lúc các tùy chọn
--headvà--body, nó in ra HTTP header và payload thô
Xuất HAR
- Có thể dump yêu cầu và phản hồi HTTP thành file HAR bằng tùy chọn
--dump-har out.har - File HAR được tạo có thể được trực quan hóa bằng nhiều HAR viewer
- Ví dụ được nêu là Google HAR Analyzer
- HAR ví dụ chứa yêu cầu
308 Redirecttớihttps://monasticacademy.orgvà yêu cầu200 OKtớihttps://www.monasticacademy.org
Truy cập localhost
- Để truy cập cổng localhost của host từ bên trong httptap, dùng
host.httptap.localhoặc169.254.77.65thay vìlocalhost - Mỗi network namespace của Linux có thiết bị loopback riêng là
127.0.0.1, nên127.0.0.1:1234bên trong httptap không phải cùng địa chỉ và cổng trên host - httptap hardcode việc định tuyến
169.254.77.65tới127.0.0.1để обход qua vấn đề này
Subprocess được daemon hóa
- Trên Linux, có thể tạo subprocess vẫn còn tồn tại sau khi tiến trình gốc đã kết thúc
- Đây là cách phổ biến với daemon và các ứng dụng GUI chạy từ dòng lệnh
- Khi chạy những tiến trình như vậy dưới httptap, tiến trình đã daemon hóa vẫn tiếp tục ở trong network namespace của httptap
- Tùy chọn
--no-exitkhiến httptap tiếp tục proxy và ghi log ngay cả sau khi subprocess được chạy tức thời đã kết thúc- Trong ví dụ Visual Studio Code, dùng dạng
httptap --no-exit -- code --ignore-certificate-errors . - Để kết thúc, cần đóng VS Code rồi dùng
Ctrl+Cđể dừng httptap
- Trong ví dụ Visual Studio Code, dùng dạng
- Nếu httptap kết thúc trước mà không có
--no-exit, dù network namespace vẫn còn, không còn tiến trình nào đọc gói từ thiết bị TUN nên kết nối mạng của ứng dụng sẽ bị ngắt - Trong ví dụ
setsid setsid curl http://httpbin.org/getvà ví dụ Pythonfork,setsid,fork, nếu không có--no-exitthì xảy ra lỗiCould not resolve host
Cách hoạt động
httptap -- <command>chạy<command>trong một network namespace cô lập, và inject cơ quan chứng thực được tạo nhanh để giải mã lưu lượng HTTPS- Nó tạo thiết bị TUN của Linux và cấu hình môi trường subprocess để toàn bộ lưu lượng mạng đi qua thiết bị đó
- Lưu lượng được ghi vào thiết bị TUN được chuyển tới file descriptor của tiến trình đã tạo thiết bị đó
- Vì thay đổi root network namespace sẽ ảnh hưởng đến lưu lượng toàn hệ thống, httptap tạo một network namespace riêng
- Namespace đó chỉ có thiết bị loopback và thiết bị TUN
- Subprocess được chạy bên trong namespace này
- Lưu lượng nhận được từ thiết bị TUN là các gói IP thô
- httptap phân tích cú pháp gói IP và các gói TCP/UDP bên trong
- Nó phải ghi lại các gói IP thô về phía subprocess
- Phần triển khai TCP/IP riêng của nó thiếu nhiều phần của toàn bộ giao thức TCP, nhưng hoạt động hợp lý cho mục đích này
- Khi subprocess gửi yêu cầu tới
www.example.com, httptap nhận TCP SYN hướng đến IP đích và phản hồi bằng SYN+ACK- Riêng nó dùng API socket thông thường của Linux kernel để thiết lập kết nối TCP tới IP đích thật
- Sau đó chuyển tiếp dữ liệu hai chiều
- Cấu trúc này là transparent TCP proxy truyền thống
- Giải mã HTTPS được xử lý bằng cách inject cơ quan chứng thực
- Khi khởi động, nó tạo cơ quan chứng thực tương ứng với private key và x509 certificate
- Ghi chứng chỉ vào filesystem chỉ subprocess nhìn thấy
- Thiết lập các biến môi trường chỉ subprocess nhìn thấy để thêm cơ quan chứng thực đó vào danh sách tin cậy
- Vì httptap có private key của cơ quan chứng thực, nó có thể chứng minh như thể mình là máy chủ mà subprocess muốn liên lạc và đọc các yêu cầu HTTP dạng plaintext
Hạn chế
- Hiện chỉ dành cho Linux và phụ thuộc vào các system call riêng của Linux như network namespace
- Tiến trình không thể lắng nghe các kết nối mạng đi vào
- Cần quyền truy cập
/dev/net/tun - Tất cả yêu cầu ICMP echo đều được echo nguyên trạng mà không gửi gói ICMP ra mạng thật
2 bình luận
it was developed at the Monastic Academy in Vermont in the US. We believe that a monastic schedule, and the practice of the Buddhist spiritual path more generally, provide ideal conditions for technological development.
Ý kiến trên Hacker News
Mục “How it was made” trong README thú vị không kém gì bản thân công cụ
Nội dung nói rằng họ sống và tu tập cùng nhau trên một mảnh đất rộng hơn 100 acre một chút, cùng tụng niệm và thiền vào buổi sáng/tối, mỗi tháng tổ chức và tham gia khoảng 1 tuần retreat thiền. Thời gian còn lại, họ cùng quản lý đất đai, bảo trì tòa nhà, nấu ăn, dọn dẹp, lập kế hoạch, gây quỹ, và trong vài năm qua còn cùng phát triển phần mềm
Vào thời điểm microcode và logic gây ra vấn đề ở cấp nano giây, một kỹ sư làm việc quá sức khi nghỉ việc đã để lại trên terminal một ghi chú như thư từ chức: “Tôi sẽ đến một commune ở Vermont và không xử lý bất kỳ đơn vị thời gian nào ngắn hơn mùa nữa”
Việc đó có phải ý tưởng hay không, hay có dẫn tới kết quả họ hình dung không, lại là chuyện khác
Sự kết hợp giữa công nghệ và thiền khá cuốn hút. Bản thân ý tưởng thì hấp dẫn, nhưng thực sự làm được có lẽ sẽ khó. Trông như một kiểu Recurse theo phong cách Phật giáo
httptap là một trình theo dõi HTTP theo phạm vi tiến trình, có thể chạy mà không cần quyền root
Nếu chạy một chương trình Linux như
httptap <chương trình>, bạn có thể thấy trace các request và response HTTP/HTTPS trên stdouthttptap -- python -c "import requests; requests.get('https://monasticacademy.org')"---> GET https://monasticacademy.org/<--- 308 https://monasticacademy.org/ (15 bytes)---> GET https://www.monasticacademy.org/<--- 200 https://www.monasticacademy.org/ (5796 bytes)Cách làm là chạy trong một network namespace bị cô lập và dùng gVisor làm TCP/IP stack riêng. Vì không phải HTTP proxy nên không phụ thuộc vào cấu hình proxy. Với lưu lượng TLS, nó tạo CA tức thời để giải mã, và không cài đặt rule
iptableshay thay đổi hệ thống toàn cụcnetstacktrong một số tính năng trên macOSĐặc biệt nếu không cần cấu hình proxy thì còn hữu ích hơn
https://blog.wireshark.org/2010/02/running-wireshark-as-you/
Ý tưởng chạy tiến trình trong một network namespace bị cô lập thật thiên tài
Phần HTTPS còn thú vị hơn. Có vẻ nó đặt các biến môi trường phổ biến[1] để chương trình dùng CA bundle trong thư mục tạm, nhưng vấn đề là chương trình có thể đơn giản bỏ qua các biến đó, giống như các biến thể của
http_proxyTôi cũng thấy nó mount một overlay filesystem lên
/etc/resolv.conf[2]. Không biết nếu httptap mount thư mục/etc/ca-certificatesthành CA bundle tạm thời thì có giúp gì không[1] https://github.com/monasticacademy/httptap/blob/cb92ee3acfb2...
[2] https://github.com/monasticacademy/httptap/blob/cb92ee3acfb2...
Việc httptap mount overlay lên
/etc/resolv.conflà vì với phân giải DNS cũng không có cách chắc chắn để nói với một tiến trình tùy ý rằng nó phải dùng DNS server nào, tương tự như CA root. Dù vậy,/etc/resolv.conflà một lựa chọn khá đáng tin. Ngay khi đưa tiến trình vào network namespace, nó không còn truy cập được resolver systemdlocalhost:53, cấu hình phổ biến nhất trên Linux desktop, nên phải cung cấp phân giải DNSMount overlay cho
/etc/ca-certificatescũng có thể hữu ích. Tuy nhiên khi nhìn cấu trúc thư mục đó thì tôi khá ngỡ ngàng vì nó quá thiếu nhất quán giữa các distro. Dù vậy vẫn làm được. Nếu ai biết cách thêm chứng chỉ vào thư mục đó sao cho ít nhất một số triển khai TLS nhận ra, tôi muốn nghe thêmLà phản ví dụ, có thể tưởng tượng một malware giao tiếp qua TLS và có mã đã biên dịch bị obfuscate mạnh. Nó có thể nhúng sẵn một tập CA certificate cố định vào binary và hoàn toàn không mở filesystem. Dù vậy nó vẫn có thể tạo kết nối TLS an toàn trong khoảng 10 năm cho đến khi phần lớn root CA certificate hết hạn. TLS được xử lý hoàn toàn trong user space, và không có gì đảm bảo nó dùng OpenSSL hay thư viện phổ biến nào khác, nên cũng không thể kỳ vọng cách hook vào một hàm OpenSSL cụ thể. Nếu server dùng chứng chỉ tự ký và client vì lý do nào đó chấp nhận nó thì còn tệ hơn
Dù vậy, với một chút công sức, chắc chắn có thể xử lý ổn định 99% trường hợp. Vẫn tốt hơn là không có gì
Dùng thiết bị TUN ở đây đúng là một ý tưởng rất hay. Phần “How it was made” trong README cũng thuộc hàng hay nhất trong những gì tôi từng đọc trên GitHub README
Tôi đang làm một thứ tên là Subtrace[1], có thể tự động chặn cả request đi vào lẫn request đi ra. Cũng buồn cười là giao diện để khởi chạy chương trình có vẻ đã hội tụ về cùng một dạng[2]. Tuy vậy, mục tiêu của Subtrace hơi khác httptap, gần với mảng quan sát/giám sát dịch vụ backend trên cloud hơn, nên nhấn mạnh request hai chiều. Cách tiếp cận cũng khác. Nó dùng Seccomp BPF để chặn khoảng 10 system call như
socket,connect,listen,accept, v.v., rồi proxy mọi kết nối TCP qua Subtrace. Sau đó nó phân tích request HTTP từ TCP stream, và tái sử dụng tab Network của Chrome DevTools để chạy trong trình duyệt như một web app thông thường rồi hiển thị cho người dùngTôi tò mò không biết có giai thoại thú vị nào khi chạy chương trình bên dưới httptap không. Cũng tò mò chương trình nào “gọi về nhà” nhiều nhất
[1] https://github.com/subtrace/subtrace
[2] https://docs.subtrace.dev/quickstart
https://github.com/M66B/NetGuard
Khó tin nhưng trong thư mục
networktabcủa repo có một thử nghiệm làm dở một nửa nhằm làm điều tương tự với tab Network của Firefox. Đây là một dự án rất hay nên tôi muốn tìm hiểu thêm, và cũng rất sẵn lòng trao đổi thêmMột công cụ khác để người dùng không có quyền đặc quyền phân tích network traffic là dùng rootless Podman với Pasta
Chỉ cần thêm phần sau vào tùy chọn
podman run--network=pasta:--pcap,myfile.pcapKhi đó Pasta sẽ ghi network traffic vào file PCAP để có thể phân tích sau. Tôi cũng đã viết một ví dụ đơn giản phân tích file PCAP đã ghi bằng
tsharkhttps://github.com/eriksjolund/podman-networking-docs?tab=re...
Khá thú vị. Tôi từng viết một thư viện có chức năng “tap” tương tự cho ứng dụng Go: https://github.com/henvic/httpretty
https://asciinema.org/a/297429
Tôi cũng từng nghĩ đến việc làm kiểu này cho chương trình bất kỳ, nhưng chưa thật sự đào sâu cách triển khai. Thấy có người làm được thì rất vui
Tôi thắc mắc vì sao không dùng eBPF. Như vậy có thể xem một lượt request HTTP của mọi process, kể cả những process đang chạy sẵn. Hơn nữa có vẻ không cần bận tâm đến TLS, ví dụ chỉ cần hook vào
write(2)là đượcwrite(2)thì giải quyết TLS như thế nào. Bạn có thể đọc và sửa ciphertext, nhưng vì process không gọiwrite(2)với byte plaintext nên bạn không đọc được request HTTP thật sự. Cuối cùng bạn chỉ thấy các byte đã mã hóa được đưa lên mạng, thứ mà NSA cũng thấy đượcCần mẹo chứng chỉ CA giống như httptap dùng. Tất nhiên có các lưu ý như certificate pinning, nhưng trong phần lớn kịch bản thực tế thì có thể làm cho nó hoạt động ổn định
Khi làm Subtrace[1], tôi đã nghĩ về riêng vấn đề này nhiều đến mức phi lý, nên nếu có cách tiếp cận đơn giản hơn hoặc thanh lịch hơn thì tôi thật sự quan tâm
[1] https://github.com/subtrace/subtrace
writebằng eBPF cũng không giúp giải mã TLSDù sao thì càng nhiều lựa chọn càng tốt
Hay đấy. Có lẽ tôi sẽ dùng ngay để debug cấu hình nginx
Hiện giờ tôi dùng
curl -vrồi phải tự dò trong output xem sai ở đâu, còn công cụ này có vẻ sẽ làm lộ ngay những thứ như vòng lặp redirectTrông rất phù hợp khi cần xem nhanh và thô call stack HTTP/S của một ứng dụng
Cá nhân tôi thích eBPF để xem mọi thứ, nhưng tiện ích này có thể giúp thu hẹp vào phần quan trọng trong tracing bằng eBPF
Trông có vẻ hay
Hồ sơ GitHub trỏ đến https://www.monasticacademy.org/about; bản thân điều đó thì tôi không có ý kiến gì đặc biệt, nhưng tôi đã tò mò không biết các khóa retreat huấn luyện kiểu tu viện của họ liên quan thế nào đến dự án GitHub này
Nhìn xuống cuối README thì thấy phần giải thích mối liên hệ: https://github.com/monasticacademy/httptap?tab=readme-ov-fil...
Điều đó có nghĩa là trên khu đất 123 mẫu Anh ở Vermont, mọi người sống cùng nhau theo một cấu trúc tu viện Phật giáo tương đối truyền thống. Chỉ là họ không phải là tu sĩ đã thọ giới chính thức. Ban ngày, họ cùng thực hiện nhiều dự án kỹ thuật/phi kỹ thuật. Liên kết README ở trên là một phần tổng quan tốt
https://github.com/monasticacademy/httptap?tab=readme-ov-fil...