Tèo's Blog

Play the way you want!


Bình luận về bài viết này

[Ansible] Phần 1 – Cài đặt và cấu hình

SystemEvolve 1x tổ chức ngày 19/06/2015 đã thảo luận về vấn đề: Cách sử dụng Ansible và một số khác biệt so với SaltStack. Vậy Ansible là gì? Sử dụng như thế nào? Trong loạt bài về Ansible, chúng ta sẽ cùng tìm hiểu từ tổng quan tới chi tiết về Ansible, các đặc điểm, cài đặt cũng như cấu trúc sử dụng trong Ansible.

Ansible là gì?

Ansible đang là công cụ Configuration Management khá nổi bật hiện nay.

  • Là công cụ mã nguồn mở dùng để quản lý cài đặt, cấu hình hệ thống một cách tập trung và cho phép thực thi câu lệnh điều khiển.
  • Sử dụng SSH (hoặc Powershell) và các module được viết bằng ngôn ngữ Python để điểu khiển hệ thống.
  • Sử dụng định dạng JSON để hiển thị thông tin và sử dụng YAML (Yet Another Markup Language) để xây dựng cấu trúc mô tả hệ thống.

Đặc điểm của Ansible

  • Không cần cài đặt phần mềm lên các agent, chỉ cần cài đặt tại master.
  • Không service, daemon, chỉ thực thi khi được gọi
  • Bảo mật cao ( do sử dụng giao thức SSH để kết nối )
  • Cú pháp dễ đọc, dễ học, dễ hiểu

Yêu cầu cài đặt

  • Hệ điều hành: Linux (Redhat, Debian, Ubuntu, Centos, …), Windows
  • Thư viện Jinja2: dùng để xây dựng template cấu hình
  • Thư viện PyYAML: hỗ trợ cấu trúc YAML
  • Python 2.4 trở lên

Cài đặt Ansible

  • Trên CentOS:
    • Cài đặt EPEL repo
    • Cài đặt thông qua yum:

sudo yum install ansible  

  • Trên Ubuntu:

Cấu hình PPA, cài đặt:

$ sudo apt-get install software-properties-common
$ sudo apt-add-repository ppa:ansible/ansible
$ sudo apt-get update
$ sudo apt-get install ansible

Trên các phiên bản Ubuntu cũ, gói software-properties-common có tên khác là python-software-properties

Cấu hình

Demo sử dụng hệ điều hành Ubuntu 14.04, với các hệ điều hành khác cũng hoàn toàn tương tự.

Server master: 192.168.1.100  
Server agent: 192.168.1.101  
  • Tạo tài khoản truy cập SSH trên agent

Do policy của hệ thống giới hạn tài khoản root truy cập cũng như để thuận tiện cho việc quản lý (tránh dùng chung account của người quản trị) thì nên tạo 1 tài khoản khác phục vụ cho ansible

Tạo tài khoản:

$ sudo adduser ansible

Cấu hình sudo cho phép tài khoản ansible sử dụng không cần password

$ sudo vi /etc/sudoers.d/ansible
ansible ALL=(ALL)   NOPASSWD:ALL  
  • Tạo ssh key

Để thuận tiện cho việc sử dụng Ansible cũng như giới hạn 1 số hệ thống chỉ cho phép xác thực qua key. (Ansible có hỗ trợ kết nối thông qua password)

Tạo ssh keyfile: ( trên master )

$ ssh-keygen -C "ansible@master"
Enter file in which to save the key (/home/ubuntu/.ssh/id_rsa): `/etc/ansible/ansible_key`  
...

Lý do không đặt ssh key ở thư mục mặc định là do rất có thể có nhiều người quản trị cùng tham gia quản lý.)

Copy keyfile sang agent:

$ ssh-copy-id -i /etc/ansible/ansible_key.pub ansible@192.168.1.101

Kiểm tra:

