Thứ Hai, 7 tháng 3, 2022

Phần 6: Redis Master-Salve sử dụng ACL

 

Phần 6: Redis Master-Salve sử dụng ACL

Seri Redis của chúng ta gồm những phần sau:

Phần 1: Cài đặt redis cơ bản + Turning redis.
Phần 2: Lệnh quản trị redis cơ bản
Phần 3: Bảo mật cho redis. (redis security)
Phần 4: Access List Redis (tính năng mới từ bản 6)
Phần 5: Các mô hình Redis replication, Ưu và nhược điểm
Phần 6: Redis Master-Salve sử dụng ACL
Phần 7: Redis Sentinel sử dụng ACL
Phần 8: Cài đặt Redis Cluster
Phần 9: Di chuyển data từ redis đơn sang cluster và ngược lại.
Phần 10: Data type trong Redis, một vài ví dụ sử dụng (String/hash/sort/list/queue/pub-sub....).
Phần 11: Một số lỗi thường gặp khi quản trị hệ thống Redis.
Phần 12: Continue...

Phần 6: Redis Master-Salve với ACL

Mô hình:
- Master: 192.168.88.12 Port 6379
- Slave:  192.168.88.13 Port 6379

Các cách cài không sử dụng ACL, các bạn vui lòng search Google và Viblo. Đã có rất nhiều bài viết hướng dẫn cài Master-Slave

Master-Slave dùng ACL.

Bước 1: Truy cập vào redis vào đặt mật khẩu cho Replication + thêm mật khẩu user default.

> ACL SETUSER default on >matkhau_default
> ACL SETUSER replicate_user on >matkhau_replicate +psync +replconf +ping
> CONFIG REWRITE
(Chú ý: chạy trên cả Master và Slave, để phục vụ dựng sentinel sau này)

Kết quả, kiểm tra file config có thêm 2 dòng ở cuối cùng:
# cat /opt/redis/conf/6379.conf | tail -n 5
user default on #231d539d073fe5d91a24a56df3196aab2ace130b905d39011840923f9a893ddb ~* &* +@all
user replicate_user on #5c15dbc0958763509a8016827032339bbd3e7cd28d43a045103e69dfff37dba4 resetchannels -@all +psync +ping +replconf

Bước 2: Sửa init file ở trên cả Master và Slave.

(Nhớ stop redis trước khi sửa, mật khẩu replicate không phải là mật khẩu user default )
[root@master-node]# redis-cli -p 6379 --user default --pass matkhau_default shutdown
# vim /etc/init.d/redis_6379
CLIEXEC="/usr/local/bin/redis-cli --user default --pass matkhau_default"
[root@master-node]# /etc/init.d/redis_6379 start

Bước 3. Sửa cấu hình bind trên cả Master và Slave, restart cả 2

# vim /opt/redis/conf/6379.conf
bind 0.0.0.0
# /etc/init.d/redis_6379 restart

Bước 4: Cấu hình Replication trên server Slave 192.168.88.13

Thêm 3 dòng config này ở dưới cùng để bật replication.
# vim /opt/redis/conf/6379.conf
replicaof 192.168.88.12 6379
masteruser replicate_user
masterauth matkhau_replicate
# /etc/init.d/redis_6379 restart (restart slave)

Bước 5: Kiểm tra:

Master: ( có 1 slave gọi vào)

# redis-cli -p 6379 --user default --pass matkhau_default info

> Replication
role:master
connected_slaves:1
slave0:ip=192.168.88.13,port=6379,state=online,offset=56,lag=0

Slave ( Có trạng thái là slave - up )

# Replication
role:slave
master_host:192.168.88.12
master_port:6379
master_link_status:up

Nguồn: https://redis.io/topics/acl

https://redis.io/topics/replication

Chủ Nhật, 6 tháng 3, 2022

Phần 5: Các mô hình Redis, Ưu và nhược điểm

 

Phần 5: Các mô hình Redis, Ưu và nhược điểm

Seri Redis của chúng ta gồm những phần sau:

Phần 1: Cài đặt redis cơ bản + Turning redis.
Phần 2: Lệnh quản trị redis cơ bản
Phần 3: Bảo mật cho redis. (redis security)
Phần 4: Access List Redis (tính năng mới từ bản 6)
Phần 5: Các mô hình Redis replication, Ưu và nhược điểm
Phần 6: Redis Master-Salve sử dụng ACL
Phần 7: Redis Sentinel sử dụng ACL
Phần 8: Cài đặt Redis Cluster
Phần 9: Di chuyển data từ redis đơn sang cluster và ngược lại.
Phần 10: Data type trong Redis, một vài ví dụ sử dụng (String/hash/sort/list/queue/pub-sub....).
Phần 11: Một số lỗi thường gặp khi quản trị hệ thống Redis.
Phần 12: Continue...

Phần 5: Mô hình Redis Replication/ Cluster / HA

1 . Mô hình đơn:



- Ưu điểm: Tiết kiệm chi phí, phù hợp với môi trường nhỏ. Hiệu suất cao - Nhược điểm: Không có tính dự phòng, nếu sập thì phải dựng lại từ đầu (nếu có backup dump.rdb thì thời gian load lại dữ liệu vài phút. VD: HDD, 50tr key tầm 2-5 phút). Có thể đưa lên k8s quản lý cho tiện. Nếu data chấp nhận tổn thất và code load lại từ Database thì sẽ gần như zero downtime (2-30s).

Phân biệt giữa Replication và Cluster:

Phân biệt:
1) Replication: 1master-1slave hoặc 1master-nhiều-Slave (mỗi node sẽ chứa đủ 100% dữ liệu). 
2) Sharding cluster: Partition data (data được chia lẻ và lưu trên nhiều node khác nhau, tổng dữ liệu riêng rẽ các node = 100%). 

>> Khi nào ta nên chọn giữa replication / cluster sharding?:
- Về cơ bản, mô hình (1Master)- (1Slave) là đủ hoàn toàn để redis chạy hết hiệu năng cho cả 1 hệ thống lớn hàng trăm nghìn truy vấn trên 1s (bank/viễn thông...). 
- Vấn đề nằm ở chỗ khi lượng Ram cần dùng để lưu trữ Data của redis > vượt quá Ram của Server đang chạy. Khi đó ta sẽ bắt đầu chia nhỏ dữ liệu ra để lưu ở "nhiều server" khác nhau. Khi client gọi vào, redis-cluster sẽ hướng dẫn truy xuất vào chính xác node nào có dữ liệu.

2. Mô hình Master-Slave hoặc 1 Master và nhiều SLAVE



Ưu điểm: - Mô hình 1Master-1Slave hoặc 1Master-(N)Slave sẽ đảm bảo dữ liệu luôn luôn được dự phòng. - Khi xảy ra sự cố với node Master, ta sẽ manual Slave node thay làm Master. - Có thể cho node M làm write, và các node S làm read, tăng khả năng chia tải. Nhược điểm: - Khi Master chết, phải cấu hình thủ công Slave lên làm Master. Và phải tự động chuyển luồng cho client gọi vào M mới. - Tối ưu hơn, ta có thể có mô hình Setinel tự động detect Master down và đẩy Slave node khác lên làm Master ở mục C. - Vẫn sẽ có độ trễ về đồng bộ thông tin từ M > S. Ví dụ ta HMSET hàng triệu key có độ dài lớn vào M.

3. Mô hình SETINEL



Ưu điểm: - Mô hình Setinel đã tối ưu ở việc "bầu chọn" đâu sẽ là Master node khi có node bị chết - Nhưng app không biết đâu là Master mới để gọi vào khi Master bị thay đổi. Để khắc phục vấn đề này, các siêu nhân khác đã đưa ra phương án dùng HA-Proxy để phát hiện và lái luồng TCP về redis master. Hoặc dùng thư viện client sẵn có (như java jedis) có thể tự detect được đâu là M trong khối Setinel (không cần cài HAProxy) Nhược điểm: - Cần nhiều tài nguyên (cần ít nhất là 3 node để tránh bị tình trạng bầu chọn không đồng đều, các slave-setinel tự nhận mình là master - hiện tượng Split-Brain)

4. Mô hình SHARDING CLUSTER

