Ghi nhật ký cục bộ, dấu thời gian của tất cả các lệnh ssh?


12

Làm cách nào tôi có thể giữ một bản ghi cục bộ, được đánh dấu thời gian của tất cả các lệnh từ xa mà tôi sử dụng ssh(máy khách openssh dòng lệnh bắt đầu thông qua bash)?

Yêu cầu:

  • Thiết yếu:

    • 100% phía khách hàng mà không cần dựa vào đăng nhập máy chủ
    • Định cấu hình hoặc cài đặt cho mỗi người dùng với các bản ghi được lưu trong thư mục chính của người dùng.
    • Hỗ trợ phân biệt giữa nhiều phiên đồng thời với nhiều người dùng và máy chủ khác nhau.
    • Không xâm nhập (không cần kích hoạt mỗi lần và không can thiệp đáng kể vào việc sử dụng ssh)
  • Ưu tiên cao:

    • Đầu ra không được ghi lại hoặc lọc ra càng nhiều càng tốt
    • Các mục nhập mật khẩu không được ghi lại hoặc tập tin được mã hóa
    • Cho biết các lệnh thực tế được sử dụng (sau khi hoàn thành tab / lịch sử, không gian, CTRL+ C, v.v ... đã được xử lý)
  • Rất vui được có:

    • Đồng thời ghi lại các lệnh trong các phiên xích (các lệnh được nhập trong từ xa sshhoặc su <user>phiên)
    • Phiên bắt đầu và kết thúc nên được ghi lại
    • Một bashgiải pháp không dựa trên cơ sở đơn giản sẽ là tốt nhất (có thể là một tập lệnh aliashoặc bashtrình bao bọc cho sshlệnh?)

Cấp độ kỹ năng của tôi:

  • Tôi không phải là người mới trong lập trình, nhưng vẫn đang học bashvà "cách Linux", vì vậy các mẫu mã với các giải thích ngắn gọn sẽ được đánh giá cao nhất.

Chiến lược có thể

  • keylogger - Vấn đề: ghi nhật ký mật khẩu, không ghi nhật ký hoàn thành tab / lịch sử (xem câu trả lời của glenn )
  • screenvới tính năng cuộn ngược lại một lần mỗi giây và diffgiữa chúng để tìm các dòng cuộn ngược mới - Vấn đề: làm thế nào điều này có thể được thực hiện theo cách tự động hữu ích?
  • ssh "$@" | tee >(some_cleaner_function >> $logfile) - Vấn đề: không thể xử lý các lệnh hoặc lịch sử đa dòng trong các phiên bị xích, cần dọn dẹp cẩn thận (xem câu trả lời của tôi)
  • Một sự kết hợp của một số ở trên

Một ví dụ

Phiên SSH sau:

user@local:~$ ssh user@remote
Last login: Tue Jun 17 16:34:23 2014 from local
user@remote:~$ cd test
user@remote:~/test$ ls
a  b
user@remote:~/test$ exit

Có thể dẫn đến một bản ghi tại, ~/logs/ssh.logchẳng hạn như:

2014-06-17 16:34:50   [user@remote - start]
2014-06-17 16:34:51   [user@remote] cd test
2014-06-17 16:34:52   [user@remote] ls
2014-06-17 16:34:53   [user@remote] exit
2014-06-17 16:34:53   [user@remote - end]

Hoặc, có lẽ một nhật ký riêng sẽ được tạo cho mỗi phiên với dòng lệnh được sử dụng để bắt đầu phiên ở đầu tệp.


Nó cũng nên xử lý các trình soạn thảo như nano hoặc vim
daisy

Câu trả lời:


4

Tôi bị thu hút bởi câu hỏi của bạn. Ban đầu tôi sẽ không đưa ra câu trả lời nhưng tôi đã bị cuốn hút.

Điều này sử dụng expectvà nó thực sự là một logger chính.

#!/usr/bin/expect -f

proc log {msg} {
    puts $::fh "[timestamp -format {%Y-%m-%d %H:%M:%S}]: $msg"
}

set ssh_host [lindex $argv 0]
set ::fh [open "sshlog.$ssh_host" a]

