Thứ tư, 26/06/2019 | 00:00 GMT+7

Cách triển khai và quản lý DNS của bạn bằng DNSControl trên Ubuntu 18.04

DNSControl là một công cụ cơ sở hạ tầng dưới dạng mã cho phép bạn triển khai và quản lý các vùng DNS của bạn bằng cách sử dụng các nguyên tắc phát triển phần mềm tiêu chuẩn, bao gồm kiểm soát version , thử nghiệm và triển khai tự động. DNSControl được tạo bởi Stack Exchange và được viết bằng Go.

Sử dụng DNSControl loại bỏ nhiều cạm bẫy của việc quản lý DNS thủ công, vì các file vùng được lưu trữ ở định dạng có thể lập trình được. Điều này cho phép bạn triển khai đồng thời các vùng cho nhiều nhà cung cấp DNS, xác định lỗi cú pháp và tự động đẩy cấu hình DNS của bạn, giảm nguy cơ do lỗi do con người gây ra. Một cách sử dụng phổ biến khác của DNSControl là nhanh chóng di chuyển DNS của bạn sang một nhà cung cấp khác; ví dụ, trong trường hợp bị tấn công DDoS hoặc hệ thống ngừng hoạt động.

Trong hướng dẫn này, bạn sẽ cài đặt và cấu hình DNSControl, tạo cấu hình DNS cơ bản và bắt đầu triển khai các bản ghi DNS cho nhà cung cấp trực tiếp. Là một phần của hướng dẫn này, ta sẽ sử dụng DigitalOcean làm nhà cung cấp DNS mẫu. Nếu bạn muốn sử dụng một nhà cung cấp khác , cách cài đặt rất giống nhau. Khi hoàn tất, bạn có thể quản lý và kiểm tra cấu hình DNS của bạn trong một môi trường offline , an toàn, sau đó tự động triển khai nó vào version production .

Yêu cầu

Trước khi bắt đầu hướng dẫn này, bạn cần những thứ sau:

  • Một server Ubuntu 18.04 được cài đặt bằng cách thực hiện theo Cài đặt server ban đầu với Ubuntu 18.04 , bao gồm một user không phải root có quyền sudo và firewall được bật để chặn các cổng không cần thiết. your-server-ipv4-address đề cập đến địa chỉ IP của server nơi bạn đang lưu trữ trang web hoặc domain của bạn .
  • Tên domain được đăng ký đầy đủ với DNS được lưu trữ bởi nhà cung cấp được hỗ trợ . Hướng dẫn này sẽ sử dụng example.com xuyên suốt và DigitalOcean làm nhà cung cấp dịch vụ.
  • Khóa API DigitalOcean (Mã truy cập cá nhân) với quyền đọc và ghi. Để tạo một mã, hãy truy cập Cách tạo mã truy cập cá nhân .

Khi đã sẵn sàng những thứ này, hãy đăng nhập vào server của bạn với quyền là user không phải root của bạn để bắt đầu.

Bước 1 - Cài đặt DNSControl

DNSControl được viết bằng Go, vì vậy bạn sẽ bắt đầu bước này bằng cách cài đặt Go to your server và cài đặt GOPATH .

Go có sẵn trong repository mặc định của Ubuntu, giúp bạn có thể cài đặt bằng các công cụ quản lý gói thông thường.

Bắt đầu bằng cách cập nhật index gói local để phản ánh mọi thay đổi ngược dòng mới:

  • sudo apt update

Sau đó, cài đặt gói golang-go :

  • sudo apt install golang-go

Sau khi xác nhận cài đặt, apt sẽ download và cài đặt Go cùng tất cả các phụ thuộc của nó.

Tiếp theo, bạn sẽ cấu hình các biến môi trường đường dẫn bắt buộc cho Go. Nếu bạn muốn biết thêm về điều này, bạn có thể đọc hướng dẫn này về Tìm hiểu GOPATH . Bắt đầu bằng cách chỉnh sửa file ~/.profile :

  • nano ~/.profile

Thêm các dòng sau vào cuối file của bạn:

~ / .profile
... export GOPATH="$HOME/go" export PATH="$PATH:$GOPATH/bin" 

Khi bạn đã thêm những dòng này vào cuối file , hãy lưu và đóng nó. Sau đó reload profile của bạn bằng cách đăng xuất và đăng nhập lại hoặc tìm nguồn cung cấp lại file :

  • source ~/.profile

