본문 바로가기
운영체제 (LNX,WIN)

n8n에서 원격 시스템 SSH 명령수행 자동화 및 명령로그 모니터링

by 날으는물고기 2024. 5. 20.

n8n에서 원격 시스템 SSH 명령수행 자동화 및 명령로그 모니터링

n8n에서 SSH를 통해 서버에 명령어를 실행하려고 할 때 나타나는 "Pseudo-terminal will not be allocated because stdin is not a terminal." 메시지는 SSH가 명령어 실행을 위해 가상 터미널을 할당하려고 시도하지만, 표준 입력(stdin)이 터미널이 아니라는 것을 나타냅니다. 이 메시지는 여러 상황에서 나타날 수 있지만, 주로 다음과 같은 이유 때문에 발생합니다.

  1. 비대화식(Non-interactive) SSH 세션: SSH 클라이언트가 스크립트나 프로그램을 통해 원격 서버에 명령어를 실행하려고 할 때, 대화형 터미널 세션이 아니라 명령어 실행 모드로 동작합니다. 이 경우, SSH 클라이언트는 표준 입력이 사용자와의 인터랙티브한 터미널이 아니라고 판단하고 가상 터미널을 할당하지 않습니다.
  2. -T 옵션 사용: SSH 명령어에 -T 옵션을 사용하면, SSH 클라이언트는 가상 터미널 할당을 시도하지 않습니다. 이 옵션은 일반적으로 배치 파일 실행이나 원격 명령어 실행에 사용되며, 이런 상황에서는 터미널 할당이 필요 없을 수 있습니다.

가상 터미널 할당이 필요한 경우, SSH 명령어에 -t 옵션을 추가하여 강제로 터미널 할당을 시도할 수 있습니다. 이 옵션은 SSH 세션을 통해 대화형 프로그램을 사용하거나 터미널 기반의 텍스트 에디터를 사용해야 할 때 유용합니다. -t 옵션은 명령어나 스크립트 실행 중에 터미널 기반 인터페이스나 사용자 입력이 필요한 경우에 특히 필요합니다.

 

SSH 세션에서 표준 입력이 대화형 터미널이 아니기 때문에 가상 터미널을 할당하지 않겠다는 것을 의미하며, 대부분의 경우 이는 예상된 동작입니다. 원하는 작업에 따라 -T 옵션을 제거하거나 -t 옵션을 추가하여 해결할 수 있습니다.

 

비대화식(Non-interactive) SSH 접근에서 중계시스템을 통해 두 번째 서버에 RSA 키를 사용하여 접근하는 방법은 몇 가지 주요 단계를 포함합니다. 이 과정에서는 중계시스템의 SSH 키를 사용하여 최종 목적지 서버에 안전하게 접근하려고 할 때 발생할 수 있는 일반적인 문제를 해결하는 방법도 포함됩니다.

1. 중계시스템에 SSH 키 준비하기

  • 중계시스템에서 사용할 RSA SSH 키가 최종 목적지 서버의 ~/.ssh/authorized_keys 파일에 등록되어 있는지 확인합니다.
  • SSH 키는 ssh-keygen 명령어를 사용하여 생성할 수 있습니다.

2. SSH 에이전트 포워딩 사용하기

  • 비대화식 SSH 접근 시, 중계시스템에서 최종 목적지 서버로의 접근에 사용할 로컬 시스템의 SSH 키를 활용하기 위해, SSH 에이전트 포워딩 기능을 사용할 수 있습니다.
  • 이 기능을 활성화하기 위해서는, 첫 번째 SSH 연결(로컬 시스템에서 중계시스템으로)을 생성할 때 ssh -A 옵션을 사용합니다. 이렇게 하면, 중계시스템에서 로컬 시스템의 SSH 키를 사용하여 다른 서버에 접근할 수 있습니다.

3. SSH 명령어 구성하기

  • 첫 번째 단계에서 로컬 시스템에서 중계시스템으로의 접근을 설정한 후, 중계시스템에서 비대화식으로 두 번째 서버에 접근하는 SSH 명령어를 구성합니다.
  • 이 명령어는 중계시스템의 SSH 클라이언트 설정 파일(~/.ssh/config)에 해당 서버에 대한 설정을 포함시키거나, 명령어 내에서 직접 필요한 옵션을 지정하여 실행할 수 있습니다.

4. 예제 SSH 명령어

여기서는 중계시스템을 통해 최종 목적지 서버에 비대화식으로 접근하는 예제 명령어를 제공합니다.

  1. 로컬 시스템에서 중계시스템으로의 SSH 접속
     ssh -A user@intermediate-system
    여기서 -A 옵션은 SSH 에이전트 포워딩을 활성화합니다.
  2. 중계시스템에서 최종 목적지 서버로의 SSH 접속
     ssh -i /path/to/intermediate_ssh_key user@final-destination-server
    이 명령어는 중계시스템에 저장된 특정 SSH 키(/path/to/intermediate_ssh_key)를 사용하여 최종 목적지 서버에 접속합니다.

주의사항

  • 중계시스템에서 SSH 에이전트 포워딩을 사용하여 최종 목적지 서버에 접근하는 경우, 보안상의 위험이 있을 수 있으므로, 이 방법은 신뢰할 수 있는 시스템에서만 사용해야 합니다.
  • n8n과 같은 자동화 도구에서 이러한 접속을 설정할 때는, 해당 도구의 문서를 참조하여 적절한 방식으로 명령어를 구성하고 실행해야 합니다.

 

