Cho ăn an toàn một chương trình bằng mật khẩu


9

Sau khi hiểu vấn đề với việc sử dụng mật khẩu trong dòng lệnh , tôi cần tìm cách cung cấp chương trình bằng mật khẩu mà không gặp sự cố (không có mật khẩu được ghi ở đâu đó).

Tôi có một tập lệnh bash tự động cài đặt toàn bộ máy chủ LAMP từ nguồn: Apache, FastCGI, PHP & MySQL. Những cài đặt này yêu cầu mật khẩu, đặc biệt là MySQL.

Làm cách nào để tạo tập lệnh hoàn toàn tự động mà không tiết lộ mật khẩu?

Chỉnh sửa (9 tháng 6, 3:55 UTC):
Tôi đang gọi mysql bằng mật khẩu trên dòng lệnh, thông qua root:

root@dor-desktop:/home/dor# PASS=`cat /home/dor/tmpf/pass`
root@dor-desktop:/home/dor# mysql -u root -p"$PASS"
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6

(PASS = "p4ssw0rd" trong trường hợp của chúng tôi)
Và tôi thực thi ps aux | grep mysqlthông qua người dùng thông thường của mình (dor), không hiển thị cho tôi mật khẩu !
(Một số) psđầu ra là:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      3562  0.0  0.0  34156  2864 pts/0    S+   05:53   0:00 mysql -u root -px xxxxxx

Làm thế nào mà có thể?


Đồng thời xem unix.stackexchange.com/q/385339/135943 , nhưng lưu ý điều này không làm cho nó an toàn!
tự đại diện

Câu trả lời:


11

Liên quan đến cập nhật của bạn:

Khi một quá trình được bắt đầu, nó có một vùng bộ nhớ dành riêng, nơi các đối số được lưu trữ và một int cho biết có bao nhiêu đối số được truyền.

MEMORY
argc    2
argv[0] program_name
argv[1] foo
argv[2] bar

MySQL kiểm tra xem mật khẩu có được truyền trên dòng lệnh -phay không và nếu nó được sao chép nó sang một biến mới không nhìn thấy được, thì hãy ghi đè lên vùng bộ nhớ đó bằng x'es.

Nói một cách đơn giản, vd:

argc 2
argv[1] -p
argv[2] p4ssw0rd

new_var = copy(argv[2]);
argv[2] = "xxxxx";

Bạn có thể tìm thấy nó, ví dụ như trong client/mysqladmin.ccmã nguồn:

  case 'p':
      ...
      opt_password=my_strdup(argument,MYF(MY_FAE));
      while (*argument) 
          *argument++= 'x';     /* Destroy argument */

Khi pschạy, nó đọc vùng nhớ của các đối số, ( argv[N]) và do đó, nó là xxxx.

Trong một thời gian rất ngắn, mật khẩu có thể nhìn thấy, nhưng chỉ trong một vài chu kỳ CPU.


Bạn có thể cập nhật mật khẩu MySQL bằng cách sử dụng --init-filetùy chọn và thủ tục đặc biệt . C.5.4.1.2. Đặt lại mật khẩu gốc: Hệ thống Unix

mysqld_safe --init-file=/home/me/mysql-init &

Biên tập:

Như @Gilles nói, bạn có thể echo,printf hoặc sử dụng heretài liệu từ một kịch bản.

Bạn cũng có thể thêm nó vào thư mục chính .my.cnfcủa bạn hoặc trong một tệp ( tạm thời ) và sử dụng --defaults-extra-filetùy chọn. (Tin rằng bạn phải thêm tùy chọn đó sớm trên dòng lệnh.) Tùy chọn cũng bao gồm người dùng. Cũng lưu ý thêm trong tên tùy chọn, trừ khi bạn muốn sử dụng chỉ tập tin đó là cấu hình:

[client]
user=foo
password='password!'
shell> chmod 400 my_tmp.cnf
shell> mysql --defaults-extra-file=my_tmp.conf -...

Tùy chọn [client]nhóm làm cho mysqldbỏ qua cấu hình.

Người ta cũng có thể sử dụng MYSQL_PWDbiến môi trường, nhưng không bao giờ được sử dụng vì bạn có thể liệt kê môi trường, trong nhiều pstriển khai bằng ps -e, trong /proc/<PID>/environtệp trên Linux, v.v.

tr '\0' '\n' < /proc/<PID>/environ

Thêm về chủ đề ở đây .

Bạn cũng có thể muốn xem Tiện ích cấu hình MySQL cho phép bạn lưu mật khẩu trong một tệp được mã hóa trong thư mục chính của bạn - .mylogin.cnf.


Có cách nào để thay đổi mã thông báo trong mysql-inittệp bằng mật khẩu được lưu trữ trong biến bash không? (không được tiết lộ)
Dor

4
@Dor Một cái gì đó giống như echo 'password=p4ssw0rd' >>mysql.cnflà an toàn, vì echođược tích hợp sẵn, vì vậy mật khẩu không xuất hiện trên dòng lệnh của bất kỳ quy trình nào. Một tài liệu ở đây cũng an toàn.
Gilles 'SO- đừng trở nên xấu xa'

4

Giải pháp điển hình là đọc mật khẩu từ một tệp hoặc từ đầu vào tiêu chuẩn (hoặc từ một mô tả tệp khác sẽ phải được truyền dưới dạng tham số).


3

Một số chương trình ( ftpví dụ dòng lệnh ) đọc mật khẩu từ /dev/tty, tệp đặc biệt theo quy trình đại diện cho TTY kiểm soát quy trình. Điều này cho phép chương trình không lặp lại mật khẩu trở lại màn hình và để có thêm một chút đảm bảo về việc mật khẩu đến từ đâu.

#!/bin/bash

stty -F /dev/tty -echo 
read PASSWORD < /dev/tty

echo $PASSWORD
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.