Tăng cường bảo mật runtime và quản trị với tiện ích mở rộng AWS Lambda Runtime proxy

Các AWS Lambda runtime Lambda Runtime API để giao tiếp với dịch vụ Lambda. Runtime sử dụng nó để nhận các sự kiện đi vào để xử lý bởi các function handler, trả về phản hồi handler thành công đến dịch vụ Lambda và báo các lỗi. Bài viết này chỉ dẫn làm thế nào để chắn các sự kiện đi vào và phản hồi đi ra mà không cần thay đổi function code sử dụng mẫu Runtime API proxy.

Hướng tiếp cận này cho phép các nhà cung cấp bảo mật và các nhóm kỹ sư cung cấp các công cụ bảo mật và quản trị một cách nâng cao và không ảnh can thiệp cho các hàm Lambda. Các trường hợp sử dụng bao gồm làm sạch payload sự kiện, chặn các sự kiện độc hại, kiểm tra và tăng cường payload.

Tổng quan

Lambda Runtime API là một HTTP endpoint có sẵn với Lambda execution environment. Nó cho phép Lambda thực thi hàm code để giao tiếp với dịch vụ Lambda. Nó được sử dụng bởi Lambda runtime được quản lý, ví dụ như Nodejs hoặc Python, cũng như là custom runtime, nó cho phép các nhà phát triển tạo Lambda runtime của riêng họ trong bất kỳ ngôn ngữ lập trình mà họ chọn.

Lambda runtime sử dụng Runtime API để nhận sự kiện đang đến tiếp theo được xử lý bởi hàm handler và trả về phản hồi handler đến dịch vụ Lambda.

Lambda Extensions cho phép bạn tích hợp các hàm Lambda với  các công cụ mà tổ chức của bạn ưa thích như giám sát, quan sát, bảo mật và quản trị. Bạn có thể dùng extensions from AWS, AWS Lambda Ready partners,và các dự án mã nguồn mở cho một khoảng lớn trường hợp sử dụng. Các tiện ích cho phép thêm chức năng như các cấu hình tải trước hoặc nâng cấp từ xa mà không cần dùng các thay đổi can thiệp vào hàm code. Lambda Extensions được đóng gói thành Lambda layers và chạy như là một quá trình độc lập ở môi trường thực thi.

Dưới đây là cách runtime và các tiện ích giao tiếp với dịch vụ Lambda thông qua Runtime API và Extensions API endpoint:

Khi bạn đăng ký tiện ích của bạn với dịch vụ Lambda, bạn có thể xác định bạn muốn nhận sự kiện INVOKE. Dịch vụ Lambda gửi sự kiện này đến tiện ích một cách bất đồng bộ khi một hàm được thực thi.

Thông tin được cung cấp gồm có metadata của hàm thực thi, nhưng không có payload sự kiện. Điều này để sự kiện có ích cho quan sát nhưng bị hạn chế cho các trường hợp bảo mật và quản trị ứng dụng, chẳng hạn như xem xét payload về các lỗ hổng, làm sạch đầu vào và chặn các sự kiện độc hại.

Lambda Runtime API proxy là một mẫu cho phép bạn móc vào chu kỳ yêu cầu và phản hồi của hàm thực thi. Nó cho phép bạn dùng các tiện ích để dùng các bảo mật nâng cao, thỏa thuận, quản trị và giám sát các kịch bản mà không cần thay đổi hàm code. Bạn có thể thêm các cơ chế bảo mật runtime, áp dụng các thủ tục kiểm tra cho luồng dữ liệu vào và ra khỏi hàm, tăng cường khả năng giám sát bằng tự động thêm việc theo dõi các header và hơn nữa.

Hiểu về quy trình hoạt động của Lambda Runtime API

Sau đây là cách Lambda Runtime tiêu thụ Lambda Runtime API:

Lambda runtime sử dụng giá trị của biến môi trường AWS_LAMBDA_RUNTIME_API để tạo các yêu cầu Runtime API. Hai endpoint chính là /next được dùng nhận sự kiện tiếp theo để xử lý và /response để trả về kết quả sự kiện đang xử lý đến dịch vụ Lambda.  Ngoài ra, Runtime API cũng cung cấp các endpoint để báo cáo lỗi. Xem toàn bộ protocol and schema definitions  của Runtime API.

Cách tiếp cận Runtime API proxy hoạt động

Runtime API proxy là một thành phần bạn có thể xây dựng để móc vào quy trình thực thi. Nó ủy quyền các yêu cầu và phản hồi, cho phép bạn tăng cường chúng và kiểm soát quy trình làm việc:

Khi dịch vụ Lambda tạo môi trường thực thi mới, nó sẽ bắt đầu bằng cách khởi tạo các tiện ích mở rộng được gắn vào hàm. Môi trường thực thi chờ tất cả các tiện ích mở rộng đăng ký với dịch vụ Lambda bằng cách gọi API tiện ích mở rộng /register endpoint, sau đó tiến hành khởi tạo runtime. Điều này cho phép bạn khởi động trình nghe HTTP proxy API thời gian chạy trong quá trình khởi tạo tiện ích mở rộng, giúp nó sẵn sàng phân phát các yêu cầu runtime.

Theo mặc định, giá trị của biến môi trường AWS_LAMBDA_RUNTIME_API trong quy trình thời gian chạy trỏ đến điểm cuối API Lambda Runtime 127.0.0.1:9001. Bạn có thể dùng một  wrapper script để thay đổi giá trị để trỏ đến Runtime API proxy endpoint thay thế.

Một wrapper script cho phép bạn tùy chỉnh hành vi bắt đầu runtime của hàm Lambda của bạn bằng cách cho bạn dùng các thông số cấu hình không thể được thay đổi trong các biến môi trường xác định ngôn ngữ. Bạn có thể thêm một wrapper script vào hàm của bạn bằng cách cài đặt biến môi trường AWS_LAMBDA_EXEC_WRAPPER. Wrapper script sau giá định rằng Runtime API  proxy đang lắng nghe trên port 9009.

#!/bin/bash
export AWS_LAMBDA_RUNTIME_API=”127.0.0.1:9009″
exec “$@”

Bạn có thể thêm dòng xuất này vào tập lệnh bao bọc hiện có hoặc tạo một tập lệnh mới.

Runtime Proxy API được khởi động bởi dịch vụ Lambda khi môi trường thực thi mới được tạo và sẵn sàng ủy quyền các yêu cầu từ Lambda runtime đến Runtime API trước khi gọi lần đầu tiên.

Triển khai Runtime API proxy logic

AWS khuyên bạn nên triển khai các tiện ích mở rộng bằng ngôn ngữ lập trình biên dịch thành tệp thực thi nhị phân, chẳng hạn như Golang hoặc Rust. Điều này cho phép bạn sử dụng tiện ích mở rộng với bất kỳ Lambda runtime nào. Các tiện ích mở rộng được triển khai bằng các ngôn ngữ thông dịch, chẳng hạn như JavaScript và Python hoặc các ngôn ngữ yêu cầu máy ảo bổ sung, chẳng hạn như Java và C#, chỉ có thể được sử dụng với runtime cụ thể đó

Sơ đồ sau hiển thị một kịch bản trong đó cả sự kiện đến và phản hồi gửi đi đều được tiện ích mở rộng xử lý. Bạn có thể sử dụng quy trình công việc này để kiểm tra tải trọng sự kiện hoặc phản hồi, dọn dẹp chúng hoặc đưa các thuộc tính bổ sung vào. Bạn có thể sử dụng nó cho các tình huống như che giấu số tài khoản, loại bỏ thông tin nhận dạng cá nhân (PII) hoặc chèn các header có thể quan sát được.

Sơ đồ này thể hiện một kịch bản nâng cao, trong đó sự kiện gửi đến đầu tiên được xác định là độc hại và bị Runtime API proxy từ chối. Hàm handler không được gọi. Sự kiện thứ hai không bị gắn cờ là độc hại và do đó được chuyển tiếp đến trình xử lý để xử lý. Bạn có thể sử dụng quy trình làm việc này cho các tình huống bảo mật như bảo vệ runtime ứng dụng.

Giải pháp đối tác AWS sử dụng Runtime API Proxy

“Sử dụng giải pháp Lambda Runtime API proxy là một cách tiếp cận mang tính thay đổi cuộc chơi đối với chúng tôi. Nó cho phép chúng tôi hỗ trợ nhiều Lambda runtime chỉ bằng một lần triển khai, cung cấp khả năng hiển thị toàn diện về quá trình thực thi Lambda và cho phép phát hiện những kẻ tấn công nhắm mục tiêu vào các ứng dụng không có máy chủ”, Julio Guerra, Giám đốc kỹ thuật, Quản lý bảo mật ứng dụng, Datadog cho biết.