$ ssh -i /etc/ansible/ansible_key ansible@192.168.1.101
  • Cấu hình host và group

Ansible lưu thông tin những hệ thống trong file /etc/ansible/hosts (inventory) theo cấu trúc dạng INI như sau:

mail.example.com

[webservers]
foo.example.com  
bar.example.com

[dbservers]
one.example.com  
two.example.com  
three.example.com  

Trong đó:
*.example.com: hostname của các host (phải cấu hình tiếp trong file /etc/hosts để xác định địa chỉ IP)
[webservers], [dbservers]: là các group

Ở ví dụ demo này, cấu hình /etc/ansible/hosts như sau:

[webservers]
web1 ansible_ssh_host=192.168.1.101
ansible_ssh_private_key_file=ansible_key
ansible_ssh_user=ansible  

List các tham số hỗ trợ: inventory parameters

Sử dụng các lệnh cơ bản

$ ansible web1 -m ping
$ ansible webservers -m ping
$ ansible all -m ping
$ ansible web1 -m command -a 'df -h'
$ ansible web1 -s -m command -a 'fdisk -l'
$ ansible -i /etc/ansible/hosts all -m ping

Chú ý:

  • Ansible cho phép chỉ định 1 host, 1 group hoặc tất cả (all) khi thực thi
  • -m: lựa chọn sử dụng module
  • -a: tham số gửi vào module
  • -s: sử dụng sudo
  • -i: chỉ định inventory file (mặc định /etc/ansible/hosts)

Ở các phần sau, chúng ta sẽ cùng tìm hiểu về cấu trúc sử dụng trong Ansible trong một số ví dụ thực tế.


Bình luận về bài viết này

Băm và lưu password đúng cách

Sau khi đọc bài viết băm mật khẩu đúng cách của anh thaidn, mình nhớ lại lúc mình mới ra trường, cũng đã từng nghĩ về vấn đề này (lúc đó mình khá thích môn Bảo Mật Thông Tin ở trường) nhưng chưa bao giờ hiểu tường tận. Chỉ biết là không nên:

Lưu password ở dạng plain-text.
Hash với một thuật toán hash mạnh, không nên xài MD5, SHA-1 …
Hash với salt.
Chỉ hiểu rằng phải nên làm thế, nhưng không hiểu tại sao lại như vậy và một số câu hỏi khác cũng chưa trả lời được như:

Password user gửi lên, nên hash ở client hay ở server.
Salt nên lưu ở đâu.
Salt có cần giữ bí mật hay không?
Salt chung cho tất cả, hay salt riêng cho từng user?
Hôm nay, mình quyết định đi tìm câu trả lời cho những vấn đề mình thắc mắc, thay vì mặc định nó đúng.

1. Tại sao không nên lưu plain-text, encrypt hoặc dùng MD5, SHA-1

Nếu lưu plain-text, database bị hack, SQL-injection, password user chìa ra theo một cách không thể dễ dàng hơn để đánh cắp.

Nếu mã hóa 2 chiều, sẽ luôn có một cách để giải mã bằng một chìa-khóa nào đó, sẽ phải tìm cách lưu chìa-khóa một cách an toàn.

MD5 và SHA-1 được chứng minh có đụng độ, nghĩa là 2 password khác nhau, khi hash bằng MD5 hoặc SHA-1 có thể ra cùng một chuỗi.

MD5 collision
SHA1 collision

2. Tại sao phải salt

Ta đã biết, hash algorithm là one-way-function, tức là không thể suy ngược trực tiếp ra password nếu có hash_value (khác với mã hóa, có thể giải mã thông qua chìa-khóa).

Tuy nhiên vẫn có cách để từ hash_value có thể suy gián tiếp ra được password ví dụ brute-force attach, dictionary attach -> điểm chung là ta cần thử và đoán password nhiều lần cho tới khi đúng cái cần tìm.

