VPC Service Controls – Lớp học lập trình về biện pháp bảo vệ BigQuery I

1. Giới thiệu

Trong lớp học lập trình này, bạn sẽ tìm hiểu cách bảo vệ BigQuery API bằng VPC Service Controls. Lớp học lập trình bắt đầu mà không có dịch vụ API nào được bảo vệ bằng chu vi dịch vụ, cho phép chạy các truy vấn trên tập dữ liệu công khai và lưu kết quả vào bảng dự án. Truy vấn chạy trong một dự án và bảng (nơi lưu kết quả) được tạo trong một dự án khác, mô phỏng một chế độ thiết lập trong đó dữ liệu có thể được lưu trữ trong một dự án nhưng cần được truy cập bằng một dự án khác.

Tiếp theo, chúng ta sẽ giới thiệu một chu vi dịch vụ để bảo vệ dự án dữ liệu. Bạn sẽ tìm hiểu cách khắc phục các lỗi vi phạm đã quan sát được bằng cách sử dụng quy tắc đầu vào và quy tắc đầu ra, sau đó thêm một cấp truy cập để hạn chế quyền truy cập bằng địa chỉ IP nội bộ. Mục tiêu của lớp học lập trình này là:

  • Tìm hiểu cách khắc phục lỗi vi phạm khi vào và ra bằng cách sử dụng quy tắc vào và ra tương ứng.
  • Tìm hiểu lý do xảy ra một lỗi vi phạm cụ thể.
  • Phân tích phạm vi của bản sửa lỗi vi phạm đã áp dụng.
  • Sửa đổi bản sửa lỗi (quy tắc vào / ra) để thay đổi phạm vi của bản sửa lỗi bằng cách tận dụng lựa chọn cho phép lưu lượng truy cập từ địa chỉ IP nội bộ trong mạng VPC bằng cách sử dụng các cấp truy cập.

2. Thiết lập và yêu cầu về tài nguyên

Trước khi bắt đầu

Trong lớp học lập trình này, chúng tôi giả định rằng bạn đã biết:

Thiết lập

Thiết lập ban đầu của chúng tôi được thiết kế như sau:

Thiết kế ban đầu với chu vi dịch vụ không bảo vệ API.

Tạo một phạm vi dịch vụ thông thường

Trong lớp học lập trình này, chúng ta sẽ sử dụng một chu vi dịch vụ thông thường để bảo vệ project-1.

Tạo máy ảo Compute Engine

Trong lớp học lập trình này, chúng ta sẽ sử dụng 1 phiên bản Compute Engine trong project-2, nằm ở us-central1 và sử dụng mạng VPC mặc định có tên là default.

Chi phí

Bạn cần bật tính năng thanh toán trong Google Cloud Console để sử dụng các tài nguyên/API trên đám mây. Bạn nên tắt các tài nguyên đã dùng để tránh phát sinh phí ngoài phạm vi lớp học lập trình này. Người dùng mới của Google Cloud đủ điều kiện tham gia chương trình Dùng thử miễn phí trị giá 300 USD.

Các tài nguyên phát sinh chi phí là BigQuery và phiên bản Compute Engine. Bạn có thể ước tính chi phí bằng công cụ tính mức giá của BigQuerycông cụ tính mức giá của Compute Engine.

3. Quyền truy cập vào BigQuery mà không có các hạn chế của VPC Service Controls

Truy vấn tập dữ liệu công khai và lưu kết quả trong project-1

  1. Truy cập vào project-2project-1 để xác minh xem bạn có thể truy cập vào BigQuery API hay không bằng cách truy cập vào trang BigQuery Studio. Bạn có thể làm như vậy vì ngay cả khi project-1 nằm trong một ranh giới dịch vụ, thì ranh giới đó vẫn chưa bảo vệ bất kỳ dịch vụ nào.
  2. Từ project-2, hãy chạy truy vấn sau để truy vấn một tập dữ liệu công khai.
SELECT  name, SUM(number) AS total
FROM  `bigquery-public-data.usa_names.usa_1910_2013`
GROUP BY   name
ORDER BY total DESC
LIMIT 10;

