Ẩn mật khẩu trong Shell Script


23

Làm cách nào để ẩn mật khẩu trong shell script? Có một số tập lệnh đang truy cập cơ sở dữ liệu. Nếu chúng ta mở tập lệnh, những người khác cũng biết tên người dùng và mật khẩu. Vì vậy, nếu có ai biết cách che giấu xin vui lòng cho tôi biết.

Tôi có một cách: đặt mật khẩu vào một tệp và làm cho tệp bị ẩn và không ai sẽ truy cập tệp (thay đổi quyền và sử dụng tệp trong tập lệnh trong khi truy cập cơ sở dữ liệu).

Câu trả lời:


35

Đầu tiên , như nhiều người đã nói, việc giữ thông tin đăng nhập tách biệt với tập lệnh là điều cần thiết. (Ngoài việc tăng cường bảo mật, điều đó cũng có nghĩa là bạn có thể sử dụng lại cùng một tập lệnh cho một số hệ thống có thông tin xác thực khác nhau.)

Thứ hai , bạn nên xem xét không chỉ sự bảo mật của thông tin đăng nhập, mà còn ảnh hưởng nếu / khi những thông tin đó bị xâm phạm. Bạn không nên chỉ có một mật khẩu cho tất cả quyền truy cập vào cơ sở dữ liệu, bạn nên có các thông tin đăng nhập khác nhau với các cấp truy cập khác nhau. Chẳng hạn, bạn có thể có một người dùng DB có khả năng thực hiện tìm kiếm trong cơ sở dữ liệu - người dùng đó nên có quyền truy cập chỉ đọc. Một người dùng khác có thể có quyền chèn các bản ghi mới, nhưng không xóa chúng. Người thứ ba có thể được phép xóa hồ sơ.

Ngoài việc hạn chế quyền cho mỗi tài khoản, bạn cũng nên có hạn chế về nơi mỗi tài khoản có thể được sử dụng. Chẳng hạn, tài khoản được sử dụng bởi máy chủ web của bạn không được phép kết nối từ bất kỳ địa chỉ IP nào khác ngoài tài khoản của máy chủ web. Một tài khoản có quyền truy cập root đầy đủ vào cơ sở dữ liệu thực sự rất hạn chế về mặt nó có thể kết nối từ đâu và không bao giờ được sử dụng ngoài mục đích tương tác. Cũng xem xét sử dụng các thủ tục được lưu trữ trong cơ sở dữ liệu để hạn chế chính xác những gì có thể được thực hiện bởi mỗi tài khoản.

Các hạn chế này cần được triển khai ở phía máy chủ DB của hệ thống, do đó ngay cả khi phía máy khách bị xâm phạm, các hạn chế không thể được thay đổi từ nó. (Và, rõ ràng, máy chủ DB cần được bảo vệ bằng tường lửa, v.v. ngoài cấu hình DB ...)

Trong trường hợp tài khoản DB chỉ được phép truy cập chỉ đọc có giới hạn và chỉ từ một địa chỉ IP cụ thể, bạn có thể không cần bất kỳ thông tin xác thực nào khác, tùy thuộc vào độ nhạy cảm của dữ liệu và bảo mật của tập lệnh máy chủ đang được điều hành từ Một ví dụ có thể là một hình thức tìm kiếm trên trang web của bạn, có thể được chạy với người dùng chỉ được phép sử dụng một quy trình được lưu trữ, chỉ trích xuất thông tin sẽ được trình bày trên trang web. Trong trường hợp này, việc thêm mật khẩu không thực sự mang lại bất kỳ bảo mật bổ sung nào, vì thông tin đó đã được công khai và người dùng không thể truy cập bất kỳ dữ liệu nào nhạy cảm hơn.

Đồng thời đảm bảo rằng kết nối đến cơ sở dữ liệu được thực hiện bằng TLS hoặc bất kỳ ai nghe trên mạng đều có thể nhận được thông tin đăng nhập của bạn.

Thứ ba , xem xét loại thông tin để sử dụng. Mật khẩu chỉ là một hình thức và không an toàn nhất. Thay vào đó, bạn có thể sử dụng một số dạng cặp khóa công khai / riêng tư hoặc AD / PAM hoặc tương tự.

