Có một số tùy chọn để lưu trữ mật khẩu và các bí mật khác mà một chương trình Python cần sử dụng, đặc biệt là một chương trình cần chạy ở chế độ nền, nơi nó không thể chỉ yêu cầu người dùng nhập mật khẩu.
Các vấn đề cần tránh:
- Kiểm tra mật khẩu để kiểm soát nguồn nơi các nhà phát triển khác hoặc thậm chí công chúng có thể nhìn thấy nó.
- Những người dùng khác trên cùng một máy chủ đọc mật khẩu từ tệp cấu hình hoặc mã nguồn.
- Có mật khẩu trong một tệp nguồn mà người khác có thể nhìn thấy nó qua vai bạn khi bạn đang chỉnh sửa nó.
Tùy chọn 1: SSH
Đây không phải lúc nào cũng là một lựa chọn, nhưng nó có lẽ là tốt nhất. Khóa riêng tư của bạn không bao giờ được truyền qua mạng, SSH chỉ chạy các phép tính toán học để chứng minh rằng bạn có đúng khóa.
Để làm cho nó hoạt động, bạn cần những điều sau:
- Cơ sở dữ liệu hoặc bất cứ thứ gì bạn đang truy cập cần phải được SSH truy cập. Thử tìm kiếm "SSH" cùng với bất kỳ dịch vụ nào bạn đang truy cập. Ví dụ: "ssh postgresql" . Nếu đây không phải là một tính năng trên cơ sở dữ liệu của bạn, hãy chuyển sang tùy chọn tiếp theo.
- Tạo một tài khoản để chạy dịch vụ sẽ thực hiện các cuộc gọi đến cơ sở dữ liệu và tạo khóa SSH .
- Thêm khóa công khai vào dịch vụ bạn sẽ gọi hoặc tạo tài khoản cục bộ trên máy chủ đó và cài đặt khóa công khai ở đó.
Tùy chọn 2: Biến môi trường
Đây là cách đơn giản nhất, vì vậy nó có thể là một nơi tốt để bắt đầu. Nó được mô tả tốt trong ứng dụng Twelve Factor . Ý tưởng cơ bản là mã nguồn của bạn chỉ lấy mật khẩu hoặc các bí mật khác từ các biến môi trường, sau đó bạn định cấu hình các biến môi trường đó trên mỗi hệ thống mà bạn chạy chương trình. Nó cũng có thể là một liên lạc tốt nếu bạn sử dụng các giá trị mặc định sẽ phù hợp với hầu hết các nhà phát triển. Bạn phải cân bằng điều đó với việc làm cho phần mềm của bạn "an toàn theo mặc định".
Dưới đây là một ví dụ lấy máy chủ, tên người dùng và mật khẩu từ các biến môi trường.
import os
server = os.getenv('MY_APP_DB_SERVER', 'localhost')
user = os.getenv('MY_APP_DB_USER', 'myapp')
password = os.getenv('MY_APP_DB_PASSWORD', '')
db_connect(server, user, password)
Tra cứu cách thiết lập các biến môi trường trong hệ điều hành của bạn và xem xét việc chạy dịch vụ theo tài khoản của chính nó. Bằng cách đó, bạn không có dữ liệu nhạy cảm trong các biến môi trường khi chạy chương trình trong tài khoản của riêng mình. Khi bạn thiết lập các biến môi trường đó, hãy cẩn thận để người dùng khác không thể đọc chúng. Kiểm tra quyền đối với tệp, chẳng hạn. Tất nhiên bất kỳ người dùng nào có quyền root sẽ có thể đọc chúng, nhưng điều đó không thể tránh được. Nếu bạn đang sử dụng systemd, hãy xem đơn vị dịch vụ và cẩn thận sử dụng EnvironmentFile
thay vì sử dụng Environment
cho bất kỳ bí mật nào. Environment
bất kỳ người dùng nào có thể xem giá trị systemctl show
.
Tùy chọn 3: Tệp cấu hình
Điều này rất giống với các biến môi trường, nhưng bạn đọc các bí mật từ một tệp văn bản. Tôi vẫn thấy các biến môi trường linh hoạt hơn cho những thứ như công cụ triển khai và máy chủ tích hợp liên tục. Nếu bạn quyết định sử dụng tệp cấu hình, Python hỗ trợ một số định dạng trong thư viện chuẩn, như JSON , INI , netrc và XML . Bạn cũng có thể tìm thấy các gói bên ngoài như PyYAML và TOML . Cá nhân tôi thấy JSON và YAML là cách sử dụng đơn giản nhất và YAML cho phép nhận xét.
Ba điều cần xem xét với các tệp cấu hình:
- Tệp ở đâu? Có thể một vị trí mặc định như
~/.my_app
, và một tùy chọn dòng lệnh để sử dụng một vị trí khác.
- Đảm bảo rằng những người dùng khác không thể đọc tệp.
- Rõ ràng, không cam kết tệp cấu hình thành mã nguồn. Bạn có thể muốn cam kết một mẫu mà người dùng có thể sao chép vào thư mục chính của họ.
Tùy chọn 4: Mô-đun Python
Một số dự án chỉ đưa các bí mật của họ vào ngay một mô-đun Python.
db_server = 'dbhost1'
db_user = 'my_app'
db_password = 'correcthorsebatterystaple'
Sau đó nhập mô-đun đó để nhận các giá trị.
from settings import db_server, db_user, db_password
db_connect(db_server, db_user, db_password)
Một dự án sử dụng kỹ thuật này là Django . Rõ ràng, bạn không nên cam kết settings.py
kiểm soát nguồn, mặc dù bạn có thể muốn cam kết một tệp được gọi là settings_template.py
người dùng có thể sao chép và sửa đổi.
Tôi thấy một số vấn đề với kỹ thuật này:
- Các nhà phát triển có thể vô tình chuyển tệp sang quyền kiểm soát nguồn. Thêm nó để
.gitignore
giảm nguy cơ đó.
- Một số mã của bạn không được kiểm soát nguồn. Nếu bạn có kỷ luật và chỉ đặt chuỗi và số ở đây, điều đó sẽ không thành vấn đề. Nếu bạn bắt đầu viết các lớp lọc ghi nhật ký ở đây, hãy dừng lại!
Nếu dự án của bạn đã sử dụng kỹ thuật này, thật dễ dàng để chuyển đổi sang các biến môi trường. Chỉ cần di chuyển tất cả các giá trị cài đặt sang các biến môi trường và thay đổi mô-đun Python để đọc từ các biến môi trường đó.