Sau khi chạy truy vấn đến tập dữ liệu công khai (trong khi vẫn ở project-2):

  1. Nhấp vào Lưu kết quả rồi chọn bảng BigQuery. (tham khảo ảnh chụp màn hình bên dưới). Lưu kết quả BigQuery.
  2. Chọn project-1 làm dự án đích.
  3. Đặt tên cho Tập dữ liệu là codelab_dataset. (Chọn TẠO TẬP DỮ LIỆU MỚI, trừ phi bạn đang sử dụng một tập dữ liệu hiện có). Chọn dự án đích trong khi lưu kết quả BigQuery.
  4. Đặt tên cho bảng là: codelab-table.
  5. Nhấp vào Lưu.

Dữ liệu tập dữ liệu công khai đã được lưu trữ thành công trong project-1 do thực thi truy vấn từ project-2.

Đã lưu Tập dữ liệu truy vấn trong project-1 từ project-2

Trong khi vẫn ở trong BigQuery Studio project-2, hãy chạy truy vấn sau để chọn dữ liệu từ:

  • Dự án: project-1
  • Tập dữ liệu: codelab_dataset
  • Bảng: codelab-table
SELECT name, total
FROM `project-1.codelab_dataset.codelab-table`
ORDER BY total DESC
LIMIT 10;

Truy vấn sẽ chạy thành công vì cả project-2project-1 đều không bị hạn chế sử dụng BigQuery. Bạn có thể truy cập vào BigQuery từ mọi nơi miễn là người dùng có các quyền IAM thích hợp.

Thiết lập lớp học lập trình mà không có ranh giới dịch vụ VPC Service Controls. Sơ đồ này minh hoạ quy trình khi một chủ thể truy vấn một tập dữ liệu BigQuery. Mỗi truy vấn BigQuery sẽ khởi tạo một tác vụ BigQuery, sau đó thực hiện thao tác thực tế, trong trường hợp này là truy xuất dữ liệu. Quyền truy cập chính được minh hoạ từ một phiên bản Compute Engine và từ Internet, trong khi truy vấn từ một tập dữ liệu công khai và từ một dự án Google Cloud riêng biệt. Quy trình truy vấn dữ liệu (GetData) diễn ra thành công mà không bị VPC Service Controls chặn.

4. Bảo vệ BigQuery API trong Dự án tập dữ liệu nguồn

Sửa đổi cấu hình của phạm vi perimeter-1 và hạn chế dịch vụ BigQuery API cùng với tài nguyên được bảo vệ là project-1.

Định cấu hình phạm vi dịch vụ

Xác minh việc thực thi phạm vi dịch vụ

Từ project-2, hãy chạy truy vấn sau trong BigQuery Studio, như trong bước trước:

SELECT name, total
FROM `project-1.codelab_dataset.codelab-table`
ORDER BY total DESC
LIMIT 10;

Sẽ xảy ra lỗi vi phạm RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER đối với VPC Service Controls

Vi phạm chế độ Kiểm soát dịch vụ VPC khi truyền dữ liệu ra ngoài

Nhật ký kiểm tra hành vi vi phạm sẽ nằm trong project-1, vì đó là nơi xảy ra hành vi vi phạm vượt quá phạm vi. Bạn có thể lọc nhật ký bằng vpcServiceControlsUniqueId đã quan sát (thay thế VPC_SC_DENIAL_UNIQUE_ID bằng mã nhận dạng duy nhất đã quan sát).

severity=ERROR
resource.type="audited_resource"
protoPayload.metadata.@type="type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
protoPayload.metadata.vpcServiceControlsUniqueId="[*VPC_SC_DENIAL_UNIQUE_ID*]"

Lỗi vi phạm là egressViolations đối với:

  • principalEmail: [tài khoản người dùng chạy truy vấn]
  • callerIp: [Địa chỉ IP của tác nhân người dùng đang chạy truy vấn]
     "egressViolations": [
       {
         "targetResource": "projects/project-2",
         "sourceType": "Resource",
         "source": "projects/project-1",
         "servicePerimeter": "accessPolicies/REDACTED/servicePerimeters/perimeter-1",
         "targetResourcePermissions": [ "bigquery.jobs.create"]
       }      ],

5. Khắc phục lỗi vi phạm để tạo công việc BigQuery