Thứ tư , xem xét các điều kiện theo đó tập lệnh sẽ được chạy:

Nếu nó được chạy tương tác, thì bạn nên nhập mật khẩu hoặc mật khẩu vào khóa riêng hoặc khóa riêng hoặc đăng nhập bằng vé Kerberos hợp lệ, khi bạn chạy nó - nói cách khác, tập lệnh sẽ nhận được mật khẩu thông tin đăng nhập trực tiếp từ bạn tại thời điểm bạn chạy nó, thay vì đọc chúng từ một số tệp.

Nếu nó được chạy từ máy chủ web, hãy xem xét việc thiết lập thông tin đăng nhập tại thời điểm bạn khởi động máy chủ web. Một ví dụ điển hình ở đây là chứng chỉ SSL - chúng có chứng chỉ chung và khóa riêng và khóa riêng có mật khẩu. Bạn có thể lưu trữ khóa riêng trên máy chủ web, nhưng bạn vẫn cần nhập mật khẩu cho nó khi bạn khởi động Apache. Bạn cũng có thể có thông tin đăng nhập trên một số loại phần cứng, chẳng hạn như thẻ vật lý hoặc HSM, có thể được gỡ bỏ hoặc khóa sau khi máy chủ được khởi động. (Tất nhiên, nhược điểm của phương pháp này là máy chủ không thể tự khởi động lại nếu có chuyện gì xảy ra. Tôi thích điều này hơn với nguy cơ hệ thống của tôi bị xâm phạm, nhưng số dặm của bạn có thể thay đổi ...)

Nếu tập lệnh đang được chạy từ cron, đây là phần khó. Bạn không muốn có thông tin xác thực nằm ở bất cứ đâu trên hệ thống của mình, nơi ai đó có thể truy cập chúng - nhưng bạn muốn có chúng nằm xung quanh để tập lệnh của bạn có thể truy cập chúng, phải không? Vâng, không hoàn toàn đúng. Xem xét chính xác những gì kịch bản đang làm. Nó cần những quyền gì trên cơ sở dữ liệu? Nó có thể bị hạn chế để nó không thành vấn đề nếu người sai kết nối với các quyền đó? Thay vào đó, bạn có thể chạy tập lệnh trực tiếp trên máy chủ DB mà không ai khác có quyền truy cập, thay vì từ máy chủ có người dùng khác không? Nếu, vì một số lý do mà tôi không thể nghĩ ra, bạn nhất định phải có tập lệnh chạy trên một máy chủ không an toàn và nó phải có thể làm điều gì đó nguy hiểm / phá hoại ... bây giờ là thời điểm tốt để suy nghĩ lại kiến ​​trúc của bạn.

Thứ năm , nếu bạn coi trọng tính bảo mật của cơ sở dữ liệu của mình, bạn không nên chạy các tập lệnh này trên các máy chủ mà người khác có quyền truy cập. Nếu ai đó đã đăng nhập vào hệ thống của bạn, thì họ sẽ có khả năng nhận được thông tin đăng nhập của bạn. Ví dụ, trong trường hợp máy chủ web có chứng chỉ SSL, ít nhất có khả năng về mặt lý thuyết là ai đó có thể lấy quyền root và truy cập vào vùng nhớ của tiến trình httpd và trích xuất thông tin đăng nhập. Đã có ít nhất một lần khai thác trong thời gian gần đây, nơi điều này có thể được thực hiện qua SSL, thậm chí không yêu cầu kẻ tấn công phải đăng nhập.

Ngoài ra, hãy cân nhắc sử dụng SELinux hoặc apparmor hoặc bất cứ thứ gì có sẵn cho hệ thống của bạn để hạn chế người dùng có thể làm gì. Họ sẽ cho phép bạn không cho phép người dùng thậm chí cố gắng kết nối với cơ sở dữ liệu, ngay cả khi họ quản lý để có quyền truy cập vào thông tin đăng nhập.