log "{session starts}"

spawn ssh $ssh_host

interact {
    -re "(.)" {
        set char $interact_out(1,string)
        if {$char eq "\r"} {
            log $keystrokes
            set keystrokes ""
        } else {
            append keystrokes $char
        }
        send -- $char
    }
    eof
}

log "{session ends}"

Ghi chú:

  • nó gắn vào một tệp có đích ssh trong tên
  • đó là một trình ghi nhật ký khóa: nếu bạn chưa thiết lập khóa ssh, bạn sẽ nhận được mật khẩu của người dùng trong tệp nhật ký
  • nó được xử lý bằng cách hoàn thành tab: nếu người dùng gõ uptTab(cho uptimelệnh), bạn sẽ nhận được "gain \ t" trong tệp nhật ký, chứ không phải "thời gian hoạt động"
  • nó lấy các ký tự ở chế độ "thô": nếu người dùng là người đánh máy kém, bạn sẽ nhận được rất nhiều ^?(ký tự xóa lùi) trong tệp nhật ký.

Cảm ơn bạn rất nhiều vì câu trả lời của bạn. Điều thú vị là dường như không có câu trả lời dễ dàng cho điều này, có lẽ là nguồn gốc của ứng dụng khách ssh. Cảm ơn bạn đã giải thích những hạn chế; Tôi nghĩ rằng việc hoàn thành tab / ghi nhật ký ký tự / ghi lại mật khẩu là đủ để ngăn tôi sử dụng điều này thường xuyên. Nó cũng khiến tôi suy nghĩ nhiều hơn về các ưu tiên của mình và tôi sẽ làm rõ những vấn đề trong câu hỏi.
Oleg

Đầu ra từ quá trình sinh sản có thể được phân tích cú pháp để trích xuất lệnh bạn muốn. Bạn cần biết lời nhắc của người dùng để làm cho nó dễ dàng hơn.
glenn jackman

Tôi sử dụng tab hoàn thành rất nhiều. Điều này không có nghĩa là những lệnh đó sẽ không được ghi lại?
Oleg

Ah, tôi thấy những gì bạn đang nói. Làm thế nào đầu ra sẽ được phân tích cú pháp? Lời nhắc có thể được nhập vào đâu đó dưới dạng tùy chọn cấu hình.
Oleg

Tôi đã thêm danh sách các giải pháp có thể ở cuối câu hỏi. ssh ... | tee -ai <logfile> hoạt động tốt để ghi nhật ký đầu vào và đầu ra một cách an toàn, nhưng tôi không biết cách thêm dấu thời gian và / hoặc lọc đầu ra trong nền.
Oleg

2

Tôi hiện đang sử dụng tập lệnh bash bên dưới. Nó có nhiều vấn đề, nhưng đó là giải pháp duy nhất tôi đã tìm thấy giải quyết tất cả các yêu cầu, ưu tiên và "tốt đẹp cho những người có tiếng" (ít nhất là hầu hết thời gian).

Câu trả lời này thảo luận về lý do tại sao đăng nhập phiên ssh cục bộ là rất khó khăn.