n8n에서 SSH 모듈을 사용할 때 직접적인 SSH 옵션을 설정하는 기능이 제한적이거나 없을 수 있습니다. 그러나, SSH 접속 시 추가적인 옵션을 사용해야 하는 경우, 몇 가지 방법으로 이 문제를 해결할 수 있습니다. 여기서는 n8n에서 SSH 옵션을 사용하기 위한 대안적인 접근 방법을 몇 가지 소개하겠습니다.

1. 커맨드 라인을 통한 SSH 명령어 실행

n8n에서 직접 SSH 클라이언트의 모든 옵션을 제어할 수 없을 때, Execute Command 노드를 사용하여 커맨드 라인에서 SSH 명령어를 직접 실행할 수 있습니다. 이 방법을 사용하면, SSH 접속 시 필요한 모든 옵션을 포함시킬 수 있습니다.

예를 들어, -o 옵션을 사용하여 특정 SSH 클라이언트 옵션을 지정할 수 있습니다.

ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null user@hostname

이 명령어는 SSH 접속 시 호스트 키 검증을 무시하고, 사용자 알려진 호스트 파일을 사용하지 않도록 설정합니다.

2. SSH 구성 파일 사용

SSH 접속에 필요한 옵션을 미리 정의해 둘 수 있는 또 다른 방법은, 사용자의 SSH 구성 파일(~/.ssh/config)에 해당 옵션을 설정하는 것입니다. 이 방법을 사용하면, n8n에서 특정 호스트 이름으로 SSH 접속 시 해당 설정이 자동으로 적용됩니다.

예를 들어, SSH 구성 파일에 다음과 같은 항목을 추가할 수 있습니다.

Host myserver
    HostName server.example.com
    User myuser
    Port 2222
    IdentityFile ~/.ssh/mykey
    StrictHostKeyChecking no
    UserKnownHostsFile=/dev/null

이 설정을 사용하면, n8nExecute Command 노드에서 ssh myserver 명령어를 실행할 때 위의 옵션이 자동으로 적용됩니다.

3. 프록시 커맨드 사용

복잡한 네트워크 환경에서 중계 서버를 통해 최종 목적지 서버에 접근해야 할 경우, ProxyCommand 옵션을 SSH 구성 파일에 추가할 수 있습니다. 이 옵션을 사용하면, 특정 목적지에 접근하기 위해 중계 서버를 자동으로 경유할 수 있습니다.

Host final-server
    HostName final.example.com
    ProxyCommand ssh -W %h:%p intermediate-server
    User finaluser

이 설정을 통해, n8n에서 ssh final-server 명령을 실행하면 자동으로 중계 서버를 경유하여 최종 서버에 접속합니다.

주의사항

  • Execute Command 노드를 사용하여 SSH 명령어를 직접 실행할 때는 보안상의 주의가 필요합니다. 특히, 공개 네트워크를 통해 민감한 정보가 전송되는 경우, 암호화되지 않은 텍스트로 비밀번호를 전송하지 않도록 주의해야 합니다.
  • 사용자의 SSH 구성 파일을 수정할 때는 오타가 없는지 주의깊게 확인하고, 설정 변경 후에는 SSH 접속이 예상대로 작동하는지 테스트해 보는 것이 좋습니다.

 

SSH 서버에서 실행되는 명령어를 추적하고 디버깅하기 위한 방법은 여러 가지가 있습니다. 이 과정에서는 보안, 프라이버시, 성능에 대한 고려가 필요하며, 일반적으로 시스템 관리자나 보안 전문가만이 이러한 작업을 수행할 권한을 갖습니다. 아래에는 SSHD(SSH Daemon)에서 명령어 실행을 추적하고 기록하기 위한 몇 가지 방법을 소개합니다.

SSHD 로깅 레벨 조정

SSHD의 로깅 레벨을 조정하여 더 많은 정보를 얻을 수 있습니다. /etc/ssh/sshd_config 파일에서 LogLevel 지시어를 찾아 수정합니다. 로그 레벨을 VERBOSEDEBUG로 설정하면 더 많은 정보를 로그로 기록할 수 있습니다.

LogLevel DEBUG

변경 후에는 SSH 서비스를 재시작해야 변경사항이 적용됩니다.

auditd 사용

auditd는 Linux 시스템에서 감사 추적을 위한 도구입니다. 특정 파일이나 명령어에 대한 실행을 추적하는 데 사용할 수 있습니다. 예를 들어, 특정 사용자 또는 그룹이 실행하는 명령어를 감시하려면 auditctl을 사용하여 규칙을 추가할 수 있습니다.

Bash History

사용자의 bash 쉘 히스토리를 활용하는 방법도 있습니다. 이는 사용자가 입력한 명령어의 기록을 저장하지만, SSH를 통해 직접 실행된 명령어 또는 스크립트 실행으로 인한 명령어는 포착하지 않을 수 있습니다.

Syslog 또는 기타 로깅 시스템