Nếu tất cả điều này nghe có vẻ quá mức đối với bạn và bạn không đủ khả năng hoặc không có thời gian để làm điều đó - thì theo ý kiến ​​của tôi (kiêu ngạo và tinh hoa), bạn không nên lưu trữ bất cứ thứ gì quan trọng hoặc nhạy cảm trong cơ sở dữ liệu của mình. Và nếu bạn không lưu trữ bất cứ thứ gì quan trọng hoặc nhạy cảm, thì nơi bạn lưu trữ thông tin đăng nhập của bạn cũng không quan trọng - trong trường hợp nào, tại sao lại sử dụng mật khẩu?

Cuối cùng , nếu bạn hoàn toàn không thể tránh lưu trữ một số loại thông tin đăng nhập, bạn có thể có thông tin chỉ đọc và sở hữu bởi root và root có thể cấp quyền sở hữu trên cơ sở tạm thời khi được yêu cầu bởi kịch bản (vì tập lệnh của bạn không nên chạy bằng root trừ khi thực sự cần thiết và việc kết nối với cơ sở dữ liệu không khiến nó cần thiết). Nhưng nó vẫn không phải là một ý tưởng tốt.


9
Không kiêu ngạo và tinh hoa chút nào. Hoặc tôi cũng vậy. "Làm thế nào tôi có thể bảo vệ đồ trang sức của mình trong trường hợp một tên trộm đột nhập?" "Đặt nó trong một két an toàn được bắt vít / hàn tại chỗ." "Đó là quá nhiều rắc rối, tôi sẽ lấy một chiếc két sắt di động và treo chìa khóa từ một cái móc." "Vậy thì đừng bận tâm sử dụng két sắt." Eminently tư vấn hợp lý.
tự đại diện

12

Trước hết, nếu có bất kỳ cách nào bạn có thể thay đổi mọi thứ để tránh phải lưu trữ mật khẩu bên trong hoặc bên cạnh tập lệnh ở vị trí đầu tiên, bạn nên cố gắng hết sức để làm điều đó. Câu trả lời của Jenny D chứa rất nhiều lời khuyên tốt cho hiệu ứng đó.

Mặt khác, ý tưởng của bạn về việc đặt mật khẩu trong một tệp riêng biệt với các quyền hạn chế là khá nhiều. Ví dụ, bạn có thể lấy tệp đó từ tập lệnh chính:

. /usr/local/etc/secret-password-here

Bạn cũng có thể hạn chế quyền của tập lệnh chính để chỉ những người được ủy quyền mới có thể thực thi tập lệnh đó, nhưng có lẽ tốt hơn là bạn nên đề xuất và chỉ lưu trữ mật khẩu trong một tệp bị hạn chế. Bằng cách đó, bạn có thể cho phép kiểm tra chính mã (không có bí mật nhạy cảm), kiểm soát phiên bản và sao chép xung quanh tập lệnh dễ dàng hơn, v.v ...


@BasileStarynkevitch ah nhưng tôi thấy rằng nó cũng nói " /usr/local/etccó thể là một liên kết tượng trưng đến /etc/local". Tôi bỏ lỡ điều đó. Vì vậy, bạn cũng đúng, nhưng đó là CÓ THỂ vì vậy nó là tùy chọn. Nhưng vâng, nó không quan trọng lắm, và sở thích cá nhân.
Celada

1
Ngoại trừ việc tôi đang sao lưu /etc/ nhưng không /usr/local/ (mà tôi cho rằng có thể được xây dựng lại sau sự cố đĩa)
Basile Starynkevitch

điểm công bằng về sao lưu
Celada

3

Các câu trả lời khác đã giải quyết như thế nào , nhưng tôi sẽ xem xét liệu . Tùy thuộc vào loại cơ sở dữ liệu mà người dùng của bạn đang kết nối, bạn có thể đã có một cơ chế phù hợp đã được các chương trình khách hàng đó sử dụng, trong trường hợp đó chắc chắn sẽ sử dụng chúng (tôi đang nghĩ đến ~/.mysqlrchoặc ~/.pgpass).