Một cách khác đó là ta có thể tính toán trước giá trị hash của tất cả các trường hợp và của tất cả các thuật toán -> cách này khó, tốn thời gian, nhưng bây giờ với tốc độ tính toán của máy tính, ta vẫn có thể làm được. Bảng lưu trữ password + hash_value của password gọi là Rainbow Table, có thể tự tạo hoặc tải một số bản miễn phí hoặc trả tiền để mua. Từ bây giờ nếu ta có hash_value ta có thể mapping để suy ra được password.

Tuy nhiên nếu ta chỉ hash mỗi password, ta gặp vấn đề đó là:

2 password giống nhau (user vô tình trùng password) thì chuỗi hash(password) sẽ giống nhau.
User cố tình đặt password đơn giản và phổ biến (ví dụ password < 4 kí tự, toàn số, toàn chữ) -> dễ nhớ cho user nhưng dễ tra ngược.
Và nếu chỉ hash password thì nếu mất hash_value, có thể tra trong rainbow table để tìm ra được password của người dùng.

Giờ ta thử thay vì hash(password) ta sẽ hash(salt + password):

Từ md5(123456)

id | hash_md5 |
—————————————
1 | e10adc3949ba59abbe56e057f20f883e |
Thành md5(7nWZLcCK0vsPzIM + 123456)

id | hash_md5 | salt |
———————————————————
1 | 0510210d4b370165658bdc0d0b005244 | 7nWZLcCK0vsPzIM |
Giờ giả sử, ta mất bảng dữ liệu gồm hash_md5, salt, kẻ tấn công sẽ phải tính toán lại rainbow table của tất cả các trường hợp cộng với salt. Nếu salt là random cho từng user, kẻ tấn công sẽ phải tính toán toàn bộ trường hợp cộng với riêng từng salt cho toàn bộ user.

Chi phí cho 2 phép tính trên là vô cùng lớn và tốn rất nhiều thời gian để thực hiện. Vậy tóm lại mục đích của salt và random-salt là:

Bảo vệ user kể cả khi user dùng password phổ biến và password không mạnh vì user không thể nhớ được các password phức tạp nhưng tốc độ tính toán của máy tính thì càng ngày càng nhanh.
Tạo ra nhiều chi phí tính toán, kẻ tấn công không thể tính toán trước rainbow table.
=> Ta trả lời đc 3 câu hỏi:

Salt có thể lưu trong database, cùng với hash_value.
Không cần tìm cách giữ bí mật salt, nhưng cũng đừng tự ý công khai salt.
Nhưng bắt buộc phải random salt cho từng user.

3. Hash ở đâu?

Giờ giả sử hash(password) ở client-side thì vấn đề là gì?

Biết được thuật toán dùng để hash.
Salt sẽ phải sinh ra ở client, vì ta cần hash password với salt (hash(salt + password)), và db chỉ lưu kết quả hash, không lưu salt.
Nhưng nếu salt sinh ra ở client và salt random thì làm sao để compare với hash_value trong database? Vì lần chứng thực tới, salt sẽ lại random và sẽ khác với kết quả trong database -> salt phải duy nhất cho tất cả các trường hợp.
Hoặc salt có thể lưu ở DB, nhưng server phải gửi salt về trước cho user trước khi thực hiện hash -> dễ dàng biết được salt hơn.
Nhìn sơ thì thấy việc dùng duy nhất một salt đã chống lại luận điểm ở mục số 2. Vậy quy trình chứng thực đúng là như thế nào?

User sẽ gửi plain-text password lên server và over HTTPs.
Server sẽ kiểm tra trong database lấy ra salt của user đó, cộng chuỗi ta được salt + password.
Thực hiện hash(salt + password) trên server side.
Compare kết quả trên với hash_md5 trong database.

4. Tại sao dùng bcrypt thay cho SHA-512

Kết quả của SHA-512 có độ dài 128 kí tự, độ dài của key là 64 bytes. Trông có vẻ cũng khá chắc chắn, vậy tại sao OWASP recommend sử dụng PBKDF2, bcrypt hoặc scrypt hơn là SHA2?