SSHD와 같은 시스템 서비스는 보통 syslog를 통해 로그를 기록합니다. /var/log/auth.log, /var/log/secure, 또는 시스템 설정에 따라 다른 위치에 로그를 저장할 수 있습니다. 이 로그 파일들을 확인하여 SSH를 통해 시도된 로그인 시도, 성공 및 실패한 인증 등의 정보를 확인할 수 있습니다.

명령어 실행 추적을 위한 커스텀 스크립트

사용자가 SSH를 통해 실행하는 모든 명령어를 로그로 남기는 커스텀 스크립트를 구성할 수도 있습니다. 예를 들어, ForceCommand 지시어를 사용하여 사용자의 모든 SSH 세션을 통해 실행되는 명령어를 포착하고 기록하는 스크립트를 실행하도록 sshd_config를 설정할 수 있습니다.

 

각 방법을 사용할 때는 보안 및 개인정보 보호 정책을 준수하고, 필요한 경우 사용자에게 해당 사실을 통지해야 합니다. 또한, 성능 저하를 피하기 위해 로깅 수준을 신중하게 선택하고, 불필요한 정보는 기록하지 않도록 주의해야 합니다.

 

Docker 컨테이너 내에서 실행되는 sshd (SSH Daemon) 로그의 위치나 처리 방법은 컨테이너의 설정과 실행 방법에 따라 달라질 수 있습니다. Docker 컨테이너는 일반적으로 표준 출력(stdout)과 표준 에러(stderr) 스트림을 통해 로그를 처리합니다. 그러나 sshd와 같은 전통적인 시스템 서비스는 종종 로그를 파일 시스템에 직접 기록하려고 시도할 수 있으며, 이는 컨테이너 환경에서 특별한 처리가 필요할 수 있습니다. 여기 몇 가지 일반적인 시나리오를 소개합니다.

1. Docker 컨테이너 로그 확인

Docker는 컨테이너의 표준 출력과 표준 에러를 자동으로 캡처합니다. sshd 로그가 이 스트림을 통해 출력되도록 설정되어 있다면, Docker 명령어를 사용하여 이 로그를 확인할 수 있습니다.

docker logs [컨테이너 ID 또는 이름]

이 명령어는 컨테이너에서 생성된 모든 출력을 보여줍니다.

2. 로그 파일 매핑

sshd가 전통적으로 사용하는 로그 파일(/var/log/auth.log, /var/log/secure 등)을 호스트 시스템과 공유하도록 Docker 컨테이너를 구성할 수 있습니다. 이를 위해 Docker 실행 시 -v (볼륨) 옵션을 사용하여 컨테이너 내부의 로그 파일 경로를 호스트 시스템의 경로에 매핑할 수 있습니다.

docker run -v /host/path/to/logs:/var/log -d sshd-image

이 방법을 사용하면, 컨테이너 내부에서 생성된 sshd 로그를 호스트 시스템의 지정된 경로에서 직접 확인할 수 있습니다.

3. 로그 드라이버 사용

Docker는 다양한 로그 드라이버를 지원하여, 컨테이너 로그를 다양한 대상에 보낼 수 있게 해줍니다. 예를 들어, syslog, fluentd, awslogs 등의 로그 드라이버를 사용할 수 있습니다. 컨테이너를 실행할 때 --log-driver 옵션을 사용하여 로그 드라이버를 지정합니다.

docker run --log-driver=syslog --log-opt syslog-address=udp://192.168.0.1:514 -d sshd-image

이렇게 하면, 컨테이너의 로그가 지정된 로그 수집 시스템으로 직접 전송됩니다.

4. sshd 로그 설정 조정

컨테이너 내부에서 sshd의 로그 설정을 조정하여 로그를 표준 출력으로 리다이렉션할 수도 있습니다. 예를 들어, sshdLogLevel을 조정하고, 로그 출력을 표준 출력에 맞게 조정할 수 있습니다. 이는 컨테이너화된 환경에서 로그 관리를 더 유연하게 할 수 있게 해줍니다.

 

컨테이너에서 sshd 로그를 관리할 때는, 로그의 양과 중요성, 보안 요구사항 등을 고려하여 적절한 전략을 선택해야 합니다. Docker의 로그 관리 기능을 최대한 활용하면, 컨테이너화된 환경에서도 효과적으로 로그를 수집하고 분석할 수 있습니다.

 

SSH 서버에서 실행된 명령어의 상세한 로깅을 얻기 위해서는 LogLevel DEBUG 설정만으로는 부족할 수 있습니다. 기본적으로, sshdDEBUG 로그 레벨은 연결과 인증 과정에 대한 자세한 정보를 제공하지만, 사용자가 실행한 명령어 자체를 로그로 남기지는 않습니다. 이는 보안과 프라이버시를 위한 의도적인 설계입니다. 사용자가 SSH를 통해 실행한 명령어를 로그로 남기려면, 다른 접근 방법을 고려해야 합니다.

1. Audit 시스템 사용

Linux에서는 auditd 시스템을 사용하여 특정 이벤트나 명령어 실행을 추적할 수 있습니다. auditd는 시스템 호출을 모니터링하고, 구성된 규칙에 따라 이벤트를 로그로 기록합니다. 사용자의 명령어 실행을 로그로 남기기 위해서는 auditd를 사용하고 적절한 규칙을 설정해야 합니다.

  • auditd 설치 및 활성화 방법은 배포판에 따라 다를 수 있으니, 배포판의 문서를 참조하세요.
  • 명령어 실행에 대한 감사 규칙을 추가하려면, auditctl 명령어를 사용합니다.