Đến đây bạn đã cài đặt và cấu hình Go, bạn có thể cài đặt DNSControl.

Lệnh go get được dùng để tìm nạp một bản sao của mã, tự động biên dịch nó và cài đặt nó vào folder Go của bạn:

  • go get github.com/StackExchange/dnscontrol

Sau khi hoàn tất, bạn có thể kiểm tra version đã cài đặt đảm bảo rằng mọi thứ đang hoạt động:

  • dnscontrol version

Đầu ra của bạn sẽ trông giống như sau:

Output
dnscontrol 0.2.8-dev

Nếu bạn thấy dnscontrol: command not found , hãy kiểm tra kỹ cài đặt đường dẫn Go của bạn.

Đến đây bạn đã cài đặt DNSControl, bạn có thể tạo một folder cấu hình và kết nối DNSControl với nhà cung cấp DNS của bạn để cho phép nó áp dụng các thay đổi đối với bản ghi DNS của bạn.

Bước 2 - Cấu hình DNSControl

Trong bước này, bạn sẽ tạo các folder cấu hình cần thiết cho DNSControl và kết nối nó với nhà cung cấp DNS của bạn để nó có thể bắt đầu áp dụng các thay đổi trực tiếp đối với bản ghi DNS của bạn.

Đầu tiên, tạo một folder mới trong đó bạn có thể lưu cấu hình DNSControl của bạn , sau đó chuyển vào đó:

  • mkdir ~/dnscontrol
  • cd ~/dnscontrol

Lưu ý: Hướng dẫn này sẽ tập trung vào việc cài đặt DNSControl ban đầu; tuy nhiên để sử dụng trong production , bạn nên lưu trữ cấu hình DNSControl của bạn trong hệ thống kiểm soát version (VCS) chẳng hạn như Git . Những ưu điểm của điều này bao gồm kiểm soát version đầy đủ, tích hợp với CI / CD để thử nghiệm, triển khai quay lại liên tục, v.v.

Nếu bạn định sử dụng DNSControl để ghi file vùng BIND, bạn cũng nên tạo folder zones :

  • mkdir ~/dnscontrol/zones

Các file vùng BIND là một phương pháp thô, được tiêu chuẩn hóa để lưu trữ các vùng / bản ghi DNS ở định dạng văn bản thuần túy. Ban đầu chúng được sử dụng cho phần mềm server DNS BIND, nhưng hiện nay đã được áp dụng rộng rãi làm phương pháp tiêu chuẩn để lưu trữ các vùng DNS. Các file vùng BIND do DNSControl tạo ra rất hữu ích nếu bạn muốn nhập chúng vào server DNS tùy chỉnh hoặc tự lưu trữ hoặc cho mục đích kiểm tra.

Tuy nhiên, nếu bạn chỉ muốn sử dụng DNSControl để đẩy các thay đổi DNS đến một nhà cung cấp được quản lý, thì folder zones sẽ không cần thiết.

Tiếp theo, bạn cần cấu hình file creds.json , file này sẽ cho phép DNSControl xác thực với nhà cung cấp DNS của bạn và thực hiện thay đổi. Định dạng của creds.json hơi khác một chút tùy thuộc vào nhà cung cấp DNS mà bạn đang sử dụng. Vui lòng xem danh sách Nhà cung cấp dịch vụ trong tài liệu chính thức của DNSControl để tìm cấu hình cho nhà cung cấp của bạn .

Tạo file creds.json trong folder ~/dnscontrol :

  • cd ~/dnscontrol
  • nano creds.json

Thêm cấu hình creds.json mẫu cho nhà cung cấp DNS của bạn vào file . Nếu bạn đang sử dụng DigitalOcean làm nhà cung cấp DNS của bạn , bạn có thể sử dụng các cách sau:

~ / dnscontrol / creds.json
{   "digitalocean": {     "token": "your-digitalocean-oauth-token"   } } 

Tệp này cho DNSControl biết nhà cung cấp DNS nào bạn muốn nó kết nối.

Bạn cần cung cấp một số hình thức xác thực cho nhà cung cấp DNS của bạn . Đây thường là khóa API hoặc mã thông báo OAuth, nhưng một số nhà cung cấp yêu cầu thông tin bổ sung, như được ghi trong danh sách Nhà cung cấp dịch vụ trong tài liệu chính thức của DNSControl.