SHA2 là hash algorithm (tất nhiên), nó được thiết kế với mục tiêu là tốc độ, với các CPU hiện đại, có thể generate hàng triệu kết quả trên giây. Nếu dùng một thuật toán có tốc độ như SHA2 tức là bạn đã đem lợi điểm tới cho kẻ tấn công brute-force. Thuật toán nhanh + cấu hình server mạnh, việc brute-force càng trở lên nhanh chóng hơn.

Trong khi đó, bcrypt được gọi là slow-hash algorithm, bcrypt() mất 100ms để tính toán ra chuỗi hash, chậm hơn 10.000 lần so với sha1().

Có nghĩa là vẫn đạt được mục đích hash nhưng giảm thiểu nguy cơ tấn công brute-force.

Tóm lại: SHA-512 không phải là một thuật toán yếu, mà vấn đề là SHA-512 không phù hợp cho việc hash password. Nếu cần hash password thì ta nên dùng các thuật toán slow hash như PBKDF2, bcrypt và scrypt.

5. Tại sao cần Pepper?

Một thực tế là nếu bạn chỉ có “muối” mà không có “tiêu”, ăn thịt gà luộc sẽ không ngon :v. Giả sử, database bạn chạy RAID-1, một ổ cứng hư và cần thay một ổ cứng mới. Nhưng như ta biết, đĩa bị hư là mirror của đĩa còn lại, bạn phải tiêu hủy ổ cứng hư đó nếu không ai đó có thể lục thùng rác và tái tạo lại một phần dữ liệu trong đĩa hư đó.

Xin lưu ý, bạn cần wipe trước khi vứt bỏ một ổ cứng có dữ liệu dù cá nhân hay server, tuy nhiên đĩa bị sốc điện, bad-sector thì wipe cũng chưa đủ an toàn, tốt nhất nên ngiền ra bã.

Dù random-salt đã làm tăng chi phí tạo ra rainbow table nhưng đời không biết đâu mà lần, kẻ tấn công luôn có những động lực không tưởng để đạt được cái mình muốn. Giả sử kẻ tấn công có một siêu siêu máy tính và một mirror ổ cứng hư lục từ một cái thùng rác nào đó. Với siêu máy tính đó, ta có rainbow-table để tra ngược ra password cần tìm.

Vậy làm sao để giảm thiểu nguy cơ trên? Nguyên tắc là không bỏ tất cả trứng trong một giỏ, đó là pepper. Pepper là một chuỗi tương tự như salt, nhưng khác biệt là ta cần giữ bí mật pepper, lưu ở một chỗ khác ngoài database, và không cần pepper-per-user, chỉ cần 1 pepper là đủ.

Từ

hash(salt + password)
Thành

hash(pepper + salt + password)
Ta nên lưu pepper ở application hoặc ở một service khác, nếu database bị compromise, thì kẻ tấn công cũng không có pepper để tạo ra rainbow-table.

6. Bonus

Trong khi tìm câu trả lời để viết bài này, mình tìm được một bài blog của dropbox nói về cách họ lưu password như thế nào. Thấy có 2 điểm khá hay nên muốn nói thêm.

Trước khi hash password với salt-per-user, họ có SHA512(password) trước để cố định độ dài của input-password. Theo Dropbox thì việc này giải quyết 2 issues của bcrypt
Một số implementation của bcrypt cắt đầu vào còn 72 bytes.
Một số implementation khác của bcrypt thì không cắt đầu vào nhưng dẫn tới một vấn đề khác là DoS attack bởi vì cho phép độ dài mật khẩu tùy ý.
Dropbox cũng có global pepper nhưng thay vì dùng nó để hash thì họ encrypt. Tức là thay vì hash(pepper + salt + password) thì họ AES256(salt + password) + global-pepper-key. Theo như họ giải thích thì pepper là một lớp phòng thủ sâu hơn và lưu trữ ở một nơi riêng biệt. Nhưng đồng nghĩa với việc là nơi lưu trữ pepper vẫn có thể bị compromise, và khi bị compromise thì việc rotate key không dễ dàng. Dùng pepper để encrypt vẫn đạt được mục đích bảo mật tương tự nhưng thêm khả năng rotate key khi bị compromise.