예를 들어, 모든 사용자의 bash 실행을 추적하려면 다음과 같은 규칙을 추가할 수 있습니다.

auditctl -a always,exit -F arch=b64 -S execve -F path=/bin/bash

2. 사용자 쉘 활동 로깅

사용자의 쉘 활동을 로그로 기록하는 방법으로, bashHISTFILE, PROMPT_COMMAND 같은 기능을 사용하여 사용자가 입력한 명령어를 로그 파일에 기록할 수 있습니다. 하지만, 이 방법은 사용자가 쉘 환경 설정을 변경할 수 있다는 단점이 있습니다.

3. 강제 커맨드 사용

SSH 연결에 대해 특정 명령어만 실행할 수 있도록 제한하거나 로깅 메커니즘을 포함한 스크립트를 강제로 실행하게 만들 수 있습니다. 이를 위해 authorized_keys 파일에 command="logging-script.sh" 옵션을 추가하거나, sshd_config 파일에 ForceCommand 지시어를 사용할 수 있습니다.

4. 서드파티 도구 사용

시스템 전반에 걸친 명령어 로깅을 위한 서드파티 솔루션을 사용할 수도 있습니다. 이러한 도구들은 종종 강화된 보안, 감사 추적 기능을 제공합니다.

주의 사항

  • 사용자의 명령어 실행을 로그로 남기는 것은 사용자의 프라이버시와 보안에 중요한 영향을 줄 수 있으므로, 이러한 모니터링은 반드시 필요한 경우에만, 그리고 적법한 절차에 따라 수행되어야 합니다.
  • 로그 데이터는 민감한 정보를 포함할 수 있으므로, 로그의 보안과 관리에 주의를 기울여야 합니다.

 

사용자가 실행한 명령어를 포함하여 sshd 활동의 상세한 로깅이 필요한 경우, 위의 방법들을 통해 목적에 맞는 로깅 전략을 수립할 수 있습니다.

 

auditctl 명령어는 Linux의 감사 시스템(auditd)에 규칙을 추가하거나 수정하는 데 사용됩니다. 특정 조건에 맞는 시스템 호출을 감시하기 위한 규칙을 감사 시스템에 추가하는 것입니다.

auditctl -a always,exit -F arch=b64 -S execve -F path=/bin/bash
  • auditctl: 감사 시스템의 컨트롤 유틸리티입니다.
  • -a always,exit: 이 규칙이 항상, 시스템 호출이 종료될 때(exit 시) 적용되어야 함을 나타냅니다.
  • -F arch=b64: 이 규칙이 64비트 아키텍처(b64)에 적용됨을 지정합니다. 시스템이 32비트인 경우, b32를 사용해야 합니다.
  • -S execve: 이 규칙이 execve 시스템 호출에 적용됨을 나타냅니다. execve는 프로그램을 실행할 때 사용되는 시스템 호출이며, 쉘 또는 다른 실행 파일이 시작될 때마다 이 시스템 호출이 사용됩니다.
  • -F path=/bin/bash: 이 규칙이 /bin/bash 경로의 실행 파일에만 적용됨을 지정합니다. 즉, bash 쉘을 시작하는 모든 행위가 감사 대상이 됩니다.

이 명령어에 의해 등록된 규칙은 시스템에서 /bin/bash 실행 파일을 시작하는 모든 시도를 감시하고, 이에 대한 로그를 감사 로그에 기록하도록 합니다. 로그는 일반적으로 /var/log/audit/audit.log 파일에 저장되며, 여기에는 실행된 명령어, 실행 시간, 실행한 사용자의 정보 등이 기록됩니다.

 

감사 규칙을 사용하는 것은 시스템에서 특정 활동을 추적하고, 보안 감사나 시스템 모니터링을 위한 중요한 정보를 수집하는 데 유용합니다. 하지만, 많은 양의 로그가 생성될 수 있으므로, 필요한 규칙만 설정하고, 로그 관리 정책을 적절히 계획하는 것이 중요합니다.

 

auditctl을 사용하여 추가한 감사 규칙은 즉시 감사 시스템에 적용되지만, 이러한 변경사항은 기본적으로 재부팅 시 지속되지 않습니다. 즉, auditctl을 통해 동적으로 추가된 규칙은 메모리에만 존재하며, 시스템을 재시작하면 사라집니다. 이 규칙을 시스템 재시작 후에도 지속적으로 적용하려면, 해당 규칙을 감사 시스템의 설정 파일에 추가해야 합니다.

 

Linux 시스템에서 감사 규칙을 영구적으로 설정하기 위해 일반적으로 사용하는 파일은 다음과 같습니다.

  • /etc/audit/audit.rules: 이 파일은 감사 시스템(auditd)이 시작할 때 읽어들이는 규칙을 포함합니다. 시스템 부팅 시 또는 auditd 서비스가 시작될 때 /etc/audit/audit.rules 파일에 지정된 규칙이 자동으로 로드되어 적용됩니다. 따라서, 영구적인 감사 규칙을 설정하고자 한다면, 이 파일에 규칙을 추가해야 합니다.