Không tạo được lưu lượng truy cập xuất cho việc tạo Công việc BigQuery. Sơ đồ này minh hoạ thời điểm một chủ thể chạy một truy vấn từ project-2 cho một tập dữ liệu trong project-1. Thao tác tạo một công việc BigQuery, từ dự án tập dữ liệu (project-1) trong dự án nơi truy vấn được chạy (project-2) không thành công do lỗi vi phạm khi xuất dữ liệu của VPC Service Controls vì phạm vi dịch vụ perimeter-1 bảo vệ BigQuery API. Khi phạm vi được thiết lập, không có yêu cầu nào về BigQuery API có thể được bắt đầu từ project-1 ra bên ngoài phạm vi hoặc được bắt đầu từ bên ngoài phạm vi vào dự án được bảo vệ, trừ phi được phép theo cấu hình phạm vi dịch vụ.

Bạn có thể khắc phục lỗi vi phạm về lưu lượng truy cập đi bằng cách tạo một quy tắc về lưu lượng truy cập đi dựa trên:

  • nguồn (TỪ): cụ thể là địa chỉ email và bối cảnh của người dùng (ví dụ: địa chỉ IP của người gọi, trạng thái thiết bị, vị trí, v.v.)
  • đích đến (TO): tức là tài nguyên, dịch vụ và phương thức hoặc quyền mục tiêu.

Để khắc phục lỗi vi phạm về lưu lượng truy cập đi ra đã quan sát được, hãy tạo một quy tắc về lưu lượng truy cập đi ra cho phép lưu lượng truy cập hướng đến targetResource (project-2) bằng tài khoản người dùng chạy truy vấn (user@example.com) trên dịch vụ BigQuery và phương thức/ quyền bigquery.jobs.create.

Cấu hình Khắc phục lỗi vi phạm khi truyền dữ liệu ra ngoài.

Hành vi dự kiến của quy tắc truyền dữ liệu ra đã định cấu hình:

  • FROM | Identities: chỉ danh tính user@example.com được chỉ định mới được phép vượt qua ranh giới chu vi.
  • TO | projects: danh tính được chỉ định chỉ có thể vượt qua ranh giới chu vi nếu đích đến là dự án project-2 được chỉ định.
  • TO | Dịch vụ: danh tính được chỉ định có thể bắt đầu lưu lượng truy cập bên ngoài chu vi, chỉ hướng đến dự án được chỉ định nếu lệnh gọi API dành cho dịch vụ và phương thức được chỉ định. Nếu không, ví dụ: nếu họ thử một dịch vụ khác được bảo vệ bằng chu vi dịch vụ, thì thao tác sẽ bị chặn vì các dịch vụ khác không được phép.

Kiểm thử bản sửa lỗi: Quy tắc truyền dữ liệu ra

Sau khi quy tắc truyền dữ liệu ra được áp dụng, hãy chạy cùng một truy vấn.

SELECT name, total
FROM `project-1.codelab_dataset.codelab-table`
ORDER BY total DESC
LIMIT 10;

Một lỗi vi phạm khác sẽ xảy ra, lần này là lỗi vi phạm NO_MATCHING_ACCESS_LEVEL. Lỗi vi phạm mới khác với lỗi đầu tiên về dự án mục tiêu và phương thức.

Vi phạm chế độ Kiểm soát dịch vụ VPC cho lưu lượng truy cập đến

Lỗi vi phạm mới là lỗi vi phạm về việc xâm nhập

  • principalEmail: [tài khoản người dùng chạy truy vấn]
  • callerIp: [Địa chỉ IP của tác nhân người dùng đang chạy truy vấn]
ingressViolations: [
0: {
 servicePerimeter: "accessPolicies/REDACTED/servicePerimeters/perimeter-1"
 targetResource: "projects/project-1"
 targetResourcePermissions: [0: "bigquery.tables.getData"]}
 ]

Lỗi vi phạm đối với phương thức bigquery.tables.getData là do một lệnh gọi API do công việc BigQuery khởi tạo khi cố gắng lấy dữ liệu từ bảng BigQuery.

6. Khắc phục lỗi vi phạm để lấy dữ liệu bảng BigQuery

Quy tắc đầu vào khắc phục lỗi vi phạm đầu vào, đồng thời cung cấp chế độ kiểm soát chi tiết về những người được phép vượt qua ranh giới chu vi dịch vụ cùng với bối cảnh của quyền truy cập được phép, chẳng hạn như dự án nguồn/ mục tiêu và phương thức API mà họ có thể truy cập.