7. Migrate

Sau khi viết bài này, bạn @vanhtuan0409 có một câu hỏi về việc làm thế nào migrate một hệ thống dùng SHA1 –> bcrypt. Mình thấy đây là một điểm cũng khá cần thiết nên xin phép note thêm.

Ở đây có 2 trường hợp:

Hash password bằng SHA1 nhưng không có salt -> mình gọi là sha1_value.
Hash password bằng SHA1 + trong DB có salt-per-user, mình có sha1_value, salt.
Về ý tưởng thì ta sẽ dùng SHA1 như cách Dropbox dùng SHA512 để cố định độ dài input.

Với trường hợp đầu ta cần sinh ra thêm salt-per-user và migrate bcrypt(salt, sha1_value) trong đó sha1_value = SHA1(password) -> Tương tự cách của dropbox, may mắn là do sai thiết kế từ đầu (thiếu salt) nên migrate dễ.

Với trường hợp thứ 2 thì hơi lằng nhằng hơn 1 xíu, ta cần migrate kiểu bcrypt(salt, SHA1(salt, password)) nếu thực sự muốn bcrypt với salt hoặc thực ra chỉ cần bcrypt(SHA1(salt, password) cũng được. Tùy tình huống bạn cần tradeoff có thể lựa chọn cách phù hợp.

 

8. Thông tin của bạn có an toàn?

Như ta thấy, ta đã làm rất nhiều thứ để đảm bảo rằng thông tin của chúng ta trở lên an toàn. Vậy thực sự thông tin của chúng ta đã an toàn hay không? Câu trả lời rất tiếc là KHÔNG? Thông tin của chúng ta có thể an toàn với “bên ngoài” nhưng không an toàn với “bên trong”. Tại sao lại vậy?

Giờ bắt đầu với thông tin cơ bản nhất như địa chỉ, email, sở thích … Khi ta build staing environment, thông tin user được copy sang một môi trường khác, developer có thể overwrite hash_value của user bằng value của hash(salt + 654321) và dễ dàng đăng nhập trên staing environment với password là 654321 và tất cả các thông tin cơ bản của user đã có thể đọc được. Nhưng developer vẫn không biết chính xác password của user là gì.

Nhưng, lại là nhưng. Người quản trị hệ thống có mọi quyền trên server mà họ quản trị, password dù đã over HTTPs nhưng tới server vẫn là plain-text. Vẫn có thể capture request ngay ở đầu server và output ra plain-text password của user và cuối cùng thì người quản trị hệ thống vẫn biết được chính xác password của user là gì. Đó là lí do tại sao ta không nên dùng một password cho tất cả các dịch vụ.

Vậy làm thế nào để bảo vệ info của user trong trường hợp này, rất tiếc về mặt kỹ thuật không có cách nào để đảm bảo việc này. Ta chỉ có thể áp dụng policy, NDA về mặt con người để hạn chế vấn đề này thôi.

9. Ref

Lưu ý:

  • Trong bài viết dùng MD5 để minh họa cho đơn giản, trong thực tế ta không dùng MD5.
  • Trong bài viết giả định kẻ tấn công bằng cách nào đó có db users, trong thực tế việc này rất khó do có các tầng bảo mật khác như thiết kế infrastructure, define rule/policy về con người … Trong bài này mình không bàn đến các vấn đề đó.

Tác giả: Quăng

Bài viết gốc được đăng tải tại https://xluffy.github.io/post/how-to-hash-store-password :point_left: :point_left: :point_left:


Bình luận về bài viết này

Hard Link và Soft Link trên Linux

Hard Link và Soft Link trên Linux là 2 khái niệm khá phức tạp nhưng rất hay. Hay vì nếu hiểu được các nguyên tắc cơ bản của hệ thống file thì ta thấy phân biệt nó đơn giản hơn nhiều.

Một số điểm cần nắm trước:

  • Về phía người sử dụng, file chứa data và được phân biệt với nhau bằng file name.
  • Về phía hệ thống, file được phân biệt bằng chỉ số index node, viết tắt là inode. Mỗi file name có 1 inode đi kèm. Chỉ số inode tham chiếu đến 1 vùng nhớ trong đó có chứa địa chỉ vùng nhớ lưu trữ data.
Hard Link

File gốc có tên là filename, số inode là inode#, vùng dữ liệu là data.

Khi tạo hard link với tên là othername thì inode đi kèm với nó sẽ chính là inode# của filename. Vì cùng inode# nên sẽ cùng tham chiếu đến 1 vùng nhớ chứa địa chỉ của data do đó có cùng tham chiếu đến vùng data.

Soft Link

Khi tạo soft link với tên là othername thì inode đi kèm sẽ là 1 inode# khác. Inode# này tham chiếu đến vùng nhớ chứa địa chỉ dẫn đến vùng data của soft link. Trong data này chứa đường dẫn đến file gốc.

Đây là điểm khác biệt cơ bản nhất của Hard Link và Soft Link. Từ đó ta có thể giải thích được tất cả những khác biệt khác, chẳng hạn chuyện gì xảy ra khi xóa file gốc.

Thực hành:

[abel@centos ~]$ echo “Original” > original.file
[abel@centos ~]$ ln original.file hardlink.file
[abel@centos ~]$ ln -s original.file softlink.file
[abel@centos ~]$ ls -il
total 20
588105 -rw-rw-r– 2 abel abel 9 Jan 12 04:04 hardlink.file
588105 -rw-rw-r– 2 abel abel 9 Jan 12 04:04 original.file
588106 lrwxrwxrwx 1 abel abel 13 Jan 12 04:04 softlink.file -> original.file

[abel@centos ~]$ cat original.file
Original
[abel@centos ~]$ cat hardlink.file
Original
[abel@centos ~]$ cat softlink.file
Original
[abel@centos ~]$ rm -f original.file
[abel@centos ~]$ cat hardlink.file
Original
[abel@centos ~]$ cat softlink.file
cat: softlink.file: No such file or directory

Bài gốc: https://kythuatmaytinh.wordpress.com/2012/02/01/hard-link-va-soft-link-tren-linux/


Bình luận về bài viết này

Ansible Vault how to – A short tutorial on how to use Vault in your Ansible workflow

A short tutorial on how to use Vault in your Ansible workflow. Ansible-vault allows you to more safely store sensitive information in a source code repository or on disk.

##Working with ansible-vault

I’ve been using a lot of Ansible lately and while almost everything has been great, finding a clean way to implement ansible-vault wasn’t immediately apparent.

What I decided on was the following: put your secret information into a vars file, reference that vars file from your task, and encrypt the whole vars file using ansible-vault encrypt.

Let’s use an example: You’re writing an Ansible role and want to encrypt the spoiler for the movie Aliens.

Your Ansible role should have the following structure similar to the following:

roles/aliens
	├── tasks
	│   └── main.yml
	└── vars
		    └── spoilers.yml

First, put your spoiler text in a roles/aliens/vars/spoilers.yml:

---
spoiler_text: | 
  people run into some space aliens
  and they end up fighting them

(Note the pipe, followed by the new line with text indented by two spaces. This allows you to easily put multi-line text into a variable.)

Then, reference your spoiler_text variable in your task:

---
- include_vars: spoilers.yml

- name: Put the spoiler text in the tmp directory on the remote server.
  copy:
    content="{{spoiler_text}}"
    dest=/tmp/spoiler_text.txt

Encrypt your spoilers file using your vault password file on the command line:

$ ansible-vault encrypt roles/aliens/vars/spoilers.yml --vault-password-file ~/.vault_pass.txt
Encryption successful

You can now safely put this file in your source control without spoiling the movie for everyone.

$ head -n3 aliens/vars/spoilers.yml
$ANSIBLE_VAULT;1.1;AES256
61616366326131636131323230613333356361333737356566646133343062623061313931666462
3933316533346664393430643963646533663737343434320a613862353665663862393939383336
...

Then, given a playbook that looks like:

---
# file: movies.yml
- hosts: all
  roles:
    - { role: aliens }

You can now run this against your server:

$ ansible-playbook -i inventory/development.hosts playbooks/movies.yml --vault-password-file ~/.vault_pass.txt

That’s it! Hop on the server and you can see that the decrypted content is there on disk:

remote_server$ cat /tmp/spoiler_text.txt 
people run into some space aliens
and they end up fighting them

This is useful for more than just movie spoilers — I use this approach to copy over my deploy-keys to make continuous integration and simple deployments a reality.

26-April-2016 edit: There’s now a “best practice” document that may be interesting to you if you’re reading this tutorial: http://docs.ansible.com/ansible/playbooks_best_practices.html#best-practices-for-variables-and-vaults

Te’s blog via https://gist.github.com/tristanfisher/e5a306144a637dc739e7


Bình luận về bài viết này

PHÂN TÍCH HOẠT ĐỘNG CỦA GIAO THỨC HTTPS

Để hiểu rõ hơn hoạt động của giao thức HTTPS được mô tả trong bài viết này, bạn nên có sẵn kiến thức cơ bản về một số khái niệm liên quan sau:

  • Symmetric Encryption (hay Secret Key Encryption) và Asymmetric Encryption (hay Public-key Cryptography).
  • Các chức năng của SSL Certificate (một loại digital certificate) cũng như là các thông tin được chứa trong nó.
  • Vai trò của Central Authority (CA).

I. Giới thiệu

Giao thức HTTPS sử dụng port 443, giúp đảm bảo các tính chất sau của thông tin:

  • Confidentiality: sử dụng phương thức encryption để đảm bảo rằng các thông điệp được trao đổi giữa client và server không bị kẻ thứ ba đọc được.
  • Integrity: sử dụng phương thức hashing để cả client và server đều có thể tin tưởng rằng thông điệp mà chúng nhận được có không bị mất mát hay chỉnh sửa.
  • Authenticity: sử dụng digital certificate để giúp client có thể tin tưởng rằng server/website mà họ đang truy cập thực sự là server/website mà họ mong muốn vào, chứ không phải bị giả mạo.

II. Sử dụng HTTPS như thế nào?

Trước hết, muốn áp dụng HTTPS thì trong quá trình cấu hình Webserver, bạn có thể dễ dàng tự tạo ra một SSL certificate dành riêng cho website của mình và nó được gọi là self-signed SSL certificate.

SSL certificate tự cấp này vẫn mang lại tính Confidentiality và Integrity cho quá trình truyền thông giữa server và client. Nhưng rõ ràng là không đạt được tính Authenticity bởi vì không có bên thứ 3 đáng tin cậy nào đứng ra kiểm chứng sự tính xác thực của certificate tự gán này. Điều này cũng giống như việc một người tự làm chứng minh nhân dân (CMND) cho mình rồi tự họ ký tên, đóng dấu luôn vậy!

Vì vậy, đối với các website quan trọng như E-Commerce, Online Payment, Web Mail,… thì họ sẽ mua một SSL certificate từ một Trusted Root CA nào đó như VeriSign, Comodo, GoDaddy,… Ở đây, các CA có  nhiệm vụ chính là cấp phát và quản lý các certificate.

Thực chất thì SSL certificate cũng là một loại digitial certificate (một loại file trên máy tính). Vì HTTPS có dính tới giao thức SSL nên người ta mới đặt tên cho nó là SSL certificate để phân biệt với các loại digital certificate khác như Personal Certificate, Server Certificate, Software Publisher Certificate, Certificate Authority Certificate.

Dưới đây là một số thông tin quan trọng được chứa trong SSL certificate:

  • Thông tin về chủ sở hữu của certificate (có thể là tổ chức, tên cá nhân hoặc tên miền của website).
  • Thông tin và digital signature của CA mà cấp certificate này.
  • Khoảng thời gian mà certificate còn hiệu lực.
  • Public key của website. Còn private key không có trong certificate mà được lưu trữ trên chính server và tuyệt đối không được để lộ cho bất cứ client nào.
  • Một số thông tin phụ khác như: loại SSL certificate, các thuật toán dùng để encryption và hashing, chiều dài (tính bằng bit) của key, cơ chế trao đổi key (như RSA, DSA).
  • v.v…

III. Quá trình giao tiếp giữa client và server thông qua HTTPS

1. Client gửi request cho một secure page (có URL bắt đầu với https://)

2. Server gửi lại cho client certificate của nó.

3. Client (web browser) tiến hành xác thực certificate này bằng cách kiểm tra (verify) tính hợp lệ của chữ ký số của CA được kèm theo certificate.

Giả sử certificate đã được xác thực và còn hạn sử dụng hoặc client vẫn cố tình truy cập mặc dù Web browser đã cảnh báo rằng không thể tin cậy được certificate này (do là dạng self-signed SSL certificate hoặc certificate hết hiệu lực, thông tin trong certificate không đúng) thì mới xảy ra bước 4 sau.

4. Client tự tạo ra ngẫu nhiên một symmetric encryption key (hay session key), rồi sử dụng public key (lấy trong certificate) để mã hóa session key này và gửi về cho server.

5. Server sử dụng private key (tương ứng với public key trong certificate ở trên) để giải mã ra session key ở trên.

6. Sau đó, cả server và client đều sử dụng session key đó để mã hóa/giải mã các thông điệp trong suốt phiên truyền thông.

Và tất nhiên, các session key sẽ được tạo ra ngẫu nhiên và khác nhau trong mỗi phiên làm việc với server. Ngoài encryption thì cơ chế hashing sẽ được sử dụng để đảm bảo tính Integrity cho các thông điệp được trao đổi.

IV. Tổng kết

HTTPS là một giao thức phổ biến trên Internet và rất cần thiết để đảm bảo an toàn, tin cậy cho môi trường Web. Tuy nhiên, vẫn có những cách thức mà attacker có thể sử dụng để “qua mặt” cơ chế bảo vệ của HTTPS (như SSLStrip).

Để kết thúc bài viết và cũng để các khái niệm liên quan tới HTTPS trở nên gần gũi và dễ hiểu hơn với mọi người, dưới đây là một tình huống thực tế:

CMND của người A do Công an ở địa phương B cấp. Người A này muốn thực hiện một giao dịch gì đó rất quan trọng với tổ chức C chẳng hạn. Và giả sử CMND của A là thứ duy nhất mà C có thể dựa vào để tin tưởng được các thông tin về A như khuôn mặt, tên, tuổi, nơi ở… Vì C thấy CMND cũng có thể bị làm giả và để chắc rằng các thông tin về A được ghi trong CMND là chính xác thì cách tốt nhất là C đem CMND của A đến nhờ bên B xác thực giùm.

Như vậy, có thể coi:

  • Bên A là website
  • Bên B là CA
  • CMND của A chính là SSL Certificate do B cấp
  • Bên C là Web client

Teo’s Blog via https://manthang.wordpress.com/2011/08/23/phan-tich-hoat-dong-cua-giao-thuc-https/