규칙을 /etc/audit/audit.rules 파일에 추가하는 방법은 매우 간단합니다.

  1. 편집기로 /etc/audit/audit.rules 파일 열기: sudo nano /etc/audit/audit.rules
  2. 파일의 끝에 규칙 추가: -a always,exit -F arch=b64 -S execve -F path=/bin/bash
  3. 파일 저장 후 편집기 종료.
  4. 감사 시스템 재시작: sudo systemctl restart auditd

이 과정을 통해, 시스템이 다시 시작되어도 지정된 감사 규칙이 유지됩니다. /etc/audit/audit.rules 파일에 추가된 규칙은 auditd 서비스가 시작될 때마다 자동으로 로드되어 감사 시스템에 적용됩니다.

 

auditctl로 추가한 감사 규칙을 삭제하려면, 해당 규칙을 명시적으로 제거하거나 감사 시스템을 재시작하여 모든 동적 규칙을 초기화할 수 있습니다. 규칙을 직접 삭제하는 방법을 선호하는 경우, 명령어는 다음과 같습니다.

규칙 삭제하기

규칙을 삭제하기 위해서는, 먼저 추가했던 규칙과 정확히 일치하는 규칙을 -d 옵션과 함께 auditctl 명령어에 제공해야 합니다. 추가했던 규칙을 삭제하는 명령어는 다음과 같습니다.

auditctl -d always,exit -F arch=b64 -S execve -F path=/bin/bash

여기서 -d 옵션은 감사 시스템에서 규칙을 삭제하라는 것을 나타냅니다. 이 명령어는 이전에 추가한 규칙을 제거합니다.

감사 시스템 재시작하기

감사 시스템(auditd)을 재시작하면, 동적으로 추가된 모든 규칙이 클리어되고, /etc/audit/audit.rules 파일에 정의된 규칙만 다시 로드됩니다. 시스템에서 auditd 서비스를 재시작하려면, 다음 명령어를 사용합니다.

sudo systemctl restart auditd

이 방법은 모든 동적 규칙을 초기화하지만, /etc/audit/audit.rules 파일에 영구적으로 추가된 규칙은 재시작 후에도 여전히 적용됩니다. 따라서, 특정 규칙을 완전히 제거하려면, 해당 규칙을 /etc/audit/audit.rules 파일에서도 삭제한 후 auditd 서비스를 재시작해야 합니다.

규칙이 여전히 적용되는지 확인하기

규칙을 삭제한 후에는 auditctl -l 명령어를 사용하여 현재 활성화된 감사 규칙 목록을 확인할 수 있습니다. 이를 통해 규칙이 성공적으로 제거되었는지 확인할 수 있습니다.

auditctl -l

규칙을 제거하는 과정에서는 각 단계를 주의 깊게 수행하여, 실수로 필요한 감사 규칙을 삭제하지 않도록 주의해야 합니다.

 

auditctl을 사용하여 /bin/bash 실행에 대한 감사 규칙을 추가했지만, n8n을 통해 sshd로 실행한 명령어가 감사 로그에 나타나지 않는 경우, 몇 가지 가능한 이유와 대안을 제시해 보겠습니다.

1. 명령어 실행 경로

  • auditctl 규칙이 /bin/bash에만 적용되기 때문에, 다른 쉘(sh, zsh, dash 등)이나 직접 실행 경로(/usr/bin/python, /usr/bin/perl 등)를 사용하여 명령어를 실행하는 경우, 해당 규칙에 의해 캡처되지 않습니다.
  • 사용자가 /bin/bash를 직접 실행하는 명령어만 감사 로그에 기록됩니다. ssh를 통해 실행하는 대부분의 명령어는 쉘을 직접 실행하지 않고, 해당 명령어의 실행 파일을 execve 시스템 호출을 통해 직접 실행하기 때문에, 이 규칙으로는 잡히지 않을 수 있습니다.

2. 명령어 실행 방식

  • n8n에서 sshd를 통해 명령어를 실행하는 경우, 명령어는 종종 non-interactive shell 또는 non-login shell을 통해 실행됩니다. 이러한 경우, 실행 환경이나 방식이 다를 수 있으며, 명령어가 특정 쉘을 거치지 않고 직접 실행될 수 있습니다.

3. 감사 규칙 조정

  • 명령어의 실행을 더 넓게 추적하려면, 다른 실행 파일에 대한 감사 규칙을 추가해야 할 수 있습니다. 예를 들어, 시스템의 모든 execve 시스템 호출을 추적하려면, 다음과 같은 감사 규칙을 추가할 수 있습니다.
    auditctl -a always,exit -F arch=b64 -S execve
    이 규칙은 모든 execve 호출을 추적하지만, 많은 양의 로그를 생성할 수 있으므로 주의해야 합니다.

4. 대안적 감사 방법 고려

  • 특정 사용자가 ssh를 통해 실행하는 모든 명령어를 추적하기 위해, pam_exec 모듈을 사용하여 사용자의 모든 ssh 세션에 대한 로깅 스크립트를 실행하도록 설정할 수 있습니다.
  • 또 다른 방법으로는, sshdForceCommand 옵션을 사용하여 모든 ssh 세션에 대해 특정 스크립트를 강제 실행하고, 이 스크립트 내에서 명령어 실행을 로그로 기록하는 방법이 있습니다.