Ưu điểm:
- Khắc phục được yếu điểm các mô hình trên là băm nhỏ dữ liệu sang các node.
- Đảm bảo downtime gần như zero. Dữ liệu luôn được đảm bảo 100% (gồm 3 node chính và 3 node phụ)
- Dễ dàng  mở rộng, chỉ cần gõ lệnh chia dữ liệu sang các node mới

Nhược Điểm:
- Cấu hình phức tạp, cần code client phải hỗ trợ cluster.
- Chỉ chạy trên db0 (không hỗ trợ multi db)

Thứ Bảy, 5 tháng 3, 2022

Phần 4: Access List Redis (tính năng mới ở bản 6)

Phần 4: Access List Redis (tính năng mới ở bản 6)

Seri Redis của chúng ta gồm những phần sau:

Phần 1: Cài đặt redis cơ bản + Turning redis.
Phần 2: Lệnh quản trị redis cơ bản
Phần 3: Bảo mật cho redis. (redis security)
Phần 4: Access List Redis (tính năng mới từ bản 6)
Phần 5: Các mô hình Redis replication, Ưu và nhược điểm
Phần 6: Redis Master-Salve sử dụng ACL
Phần 7: Redis Sentinel sử dụng ACL
Phần 8: Cài đặt Redis Cluster
Phần 9: Di chuyển data từ redis đơn sang cluster và ngược lại.
Phần 10: Data type trong Redis, một vài ví dụ sử dụng (String/hash/sort/list/queue/pub-sub....).
Phần 11: Một số lỗi thường gặp khi quản trị hệ thống Redis.
Phần 12: Continue...

Phần 4: Access List Redis (ACL tính năng mới ở bản 6 + 7)

ACL trong Redis giống với gán Role quyền trong Database vậy. Đôi khi 1 client kết nối mà chọc được toàn bộ dữ liệu redis vẫn là quá rủi ro về bảo mật (nhẹ thì bị xóa trắng, mà nặng thì public data ngoài internet). Để enable ACL, nếu hệ thống mới ta sẽ extend quyền dần, nhưng hệ thống cũ đã chạy - bạn cần nắm rõ code đang chạy loại dữ liệu gì để giới hạn quyền thật chuẩn, tránh việc làm lỗi hệ thống. (sử dụng lệnh MONITOR đến giám sát code đang gọi redis như nào và nên trao đổi với DEV Team).

Mặc định redis luôn có user là default và không có mật khẩu:

127.0.0.1:6379> ACL LIST
1) "user default on nopass ~* &* +@all"

Để đặt password cho user default này ta làm như sau:

127.0.0.1:6379> ACL SETUSER default on >matkhau_default
OK
127.0.0.1:6379> ACL LIST
1) "user default on #231d539d073fe5d91a24a56df3196aab2ace130b905d39011840923f9a893ddb ~* &* +@all"
127.0.0.1:6379> CONFIG REWRITE
OK

Để đăng nhập lại vào redis-cli ta cần gõ thêm mật khẩu và user để vào đc:

[root@master-node conf]# redis-cli --user default --pass matkhau_default
hoặc
[root@master-node conf]# redis-cli 
127.0.0.1:6379> AUTH default matkhau_default
OK

Cấu trúc cơ bản của 1 lệnh ACL redis bao gồm

ACL SETUSER <username> on ... acl rules ...
ACL SETUSER <username> on >password +<quyền> ~<key> &<channel>
--------------------
Quyền sẽ được load từ trái sang phải, chi tiết như sau:
1) on / off : khóa user
2) >matkhau :đặt mật khẩu cho user. (Ví dụ >5ppW3IDwzKcS)
3) +/- : Command redis được phép chạy, ví dụ +get, +set, +info, hoặc +@<nhóm quyền>.
4) ~ : phạm vi key được áp dụng (để mở toàn bộ bằng ~* , )
5) & : Liên quan đến pub/sub channel của redis (để mở toàn bộ &*).
>

Để kiểm tra redis đang có user mặc định nào, và có những quyền gì bằng lệnh ACL LIST