Quy tắc chuyển dữ liệu vào được định cấu hình bằng:

  • nguồn (TỪ): cụ thể là địa chỉ email và bối cảnh của người dùng (ví dụ: địa chỉ IP của người gọi, trạng thái thiết bị, vị trí, v.v.)
  • đích đến (TO): tức là tài nguyên, dịch vụ và phương thức hoặc quyền mục tiêu.

Quy tắc chuyển hướng sẽ cho phép lưu lượng truy cập đến project-1 theo người dùng được chỉ định trên dịch vụ và phương thức được chỉ định.

Khắc phục lỗi vi phạm về việc xâm nhập

Hành vi dự kiến của quy tắc chuyển hướng đã định cấu hình:

  • FROM | Identities: chỉ danh tính user@example.com được chỉ định mới được phép vượt qua ranh giới chu vi.
  • TO | projects: danh tính được chỉ định chỉ có thể vượt qua ranh giới chu vi nếu đích đến là dự án được chỉ định project-1.
  • TO | Dịch vụ: danh tính được chỉ định chỉ có thể bắt đầu lưu lượng truy cập bên trong chu vi nếu lệnh gọi API là cho BigQuery API và phương thức được chỉ định bigquery.tables.getData.

Từ nay trở đi, việc thực thi truy vấn giống hệt sẽ hoạt động đúng cách mà không vi phạm VPC Service Controls.

Chúng tôi đã hạn chế thành công BigQuery API trong project-1 để chỉ user@example.com mới có thể sử dụng API này chứ không phải user2@example.com.

VPC Service Controls bảo vệ BigQuery API Sơ đồ này minh hoạ cách hai đối tượng chính khác nhau cố gắng truy vấn cùng một tập dữ liệu. VPC Service Controls từ chối quyền truy cập của user2@example.com (đường màu xanh dương chấm bi), vì cấu hình phạm vi dịch vụ không cho phép họ chạy các thao tác BigQuery từ hoặc đến project-1. user@example.com (đường liền nét màu xanh lục) truy cập thành công vì được cấu hình VPC Service Controls cho phép thực hiện các thao tác từ và đến project-1.

7. Hạn chế lưu lượng truy cập được cho phép theo ranh giới dịch vụ dựa trên địa chỉ IP nội bộ

Cấu hình hiện tại cho phép người dùng được chỉ định chạy các truy vấn trên BigQuery trong project-1 từ mọi vị trí; ở bất kỳ đâu trên Internet, nếu họ được cấp quyền IAM để truy vấn dữ liệu và miễn là họ sử dụng tài khoản của mình. Về mặt bảo mật, điều này có nghĩa là nếu tài khoản bị xâm nhập, bất kỳ cá nhân nào có quyền truy cập vào tài khoản đều có thể truy cập vào dữ liệu BigQuery mà không có thêm bất kỳ hạn chế nào.

Bạn có thể triển khai các quy tắc hạn chế khác bằng cách sử dụng cấp truy cập trong các quy tắc đầu vào và đầu ra để chỉ định bối cảnh người dùng. Ví dụ: bạn có thể cho phép truy cập dựa trên IP nguồn cùng với một quy tắc chuyển tiếp dữ liệu vào đã được định cấu hình trước đó để cho phép truy cập theo danh tính của phương thức gọi. Quyền truy cập theo IP nguồn có thể thực hiện được cho cả dải CIDR IP công khai, miễn là máy khách người dùng có một IP công khai được chỉ định hoặc bằng cách sử dụng địa chỉ IP nội bộ nếu máy khách người dùng hoạt động từ một dự án trên Google Cloud.

Tạo cấp truy cập có điều kiện truy cập bằng địa chỉ IP nội bộ