5. 로그 위치와 검토

  • 설정한 감사 규칙에 의해 생성된 로그는 주로 /var/log/audit/audit.log 파일에 저장됩니다. 감사 로그가 예상대로 생성되고 있는지 확인하려면, 이 파일을 직접 검토해 보세요.

 

감사 시스템을 사용할 때는 로그의 양과 중요성을 고려하여, 필요한 정보를 효과적으로 캡처하면서도 시스템의 성능에 불필요한 부하를 주지 않도록 적절한 규칙을 설정하는 것이 중요합니다.

 

pam_exec 모듈을 사용하여 SSH를 통해 실행된 모든 명령어를 기록하는 방법은 PAM (Pluggable Authentication Modules) 시스템의 일부로 동작합니다. 이 방법을 사용하면, SSH 세션 시작 시 스크립트를 실행하여 사용자가 입력하는 명령어를 로그 파일에 기록할 수 있습니다. 아래 단계를 따라 설정할 수 있습니다.

1. 로깅 스크립트 작성

사용자 명령어를 로그로 기록할 스크립트를 작성합니다. 예를 들어, /usr/local/bin/ssh-commands-logger.sh에 다음과 같은 내용을 포함시킬 수 있습니다.

#!/bin/bash
LOG_FILE="/var/log/ssh_commands.log"
DATE=`date "+%Y-%m-%d %H:%M:%S"`
echo "Date: $DATE User: $PAM_USER Remote Host: $PAM_RHOST Command: $PAM_TTY" >> $LOG_FILE
  • 이 스크립트는 로그 파일에 날짜, 사용자 이름, 원격 호스트 주소, 그리고 실행된 명령어를 기록합니다. PAM_* 환경 변수들은 PAM으로부터 제공받는 정보를 포함합니다.

스크립트에 실행 권한을 부여합니다.

chmod +x /usr/local/bin/ssh-commands-logger.sh

2. PAM 구성 수정

/etc/pam.d/sshd 파일을 열고, pam_exec.so 모듈을 사용하여 앞서 작성한 스크립트를 실행하도록 구성을 추가합니다. 파일에 다음 줄을 추가하세요.

session optional pam_exec.so /usr/local/bin/ssh-commands-logger.sh
  • 여기서 optional은 이 모듈이 실패해도 세션 설정이 계속 진행됨을 의미합니다. 필요에 따라 required로 변경할 수 있으나, 스크립트 실행에 실패하면 사용자가 SSH 세션을 시작할 수 없게 될 수 있으므로 주의가 필요합니다.

3. 로그 파일 설정 확인

로그 파일(/var/log/ssh_commands.log)에 쓰기 위해 적절한 권한이 설정되어 있는지 확인하세요. 일반적으로는 root 사용자만이 이 파일에 쓰기 권한을 가지며, 로그 파일의 보안을 유지하는 것이 중요합니다.

4. SSH 서비스 재시작

설정 변경 후에는 SSH 서비스를 재시작하여 변경사항을 적용합니다.

sudo systemctl restart sshd

SSH를 통해 시스템에 로그인한 사용자가 실행하는 모든 명령어가 /var/log/ssh_commands.log 파일에 기록됩니다.

주의사항

  • 이 설정은 시스템에 보안상의 위험을 초래할 수 있으며, 사용자의 프라이버시와 관련된 법적 요구사항을 준수해야 합니다.
  • PAM 환경 변수는 스크립트 실행 시점에 따라 다른 정보를 포함할 수 있습니다. 예제 스크립트는 기본적인 정보만을 로그로 기록합니다.
  • 시스템의 보안 정책에 따라 로그 파일의 접근 권한을 엄격히 관리해야 합니다.

 

이 방법은 시스템의 사용자 활동을 모니터링하는 데 유용할 수 있지만, 사용 전에 관련 법규, 정책, 그리고 시스템의 보안 요구사항을 충분히 고려해야 합니다.

 

pam_exec 모듈을 사용하여 SSH를 통해 수행한 명령어를 기록하려는 경우, 몇 가지 중요한 고려사항이 있습니다. pam_exec는 주로 PAM (Pluggable Authentication Modules)을 통한 사용자 세션의 시작과 종료 시점에 스크립트를 실행하는 데 사용됩니다. 이는 사용자가 대화식 로그인 세션을 시작할 때 효과적으로 작동합니다. 그러나 비대화식 명령어 실행, 즉 SSH를 통해 직접 명령어를 실행하는 경우(ssh user@host 'command' 형태)는 다를 수 있습니다.

비대화식 SSH 명령어 실행과 pam_exec

  • 대화식 세션: 사용자가 SSH를 통해 서버에 로그인하고 쉘 세션을 시작할 때, pam_exec에 의해 구성된 스크립트가 실행됩니다. 이는 로그인과 로그아웃 시점에 발생하는 이벤트를 기준으로 합니다.
  • 비대화식 명령어 실행: 사용자가 SSH를 통해 서버에 로그인하지 않고 직접 명령어를 실행하는 경우(예: ssh user@host 'ls -l'), 이 명령어는 새로운 로그인 세션을 생성하지 않고, 대신 SSH 서비스에 의해 직접 처리됩니다. 이러한 비대화식 실행은 pam_exec가 감지하는 세션 시작 또는 종료 이벤트를 발생시키지 않을 수 있습니다.

