12/08/2018, 16:24

SSH hoạt động như thế nào?

Là 1 lập trình viên web/ server hẳn các bạn cũng rất quen thuộc với việc chạy remote shell, commit git, chạy các background-job từ các máy chủ khác nhau. Rất nhiều giao thức và công cụ được tạo ra để thực thi công việc này. Cùng với sự phát triển của server/web đòi hỏi các công cụ remote control ...

Là 1 lập trình viên web/ server hẳn các bạn cũng rất quen thuộc với việc chạy remote shell, commit git, chạy các background-job từ các máy chủ khác nhau. Rất nhiều giao thức và công cụ được tạo ra để thực thi công việc này. Cùng với sự phát triển của server/web đòi hỏi các công cụ remote control ngày càng phải được cải tiến hơn.

1 trong số những công cụ nổi tiếng và phổ biến nhất hiện nay là SSH hay Secure Shell. SSH mang đầy đủ những ưu việt của 1 remote login program:

  • Tính bảo mật của kết nối, đảm bảo mọi gói tin giữa remote-client được mã hóa cũng như khả năng phòng chống eavesdropping
  • Tính bảo toàn của dữ liệu, đảm bảo dữ liệu gửi lên là duy nhất, không thể thay đổi từ cả 2 phía
  • Định danh của 2 chủ thể server và client tham gia vào kết nối.

SSH nâng cấp và mở rộng khả năng của các remote login program đã tồn tại từ trước như: rlogin, telnet ,... Bên cạnh các chức năng xác thực và ủy quyền giữa client và server SSH cũng cung cấp thêm 1 vài tính năng khác như:

  • SSH Tunneling
  • TCP port forwarding Mặc dù vậy chúng ta sẽ không đi vào các tính năng đó trong bài viết này. Trong khuôn khổ bài viết này, tôi sẽ giới thiệu flow hoàn chỉnh của SSH connection dưới góc nhìn client - remote(server).

Ngoài lề 1 chút, không biết có ai như tôi trước đây là bị nhầm lẫn giữa Asymetric Cryptography với SSH không? Khi thấy mình phải cài đặt public key của máy trên server của github mới có thể ssh được, lúc đó khá là thắc mắc về việc public key đáng nhẽ sẽ phải gửi cho các client - bởi client mới là chủ thể gửi đi các commit, github là chủ thể nhận - (giống như mô hình digital Signature chẳng hạn) thì mình lại cung cấp public key cho remote? có gì sai sai ở đây không nhỉ? Chắc là không rồi =)) Và trong bài viết này chúng ta cũng sẽ làm sáng tỏ được điều này

SSH cũng có nhiều phiên bản và phiên bản thông thường đang được khuyến nghị hiện nay là SSH protocol 2. Khi nghiên cứu về baỏ mật cũng như mã hóa, có 2 hệ thống mật mã chính mà bạn cần nắm được:

  • Public Key Cryptography - Hay mật mã bất đối xứng - Sử dụng trong Digital Signature là nổi tiếng nhất
  • Secret Key Cryptography - Hay mật mã đối xứng - Sử dụng Secret key để mã hóa và giải mã hóa, tương tự như cách cách server mã hóa session là 1 ví dụ.

Hầu hết các hệ thống bảo mật ngày nay đều sử dụng 2 loại này, được thể hiện trong nhiều dạng khác nhau. Để hiểu rõ nhất về SSH bạn nên tìm hiểu trước về cách hoạt động của 2 hệ thống mật mã này. Về SSH thì nó ứng dụng cả Asymmetric và Symmetric Encryption Sơ lược SSH gồm 3 bước chính :

  • Bước đầu tiên là khởi tạo 1 kết nối SSH, chính là tạo ra 1 kênh giao tiếp bảo mật giữa server và client.
  • Bởi chủ thể khởi tạo kết nối là Client nên ở bước đầu này Client sẽ phải xác thực Server. Sau khi Client xác định được định danh của Server 1 kết nối bảo mật đối xứng được hình thành giữa 2 bên.
  • Kết nối này sẽ được sử dụng để Server xác thực Client ( ở bước trước mới chỉ có Client định danh được Server - hay nói cách khác mới chỉ có Server đảm bảo tin tưởng khi đứng từ phía Client )

Để chi tiết chúng ta sẽ chia nhỏ các bước này và đi sâu vào chi tiết từng bước 1.

Step 1:

Khi khởi tạo 1 TCP connection tới 1 port ở server, Client sẽ nhận được được 2 thông tin:

  • Phiên bản Protocol mà Server hỗ trợ
  • SSH package version của Server
[root@slashroot1 ~]# telnet 192.168.0.105 22
<div id="edfs"><a href="http://graciatelevisio.cat/payday-loans-direct-lenders-instant-approval">graciatelevisio.cat/payday-loans-direct-lenders-instant-approval</a></div>
Trying 192.168.0.105...
Connected to 192.168.0.105 (192.168.0.105).
Escape character is '^]'.
SSH-2.0-OpenSSH_4.3

Nếu phiên bản Protocol của Server phù hợp với Client thì kết nối mới được tiếp tục.