Trong cùng một thư mục chính sách truy cập có phạm vi, hãy mở trang Access Context Manager để tạo cấp truy cập.

  1. Trên trang Access Context Manager, hãy chọn TẠO CẤP TRUY CẬP.
  2. Trong ngăn Cấp truy cập mới:
    1. Cung cấp một tiêu đề: bạn có thể dùng codelab-al.
    2. Trong phần Điều kiện, hãy nhấp vào Mạng con IP.
    3. Chọn thẻ IP riêng tư rồi nhấp vào CHỌN MẠNG VPC.
    4. Trong ngăn Thêm mạng VPC, bạn có thể duyệt xem và tìm mạng default hoặc nhập tên đầy đủ của mạng theo cách thủ công ở định dạng //compute.googleapis.com/projects/project-2/global/networks/default.
    5. Nhấp vào THÊM MẠNG VPC.
    6. Nhấp vào CHỌN MẠNG CON IP.
    7. Chọn khu vực nơi đặt phiên bản VM. Trong lớp học lập trình này, đó là us-central1.
    8. Nhấp vào LƯU.

Chúng tôi đã tạo một cấp truy cập, nhưng cấp này vẫn chưa được thực thi trên bất kỳ chính sách nào về ranh giới hoặc chính sách truy cập/thoát.

Cấp truy cập được định cấu hình bằng Mạng con IP

Thêm cấp truy cập vào quy tắc chuyển dữ liệu vào

Để thực thi rằng người dùng được cho phép theo quy tắc chuyển dữ liệu vào cũng được xác minh theo cấp truy cập, bạn cần phải định cấu hình cấp truy cập trong quy tắc chuyển dữ liệu vào. Quy tắc đầu vào cho phép truy cập vào dữ liệu truy vấn nằm trong perimeter-1. Thay đổi quy tắc chuyển dữ liệu vào để xác định nguồn là cấp truy cập codelab-al.

Cấp truy cập bằng mạng VPC

Kiểm thử cấu hình mới

Sau khi bạn thêm cấp độ truy cập vào quy tắc chuyển tiếp, cùng một truy vấn BigQuery sẽ không thành công, trừ phi được thực thi từ máy khách trong mạng VPC default cho dự án project-2. Để xác minh hành vi này, hãy thực thi truy vấn từ bảng điều khiển Google Cloud trong khi thiết bị điểm cuối được kết nối với Internet. Truy vấn sẽ kết thúc không thành công, kèm theo dấu hiệu Vi phạm đầu vào.

Bạn có thể chạy cùng một truy vấn từ mạng VPC default, nằm trong project-2. Tương tự, việc thực thi cùng một truy vấn BigQuery từ một phiên bản Compute Engine nằm trong project-2 bằng cách sử dụng mạng VPC default cũng sẽ không thành công. Nguyên nhân là do quy tắc chuyển hướng vẫn được định cấu hình để chỉ cho phép đối tượng chính user@example.com. Tuy nhiên, VM đang sử dụng tài khoản dịch vụ mặc định của Compute Engine.

Để chạy thành công cùng một lệnh từ phiên bản Compute Engine trong project-2,hãy đảm bảo rằng:

  • VM có phạm vi truy cập để sử dụng BigQuery API. Bạn có thể thực hiện việc này bằng cách chọn Cho phép truy cập đầy đủ vào tất cả các API trên đám mây làm phạm vi truy cập của VM.
  • Tài khoản dịch vụ được đính kèm vào VM cần có quyền IAM để:
    • Tạo các lệnh BigQuery trong project-2
    • Lấy dữ liệu BigQuery từ bảng BigQuery nằm trong project-1
  • Quy tắc đầu vào và đầu ra cần cho phép tài khoản dịch vụ Compute Engine mặc định.

Giờ đây, chúng ta cần thêm tài khoản dịch vụ mặc định của Compute Engine vào các quy tắc nhập (để cho phép nhận dữ liệu từ bảng BigQuery) và vào quy tắc xuất (để cho phép tạo các công việc BigQuery).

Cấu hình phạm vi dịch vụ VPC Service Controls có cấp độ truy cập

Từ một phiên bản Compute Engine trong project-2 trên mạng VPC default, hãy chạy lệnh truy vấn bq sau:

bq query --nouse_legacy_sql \
'SELECT name, total
FROM `project-1.codelab_dataset.codelab-table`
ORDER BY total DESC
LIMIT 10;'

Với cấu hình hiện tại, lệnh BigQuery sẽ chỉ thành công nếu:

  • chạy trên một VM bằng mạng VPC mặc định trong project-2
  • nằm trong khu vực us-central1 được chỉ định (mạng con IP), và
  • chạy bằng tài khoản dịch vụ Compute Engine mặc định được định cấu hình trong chu vi dịch vụ.