[root@master-node conf]# redis-cli 
127.0.0.1:6379> ACL LIST
1) "user default on nopass ~* &* +@all"
Giải thích: User default, trạng thái enable ON, không cần pass đăng nhập nopass, full quyền với các key ~*, full quyền với channel &*, full câu lệnh được sử dụng +@all

Để biết redis có những nhóm quyền nào +@<nhóm quyền> , để dễ gán nhóm quyền cho user. Ta dùng lệnh ACL CAT

127.0.0.1:6379> ACL CAT
 1) "keyspace"
...
...
...
...
4) "set"
18) "dangerous"

Bài Toán 1:

- Tôi muốn phân quyền cho developer1 có mk là matkhau1. 
- Có quyền trên cho toàn bộ data type redis và channel: 
- Quyền sử dụng toàn bộ lệnh của redis.
- bỏ quyền hệ thống admin.
- bỏ quyền sử dụng câu lệnh nguy hiểm. 
1) Để xem nhóm quyền admin, dangerous có những lệnh nào
127.0.0.1:6379> ACL CAT admin
127.0.0.1:6379> ACL CAT dangerous

2) Xử lý bài toán
127.0.0.1:6379> ACL SETUSER developer1 on >matkhau1  ~* &* +@all -@admin -@dangerous -@admin
127.0.0.1:6379> CONFIG REWRITE

Bài Toán 2:

Redis của tôi chỉ có 2 loại dữ liệu là String và Hash (bao gồm GET/HGET/HGETALL). 
Tôi muốn bạn developer2 mới vào , đăng nhập bằng matkhau2, 
chỉ đọc được dữ liệu string và hash. 
Ngoài ra không được chạy lệnh nào khác.
1) Đặt quyền
127.0.0.1:6379> ACL SETUSER developer2 on >matkhau2 ~* &* -@all +get +hget +hgetall
127.0.0.1:6379> CONFIG REWRITE

2 )Thử đăng nhập vào user developer2. Có quyền get nhưng ko cho set.
127.0.0.1:6379> AUTH developer2 matkhau2
127.0.0.1:6379> get tuanda
"111"
127.0.0.1:6379> set tuanda newvalue
(error) NOPERM this user has no permissions to run the 'set' command or its subcommand

3) kiểm tra với Hash:
127.0.0.1:6379> hgetall user:tuanda
1) "id"
2) "100"

Bài Toán 3:

Tôi muốn developer3 đăng nhập bằng matkhau3 (accout này sẽ cho code chạy). 
Phạm vi quyền là set/get theo các key "user:XXXXXXXXXXXXX"
không có quyền can thiệp vào các key value khác.
127.0.0.1:6379> ACL SETUSER developer3 on >matkhau3 ~user:* -@all +get +set 
127.0.0.1:6379> CONFIG REWRITE
127.0.0.1:6379> AUTH developer3 matkhau3
127.0.0.1:6379> get user:tuanda
"9999"
127.0.0.1:6379> get category:tuanda
(error) NOPERM this user has no permissions to access one of the keys used as arguments
127.0.0.1:6379> get test
(error) NOPERM this user has no permissions to access one of the keys used as arguments
127.0.0.1:6379> set user:newuser2 8888
OK

Chú ý cách đặt thứ tự quyền:

Lệnh 1_ 127.0.0.1:6379> ACL SETUSER developer4 on >matkhau4 ~* -set +@all
Lệnh 2_127.0.0.1:6379> ACL SETUSER developer4 on >matkhau4 ~* +@all -set

hai lệnh này sẽ khác nhau. Vì redis load ACL từ trái qua phải:

  • Với lệnh 1 khi -set xong ta lại +all thế hóa ra cuối cùng là Full quyền bao gồm cả set.
  • Với lệnh 2 ta đã cho all quyền, nhưng lại -set > nên cuối cùng không có quyền SET.

Chi tiết thêm về nhiều ví dụ về ACL, mời các bạn đọc

https://redis.io/topics/acl

https://redis.io/commands#server

Phần 3: Bảo mật cho redis. (redis security)

Phần 3: Bảo mật cho redis. (redis security)

Seri Redis của chúng ta gồm những phần sau:

Phần 1: Cài đặt redis cơ bản + Turning redis.
Phần 2: Lệnh quản trị redis cơ bản
Phần 3: Bảo mật cho redis. (redis security)
Phần 4: Access List Redis (tính năng mới từ bản 6)
Phần 5: Các mô hình Redis replication, Ưu và nhược điểm
Phần 6: Redis Master-Salve sử dụng ACL
Phần 7: Redis Sentinel sử dụng ACL
Phần 8: Cài đặt Redis Cluster
Phần 9: Di chuyển data từ redis đơn sang cluster và ngược lại.
Phần 10: Data type trong Redis, một vài ví dụ sử dụng (String/hash/sort/list/queue/pub-sub....).
Phần 11: Một số lỗi thường gặp khi quản trị hệ thống Redis.
Phần 12: Continue...

Phần 3: Bảo mật cho redis. (redis security)

Trên thế giới, có rất nhiều vụ redis phơi port ra ngoài bị chiếm quyền điều khiển để cài miner, hoặc xóa sạch dữ liệu redis, thay đổi dữ liệu để trục lợi. Vì vậy ta luôn sẵn tinh thần bảo mật cho redis:

1. Thay đổi Port

Thay đổi port để tránh bị scan tấn công:

[root@master-node ~]# /etc/init.d/redis_6379 stop
[root@master-node ~]# cat /opt/redis/conf/6379.conf  | grep 'port 6379'
port 6379
[root@master-node ~]# cat /etc/init.d/redis_6379 | grep REDISPORT
REDISPORT="6379"

# VD ta đổi thành port 6800, cần đổi ở trong file config và file khởi động.
[root@master-node ~]# vi /opt/redis/conf/6379.conf 
port 6800
[root@master-node ~]# vi /etc/init.d/redis_6379
REDISPORT="6800"

#Kiểm tra:
[root@master-node ~]# ps aux | grep redis | grep server
root      97040  0.1  0.1 165072  3032 ?        Ssl  13:09   0:00 /usr/local/bin/redis-server 127.0.0.1:6800
[root@master-node ~]# redis-cli -h 127.0.0.1 -p 6800 INFO

2. Chặn firewall

  • Nếu bạn chạy app và redis chung 1 server, giữ nguyên bind 127.0.0.1, Port redis chỉ lắng nghe nội bộ nên khá an toàn.
  • Trường hợp App và redis nằm ở riêng 2 server khác nhau, ta để bind 0.0.0.0 nhưng chú ý Chặn Firewall hoặc chặn network ở mạng nội bộ DMZ.

Cách public port redis như sau:

[root@master-node ~]# cat /opt/redis/conf/6379.conf | grep bind | grep -v '#'
bind 127.0.0.1 -::1
Sửa thành bind 0.0.0.0 . Và chú ý về Firewall, chặn không cho bên ngoài tấn công.

3. Đặt mật khẩu cho redis

Có 2 cách đặt mật khẩu, bản redis 6 ra tính năng mới ra ACL, mình khuyến khích các bạn dùng ACL này về sau. Các phần tiếp theo tôi sẽ hướng dẫn các bạn sử dụng thành thạo ACL.

[root@master-node conf]# redis-cli -p 6800
127.0.0.1:6800> ACL SETUSER default on >matkhau ~* &* +@all
OK
127.0.0.1:6800> CONFIG REWRITE
OK
[root@master-node conf]# redis-cli --user default --pass matkhau -p 6800 INFO
Ta kiểm tra config sẽ có thêm 1 dòng sau:
[root@master-node conf]# cat /opt/redis/conf/6379.conf | grep 'user default'
user default on #6445e373d7fcde106bfcb897ee8f0bb28589bd7797f54f1ef4e5d5447cfbd011 ~* &* +@all

Sửa lại init file, nếu không sửa bạn sẽ không bật tắt đc redis bằng init/systemd:
[root@master-node conf]# vi /etc/init.d/redis_6379  | grep cli
CLIEXEC="/usr/local/bin/redis-cli --user default --pass matkhau"

Cách 2: Không sử dụng ACL (không khuyến khích về sau, dùng cho các thư viện code cũ, bạn phải đảm bảo trong config đang không dùng ACL)