Step 2:

Ngay sau khi Client tiếp tục kết nối, Server - Client sẽ chuyển đổi sang "Binary Packet Protocol". Bộ giao thức này có thể chứa package độ dài 32bits. Từ giờ Client và Server sẽ giao tiếp bằng bộ giao thức này.

Step 3:

Lúc này, Server sẽ gửi các thông tin quan trọng hơn tới Client, đây là những thông tin nắm vai trò chính trong phiên làm việc hiện tại:

[root@slashroot1 ssh]# pwd
/etc/ssh
[root@slashroot1 ssh]# cat ssh_host_rsa_key.pub
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxlwxaB4wKrFHGsqUYEzYtTIJWjgul8ML+bnnJIg0HER1wnW2QitRqDzw6f9cr3WKvwqAQh/Sf4bM0LqUAXZre+J6oiLY7X8V6NtEA8nHO1qryueNe44rI6HYunZ3yo4UAXUZqxhjer+tA8OCD6DLRfXOWIMsBUBXJuB+yl1/qGH2J0Kjrnpj17N0mPMqGmMb8+9EjV1Rs1aSDriIWjDsJIDd8fz4gRoelB5mFsEQ7rD+m/RNWxbAhkBoNcFadRg30LqhCtGYQsWADv0p4THCDVZxB3u9VSWK9qZRgF7LbGRdgiVgJjGDPqCO3cWlnQzxcZ9VdvKy+em1RB9BJ++kuw==
[root@slashroot1 ~]# ssh 192.168.0.105
The authenticity of host '192.168.0.105 (192.168.0.105)' can't be established.
RSA key fingerprint is c7:14:f4:85:5f:52:cb:f9:53:56:9d:b3:0c:1e:a3:1f.
Are you sure you want to continue connecting (yes/no)?
  • Server cho Client biết định danh của mình bằng rsa public key trên server. Key này được tạo ra sử dụng openssh. Nếu đây là lần đầu tiên Client kết nối tới Server thì Client sẽ nhận được 1 cảnh báo, nếu chấp nhận thì rsa public key của server sẽ được lưu vào known_hosts file. Kể từ nay về sau Client xác nhận server này là 1 server đã biết và không còn cảnh báo nữa. Mọi Client connect tới Server đều nhận được rsa public key này giống nhau.
[root@slashroot1 ~]# cd .ssh/
[root@slashroot1 .ssh]# ll -a
total 16
drwx------ 2 root root 4096 Feb 25 14:19 .
drwxr-x--- 9 root root 4096 Feb 25 09:58 ..
-rw-r--r-- 1 root root    0 Feb 25 14:08 known_hosts
[root@slashroot1 .ssh]#
  • Server key. Server key này được regenerate theo mỗi khoảng thời gian nhất định.
# Lifetime and size of ephemeral version 1 server key
#KeyRegenerationInterval 1h
#ServerKeyBits 768
  • 1 chuỗi 8 bytes ngẫu nhiên được gọi là checkbytes. Sau này Client sẽ sử dụng chuỗi này để reply lại cho Server.
  • Cuối cùng, Server cấp cho Client biết toàn bộ các phương thức bảo mật, mã hóa mà Server hỗ trợ.

Step 4:

Dựa vào danh sách các phương thức mã hóa mà Server hỗ trợ, Client tạo ra 1 symmetric key ngẫu nhiên và gửi cho server. Key này sẽ được sử dụng để mã hóa và giải mã hóa trong toàn bộ quá trình giao tiếp giữa 2 bên, đây còn được gọi là session key, session key sẽ được mã hóa dựa vào rsa public key của server cũng như Server key (được thay đổi theo thời gian). Điều này đảm bảo cho dù rsa public key (/etc/ssh/ssh_host_rsa_key) có bị lộ thì cũng không thể giải mã gói tin (có chứa session key). Đây chính là điểm mấu chốt của vấn đề sự khác nhau của cách triển khai public key giữa digital signature và SSH.

Step 5:

Cho đến lúc này Client vẫn chưa thể xác thực được Server, nó chỉ biết được định danh của Server mà thôi (dựa vào rsa public key) Để xác thực Server thì Client phải chắc chắn Server có khả năng giải mã được session key đã gửi ở bước 4. Bởi vậy sau khi gửi session key xong Client sẽ chờ hồi âm từ phía Server. Cho tới khi nhận được thông báo xác nhận Client đã sẵn sàng để xác thực được Server đúng là địa chỉ mà nó cần giao tiếp. Ngược lại Server vẫn chưa thể chứng thực Client.

Reference

Để Server có thể chứng thực được Client có nhiều phương pháp, trong đó có 2 phương án sau là phổ biến nhất:

  1. Password Authentication: Đây là phương pháp phổ biến và đơn giản nhất. Remote server yêu cầu Client cung cấp định danh cũng như mật khẩu.
  2. Public Key Authentication: Authenticate bằng Public key là 1 trong những trải nghiệm tuyệt vời nhất khi làm việc remote             </div>
            
            <div class=
0