Redis là một kho lưu trữ key-value trong bộ nhớ nổi tiếng với tính linh hoạt, hiệu năng cao và hỗ trợ đa ngôn ngữ. Bài hướng dẫn này sẽ trình bày cách cài đặt, cấu hình và bảo mật Redis trên một máy chủ Ubuntu 22.04.
Yêu cầu cần thiết
Để hoàn thành hướng dẫn này, bạn cần có quyền truy cập vào một máy chủ Ubuntu 22.04 có một người dùng không phải root với quyền sudo và một tường lửa được cấu hình bằng ufw. Bạn có thể thiết lập điều này theo hướng dẫn Cài Đặt Máy Chủ Ban Đầu cho Ubuntu 22.04.
Bước 1 – Cài Đặt và Cấu Hình Redis
Chúng ta sẽ sử dụng trình quản lý gói APT để cài đặt Redis từ kho lưu trữ chính thức của Ubuntu. Tính đến thời điểm viết bài này, phiên bản có sẵn trong kho lưu trữ mặc định là 6.0.16.
Bắt đầu bằng việc cập nhật bộ nhớ cache các gói của apt:
sudo apt update
Tiếp theo, cài đặt Redis bằng lệnh:
sudo apt install redis-server
Lệnh trên sẽ tải về và cài đặt Redis cùng với các phụ thuộc cần thiết. Sau đó, bạn cần thực hiện một thay đổi cấu hình quan trọng trong file cấu hình Redis (được tạo tự động trong quá trình cài đặt).
Mở file cấu hình bằng trình soạn thảo ưa thích của bạn:
sudo nano /etc/redis/redis.conf
Bên trong file, tìm dòng chỉ thị supervised. Chỉ thị này cho phép bạn khai báo hệ thống init để quản lý Redis như một dịch vụ, giúp bạn kiểm soát hoạt động của nó tốt hơn. Mặc định, chỉ thị supervised được đặt là no
. Vì bạn đang chạy Ubuntu sử dụng hệ thống init systemd, hãy thay đổi nó thành:
. . . # If you run Redis from upstart or systemd, Redis can interact with your # supervision tree. Options: # supervised no - no supervision interaction # supervised upstart - signal upstart by putting Redis into SIGSTOP mode # supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET # supervised auto - detect upstart or systemd method based on # UPSTART_JOB or NOTIFY_SOCKET environment variables # Note: these supervision methods only signal "process is ready." # They do not enable continuous liveness pings back to your supervisor. supervised systemd . . .
Đây là thay đổi duy nhất cần thực hiện trong file cấu hình Redis tại thời điểm này. Sau khi chỉnh sửa xong, lưu và đóng file (nếu dùng nano, nhấn CTRL + X, sau đó Y và ENTER).
Tiếp theo, khởi động lại dịch vụ Redis để áp dụng các thay đổi:
sudo systemctl restart redis.service
Với những bước trên, bạn đã cài đặt và cấu hình Redis, và nó đang chạy trên máy của bạn. Tuy nhiên, trước khi sử dụng, hãy kiểm tra xem Redis có hoạt động chính xác hay không.
Bước 2 – Kiểm Tra Redis
Như với bất kỳ phần mềm mới cài đặt nào, nên kiểm tra để đảm bảo Redis hoạt động như mong đợi trước khi thay đổi cấu hình thêm. Chúng ta sẽ xem qua một số cách để kiểm tra Redis có hoạt động đúng không.
Bắt đầu bằng cách kiểm tra xem dịch vụ Redis có đang chạy không:
sudo systemctl status redis
Nếu không có lỗi, lệnh trên sẽ cho ra kết quả tương tự:
Output
● redis-server.service - Advanced key-value store Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2022-04-20 20:40:52 UTC; 4s ago Docs: http://redis.io/documentation, man:redis-server(1) Main PID: 2899 (redis-server) Status: "Ready to accept connections" Tasks: 5 (limit: 2327) Memory: 2.5M CPU: 65ms CGroup: /system.slice/redis-server.service └─2899 "/usr/bin/redis-server 127.0.0.1:6379 . . .
Đầu ra cho thấy Redis đang chạy và đã được kích hoạt, tức là nó sẽ tự động khởi động mỗi khi máy chủ khởi động.
Lưu ý: Cài đặt này phù hợp với nhiều trường hợp sử dụng Redis phổ biến. Tuy nhiên, nếu bạn muốn khởi động Redis thủ công mỗi lần máy chủ khởi động, hãy cấu hình bằng lệnh:
sudo systemctl disable redis
Để kiểm tra Redis có hoạt động đúng không, kết nối đến máy chủ bằng redis-cli – giao diện dòng lệnh của Redis:
redis-cli
Trong giao diện, kiểm tra kết nối bằng lệnh ping:
ping
Output
PONG
Đầu ra này xác nhận kết nối với máy chủ vẫn hoạt động. Tiếp theo, kiểm tra xem bạn có thể thiết lập key bằng lệnh:
set test "It's working!"
Output
OK
Lấy giá trị vừa thiết lập bằng lệnh:
get test
Nếu mọi thứ ổn, kết quả sẽ hiển thị:
Output
"It's working!"
Sau khi xác nhận có thể truy xuất giá trị, thoát khỏi giao diện Redis để trở lại shell:
exit
Lần cuối, để kiểm tra xem Redis có lưu trữ dữ liệu ngay cả sau khi dừng hoặc khởi động lại không, hãy thực hiện:
- Khởi động lại phiên bản Redis:
sudo systemctl restart redis
- Kết nối lại với redis-cli:
redis-cli
- Kiểm tra lại giá trị bằng lệnh:
get test
Kết quả:
Output
"It's working!"
Sau đó, thoát shell:
exit
Với những bước này, cài đặt Redis của bạn đã hoạt động hoàn chỉnh và sẵn sàng sử dụng. Tuy nhiên, một số cài đặt mặc định của Redis không an toàn, tạo cơ hội cho kẻ xâm nhập tấn công và truy cập vào máy chủ cũng như dữ liệu của bạn. Các bước tiếp theo của bài hướng dẫn sẽ giới thiệu các phương pháp giảm thiểu lỗ hổng bảo mật này, theo khuyến cáo của trang web chính thức của Redis. Mặc dù các bước này là tùy chọn và Redis vẫn hoạt động nếu bạn không thực hiện chúng, nhưng rất nên làm để tăng cường bảo mật cho hệ thống của bạn.
Bước 3 – Ràng Buộc với localhost
Mặc định, Redis chỉ cho phép truy cập từ localhost. Tuy nhiên, nếu bạn đã cài đặt và cấu hình Redis theo một hướng dẫn khác, có thể bạn đã sửa file cấu hình để cho phép kết nối từ bất cứ đâu – điều này không an toàn bằng việc ràng buộc với localhost.
Để khắc phục, mở file cấu hình Redis để chỉnh sửa:
sudo nano /etc/redis/redis.conf
Tìm dòng dưới đây và đảm bảo nó được bỏ chú thích (loại bỏ dấu #
nếu có):
. . . bind 127.0.0.1 ::1 . . .
Lưu và đóng file (nhấn CTRL + X, sau đó Y và ENTER).
Tiếp theo, khởi động lại dịch vụ để systemd áp dụng thay đổi:
sudo systemctl restart redis
Để kiểm tra thay đổi đã có hiệu lực, chạy lệnh netstat:
sudo netstat -lnp | grep redis
Output
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 14222/redis-server tcp6 0 0 ::1:6379 :::* LISTEN 14222/redis-server
Lưu ý: Lệnh netstat có thể không có sẵn trên hệ thống của bạn. Nếu vậy, bạn có thể cài đặt nó (cùng với nhiều công cụ mạng hữu ích khác) bằng lệnh:
sudo apt install net-tools
Đầu ra cho thấy chương trình redis-server đã được ràng buộc với localhost (127.0.0.1), phản ánh thay đổi bạn vừa thực hiện. Nếu cột đó hiển thị địa chỉ IP khác (ví dụ: 0.0.0.0), hãy kiểm tra lại xem bạn đã bỏ chú thích đúng dòng và khởi động lại dịch vụ Redis.
Khi Redis chỉ lắng nghe trên localhost, việc kẻ xâm nhập truy cập vào máy chủ sẽ khó khăn hơn. Tuy nhiên, hiện tại Redis chưa yêu cầu người dùng xác thực trước khi thay đổi cấu hình hay dữ liệu. Để khắc phục, Redis cho phép yêu cầu xác thực bằng mật khẩu trước khi thay đổi thông qua client (redis-cli).
Bước 4 – Cấu Hình Mật Khẩu cho Redis
Việc cấu hình mật khẩu cho Redis kích hoạt một trong hai tính năng bảo mật tích hợp – lệnh auth, yêu cầu các client xác thực để truy cập cơ sở dữ liệu. Mật khẩu được cấu hình trực tiếp trong file /etc/redis/redis.conf, vì vậy mở lại file này bằng trình soạn thảo bạn ưa thích:
sudo nano /etc/redis/redis.conf
Cuộn xuống phần SECURITY và tìm dòng chỉ thị có chú thích như sau:
. . . # requirepass foobared . . .
Bỏ dấu #
và thay foobared
bằng một mật khẩu an toàn.
Lưu ý: Phía trên dòng requirepass trong file redis.conf có một cảnh báo:
. . . # Warning: since Redis is pretty fast an outside user can try up to # 150k passwords per second against a good box. This means that you should # use a very strong password otherwise it will be very easy to break. # . . .
Do đó, điều quan trọng là bạn phải chỉ định một giá trị mật khẩu rất mạnh và dài. Thay vì tự tạo mật khẩu, bạn có thể sử dụng lệnh openssl để tạo mật khẩu ngẫu nhiên, như ví dụ dưới đây. Bằng cách chuyển đầu ra của lệnh đầu tiên sang lệnh openssl thứ hai, nó sẽ loại bỏ các ký tự ngắt dòng không mong muốn:
openssl rand 60 | openssl base64 -A
Lệnh trên sẽ trả về kết quả như sau:
Output
RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE
Sau khi sao chép và dán đầu ra này làm giá trị mới cho requirepass, file sẽ hiển thị như sau:
requirepass RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE
Sau khi thiết lập mật khẩu, lưu và đóng file, sau đó khởi động lại Redis:
sudo systemctl restart redis.service
Để kiểm tra mật khẩu có hoạt động không, mở Redis client:
redis-cli
Chuỗi các lệnh dưới đây được sử dụng để kiểm tra tính năng mật khẩu của Redis. Lệnh đầu tiên thử thiết lập một key trước khi xác thực:
set key1 10
Lệnh này sẽ không hoạt động vì bạn chưa xác thực, nên Redis trả về lỗi:
Output
(error) NOAUTH Authentication required.
Lệnh tiếp theo xác thực bằng mật khẩu đã thiết lập trong file cấu hình:
auth your_redis_password
Redis sẽ xác nhận:
Output
OK
Sau đó, chạy lại lệnh trước đó sẽ thành công:
set key1 10
Output
OK
Lệnh sau, get key1, truy vấn giá trị của key:
get key1
Output
"10"
Sau khi xác nhận các lệnh đã hoạt động sau khi xác thực, thoát khỏi redis-cli:
quit
Tiếp theo, chúng ta sẽ tìm hiểu cách đổi tên các lệnh Redis – bước này quan trọng vì nếu nhập nhầm hoặc do kẻ xâm nhập sử dụng, chúng có thể gây ảnh hưởng nghiêm trọng đến dữ liệu của bạn.
Bước 5 – Đổi Tên Các Lệnh Nguy Hiểm
Tính năng bảo mật khác tích hợp trong Redis là cho phép đổi tên hoặc vô hiệu hóa hoàn toàn một số lệnh được coi là nguy hiểm. Khi được thực hiện bởi người dùng không được phép, những lệnh này có thể được sử dụng để cấu hình lại, phá hủy hoặc xóa sạch dữ liệu của bạn. Giống như mật khẩu xác thực, việc đổi tên hoặc vô hiệu hóa các lệnh được cấu hình trong cùng phần SECURITY của file /etc/redis/redis.conf.
Một số lệnh được coi là nguy hiểm bao gồm:
FLUSHDB, FLUSHALL, KEYS, PEXPIRE, DEL, CONFIG, SHUTDOWN, BGREWRITEAOF, BGSAVE, SAVE, SPOP, SREM, RENAME, DEBUG.
Đây không phải là danh sách đầy đủ, nhưng đổi tên hoặc vô hiệu hóa tất cả các lệnh này là một điểm khởi đầu tốt để tăng cường bảo mật cho máy chủ Redis của bạn.
Việc bạn nên vô hiệu hóa hay đổi tên một lệnh phụ thuộc vào nhu cầu cụ thể của bạn hoặc của trang web. Nếu bạn biết rằng bạn sẽ không bao giờ sử dụng một lệnh có khả năng bị lạm dụng, bạn có thể vô hiệu hóa nó; ngược lại, tốt hơn hết nên đổi tên.
Để đổi tên hoặc vô hiệu hóa các lệnh Redis, mở lại file cấu hình:
sudo nano /etc/redis/redis.conf
Cảnh báo: Các bước dưới đây minh họa cách vô hiệu hóa và đổi tên lệnh chỉ mang tính ví dụ. Bạn chỉ nên chọn vô hiệu hóa hoặc đổi tên những lệnh phù hợp với nhu cầu của mình. Bạn có thể tự xem danh sách đầy đủ các lệnh và đánh giá cách chúng có thể bị lạm dụng tại redis.io/commands.
Để vô hiệu hóa một lệnh, đổi tên nó thành chuỗi rỗng (được biểu thị bằng cặp dấu ngoặc kép không có ký tự nào ở giữa), như ví dụ dưới đây:
. . . # It is also possible to completely kill a command by renaming it into # an empty string: # rename-command FLUSHDB "" rename-command FLUSHALL "" rename-command DEBUG "" . . .
Để đổi tên một lệnh, hãy đặt cho nó một tên khác như các ví dụ dưới đây. Các lệnh đổi tên nên khó đoán đối với người khác nhưng dễ nhớ với bạn:
. . . # rename-command CONFIG "" rename-command SHUTDOWN SHUTDOWN_MENOT rename-command CONFIG ASC12_CONFIG . . .
Sau khi chỉnh sửa, lưu lại các thay đổi và đóng file.
Để áp dụng thay đổi, khởi động lại Redis:
sudo systemctl restart redis.service
Để kiểm tra lệnh mới, mở giao diện dòng lệnh của Redis:
redis-cli
Sau đó, xác thực:
auth your_redis_password
Output
OK
Giả sử bạn đã đổi tên lệnh CONFIG thành ASC12_CONFIG như ví dụ trên. Đầu tiên, thử dùng lệnh CONFIG gốc – lệnh này sẽ không hoạt động vì đã được đổi tên:
config get requirepass
Output
(error) ERR unknown command `config`, with args beginning with:
Tuy nhiên, gọi lệnh đã được đổi tên sẽ thành công (lệnh không phân biệt chữ hoa chữ thường):
asc12_config get requirepass
Output
1) "requirepass" 2) "your_redis_password"
Cuối cùng, thoát khỏi redis-cli:
exit
Lưu ý rằng nếu bạn đang sử dụng giao diện dòng lệnh Redis và sau đó khởi động lại Redis, bạn sẽ cần xác thực lại. Nếu không, khi nhập lệnh, bạn sẽ gặp lỗi:
Output
NOAUTH Authentication required.
Cảnh báo: Về việc đổi tên lệnh, có một tuyên bố cảnh báo ở cuối phần SECURITY của file /etc/redis/redis.conf
:
. . . # Please note that changing the name of commands that are logged into the # AOF file or transmitted to replicas may cause problems. . . .
Lưu ý: Dự án Redis chọn sử dụng các thuật ngữ “master” và “slave”, trong khi DataOnline thường ưu tiên sử dụng “primary” và “secondary”. Để tránh nhầm lẫn, bài viết này sử dụng các thuật ngữ được sử dụng trong tài liệu của Redis. Điều này có nghĩa là nếu lệnh đã được đổi tên không có trong file AOF, hoặc có nhưng file AOF chưa được truyền tới các slave, thì sẽ không có vấn đề gì.
Hãy ghi nhớ điều này khi đổi tên lệnh. Thời điểm tốt nhất để đổi tên một lệnh là khi bạn không sử dụng tính năng lưu trữ AOF, hoặc ngay sau khi cài đặt – tức là trước khi ứng dụng sử dụng Redis của bạn được triển khai.
Khi sử dụng AOF và làm việc với cài đặt master-slave, hãy tham khảo câu trả lời từ trang GitHub issue của dự án. Dưới đây là phản hồi cho câu hỏi của tác giả:
Các lệnh được ghi vào file AOF và được nhân bản sang slave theo cùng cách chúng được gửi, vì vậy nếu bạn cố gắng phát lại file AOF trên một instance không có cùng quy tắc đổi tên, bạn có thể gặp phải sự không nhất quán do lệnh không thể thực thi (tương tự với các slave).
Do đó, cách tốt nhất là đảm bảo rằng các lệnh đã đổi tên được áp dụng cho tất cả các instance trong cài đặt master-slave.
Kết Luận
Trong bài hướng dẫn này, bạn đã cài đặt và cấu hình Redis, xác nhận rằng cài đặt Redis của bạn hoạt động đúng cách, và sử dụng các tính năng bảo mật tích hợp để làm cho hệ thống bớt dễ bị tấn công từ các kẻ xâm nhập.
Hãy nhớ rằng, một khi ai đó đã đăng nhập vào máy chủ của bạn, rất dễ để vượt qua các tính năng bảo mật đặc thù của Redis mà chúng ta đã thiết lập. Vì vậy, tính năng bảo mật quan trọng nhất của máy chủ Redis của bạn chính là tường lửa (đã được cấu hình nếu bạn đã theo hướng dẫn Cài Đặt Máy Chủ Ban Đầu), vì nó khiến cho việc vượt qua lớp bảo vệ trở nên cực kỳ khó khăn đối với kẻ xâm nhập.