비대화식 명령어 기록

비대화식 명령어 실행을 기록하고자 할 때, pam_exec만으로는 충분하지 않을 수 있으며, 다음과 같은 방법을 고려해 볼 수 있습니다.

  • 감사 시스템(auditd) 사용: 시스템의 감사 프레임워크를 사용하여 특정 이벤트나 시스템 호출을 기록할 수 있습니다. 예를 들어, execve 시스템 호출을 추적하여 사용자가 실행하는 모든 명령어를 로그로 남길 수 있습니다.
  • SSH 서버 설정 변경: ForceCommand 같은 SSH 서버의 구성 옵션을 사용하여 모든 SSH 세션(대화식 및 비대화식 모두)에 대해 특정 명령어 또는 스크립트를 강제로 실행하도록 설정할 수 있습니다. 이 방법은 모든 사용자 또는 특정 사용자에 대한 모든 명령어 실행을 중앙에서 기록하는 데 사용할 수 있습니다.
  • 커스텀 로깅 솔루션: 명령어 실행을 감지하고 기록하기 위한 커스텀 스크립트 또는 도구를 개발할 수 있습니다. 이는 복잡하고, 시스템에 특화된 요구사항을 충족시키기 위해 필요할 수 있습니다.

 

비대화식 SSH 명령어 실행을 기록하려는 경우 pam_exec만으로는 일부 제한이 있을 수 있으며, 시스템의 보안 정책과 요구사항에 맞는 다른 방법을 함께 고려해야 할 수 있습니다.

 

SSH에서 ForceCommand를 사용하는 것은 서버 설정에서 특정 사용자 또는 모든 사용자의 세션에 대해 강제로 특정 명령어나 스크립트를 실행하도록 설정하는 방법입니다. 이 기능을 이용하면, 대화식 및 비대화식 모드에서 실행되는 모든 명령어를 포착하여 로깅하는 등의 작업을 수행할 수 있습니다. 이 방식은 특히 보안 감사 또는 시스템 모니터링 목적으로 유용합니다.

ForceCommand 사용하기

  1. 로깅 스크립트 작성: 사용자가 실행하는 모든 명령어를 로그 파일에 기록하는 스크립트를 작성합니다. 예를 들어, /usr/local/bin/log-all-commands.sh라는 스크립트를 만들고, 다음과 같은 내용을 포함시킵니다.
    #!/bin/bash
    
    # 로그 파일 경로 설정
    LOG_FILE="/var/log/user_commands.log"
    
    # 실행된 명령어, 사용자 이름, 시간 등을 로그 파일에 기록
    echo "$(date) - USER: $USER, COMMAND: $SSH_ORIGINAL_COMMAND" >> $LOG_FILE
    
    # 원래 실행하려고 했던 명령어 실행. 비어있는 경우 쉘 시작
    if [ -z "$SSH_ORIGINAL_COMMAND" ]; then
      exec /bin/bash
    else
      exec $SSH_ORIGINAL_COMMAND
    fi
    이 스크립트는 SSH를 통해 실행된 명령어(비대화식)를 로그로 기록하고, 명령어가 없는 경우(대화식) 쉘을 시작합니다.
  2. 실행 권한 부여: 스크립트에 실행 권한을 부여합니다.
    chmod +x /usr/local/bin/log-all-commands.sh
  3. sshd_config 파일 수정: SSH 서버 설정 파일(/etc/ssh/sshd_config)을 열고, ForceCommand 지시어를 사용하여 위에서 작성한 스크립트를 강제 실행하도록 설정합니다. 이를 전체 사용자에게 적용하려면, 파일의 맨 아래에 다음 줄을 추가합니다.
    ForceCommand /usr/local/bin/log-all-commands.sh
    특정 사용자에게만 이 설정을 적용하려면, Match User 지시어를 사용하여 설정할 수 있습니다.
    Match User specific_user
    ForceCommand /usr/local/bin/log-all-commands.sh
  4. SSH 서비스 재시작: 설정 변경사항을 적용하기 위해 SSH 서비스를 재시작합니다.
    sudo systemctl restart sshd

주의사항

  • ForceCommand는 모든 SSH 세션에 대해 특정 명령어나 스크립트를 강제로 실행하므로, 사용에 있어 주의가 필요합니다. 특히, 스크립트에 오류가 있거나 예상치 못한 동작을 할 경우 사용자의 SSH 접근에 영향을 줄 수 있습니다.
  • 로그 파일(/var/log/user_commands.log)의 접근 권한을 적절히 설정하여, 민감한 정보가 외부에 유출되지 않도록 보호해야 합니다.
  • 이 설정은 모든 명령어 실행을 기록하므로, 생성되는 로그의 양이 많을 수 있습니다. 따라서, 로그 파일의 관리 및 로테이션 정책을 적절히 설정하는 것이 중요합니다.

 

ForceCommand를 사용한 명령어 로깅은 강력한 도구일 수 있지만, 시스템의 보안 정책과 사용자의 프라이버시 권리를 고려하여 신중하게 사용해야 합니다.

 

SSH 서버의 sshd_config 파일을 수정하여 ForceCommand가 특정 그룹에만 적용되도록 설정할 수 있습니다. 이를 통해 해당 그룹의 사용자가 SSH를 통해 서버에 접속할 때만 특정 명령어 또는 스크립트가 강제로 실행되도록 할 수 있습니다.