Nếu bạn cung cấp cho nhiều người dùng khả năng truy cập cơ sở dữ liệu để thực hiện các truy vấn cụ thể bằng tài khoản được chia sẻ, thì có lẽ bạn không nên. Thay vào đó, hãy đảm bảo rằng họ có tài khoản trên cơ sở dữ liệu và những tài khoản đó không có nhiều quyền hơn họ cần (có thể đọc nhiều trên đó và rất ít quyền truy cập ghi). Nếu họ cần thực hiện các truy vấn cụ thể trên các bảng nhất định mà họ không thể truy cập, hãy cung cấp các quy trình được lưu trữ SECURTY DEFINERđể cho phép họ làm như vậy.

Nếu không có điều nào ở trên tránh được bạn cần lưu trữ thông tin đăng nhập, thì hãy đọc các câu trả lời khác tại đây.


1

Ý tưởng của bạn về việc ẩn mật khẩu ở một nơi không thể truy cập có thể ổn tùy theo hoàn cảnh.

Nếu thông tin là riêng biệt, điều đó có nghĩa là chỉnh sửa tệp đơn giản, ví dụ trong quá trình xem lại mã với đồng nghiệp sẽ không hiển thị. Nhưng nhận ra bất cứ ai có quyền truy cập vào tài khoản của bạn đều có thể dễ dàng tìm thấy một tệp như vậy. Tôi đã sử dụng một thư mục con ~/.sshcho các mục đích như vậy, vì lý do đơn giản là sshphàn nàn nếu quyền truy cập ~/.sshkhông bị hạn chế đủ.

Tuy nhiên, có những điều khác bạn có thể làm để ngăn chặn việc liếc qua tên người dùng và / hoặc mật khẩu.

Obfuscating : Nếu bạn không muốn ai đọc tên người dùng hoặc mật khẩu trong khi bạn chỉnh sửa tập lệnh, bạn có thể đặt nó vào văn bản nhưng không phải là văn bản thuần túy, nhưng bị xáo trộn. Nếu phiên bản bị che khuất đủ dài để ngăn việc ghi nhớ của nó bởi một người nào đó nhìn vào nó, thì không thể biết được ngay cả khi phương thức giải mã và khóa nằm trong tầm nhìn rõ ràng. Điều này tất nhiên vẫn sẽ bị phá vỡ một cách tầm thường bởi ai đó có quyền truy cập vào tài khoản của bạn.

Sử dụng GPG :

Tốt hơn một chút, nhưng vẫn không có bằng chứng đầy đủ chống lại các cuộc tấn công của người dùng root trên hệ thống của bạn, là mã hóa các cặp tên người dùng / mật khẩu trong một tệp của bạn gpgvà có tập lệnh lấy nội dung trên tệp (nếu có thể nhắc bạn nhập mật khẩu, nếu không lưu trữ / hết hạn). Tôi sử dụng thẻ ggp để khi tôi để máy tính xách tay của mình xung quanh nhưng rút thẻ ra, không thể truy cập được ngay cả khi pin vẫn được lưu trong bộ nhớ cache. Ít nhất nếu tôi chạy mọi thứ 20 lần trong vài phút tôi chỉ phải cung cấp mã pin một lần.

Bảo mật dường như luôn liên quan nghịch đảo đến sự thuận tiện (thiết lập và sử dụng).


0

Có một cách để lưu trữ mật khẩu trong tập lệnh bash nhưng bạn phải mã hóa và làm xáo trộn tập lệnh để không ai có thể thực sự đọc nó hoặc chạy bất kỳ loại trình gỡ lỗi nào trên đó để xem chính xác nó đang làm gì. Để mã hóa và làm xáo trộn tập lệnh bash / shell và để nó thực sự có thể thực thi được, hãy thử sao chép và dán nó ở đây:

http://www.kinglazy.com/shell-script-encoding-kinglazy-shieldx.htm

Trên trang trên, tất cả những gì bạn phải làm là gửi tập lệnh của mình (trước tiên bạn có thể gửi tập lệnh mẫu để bạn yên tâm). Một tệp zip sẽ được tạo cho bạn. Nhấp chuột phải vào liên kết tải xuống và sao chép URL bạn được cung cấp. Sau đó, đi đến hộp UNIX của bạn và thực hiện các bước sau.