“Lambda Runtime API proxy là một giải pháp đơn giản cung cấp cho chúng tôi một cách có thể cắm được để bảo vệ các URL hàm Lambda.Chúng tôi có thể triển khai ủy quyền và làm phong phú yêu cầu mà không cần thay đổi hàm code.” Ilya Zilber, Giám đốc cấp cao, Solutions Engineering, Okta Inc. cho biết.

Các biện pháp bảo mật tốt nhất

Các tiện ích mở rộng chạy trong cùng môi trường thực thi với hàm, vì vậy chúng có cùng mức truy cập vào các tài nguyên như file system, networking và các biến môi trường. Các quyền IAM được gán cho hàm này sẽ được chia sẻ với các tiện ích mở rộng. Hướng dẫn của chúng tôi là chỉ định các đặc quyền yêu cầu tối thiểu cho các chức năng của bạn.

Luôn luôn cài đặt các tiện ích chỉ từ nguồn tin tưởng. Sử dụng các công cụ hạ tầng dạng mã (IaC), như  AWS CloudFormation, để đơn giản hóa công việc gắn cấu hình tiện ích giống nhau, bao gồm các quyền  AWS Identity and Access Management (IAM) cho nhiều hàm. Ngoài ra, các công cụ IaC cho phép bạn có một bảng ghi kiểm tra của các tiện ích và các phiên bản bạn đã từng sử dụng trước đó.

Khi xây dựng các tiện ích, không ghi các dữ liệu nhạy cảm. Dọn sạch payload và metadata trước khi ghi hoặc lưu trữ chúng cho các mục đích kiểm tra.

Các cân nhắc

Phương pháp Runtime API proxy cho phép bạn kết nối với quy trình yêu cầu/phản hồi của Lambda, hỗ trợ các trường hợp sử dụng bảo mật và khả năng quan sát mới. Có một số cân nhắc quan trọng:

  • Điều này đòi hỏi bạn phải hiểu rõ về vòng đời của môi trường thực thi Lambda và API thời gian chạy Lambda. Bạn phải triển khai ủy quyền cho tất cả các điểm cuối API thời gian chạy và xử lý các lỗi thời gian chạy tiềm ẩn.
  • Chuẩn bị tiện ích của bạn cho khả năng kết hợp khi nhiều kịch bản có nhiều hơn một tiện ích triển khai mẫu Runtime API proxy. Cho phép các khách hàng của tiện ích cấu hình tiện ích thông qua các biến môi trường dùng ít nhất 2 thông số – port mà proxy lắng nghe và Runtime API endpoint proxy của bạn điều hướng các yêu cầu tới. Giá trị sau nên mặc định là giá trị gốc của biến môi trường AWS_LAMBDA_RUNTIME_API. Xem ví dụ triển khai ở chi tiết bên dưới.
  • Các yêu cầu Proxying API với các phản hồi đệm mặc định yêu cầu thêm việc hỗ trợ các hàm với response payload streaming.
  • Các yêu cầu Proxying API làm tăng độ trễ. Chi phí bổ sung phụ thuộc vào cách triển khai của bạn. AWS đề nghị sử dụng các ngôn ngữ lập trình có thể được biên dịch thành một tệp thực thi nhị phân, chẳng hạn như Rust và Golang, và giữ các tiện ích của bạn nhẹ và tối ưu.

Các ví dụ

Bạn có thể tìm thấy các tiện ích mở rộng mẫu triển khai Runtime Proxy API tại https://github.com/aws-samples/aws-lambda-extensions/. Xem các mẫu Golang, Rust, và Node.js.

Làm theo hướng dẫn được mô tả trong README.md để biết hướng dẫn từng bước về cách chạy tiện ích mở rộng.

Kết luận

Bài viết này giới thiệu và minh họa mẫu Lambda Runtime API proxy. Bạn có thể sử dụng mẫu này để kết nối với quy trình phản hồi và yêu cầu hàm Lambda nhằm chặn, xử lý, kiểm tra, sửa đổi và chặn các sự kiện gửi đến cũng như phản hồi handler.

Bạn có thể sử dụng mẫu này để triển khai các kịch bản quản trị và bảo mật runtime nâng cao cũng như các kịch bản từ các miền khác. Khách hàng và đối tác của AWS có thể sử dụng phương pháp tiếp cận giải pháp nâng cao này để tăng cường tính bảo mật và khả năng quan sát nâng cao cho các hàm Lambda mà không yêu cầu thay đổi code.

Để có thêm tài nguyên học tập serverless, truy cập Serverless Land.