Blog Go
Ra mắt Module Mirror và Cơ sở dữ liệu Checksum
Chúng tôi vui mừng chia sẻ rằng mirror,
index, và
cơ sở dữ liệu checksum module của chúng tôi hiện đã sẵn sàng cho môi trường production! Lệnh go
sẽ mặc định sử dụng module mirror và cơ sở dữ liệu checksum cho
người dùng module Go 1.13. Xem
proxy.golang.org/privacy để biết thông tin về quyền riêng tư
của các dịch vụ này và
tài liệu lệnh go
để biết chi tiết cấu hình, bao gồm cách tắt việc sử dụng các máy chủ này hoặc
sử dụng các máy chủ khác. Nếu bạn phụ thuộc vào các module không công khai, hãy xem
tài liệu về cấu hình môi trường của bạn.
Bài viết này sẽ mô tả các dịch vụ này và lợi ích của việc sử dụng chúng, và tóm tắt một số điểm từ bài nói Go Module Proxy: Life of a Query tại Gophercon 2019. Xem bản ghi nếu bạn quan tâm đến bài nói đầy đủ.
Module Mirror
Modules là các tập hợp package Go
được đánh phiên bản cùng nhau, và nội dung của mỗi phiên bản là bất biến.
Tính bất biến đó cung cấp các cơ hội mới cho việc cache và xác thực.
Khi go get chạy trong chế độ module, nó phải tìm nạp module chứa
các package được yêu cầu, cũng như bất kỳ dependency mới nào được giới thiệu bởi module đó,
cập nhật các tệp
go.mod và
go.sum
khi cần. Việc tìm nạp module từ hệ thống quản lý phiên bản có thể tốn kém về
độ trễ và lưu trữ trong hệ thống: lệnh go có thể bị buộc phải tải xuống
toàn bộ lịch sử commit của kho lưu trữ chứa dependency bắc cầu, ngay cả
cái không được build, chỉ để giải quyết phiên bản của nó.
Giải pháp là sử dụng module proxy, nói API phù hợp hơn với
nhu cầu của lệnh go (xem go help goproxy). Khi go get chạy trong
chế độ module với một proxy, nó sẽ hoạt động nhanh hơn bằng cách chỉ yêu cầu siêu dữ liệu module
hoặc mã nguồn cụ thể mà nó cần, và không lo lắng về phần còn lại. Dưới đây là
ví dụ về cách lệnh go có thể sử dụng proxy với go get bằng cách yêu cầu danh sách
phiên bản, sau đó tệp info, mod, và zip cho phiên bản tagged mới nhất.
Module mirror là một loại module proxy đặc biệt lưu trữ siêu dữ liệu và mã nguồn trong hệ thống lưu trữ của riêng nó, cho phép mirror tiếp tục phục vụ mã nguồn không còn có sẵn từ các vị trí gốc. Điều này có thể tăng tốc tải xuống và bảo vệ bạn khỏi các dependency biến mất. Xem Go Modules trong năm 2019 để biết thêm thông tin.
Nhóm Go duy trì một module mirror, được phục vụ tại
proxy.golang.org, mà lệnh go sẽ sử dụng theo
mặc định cho người dùng module kể từ Go 1.13. Nếu bạn đang chạy phiên bản trước đó của lệnh go,
bạn có thể sử dụng dịch vụ này bằng cách đặt
GOPROXY=https://proxy.golang.org trong môi trường cục bộ của bạn.
Cơ sở dữ liệu Checksum
Modules đã giới thiệu tệp go.sum, là danh sách các hash SHA-256 của
mã nguồn và các tệp go.mod của mỗi dependency khi được tải xuống lần đầu.
Lệnh go có thể sử dụng các hash để phát hiện hành vi sai của máy chủ gốc hoặc
proxy cho bạn code khác nhau cho cùng phiên bản.
Hạn chế của tệp go.sum này là nó hoàn toàn hoạt động dựa trên tin tưởng vào lần đầu tiên bạn dùng. Khi bạn thêm một phiên bản của dependency mà bạn chưa từng thấy trước đó
vào module của bạn (có thể bằng cách nâng cấp một dependency hiện có), lệnh go
tìm nạp code và thêm các dòng vào tệp go.sum ngay lập tức. Vấn đề là
những dòng go.sum đó không được kiểm tra với bất kỳ ai khác: chúng có thể
khác với các dòng go.sum mà lệnh go vừa tạo ra cho
người khác, có thể vì proxy đã cố ý phục vụ code độc hại
nhắm vào bạn.
Giải pháp của Go là một nguồn toàn cầu của các dòng go.sum, được gọi là
cơ sở dữ liệu checksum,
đảm bảo rằng lệnh go luôn thêm cùng các dòng vào tệp go.sum của mọi người.
Bất cứ khi nào lệnh go nhận mã nguồn mới, nó có thể xác minh hash
của code đó với cơ sở dữ liệu toàn cầu này để đảm bảo các hash khớp,
đảm bảo rằng mọi người đang sử dụng cùng code cho một phiên bản nhất định.
Cơ sở dữ liệu checksum được phục vụ bởi sum.golang.org, và
được xây dựng trên Transparent Log (hay “Merkle
tree”) của các hash được hỗ trợ bởi Trillian. Ưu điểm
chính của Merkle tree là nó chống giả mạo và có các đặc tính
không cho phép hành vi sai phát hiện được, làm cho nó đáng tin cậy hơn
một cơ sở dữ liệu đơn giản. Lệnh go sử dụng cây này để kiểm tra
bằng chứng “inclusion” (rằng một bản ghi cụ thể tồn tại trong log) và bằng chứng “consistency”
(rằng cây chưa bị giả mạo) trước khi thêm các dòng go.sum mới
vào tệp go.sum của module. Dưới đây là một ví dụ về cây như vậy.
Cơ sở dữ liệu checksum hỗ trợ
một tập hợp các endpoint
được sử dụng bởi lệnh go để yêu cầu và xác minh các dòng go.sum. Endpoint /lookup
cung cấp “signed tree head” (STH) và các dòng go.sum được yêu cầu. Endpoint
/tile cung cấp các chunk của cây được gọi là tiles mà lệnh go
có thể sử dụng cho các bằng chứng. Dưới đây là ví dụ về cách lệnh go có thể
tương tác với cơ sở dữ liệu checksum bằng cách thực hiện /lookup một phiên bản module, rồi
yêu cầu các tile cần thiết cho các bằng chứng.
Cơ sở dữ liệu checksum này cho phép lệnh go sử dụng an toàn một proxy
không tin cậy. Vì có một lớp bảo mật có thể kiểm tra nằm ở trên,
một proxy hoặc máy chủ gốc không thể cố ý, tùy tiện, hoặc vô tình
bắt đầu cung cấp cho bạn code sai mà không bị phát hiện. Ngay cả tác giả của một
module cũng không thể di chuyển thẻ của họ hoặc thay đổi các bit liên quan đến
một phiên bản cụ thể từ ngày này sang ngày khác mà không bị phát hiện.
Nếu bạn đang dùng Go 1.12 hoặc cũ hơn, bạn có thể kiểm tra thủ công tệp go.sum
với cơ sở dữ liệu checksum bằng
gosumcheck:
$ go get golang.org/x/mod/gosumcheck
$ gosumcheck /path/to/go.sum
Ngoài việc xác minh được thực hiện bởi lệnh go, các
kiểm toán viên bên thứ ba có thể giúp cơ sở dữ liệu checksum chịu trách nhiệm bằng cách lặp qua log
để tìm các mục xấu. Họ có thể làm việc cùng nhau và lan truyền thông tin về trạng thái
của cây khi nó phát triển để đảm bảo rằng nó vẫn không bị xâm phạm, và chúng tôi hy vọng
cộng đồng Go sẽ vận hành chúng.
Module Index
Module index được phục vụ bởi index.golang.org, và là nguồn cấp dữ liệu công khai của các phiên bản module mới có sẵn thông qua proxy.golang.org. Điều này đặc biệt hữu ích cho các nhà phát triển công cụ muốn duy trì cache của riêng họ về những gì có sẵn trong proxy.golang.org, hoặc cập nhật về một số module mới nhất mà mọi người đang sử dụng.
Phản hồi hoặc lỗi
Chúng tôi hy vọng các dịch vụ này cải thiện trải nghiệm của bạn với modules, và khuyến khích bạn ghi lỗi nếu bạn gặp phải vấn đề hoặc có phản hồi!
Bài tiếp theo: Go 1.13 đã được phát hành
Bài trước: Chuyển đổi sang Go Modules
Mục lục blog