Cài đặt:

  1. wget link-to-the-zip-file

  2. giải nén tệp mới được tải xuống

  3. cd / tmp / KingLazySHIELD

  4. ./install.sh / var / tmp / KINGLAZY / SHIELDX- (tên tập lệnh của bạn) / home / (tên người dùng của bạn) -force

Lệnh cài đặt ở trên sẽ làm gì cho bạn là:

  1. Nó sẽ cài đặt phiên bản mã hóa của tập lệnh của bạn trong thư mục / var / tmp / KINGLAZY / SHIELDX- (tên tập lệnh của bạn).

  2. Nó sẽ đặt một liên kết đến tập lệnh được mã hóa này trong bất kỳ thư mục nào bạn chỉ định thay thế / home / (tên người dùng của bạn) - theo cách đó, nó cho phép bạn dễ dàng truy cập tập lệnh mà không cần phải nhập đường dẫn tuyệt đối.

  3. Đảm bảo KHÔNG ai có thể sửa đổi tập lệnh - Mọi nỗ lực sửa đổi tập lệnh được mã hóa sẽ khiến tập lệnh không thể hoạt động ... cho đến khi những lần thử đó bị dừng hoặc xóa. Nó thậm chí có thể được cấu hình để thông báo cho bạn bất cứ khi nào ai đó cố gắng làm bất cứ điều gì với tập lệnh ngoài việc chạy nó ... tức là hack hoặc sửa đổi các nỗ lực.

  4. Đảm bảo hoàn toàn KHÔNG ai có thể tạo bản sao của nó. Không ai có thể sao chép tập lệnh của bạn đến một vị trí tách biệt và cố gắng xoay quanh nó để xem nó hoạt động như thế nào. Tất cả các bản sao của tập lệnh phải là liên kết đến vị trí ban đầu mà bạn đã chỉ định trong khi cài đặt (bước 4).

CHÚ THÍCH:

Tôi không tin rằng điều này hoạt động cho các kịch bản tương tác nhắc người dùng phản hồi. Các giá trị nên được mã hóa cứng vào tập lệnh. Mã hóa đảm bảo không ai có thể thực sự nhìn thấy các giá trị đó, do đó bạn không cần phải lo lắng về điều đó.


0

Một giải pháp khác, không liên quan đến bảo mật (tôi cũng nghĩ tốt hơn là giữ thông tin đăng nhập trong một tệp khác hoặc trong cơ sở dữ liệu) là mã hóa mật khẩu bằng gpg và chèn nó vào tập lệnh.

Tôi sử dụng cặp khóa gpg không có mật khẩu mà tôi giữ trong usb. (Lưu ý: Khi bạn xuất cặp khóa này không sử dụng --armor, hãy xuất chúng ở định dạng nhị phân).

Đầu tiên mã hóa mật khẩu của bạn:

echo -n "pAssw0rd" | gpg --armor --no-default-keyring --keyring /media/usb/key.pub --recipient someone@mail.com --encrypt

Điều đó sẽ được in ra mật khẩu được mã hóa gpg trong đầu ra standart. Sao chép toàn bộ tin nhắn và thêm nó vào tập lệnh:

password=$(gpg --batch --quiet --no-default-keyring --secret-keyring /media/usb/key.priv --decrypt <<EOF 
-----BEGIN PGP MESSAGE-----

hQEMA0CjbyauRLJ8AQgAkZT5gK8TrdH6cZEy+Ufl0PObGZJ1YEbshacZb88RlRB9
h2z+s/Bso5HQxNd5tzkwulvhmoGu6K6hpMXM3mbYl07jHF4qr+oWijDkdjHBVcn5
0mkpYO1riUf0HXIYnvCZq/4k/ajGZRm8EdDy2JIWuwiidQ18irp07UUNO+AB9mq8
5VXUjUN3tLTexg4sLZDKFYGRi4fyVrYKGsi0i5AEHKwn5SmTb3f1pa5yXbv68eYE
lCVfy51rBbG87UTycZ3gFQjf1UkNVbp0WV+RPEM9JR7dgR+9I8bKCuKLFLnGaqvc
beA3A6eMpzXQqsAg6GGo3PW6fMHqe1ZCvidi6e4a/dJDAbHq0XWp93qcwygnWeQW
Ozr1hr5mCa+QkUSymxiUrRncRhyqSP0ok5j4rjwSJu9vmHTEUapiyQMQaEIF2e2S
/NIWGg==
=uriR
-----END PGP MESSAGE-----
EOF)