Cảnh báo: Mã thông báo này sẽ cấp quyền truy cập vào account nhà cung cấp DNS của bạn, vì vậy bạn nên bảo vệ nó như password . Ngoài ra, hãy đảm bảo nếu bạn đang sử dụng hệ thống kiểm soát version , thì file chứa mã thông báo sẽ bị loại trừ (ví dụ: sử dụng .gitignore ) hoặc được mã hóa an toàn theo một cách nào đó.

Nếu bạn đang sử dụng DigitalOcean làm nhà cung cấp DNS của bạn , bạn có thể sử dụng mã thông báo OAuth bắt buộc trong cài đặt account DigitalOcean mà bạn đã tạo như một phần của yêu cầu .

Nếu bạn có nhiều nhà cung cấp DNS khác nhau — ví dụ: đối với nhiều domain hoặc vùng DNS được ủy quyền — bạn có thể xác định tất cả những nhà cung cấp này trong cùng một file tin creds.json .

Bạn đã cài đặt các folder cấu hình DNSControl ban đầu và cấu hình creds.json để cho phép DNSControl xác thực với nhà cung cấp DNS của bạn và áp dụng các thay đổi . Tiếp theo, bạn sẽ tạo cấu hình cho các vùng DNS của bạn .

Bước 3 - Tạo file cấu hình DNS

Trong bước này, bạn sẽ tạo một file cấu hình DNS ban đầu, file này sẽ chứa các bản ghi DNS cho domain hoặc vùng DNS được ủy quyền của bạn.

dnsconfig.js là file cấu hình DNS chính cho DNSControl. Trong file này, các vùng DNS và các bản ghi tương ứng của chúng được xác định bằng cú pháp JavaScript. Đây được gọi là DSL hoặc Ngôn ngữ dành riêng cho domain . Trang JavaScript DSL trong tài liệu chính thức của DNSControl cung cấp thêm chi tiết.

Để bắt đầu, hãy tạo file cấu hình DNS trong folder ~/dnscontrol :

  • cd ~/dnscontrol
  • nano dnsconfig.js

Sau đó, thêm cấu hình mẫu sau vào file :

~ / dnscontrol / dnsconfig.js
// Providers:  var REG_NONE = NewRegistrar('none', 'NONE'); var DNS_DIGITALOCEAN = NewDnsProvider('digitalocean', 'DIGITALOCEAN');  // Domains:  D('example.com', REG_NONE, DnsProvider(DNS_DIGITALOCEAN),     A('@', 'your-server-ipv4-address') ); 

Tệp mẫu này xác định domain hoặc vùng DNS tại một nhà cung cấp cụ thể, trong trường hợp này là example.com do DigitalOcean lưu trữ. Ví dụ A bản ghi cũng được xác định cho root vùng ( @ ), trỏ đến địa chỉ IPv4 của server mà bạn đang lưu trữ domain / trang web của bạn .

Có ba chức năng chính tạo nên file cấu hình DNSControl cơ bản:

  • NewRegistrar(name, type, metadata) : xác định công ty đăng ký domain cho domain của bạn. DNSControl có thể sử dụng điều này để áp dụng các thay đổi bắt buộc, chẳng hạn như sửa đổi server định danh có thẩm quyền. Nếu bạn chỉ muốn sử dụng DNSControl để quản lý các vùng DNS của bạn , điều này thường có thể được để là NONE .

  • NewDnsProvider(name, type, metadata) : xác định nhà cung cấp dịch vụ DNS cho domain hoặc vùng được ủy quyền của bạn. Đây là nơi DNSControl sẽ đẩy các thay đổi DNS mà bạn thực hiện.

  • D(name, registrar, modifiers) : xác định domain hoặc vùng DNS được ủy quyền cho DNSControl quản lý, cũng như các bản ghi DNS có trong vùng.

Bạn nên cấu hình NewRegistrar() , NewDnsProvider()D() phù hợp bằng cách sử dụng danh sách Nhà cung cấp dịch vụ trong tài liệu chính thức của DNSControl.

Nếu bạn đang sử dụng DigitalOcean làm nhà cung cấp DNS của bạn và chỉ cần có thể thực hiện thay đổi DNS (chứ không phải server định danh có thẩm quyền), thì mẫu trong khối mã trước đó đã chính xác.