Truy vấn lệnh BigQuery sẽ không thành công nếu chạy ở bất kỳ nơi nào khác, bao gồm cả:

  • nếu chạy trên một VM bằng mạng VPC mặc định trong project-2 nhưng nằm ở một khu vực khác với mạng con được thêm vào cấp truy cập, hoặc
  • nếu người dùng user@example.com chạy bằng ứng dụng người dùng trên Internet.

Ranh giới dịch vụ cho phép tài khoản dịch vụ mặc định của GCE truy cập. Sơ đồ này minh hoạ quyền truy cập do cùng một chủ thể (user@example.com) khởi tạo từ 2 vị trí khác nhau: Internet và một phiên bản Compute Engine. VPC Service Controls chặn quyền truy cập vào BigQuery trực tiếp từ Internet (đường chấm màu xanh dương), trong khi quyền truy cập từ một VM (đường liền nét màu xanh lục) – trong khi mạo danh tài khoản dịch vụ mặc định của Compute Engine – được cho phép. Quyền truy cập được cho phép là do phạm vi dịch vụ được định cấu hình để cho phép truy cập vào các tài nguyên được bảo vệ từ một địa chỉ IP nội bộ.

8. Dọn dẹp

Mặc dù bạn không phải trả phí riêng khi sử dụng VPC Service Controls nếu không dùng dịch vụ, nhưng bạn nên dọn dẹp chế độ thiết lập đã dùng trong phòng thí nghiệm này. Bạn cũng có thể xoá phiên bản máy ảo và tập dữ liệu BigQuery hoặc các dự án trên Google Cloud để tránh phát sinh phí. Khi bạn xoá dự án trên Cloud, hệ thống sẽ ngừng tính phí cho tất cả tài nguyên được dùng trong dự án đó.

  • Để xoá phiên bản VM, hãy hoàn tất các bước sau:
    • Trong bảng điều khiển Google Cloud, hãy chuyển đến trang phiên bản máy ảo.
    • Chọn hộp đánh dấu ở bên trái tên phiên bản máy ảo, sau đó chọn Xoá, rồi nhấp lại vào Xoá để xác nhận. Xoá phiên bản đối tượng Compute Engine.
  • Để xoá phạm vi dịch vụ, hãy hoàn tất các bước sau:
    • Trong bảng điều khiển Google Cloud, hãy chọn Bảo mật, rồi chọn VPC Service Controls ở cấp độ mà chính sách truy cập được đặt phạm vi, trong trường hợp này là ở cấp độ thư mục.
    • Trên trang VPC Service Controls, trong hàng của bảng tương ứng với ranh giới mà bạn muốn xoá, hãy nhấp vào Xoá.
  • Để xoá Cấp truy cập, hãy hoàn tất các bước sau:
    • Trong Google Cloud Console, hãy mở trang Access Context Manager (Trình quản lý bối cảnh truy cập) ở phạm vi Thư mục.
    • Trong lưới, hãy xác định hàng của cấp truy cập mà bạn muốn xoá, chọn trình đơn có biểu tượng 3 dấu chấm, rồi chọn Xoá.
  • Để tắt các dự án, hãy hoàn tất các bước sau:
    • Trong Google Cloud Console, hãy chuyển đến trang IAM & Admin Settings (IAM và chế độ cài đặt quản trị) của dự án mà bạn muốn xoá.
    • Trên trang Cài đặt IAM và Quản trị, hãy chọn Tắt.
    • Nhập mã dự án rồi chọn Tắt dù sao đi nữa.

9. Xin chúc mừng!

Trong lớp học lập trình này, bạn đã tạo, thực thi và khắc phục sự cố cho một ranh giới VPC Service Controls.

Tìm hiểu thêm

Bạn cũng có thể khám phá các trường hợp sau:

  • Chạy cùng một truy vấn trên tập dữ liệu công khai, sau khi dự án được bảo vệ bằng VPC Service Controls.
  • Thêm project-2 vào cùng một chu vi với project-1.
  • Thêm project-2 vào chu vi riêng và giữ project-1 trong chu vi hiện tại.
  • Chạy truy vấn để cập nhật dữ liệu trong bảng, chứ không chỉ truy xuất dữ liệu.

Giấy phép

Tác phẩm này được cấp phép theo Giấy phép chung Ghi nhận tác giả theo Creative Commons 2.0.