Theo cách này chỉ khi usb được gắn trong hệ thống, mật khẩu có thể được giải mã. Tất nhiên, bạn cũng có thể nhập khóa vào hệ thống (kém an toàn hoặc không bảo mật) hoặc bạn có thể bảo vệ khóa riêng bằng mật khẩu (vì vậy không thể tự động hóa).


-2
#!/bin/bash
unset username
unset password
unset dbname
echo -n "username:"
read username
echo -n "dbname:"
read dbname
prompt="password:"

    while IFS= read -p "$prompt" -r -s -n 1 char
            do
                    if [[ $char == $'\0' ]]
                            then
                                    break
                    fi
                    prompt='*'
                    password+="$char"
            #       read -s -p "Enter Password: "  pswd
            #       echo -e "\nYour password is: " $pswd
            done

3
Tôi thụt mã của bạn, có lẽ bạn có thể giải thích những gì bạn đang cố gắng làm?
Archemar

-6

Tôi không tin bạn nên lưu trữ mật khẩu. Tôi không thể nghĩ ra một lý do chính đáng nào cho việc đó. Thay vào đó, bạn nên lưu trữ hàm băm của mật khẩu đó - một số chuỗi được tạo ra một cách đáng tin cậy bởi một số chức năng khi mật khẩu ban đầu được chuyển làm đầu vào, nhưng không bao giờ là mật khẩu .


5
Tôi không rõ làm thế nào điều này sẽ giải quyết vấn đề a) có thể kết nối với dịch vụ yêu cầu mật khẩu và b) người dùng có thể xem tập lệnh và do đó có thể tìm ra các chi tiết xác thực, cho dù đó là mật khẩu hoặc không
Jenny D

1
Bạn đang tuyên bố muốn biết câu trả lời của tôi trước khi tôi viết nó.
Jenny D

1
Tôi đã viết câu trả lời của tôi bây giờ. Những gì tôi đã cố gắng nhận được từ bạn là một phần điểm thứ năm của tôi - một khi thông tin đăng nhập được lưu trữ trong bộ nhớ, chúng không hoàn toàn an toàn trước kẻ tấn công có quyền truy cập vào máy chủ. Ngoài ra, câu trả lời ngắn gọn của bạn không hữu ích lắm, mặc dù không sai. Tôi đang nghĩ đến việc chỉ vào nó vào lần tới khi ai đó phàn nàn rằng chúng tôi tại ServerFault không đẹp như mọi người ở Unix / Linux :-)
Jenny D

2
@JennyD - một khi tín dụng đã ở trong bộ nhớ - chắc chắn không cần phải ở đó - và đó là lý do rất chính đáng để xử lý các băm thay thế. Tuy nhiên, tôi sẽ vui vẻ đại diện cho các tiêu chuẩn lịch sự của cộng đồng như là một ví dụ điển hình - thực sự tôi rất nổi tiếng với đặc điểm đó.
mikeerv

4
Sau cuộc thảo luận lớn của bạn, tôi chỉ muốn đề cập đến trong trường hợp có bất kỳ sự hiểu lầm nào rằng chính tôi là người bị hạ bệ chứ không phải Jenny. Và lý do không phải là ý kiến ​​về việc có nên sử dụng chứng chỉ & mật khẩu hoặc mật khẩu được nhập tương tác hay làm những gì OP muốn hay không. Đó là bởi vì câu trả lời là sai: lưu trữ mật khẩu băm của mật khẩu dưới dạng thông tin khách hàng không phải là một điều: băm muối là điều bạn giữ ở cuối kết nối đang xác minh xác thực, không phải trên bên đó đang đệ trình nó
Celada
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.