Sau khi hoàn tất, hãy lưu file .

Trong bước này, bạn cài đặt file cấu hình DNS cho DNSControl, với các nhà cung cấp liên quan được xác định. Tiếp theo, bạn sẽ điền vào file một số bản ghi DNS hữu ích.

Bước 4 - Nhập file cấu hình DNS của bạn

Tiếp theo, bạn có thể điền vào file cấu hình DNS với các bản ghi DNS hữu ích cho trang web hoặc dịch vụ của bạn bằng cách sử dụng cú pháp DNSControl.

Không giống như các file vùng BIND truyền thống, nơi các bản ghi DNS được ghi ở định dạng thô, từng dòng, các bản ghi DNS trong DNSControl được định nghĩa là một tham số hàm (công cụ sửa đổi domain ) cho hàm D() , như được trình bày ngắn gọn trong Bước 3.

Công cụ sửa đổi domain tồn tại cho mỗi loại bản ghi DNS tiêu chuẩn, bao gồm A , AAAA , MX , TXT , NS , CAA , v.v. Danh sách đầy đủ các loại bản ghi có sẵn có sẵn trong phần Công cụ sửa đổi domain của tài liệu DNSControl.

Các công cụ sửa đổi cho các bản ghi riêng lẻ cũng có sẵn (các công cụ sửa đổi bản ghi). Hiện tại, chúng chủ yếu được sử dụng để cài đặt TTL (thời gian tồn tại) của các bản ghi cá nhân. Danh sách đầy đủ các công cụ sửa đổi bản ghi có sẵn trong phần Các công cụ sửa đổi bản ghi của tài liệu DNSControl. Các công cụ sửa đổi bản ghi là tùy chọn và trong hầu hết các trường hợp sử dụng cơ bản có thể bị bỏ qua.

Cú pháp để cài đặt bản ghi DNS hơi khác nhau đối với từng loại bản ghi. Sau đây là một số ví dụ cho các loại bản ghi phổ biến nhất:

  • A profile :

    • Mục đích: Để trỏ đến địa chỉ IPv4.
    • Cú pháp: A(' name ', ' address ', optional record modifiers)
    • Ví dụ: A(' @ ', ' your-server-ipv4-address ', TTL( 30 ))
  • Hồ sơ AAAA :

    • Mục đích: Để trỏ đến địa chỉ IPv6.
    • Cú pháp: AAAA(' name ', ' address ', optional record modifiers)
    • Ví dụ: AAAA(' @ ', ' your-server-ipv6-address ') (công cụ sửa đổi bản ghi bị bỏ trống, vì vậy TTL mặc định sẽ được sử dụng)
  • CNAME :

    • Mục đích: Để đặt domain / domain phụ của bạn thành alias của domain khác.
    • Cú pháp: CNAME(' name ', ' target ', optional record modifiers)
    • Ví dụ: CNAME(' subdomain1 ', ' example.org.') ( Lưu ý một dấu . Phải được bao gồm nếu có bất kỳ dấu chấm trong các giá trị)
  • Bản ghi MX :

    • Mục đích: Để chuyển hướng email đến các server / địa chỉ cụ thể.
    • Cú pháp: MX(' name ', ' priority ', ' target ', optional record modifiers)
    • Ví dụ: MX(' @ ', 10 , ' mail.example.net ') ( lưu ý một dấu . Phải được bao gồm nếu có bất kỳ dấu chấm trong các giá trị)
  • Bản ghi TXT :

    • Mục đích: Để thêm văn bản thuần túy tùy ý, thường được sử dụng cho các cấu hình không có loại bản ghi chuyên dụng của riêng chúng.
    • Cú pháp: TXT(' name ', ' content ', optional record modifiers)
    • Ví dụ: TXT(' @ ', ' This is a TXT record. ')
  • Hồ sơ CAA :

    • Mục đích: Để hạn chế và báo cáo về Tổ chức phát hành certificate (CA) có thể cấp certificate TLS cho domain / domain phụ của bạn.
    • Cú pháp: CAA(' name ', ' tag ', ' value ', optional record modifiers)
    • Ví dụ: CAA(' @ ', ' issue ', ' letsencrypt.org ')