1단계: 그룹 확인 또는 생성

ForceCommand를 적용하고자 하는 사용자들이 속한 그룹이 이미 있는지 확인하거나, 새로운 그룹을 생성해야 할 수도 있습니다. 새 그룹을 생성하려면 다음 명령어를 사용합니다.

sudo groupadd my_special_group

이 명령어는 my_special_group이라는 새로운 그룹을 생성합니다. 필요한 사용자를 이 그룹에 추가해야 합니다.

sudo usermod -a -G my_special_group username

username을 해당 그룹에 추가하려는 사용자의 이름으로 바꾸세요.

2단계: sshd_config에서 그룹에 대한 설정 추가

/etc/ssh/sshd_config 파일을 편집하여 특정 그룹에 대해 ForceCommand를 적용하는 설정을 추가합니다. 파일을 안전하게 편집하기 위해, 관리자 권한이 필요한 텍스트 편집기를 사용하세요.

sudo nano /etc/ssh/sshd_config

그런 다음, 파일의 맨 아래에 다음과 같은 섹션을 추가합니다.

Match Group my_special_group
    ForceCommand /usr/local/bin/log-all-commands.sh

여기서 my_special_group은 앞서 선택하거나 생성한 그룹 이름이며, /usr/local/bin/log-all-commands.sh은 해당 그룹의 사용자가 SSH를 통해 접속할 때 강제로 실행되어야 하는 스크립트나 명령어입니다.

3단계: SSH 서비스 재시작

변경사항을 적용하기 위해 SSH 서비스를 재시작하거나 리로드합니다.

sudo systemctl restart sshd

또는

sudo service ssh restart

사용하는 시스템에 따라 적절한 명령어를 사용하세요.

주의사항

      • ForceCommand는 사용자가 SSH를 통해 서버에 접속할 때 실행되는 모든 명령어를 오버라이드합니다. 사용자가 입력하는 명령어 대신, 지정된 스크립트 또는 명령어가 실행됩니다.
      • 이 설정은 보안 감사, 로깅, 또는 특정 작업의 자동화를 목적으로 사용될 수 있습니다. 그러나 사용자가 서버에서 수행할 수 있는 작업을 제한하기 때문에, 신중하게 사용해야 합니다.
      • 설정을 변경하기 전에, sshd_config 파일의 백업 본을 만들어 두는 것이 좋습니다. 만약 문제가 발생하면 원래 설정으로 쉽게 복원할 수 있습니다.

 

OpenSSH의 sshd_config 파일에서 특정 사용자를 제외하고 ForceCommand를 적용하는 직접적인 방법은 제공되지 않습니다. OpenSSH 구성은 주로 포함(inclusion) 기반으로 작동하며, 제외(exclusion)를 직접 지정하는 기능은 제한적입니다.

1. 스크립트에서 사용자 검사

ForceCommand에 지정된 스크립트 내에서 특정 사용자를 체크하여, 제외하고자 하는 사용자인 경우 다른 동작을 하도록 구성할 수 있습니다. 예를 들어, /usr/local/bin/log-all-commands.sh 스크립트 안에서 다음과 같이 특정 사용자를 체크할 수 있습니다.

#!/bin/bash

# 제외할 사용자 이름
EXCLUDE_USER="specific_user"

# 현재 로그인한 사용자가 제외할 사용자인지 확인
if [ "$USER" == "$EXCLUDE_USER" ]; then
  # 제외할 사용자의 경우 원래 명령어 실행 또는 쉘 제공
  if [ -n "$SSH_ORIGINAL_COMMAND" ]; then
    exec $SSH_ORIGINAL_COMMAND
  else
    exec /bin/bash
  fi
else
  # 로깅 스크립트 또는 원하는 명령어 실행
  LOG_FILE="/var/log/user_commands.log"
  echo "$(date) - USER: $USER, COMMAND: $SSH_ORIGINAL_COMMAND" >> $LOG_FILE
  # 원래 명령어 실행
  if [ -n "$SSH_ORIGINAL_COMMAND" ]; then
    exec $SSH_ORIGINAL_COMMAND
  else
    exec /bin/bash
  fi
fi

2. Match User와 Match Group 사용

sshd_config에서 여러 Match 블록을 사용하여, 제외하고자 하는 사용자를 특정 그룹에 포함시키고, 나머지 사용자에 대해 ForceCommand를 적용할 수 있습니다. 예를 들어, 제외할 사용자를 "excluded_group" 그룹에 포함시키고, 그룹이 아닌 사용자에 대해 ForceCommand를 적용하는 방식입니다.

# 제외할 사용자가 속한 그룹에 대해 ForceCommand를 적용하지 않음
Match Group excluded_group
  ForceCommand none

# 나머지 모든 사용자에 대해 ForceCommand 적용
Match all
  ForceCommand /usr/local/bin/log-all-commands.sh

이 방법의 효율성은 OpenSSH 버전과 구성에 따라 다를 수 있으며, 모든 버전에서 Match all 구문이 예상대로 작동하지 않을 수 있습니다. OpenSSH의 문서와 해당 버전의 sshd_config 매뉴얼 페이지를 참조하여, 사용 가능한 옵션을 확인하세요.

728x90

댓글