Các vấn đề với kịch bản tôi tìm thấy cho đến nay:

  1. Các lệnh đa dòng gây ra các vấn đề:

    • Nếu bạn trang thông qua một mục đa dòng trong lịch sử từ xa (với các phím lên / xuống), nó sẽ ghi nhật ký một mục lịch sử thay vì lệnh mới nhất. Bạn có thể tránh điều này bằng cách xóa khỏi lịch sử bash bất kỳ lệnh đa dòng nào ngay sau khi chúng được sử dụng.
    • Chỉ dòng đầu tiên của lệnh multiline được ghi lại.
  2. Các phiên bị xiềng xích (sử dụng sshhoặc sucác lệnh ở đầu từ xa) gây ra cuộn lịch sử để ghi lại các lệnh được cuộn qua thay vì các lệnh thực tế được sử dụng

  3. Các biểu thức chính quy có thể được cải thiện và có thể cần phải sửa đổi cho một số môi trường nhất định:

    • Tôi gian lận bằng cách chuyển đổi các ký tự không in với cat -vtrước khi làm sạch. Do đó, nội dung hợp lệ có thể bị xóa nếu bạn từng sử dụng các chuỗi như ^[[trong các lệnh của mình.
    • Đôi khi bạn nhận được thêm đầu vào đăng nhập trước lệnh, chẳng hạn như nếu bạn lướt qua lịch sử rất nhanh. Điều này thường được theo sau bởi một "^ M" trước lệnh thực tế và do đó có thể bị loại bỏ nếu muốn.
    • Nhân vật điều khiển khác đôi khi xảy ra. Bây giờ tôi sẽ để lại tất cả cho đến khi tôi biết cái nào an toàn để loại bỏ. ^ M như tôi vừa đề cập là hữu ích để phát hiện đầu vào được ghi không hợp lệ và ^ C sẽ cho bạn biết nếu lệnh bị hủy bỏ.
    • Regex nhắc nhở có thể cần phải được sửa đổi cho các lời nhắc cụ thể và tôi có thể tưởng tượng rằng các môi trường từ xa khác nhau có thể có các mẫu ký tự điều khiển khác nhau.
  4. Không hoàn thành bash lệnh ssh, chẳng hạn như đối với tên máy chủ. Bạn có thể nhận được bash hoàn thành nếu bạn đặt bí danh cho tập lệnh này sshvớialias ssh="sshlog"

Nguồn script và cài đặt:

Để cài đặt, dán phần sau vào ~ / bin / sshlog và thực thi. Gọi với sshlog <ssh command options>. Tùy chọn bí danh cho 'ssh' trong tệp .bashrc của người dùng.

#!/bin/bash
# A wrapper for the ssh command that produces a timestamped log of all ssh commands
declare -r logfile=~/logs/ssh.log
declare -r description="sshlog-${$} ${@}"
declare -r TAB=$'\t'

logdir=`dirname ${logfile}`
[ -d ${logdir} ] || mkdir "${logdir}";

clean_control_chars() {
    while IFS= read -r line; do
        # remove KNOWN control characters. Leave the rest for now.
        # line=$(echo "${line}" | sed 's/\^\[\[K//g')  # unkown control character: ^[[K
        # line=$(echo "${line}" | sed 's/\^\[\[[0-9]\+[P]//g')  # these are generated by up/down completion - e.g. ^[[2P
        line=$(echo "${line}" | sed 's/\^\[\[[0-9]*[A-Z]//g')  # all other ^[[..
        # replay character deletions (backspaces)
        while [[ $(echo "${line}" | grep -E --color=never '.\^H') != "" ]]; do
            line=$(echo "${line}" | sed 's/.\^H//')
        done
        # remove common control characters
        line=$(echo "${line}" | sed 's/\^M$//')  # remove end of line marker from end
        line=$(echo "${line}" | sed 's/^\^G//g')  # remove start marker from start
        # remove ^G from other locations - possibly a good idea
        # line=$(echo "${line}" | sed 's/\^G//g')
        # remove all other control characters - not recommended (many like ^C and ^M indicate which section was processed/ ignored)
        # line=$(echo "${line}" | sed 's/\^[A-Z]//g')
        echo ${line};
    done
}

filter_output() {
    while IFS= read -r line; do
        # convert nonprinting characters and filter out non-prompt (in Ubuntu 14.04 tests, ^G indicates prompt start)
        line=$(echo "${line}" | cat -v | grep -Eo '[\^][G].*[\$#].*')
        [[ ${line} != "" ]] && echo "${line}"
    done
}

format_line() {
    while IFS= read -r line; do
        raw=${line};
        line=$(echo "${line}" | clean_control_chars);
        prompt=$(echo "${line}" | grep -Po '^.*?(\$|#)[\s]*')
        command=${line:${#prompt}}
        timestamp=`date +"%Y-%m-%d %H:%M:%S %z"`
        echo -e "${timestamp}${TAB}${description}${TAB}${prompt}${TAB}${command}"
    done
}

echo "Logging ssh session: ${description}"
echo "[START]" | format_line >> ${logfile}
/usr/bin/ssh "$@" | tee >(filter_output | format_line >> ${logfile})
echo "[END]" | format_line >> ${logfile}

Nội dung nhật ký ví dụ:

2014-06-29 23:04:06 -0700   sshlog-24176 remote [START]
2014-06-29 23:04:12 -0700   sshlog-24176 remote oleg@remote:~$  cd test
2014-06-29 23:04:13 -0700   sshlog-24176 remote oleg@remote:~/test$     ls
2014-06-29 23:04:14 -0700   sshlog-24176 remote oleg@remote:~/test$     exit
2014-06-29 23:04:14 -0700   sshlog-24176 remote [END]

0

Tôi có một câu trả lời ít phức tạp hơn, và chắc chắn không phải là một keylogger. Tôi không có quan điểm độc lập với nhật ký máy chủ (điều này có nghĩa là tất cả các hành động cần phải được thực hiện đối với máy chủ và tất cả các nhật ký là nhật ký phía máy chủ), và do đó tôi nghĩ rằng một ý tưởng hay là chuyển sang bashrc trên toàn hệ thống một lệnh nhắc nhở như:


PROMPT_COMMAND='history -a >(tee -a ~/.bash_history | logger -t "$USER[$$] $SSH_CONNECTION")'

Trong debian, bạn nên chỉnh sửa tệp: /etc/bash.bashrc và tính bằng centos tệp: / etc / bashrc

Nếu bạn muốn bắt đầu đăng nhập cho phiên bạn đang tham gia, bạn phải lấy nguồn tệp bạn đã chỉnh sửa, ví dụ thực hiện:


source /etc/bash.bashrc

trong một hệ thống debian hoặc


source /etc/bashrc
trong một hệ thống centos.

Từ giờ trở đi, mọi lệnh, của mỗi phiên ssh sẽ được ghi lại tại / var / log / syslog trên hệ thống debian và tại / var / log / message trên hệ thống centos.

Trong trường hợp bạn muốn đăng nhập chúng trên một tệp riêng biệt và không gây rối với các tệp nhật ký khác, bạn có thể sử dụng:


PROMPT_COMMAND='history -a >(tee -a ~/.bash_history | logger -p local6.info -t "$USER[$$] $SSH_CONNECTION")'
thay vì ví dụ PROMPT_COMMAND trước đó và sau đó định cấu hình rsyslogd khi cần.

Ví dụ: tại Hệ thống Debian chỉnh sửa tệp /etc/rsyslog.conf : thay đổi dòng:


.;auth,authpriv.none           -/var/log/syslog
đến

.;auth,authpriv.none,local6           -/var/log/syslog
và thêm dòng sau vào cuối tập tin:

local6.info                     /var/log/history.log

sau đó thực hiện:

touch /var/log/history.log && /etc/init.d/rsyslog restart


Câu hỏi này đặc biệt về vấn đề ghi nhật ký phiên ssh ở bên cạnh máy tính khởi tạo / cục bộ / máy khách, mà không phải (nhớ / được phép) để định cấu hình từng máy chủ từ xa hoặc phải tải xuống nhật ký từ tất cả các máy chủ từ xa mà bạn kết nối đến. Tôi nghĩ rằng câu trả lời của bạn, trong khi nó không trả lời câu hỏi này, sẽ hữu ích cho ai đó quan tâm đến việc cải thiện kiểm toán máy chủ của họ và có lẽ nên chuyển sang một câu hỏi phù hợp hơn.
Oleg

0

Thế còn strace -o /tmp/ssh_log -ff -s8192 -T -ttt -fp $(pidof sshd)? Điều này ghi lại tất cả các phiên ssh. Bạn có thể cần một công cụ để phân tích nhật ký sau đó, hoặc chỉ sử dụng grep, awkv.v.

  • -f: dấu vết ngã ba
  • -ff: đăng nhập riêng từng đứa trẻ vào ssh_log.PID
  • -s8192: tăng giới hạn ghi nhật ký chuỗi (nếu cần)
  • -T -ttt: dập micrô giây tính bằng giây kể từ Kỷ nguyên
  • -p N: gắn vào pid N
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.