Để bắt đầu thêm bản ghi DNS cho domain của bạn hoặc vùng DNS được ủy quyền, hãy chỉnh sửa file cấu hình DNS của bạn:

  • cd ~/dnscontrol
  • nano dnsconfig.js

Tiếp theo, bạn có thể bắt đầu điền các tham số cho hàm D() hiện có bằng cách sử dụng cú pháp được mô tả trong danh sách trước, cũng như phần Công cụ sửa đổi domain của tài liệu chính thức của DNSControl. Dấu phẩy ( , ) phải được sử dụng ở giữa mỗi bản ghi.

Để tham khảo, khối mã ở đây chứa cấu hình mẫu đầy đủ cho cài đặt DNS ban đầu, cơ bản:

~ / dnscontrol / dnsconfig.js
...  D('example.com', REG_NONE, DnsProvider(DNS_DIGITALOCEAN),     A('@', 'your-server-ipv4-address'),     A('www', 'your-server-ipv4-address'),     A('mail', 'your-server-ipv4-address'),     AAAA('@', 'your-server-ipv6-address'),     AAAA('www', 'your-server-ipv6-address'),     AAAA('mail', 'your-server-ipv6-address'),     MX('@', 10, 'mail.example.com.'),     TXT('@', 'v=spf1 -all'),     TXT('_dmarc', 'v=DMARC1; p=reject; rua=mailto:abuse@example.com; aspf=s; adkim=s;') ); 

Khi bạn đã hoàn thành cấu hình DNS ban đầu, hãy lưu file .

Trong bước này, bạn cài đặt file cấu hình DNS ban đầu, chứa các bản ghi DNS của bạn. Tiếp theo, bạn sẽ kiểm tra cấu hình và triển khai nó.

Bước 5 - Kiểm tra và triển khai cấu hình DNS của bạn

Trong bước này, bạn sẽ chạy kiểm tra cú pháp local trên cấu hình DNS của bạn , sau đó áp dụng các thay đổi đối với server / nhà cung cấp DNS trực tiếp.

Đầu tiên, chuyển vào folder dnscontrol của bạn:

  • cd ~/dnscontrol

Tiếp theo, sử dụng chức năng preview của DNSControl để kiểm tra cú pháp file của bạn và xuất ra những thay đổi mà nó sẽ thực hiện (mà không thực sự thực hiện chúng):

  • dnscontrol preview

Nếu cú pháp của file cấu hình DNS của bạn chính xác, DNSControl sẽ xuất ra thông tin tổng quan về những thay đổi mà nó sẽ thực hiện. Điều này sẽ trông giống như sau:

Output
******************** Domain: example.com ----- Getting nameservers from: digitalocean ----- DNS Provider: digitalocean...8 corrections #1: CREATE A example.com your-server-ipv4-address ttl=300 #2: CREATE A www.example.com your-server-ipv4-address ttl=300 #3: CREATE A mail.example.com your-server-ipv4-address ttl=300 #4: CREATE AAAA example.com your-server-ipv6-address ttl=300 #5: CREATE TXT _dmarc.example.com "v=DMARC1; p=reject; rua=mailto:abuse@example.com; aspf=s; adkim=s;" ttl=300 #6: CREATE AAAA www.example.com your-server-ipv6-address ttl=300 #7: CREATE AAAA mail.example.com your-server-ipv6-address ttl=300 #8: CREATE MX example.com 10 mail.example.com. ttl=300 ----- Registrar: none...0 corrections Done. 8 corrections.

Nếu bạn thấy cảnh báo lỗi trong kết quả của bạn , DNSControl sẽ cung cấp chi tiết về lỗi và vị trí nằm trong file của bạn.

Cảnh báo: Lệnh tiếp theo sẽ áp dụng các thay đổi trực tiếp đối với bản ghi DNS của bạn và có thể là các cài đặt khác. Hãy đảm bảo bạn đã chuẩn bị sẵn sàng cho việc này, bao gồm cả việc backup cấu hình DNS hiện có của bạn, cũng như đảm bảo bạn có phương tiện để khôi phục nếu cần.

Cuối cùng, bạn có thể áp dụng các thay đổi đối với nhà cung cấp DNS trực tiếp của bạn :

  • dnscontrol push

Bạn sẽ thấy một kết quả tương tự như sau:

Output
******************** Domain: example.com ----- Getting nameservers from: digitalocean ----- DNS Provider: digitalocean...8 corrections #1: CREATE TXT _dmarc.example.com "v=DMARC1; p=reject; rua=mailto:abuse@example.com; aspf=s; adkim=s;" ttl=300 SUCCESS! #2: CREATE A example.com your-server-ipv4-address ttl=300 SUCCESS! #3: CREATE AAAA example.com your-server-ipv6-address ttl=300 SUCCESS! #4: CREATE AAAA www.example.com your-server-ipv6-address ttl=300 SUCCESS! #5: CREATE AAAA mail.example.com your-server-ipv6-address ttl=300 SUCCESS! #6: CREATE A www.example.com your-server-ipv4-address ttl=300 SUCCESS! #7: CREATE A mail.example.com your-server-ipv4-address ttl=300 SUCCESS! #8: CREATE MX example.com 10 mail.example.com. ttl=300 SUCCESS! ----- Registrar: none...0 corrections Done. 8 corrections.

Bây giờ, nếu bạn kiểm tra cài đặt DNS cho domain của bạn trong console DigitalOcean, bạn sẽ thấy các thay đổi.

Ảnh chụp màn hình console  DigitalOcean, hiển thị một số thay đổi DNS mà DNSControl đã thực hiện.

Bạn cũng có thể kiểm tra việc tạo bản ghi bằng cách chạy truy vấn DNS cho domain / vùng được ủy quyền của bạn. Bạn sẽ thấy rằng các bản ghi đã được cập nhật tương ứng:

  • dig +short example.com

Bạn sẽ thấy kết quả hiển thị địa chỉ IP và bản ghi DNS liên quan từ vùng của bạn đã được triển khai bằng DNSControl. Bản ghi DNS có thể mất một khoảng thời gian để phổ biến, vì vậy bạn có thể cần đợi và chạy lại lệnh này.

Trong bước cuối cùng này, bạn đã chạy kiểm tra cú pháp local của file cấu hình DNS, sau đó triển khai nó tới nhà cung cấp DNS trực tiếp của bạn và kiểm tra xem các thay đổi đã được thực hiện thành công chưa.

Kết luận

Trong bài viết này, bạn cài đặt DNSControl và triển khai cấu hình DNS cho nhà cung cấp trực tiếp. Như vậy, bạn có thể quản lý và kiểm tra các thay đổi cấu hình DNS của bạn trong môi trường offline , an toàn trước khi triển khai chúng vào version production .

Nếu bạn muốn khám phá thêm chủ đề này, DNSControl được thiết kế để tích hợp vào đường dẫn CI / CD của bạn, cho phép bạn chạy các bài kiểm tra chuyên sâu và kiểm soát nhiều hơn việc triển khai đến production . Bạn cũng có thể xem xét việc tích hợp DNSControl vào quy trình xây dựng / triển khai cơ sở hạ tầng của bạn , cho phép bạn triển khai server và thêm chúng vào DNS hoàn toàn tự động.

Nếu bạn muốn tiến xa hơn với DNSControl, các bài viết DigitalOcean sau cung cấp một số bước tiếp theo thú vị để giúp tích hợp DNSControl vào quy trình quản lý thay đổi và triển khai cơ sở hạ tầng của bạn:


Tags:

Các tin liên quan

Cách cấu hình Cụm Galera với MariaDB trên server Ubuntu 18.04
2019-06-20
Cách backup thư mục lớn với Unison trên Ubuntu 18.04
2019-05-21
Cách tạo một cụm Kubernetes bằng Kubeadm trên Ubuntu 18.04
2019-04-24
Cách tạo một cụm Kubernetes bằng Kubeadm trên Ubuntu 16.04
2019-04-24
Cách tạo một cụm Kubernetes bằng Kubeadm trên Ubuntu 18.04
2019-04-24
Cách tạo một cụm Kubernetes bằng Kubeadm trên Ubuntu 16.04
2019-04-24
Cách cài đặt và cấu hình Zabbix để giám sát an toàn server từ xa trên Ubuntu 18.04
2019-04-18
Cách cài đặt Anaconda trên Ubuntu 18.04 [Quickstart]
2019-04-18
Cách cài đặt Go và thiết lập môi trường lập trình cục bộ trên Ubuntu 18.04
2019-04-09
Cách backup thư mục lớn với Unison trên Ubuntu 16.04
2019-04-08