[root@master-node conf]# cat /opt/redis/conf/6379.conf | grep 'user default'
user default on #64xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxe5d5447cfbd011 ~* &* +@all
Nếu có dòng này, bạn hãy comment # lại. Vì nếu ACL cách 1 đã có, thì cách 2 ở dưới bị vô hiệu.

Sửa config như sau: 
[root@master-node conf]# vi /opt/redis/conf/6379.conf
requirepass "matkhau"

Kiểm tra:
[root@master-node conf]# redis-cli -p 6800 -a matkhau INFO

Sửa init file: 
[root@master-node conf]# vi /etc/init.d/redis_6379  | grep cli
CLIEXEC="/usr/local/bin/redis-cli -a matkhau"

4. Xóa những lệnh nguy hiểm

Liệt kê những lệnh nguy hiểm (chỉ dành cho quản lý redis, không dành cho role dev, app):

127.0.0.1:6379> ACL CAT dangerous
 1) "replconf"
 2) "restore"
 3) "cluster"
 4) "pfdebug"
 5) "bgrewriteaof"
 6) "latency"
 7) "acl"
 8) "swapdb"
 9) "info"
10) "replicaof"
11) "migrate"
12) "flushall"
13) "flushdb"
14) "lastsave"
15) "keys"
16) "save"
17) "config"
18) "pfselftest"
19) "restore-asking"
20) "slaveof"
21) "sync"
22) "failover"
23) "debug"
24) "slowlog"
25) "role"
26) "module"
27) "psync"
28) "sort"
29) "client"
30) "monitor"
31) "bgsave"
32) "shutdown"

Thay command nguy hiểm xóa hết dữ liệu hoặc làm giảm hiệu năng redis. Ta sửa config như sau:

[root@master-node conf]# tail /opt/redis/conf/6379.conf
rename-command FLUSHALL XOAHETDATA
rename-command FLUSHDB XOADATADBHIENTAI
[root@master-node conf]# redis-cli -p 6800
127.0.0.1:6800> flushall
(error) ERR unknown command `flushall`, with args beginning with:   > OK , đã xóa lệnh flushall

5 Không cho redis chạy quyền root.

Với hệ thống dùng Systemd ta thêm User và Group=redis như sau:

[root@master-node ~]# adduser redis --no-create-home
[root@master-node ~]# vi /etc/systemd/system/redis.service
[Unit]
Description=Redis data structure server
Documentation=https://redis.io/documentation
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/local/bin/redis-server /opt/redis/conf/6379.conf --supervised systemd --daemonize no
ExecStop=/usr/local/bin/redis-cli SHUTDOWN
#ExecStop=/usr/local/bin/redis-cli --user default --pass matkhau SHUTDOWN
LimitNOFILE=10032
User=redis
Group=redis

[Install]
WantedBy=multi-user.target

Với hệ thống dùng init file ta chạy thẳng start bằng user redis.

[root@master-node ~]# /etc/init.d/redis_6379 stop
[root@master-node ~]# adduser redis --no-create-home
[root@master-node ~]# chown -R redis.root /opt/redis
[root@master-node ~]# chown redis.redis /etc/init.d/redis_6379
[root@master-node ~]# su - redis
-bash-4.2$ /etc/init.d/redis_6379 start
Starting Redis server..
-bash-4.2$ ps aux | grep redis
redis     85679  0.3  0.1 162512  3216 ?        Ssl  08:47   0:00 /usr/local/bin/redis-server 0.0.0.0:6379

Ngoài ra , để bảo mật redis còn có các đề nghị sau đây:

  • Phân quyền chạy và đọc file tối thiểu (file chạy là 750, file log, config là 640)
  • Đặt lịch Backup log, config, dump
  • Bật TLS giữa client và redis-server.

Phần sau, tôi sẽ hướng dẫn bạn một cách khác là dùng ACL để khóa các command nguy hiểm này

Debug exec pod with no any command support

  Một ngày đẹp trời pod bị lỗi. Bạn thử ngay lệnh "kubectl exec -it ..." vào pod kiểm tra. Nhưng quãi đạn, pod không hỗ trợ bất kỳ...