[태그:] 리눅스

  • [Linux]자주_쓰는_명령어

    리눅스 vi 편집기 마스터하기: 자주 쓰는 명령어 💡

    리눅스 작업 중 코드 수정이 필요할 때 vi 편집기를 자주 사용하게 됨.
    매번 찾아보기 귀찮아서 자주 쓰는 명령어와 문제 해결 팁을 정리했음.


    vi 명령어

    vi 편집기를 사용할 때 유용한 명령어들은 다음과 같음.

    명령어설명
    vi [파일명]vi 편집기로 파일을 수정
    i, a입력 모드 (명령 모드로 가려면 ESC 누름)
    :set nu, :set number라인번호(줄번호) 표시
    숫자 입력 Enter해당 라인으로 이동
    gg맨 위로 이동
    shift + g, :$맨 아래로 이동
    u방금 한 명령 취소 (undo)
    W현재 파일명으로 파일 저장 (저장만 하고 종료되지 않음)
    :w[파일명]입력한 파일명으로 파일 저장 (저장만 하고 종료되지 않음)
    :qvi 종료 (저장 안 됨)
    :q!vi 강제 종료
    :wq저장 후 종료
    :wq!vi 강제 저장 후 종료
    /문자열현재 커서 위치부터 앞으로 문자열 탐색
    ?문자열현재 커서 위치부터 뒤쪽으로 문자열 탐색

    🚨 vi 안 될 때

    간혹 vi 명령어를 입력하고 화면이 멈춘 것처럼 보일 때가 있음.
    이럴 때 다음 명령어를 터미널에 입력하면 해결될 수 있음.

    명령어터미널설명
    LC_ALL=C.UTF-8터미널 입력vi . 명령어 입력 후 멈춘 듯할 때 사용 가능
  • 로그 관리와 모니터링 실전 가이드: 시스템을 눈으로 보는 기술

    안녕하세요, 성장하는 개발자 여러분!

    서버에 문제가 생겼을 때 여러분은 어디부터 보시나요? CPU? 메모리? 아니면 그냥… 재시작? 😅

    실제로는 로그가 모든 문제의 답을 가지고 있습니다. 서버가 무엇을 하고 있는지, 어떤 에러가 발생했는지, 언제 문제가 시작되었는지… 모든 것이 로그에 기록되어 있어요.

    오늘은 제가 실무에서 수없이 겪었던 장애 상황들을 통해 배운 로그 관리와 모니터링의 실전 노하우를 공유하겠습니다. 이론보다는 “지금 당장 문제를 찾고 해결하는” 관점에서 설명하겠습니다! 🔍

    1. 로그의 기본: 리눅스 로깅 시스템 이해하기

    로그 아키텍처: 누가 무엇을 어디에 기록하나?

    현대 리눅스 시스템의 로깅은 두 주인공이 있습니다:

    # 로그 시스템 구조
    시스템 이벤트 → systemd-journald → rsyslogd → /var/log 파일들
                          ↓
                       /run/log/journal (바이너리)

    핵심 개념:

    • systemd-journald: 부팅부터 모든 로그를 수집하는 중앙 집중화된 로그 수집기
    • rsyslogd: 전통적인 텍스트 기반 로그 파일 생성기
    • 두 시스템이 함께 동작: 호환성과 편의성을 모두 제공

    실무에서 자주 확인하는 로그 파일들

    # 주요 시스템 로그 위치와 용도
    echo "=== 핵심 로그 파일들 ==="
    
    # 1. 시스템 전반적인 로그
    /var/log/messages     # 대부분의 시스템 메시지
    /var/log/syslog       # 시스템 로그 (Ubuntu/Debian)
    
    # 2. 보안 관련 로그
    /var/log/secure       # SSH, sudo, 인증 관련 (RHEL/CentOS)
    /var/log/auth.log     # 인증 로그 (Ubuntu/Debian)
    
    # 3. 서비스별 로그
    /var/log/httpd/       # Apache 웹서버
    /var/log/nginx/       # Nginx 웹서버
    /var/log/mysql/       # MySQL 데이터베이스
    /var/log/postgresql/  # PostgreSQL 데이터베이스
    
    # 4. 시스템 부팅 로그
    /var/log/boot.log     # 부팅 과정 로그
    /var/log/dmesg        # 커널 메시지
    
    # 5. 크론 작업 로그
    /var/log/cron         # 스케줄 작업 로그

    실무 팁: 로그 파일 빠르게 파악하기

    # 각 로그 파일의 크기와 최근 수정 시간 확인
    ls -lah /var/log/ | head -10
    
    # 가장 큰 로그 파일들 찾기
    du -ah /var/log/ | sort -hr | head -10
    
    # 오늘 생성된 로그 파일들
    find /var/log -name "*.log" -mtime 0
    
    # 실시간으로 변화하는 로그 파일들 확인
    lsof +D /var/log | grep -v "(deleted)"

    2. journalctl: 현대적 로그 분석의 핵심 도구

    기본 사용법과 핵심 옵션들

    # 1. 전체 로그 확인 (기본)
    journalctl
    
    # 2. 실시간 로그 모니터링 (가장 많이 사용!)
    journalctl -f
    
    # 3. 최근 로그만 확인
    journalctl -n 50        # 최근 50줄
    journalctl --since today # 오늘부터
    journalctl --since "2024-01-15 14:00:00"
    
    # 4. 특정 기간 로그 확인
    journalctl --since "2024-01-15" --until "2024-01-16"
    journalctl --since "1 hour ago"
    journalctl --since "30 minutes ago"

    서비스별 로그 분석

    # 특정 서비스 로그만 확인
    journalctl -u nginx
    journalctl -u mysql
    journalctl -u ssh
    
    # 여러 서비스 동시에 확인
    journalctl -u nginx -u mysql
    
    # 서비스 로그 실시간 모니터링
    journalctl -u nginx -f
    
    # 서비스 로그 with 우선순위
    journalctl -u nginx -p err    # 에러 레벨만
    journalctl -u nginx -p warning # 경고 이상만

    실전 시나리오별 로그 분석

    시나리오 1: “웹사이트가 갑자기 느려졌어요!”

    # 1단계: 웹서버 에러 로그 확인
    journalctl -u nginx -p err --since "1 hour ago"
    
    # 2단계: 시스템 자원 관련 로그
    journalctl -p crit --since "1 hour ago"
    
    # 3단계: 데이터베이스 관련 로그
    journalctl -u mysql --since "1 hour ago" | grep -i "slow|error|warning"
    
    # 4단계: 메모리/디스크 관련 로그
    journalctl -k --since "1 hour ago" | grep -i "oom|memory|disk"

    시나리오 2: “서버에 이상한 접근이 있었나요?”

    # SSH 접근 시도 분석
    journalctl -u ssh --since today | grep "Failed password"
    
    # 성공한 로그인 확인
    journalctl -u ssh --since today | grep "Accepted"
    
    # 특정 IP의 활동 추적
    journalctl --since today | grep "192.168.1.100"
    
    # sudo 사용 내역 확인
    journalctl --since today | grep sudo

    시나리오 3: “서비스가 자꾸 재시작돼요!”

    # 서비스 시작/중지 이력 확인
    journalctl -u myapp --since "24 hours ago" | grep -E "(Started|Stopped|Failed)"
    
    # 시스템 재부팅 이력
    journalctl --list-boots
    
    # 특정 부팅 세션의 로그
    journalctl -b -1  # 이전 부팅
    journalctl -b 0   # 현재 부팅
    
    # 크래시 관련 로그
    journalctl -p crit --since "24 hours ago"

    고급 journalctl 활용법

    # 1. JSON 형태로 상세 정보 확인
    journalctl -o json-pretty -n 5
    
    # 2. 특정 필드로 필터링
    journalctl _PID=1234              # 특정 프로세스 ID
    journalctl _UID=1000              # 특정 사용자 ID
    journalctl _COMM=nginx            # 특정 명령어
    journalctl PRIORITY=3             # 특정 우선순위 (3=err)
    
    # 3. 로그 크기 관리
    journalctl --disk-usage           # 저널 로그 용량 확인
    sudo journalctl --vacuum-time=30d # 30일 이상 로그 삭제
    sudo journalctl --vacuum-size=1G  # 1GB 이상 로그 삭제
    
    # 4. 로그 내보내기
    journalctl --since today -o export > system_logs_$(date +%Y%m%d).journal

    3. 전통적 로그 파일 분석: grep, awk, sed 마스터하기

    핵심 로그 분석 명령어들

    # 1. 기본 로그 읽기
    tail -f /var/log/messages          # 실시간 모니터링
    tail -100 /var/log/secure          # 마지막 100줄
    head -50 /var/log/nginx/access.log # 처음 50줄
    
    # 2. 로그 검색과 필터링
    grep "error" /var/log/messages
    grep -i "failed" /var/log/secure   # 대소문자 구분 없이
    grep -v "INFO" /var/log/app.log    # INFO가 없는 줄만
    grep -A 5 -B 5 "ERROR" /var/log/app.log # 앞뒤 5줄 포함
    
    # 3. 여러 파일에서 동시 검색
    grep -r "database connection" /var/log/
    find /var/log -name "*.log" -exec grep -l "error" {} ;

    실무에서 자주 사용하는 로그 분석 패턴

    웹서버 로그 분석

    # Nginx access 로그 분석
    # 가장 많이 접근한 IP 찾기
    awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
    
    # 404 에러가 많은 페이지 찾기
    grep " 404 " /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -nr
    
    # 시간대별 요청 수 분석
    awk '{print $4}' /var/log/nginx/access.log | cut -d: -f2 | sort | uniq -c
    
    # 특정 시간대의 로그만 확인
    awk '$4 ~ /15/Jan/2024:14/ {print}' /var/log/nginx/access.log
    
    # User-Agent 분석 (봇 탐지)
    awk -F'"' '{print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

    보안 로그 분석

    # SSH 무차별 대입 공격 탐지
    grep "Failed password" /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -nr
    
    # 성공한 로그인 후 바로 실패한 케이스 (의심스러운 활동)
    grep -E "(Accepted|Failed)" /var/log/secure | grep -A1 "Accepted" | grep "Failed"
    
    # 루트 계정 접근 시도
    grep "Failed password for root" /var/log/secure
    
    # 새로운 SSH 키 추가 감지
    grep "Accepted publickey" /var/log/secure | awk '{print $9, $11}' | sort -u

    시스템 성능 로그 분석

    # Out of Memory 이벤트 찾기
    dmesg | grep -i "out of memory"
    grep -i "oom" /var/log/messages
    
    # 디스크 관련 에러
    grep -i "disk|ata|scsi" /var/log/messages | grep -i error
    
    # 네트워크 관련 에러
    grep -i "network|eth0|connection" /var/log/messages | grep -i error

    로그 분석 자동화 스크립트

    #!/bin/bash
    # log_analyzer.sh - 종합 로그 분석 스크립트
    
    LOG_DATE=$(date +%Y%m%d)
    REPORT_FILE="/tmp/log_analysis_${LOG_DATE}.txt"
    
    echo "=== 시스템 로그 분석 리포트 $(date) ===" > $REPORT_FILE
    
    # 1. 시스템 에러 요약
    echo "1. 시스템 에러 요약:" >> $REPORT_FILE
    journalctl -p err --since today --no-pager | wc -l >> $REPORT_FILE
    echo "총 에러 수: $(journalctl -p err --since today --no-pager | wc -l)" >> $REPORT_FILE
    
    # 2. 가장 많이 발생한 에러들
    echo -e "n2. 주요 에러 메시지:" >> $REPORT_FILE
    journalctl -p err --since today --no-pager | awk '{$1=$2=$3=""; print $0}' | sort | uniq -c | sort -nr | head -5 >> $REPORT_FILE
    
    # 3. SSH 접근 분석
    echo -e "n3. SSH 접근 분석:" >> $REPORT_FILE
    echo "실패한 로그인 시도: $(grep "Failed password" /var/log/secure | grep "$(date +%b %d)" | wc -l)" >> $REPORT_FILE
    echo "성공한 로그인: $(grep "Accepted" /var/log/secure | grep "$(date +%b %d)" | wc -l)" >> $REPORT_FILE
    
    # 4. 상위 공격자 IP
    echo -e "n4. 상위 공격자 IP (실패한 로그인):" >> $REPORT_FILE
    grep "Failed password" /var/log/secure | grep "$(date +%b %d)" | awk '{print $11}' | sort | uniq -c | sort -nr | head -5 >> $REPORT_FILE
    
    # 5. 디스크 사용량과 로그 크기
    echo -e "n5. 로그 파일 크기 분석:" >> $REPORT_FILE
    echo "전체 /var/log 사용량: $(du -sh /var/log | cut -f1)" >> $REPORT_FILE
    echo "journalctl 사용량: $(journalctl --disk-usage | grep -o '[0-9.]*[KMGT]B')" >> $REPORT_FILE
    
    # 6. 서비스 상태 요약
    echo -e "n6. 주요 서비스 상태:" >> $REPORT_FILE
    for service in nginx mysql ssh firewalld; do
        if systemctl is-active $service > /dev/null 2>&1; then
            echo "$service: 정상" >> $REPORT_FILE
        else
            echo "$service: 비정상" >> $REPORT_FILE
        fi
    done
    
    echo "분석 완료: $REPORT_FILE"
    cat $REPORT_FILE

    4. 실시간 모니터링과 알림 시스템 구축

    실시간 로그 모니터링 대시보드

    # 멀티 터미널 모니터링 스크립트
    #!/bin/bash
    # monitor_dashboard.sh
    
    # 터미널을 4개 영역으로 분할하여 실시간 모니터링
    tmux new-session -d -s monitoring
    
    # 상단 좌측: 시스템 전체 에러 로그
    tmux send-keys -t monitoring "journalctl -f -p err" Enter
    
    # 상단 우측: 웹서버 로그
    tmux split-window -h -t monitoring
    tmux send-keys -t monitoring "tail -f /var/log/nginx/error.log" Enter
    
    # 하단 좌측: SSH 접근 로그
    tmux split-window -v -t monitoring:0.0
    tmux send-keys -t monitoring "journalctl -u ssh -f" Enter
    
    # 하단 우측: 시스템 리소스
    tmux split-window -v -t monitoring:0.1
    tmux send-keys -t monitoring "htop" Enter
    
    # 세션 접속
    tmux attach-session -t monitoring

    로그 기반 알림 시스템

    #!/bin/bash
    # log_alert_system.sh - 로그 기반 실시간 알림
    
    WEBHOOK_URL="YOUR_SLACK_WEBHOOK_URL"
    ALERT_LOG="/var/log/alert_system.log"
    
    # 슬랙 알림 함수
    send_slack_alert() {
        local message="$1"
        local level="$2"
        local emoji="🔴"
    
        case $level in
            "warning") emoji="⚠️" ;;
            "info") emoji="ℹ️" ;;
            "critical") emoji="🚨" ;;
        esac
    
        curl -X POST -H 'Content-type: application/json' 
            --data "{"text":"$emoji $message"}" 
            $WEBHOOK_URL
    }
    
    # 1. SSH 무차별 대입 공격 감지
    check_ssh_attacks() {
        local attacks=$(grep "Failed password" /var/log/secure | grep "$(date +%b %d)" | wc -l)
    
        if [ $attacks -gt 50 ]; then
            local top_attacker=$(grep "Failed password" /var/log/secure | grep "$(date +%b %d)" | 
                               awk '{print $11}' | sort | uniq -c | sort -nr | head -1)
            send_slack_alert "SSH 무차별 대입 공격 감지! 총 $attacks 회 시도. 주요 공격자: $top_attacker" "critical"
        fi
    }
    
    # 2. 시스템 에러 급증 감지
    check_system_errors() {
        local errors=$(journalctl -p err --since "10 minutes ago" --no-pager | wc -l)
    
        if [ $errors -gt 20 ]; then
            send_slack_alert "시스템 에러 급증! 최근 10분간 $errors 개 에러 발생" "critical"
        fi
    }
    
    # 3. 디스크 공간 부족 경고
    check_disk_space() {
        local usage=$(df /var/log | tail -1 | awk '{print $5}' | sed 's/%//')
    
        if [ $usage -gt 90 ]; then
            send_slack_alert "로그 디스크 공간 부족! 현재 사용률: ${usage}%" "warning"
        fi
    }
    
    # 4. 중요 서비스 다운 감지
    check_critical_services() {
        for service in nginx mysql ssh; do
            if ! systemctl is-active $service > /dev/null 2>&1; then
                send_slack_alert "$service 서비스가 중지되었습니다!" "critical"
            fi
        done
    }
    
    # 5. OOM(Out of Memory) 이벤트 감지
    check_oom_events() {
        local oom_count=$(dmesg | grep -i "killed process" | grep "$(date +%b %d)" | wc -l)
    
        if [ $oom_count -gt 0 ]; then
            local killed_process=$(dmesg | grep -i "killed process" | tail -1 | awk '{print $NF}')
            send_slack_alert "메모리 부족으로 프로세스 종료! 종료된 프로세스: $killed_process" "critical"
        fi
    }
    
    # 메인 실행부
    main() {
        echo "$(date): 로그 모니터링 시작" >> $ALERT_LOG
    
        check_ssh_attacks
        check_system_errors
        check_disk_space
        check_critical_services
        check_oom_events
    
        echo "$(date): 로그 모니터링 완료" >> $ALERT_LOG
    }
    
    # crontab에 등록: */5 * * * * /path/to/log_alert_system.sh
    main

    로그 순환(Log Rotation) 관리

    # logrotate 설정 최적화
    sudo nano /etc/logrotate.d/custom-app
    
    # 커스텀 애플리케이션 로그 순환 설정
    /var/log/myapp/*.log {
        daily                    # 매일 순환
        rotate 30               # 30개 파일 보관
        compress                # 압축 저장
        delaycompress          # 다음 순환 때 압축
        missingok              # 파일이 없어도 에러 없음
        notifempty             # 빈 파일은 순환하지 않음
        create 644 myapp myapp # 새 파일 권한 설정
        postrotate
            systemctl reload myapp
        endscript
    }
    
    # logrotate 테스트
    sudo logrotate -d /etc/logrotate.d/custom-app  # 드라이런
    sudo logrotate -f /etc/logrotate.d/custom-app  # 강제 실행

    5. 성능 모니터링과 프로파일링

    시스템 성능 로그 분석

    # 1. CPU 사용률 이력 확인
    sar -u 1 10    # 1초마다 10번 CPU 사용률 확인
    sar -u -f /var/log/sa/sa$(date +%d)  # 오늘의 CPU 이력
    
    # 2. 메모리 사용 패턴 분석
    sar -r 1 10    # 메모리 사용률
    free -h && cat /proc/meminfo | grep -E "(MemTotal|MemFree|MemAvailable|Buffers|Cached)"
    
    # 3. 디스크 I/O 분석
    iotop -o      # I/O 사용량이 높은 프로세스만
    iostat -x 1 5 # 디스크 I/O 상세 통계
    
    # 4. 네트워크 연결 상태 분석
    ss -tuln | awk '{print $1}' | sort | uniq -c  # 연결 타입별 통계
    netstat -i    # 인터페이스별 통계

    애플리케이션 성능 모니터링

    # 1. 프로세스별 리소스 사용량 추적
    pidstat -u -r -d 1 10 -p $(pgrep nginx)  # nginx 프로세스 모니터링
    
    # 2. 시스템 콜 추적
    strace -c -p $(pgrep nginx)  # nginx의 시스템 콜 통계
    strace -f -e trace=file nginx  # 파일 관련 시스템 콜만
    
    # 3. 네트워크 연결 모니터링
    ss -i  # 소켓 상세 정보
    lsof -i :80  # 80 포트 사용 프로세스

    종합 모니터링 스크립트

    #!/bin/bash
    # comprehensive_monitor.sh - 종합 시스템 모니터링
    
    REPORT_DIR="/var/log/monitoring"
    TIMESTAMP=$(date +%Y%m%d_%H%M%S)
    REPORT_FILE="$REPORT_DIR/system_report_$TIMESTAMP.txt"
    
    mkdir -p $REPORT_DIR
    
    exec > >(tee $REPORT_FILE)
    exec 2>&1
    
    echo "=== 종합 시스템 모니터링 리포트 $(date) ==="
    
    # 1. 시스템 기본 정보
    echo -e "n1. 시스템 기본 정보:"
    echo "호스트명: $(hostname)"
    echo "운영체제: $(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2)"
    echo "커널: $(uname -r)"
    echo "업타임: $(uptime -p)"
    echo "부하 평균: $(uptime | cut -d':' -f4-)"
    
    # 2. CPU 및 메모리 상태
    echo -e "n2. CPU 및 메모리 상태:"
    echo "CPU 코어 수: $(nproc)"
    echo "CPU 사용률 (1분 평균): $(sar -u 1 1 | tail -1 | awk '{print 100-$8}')%"
    echo "메모리 사용률: $(free | grep Mem | awk '{printf "%.1f%%", $3/$2 * 100.0}')"
    echo "스왑 사용률: $(free | grep Swap | awk '{printf "%.1f%%", $3/$2 * 100.0}')"
    
    # 3. 디스크 사용량
    echo -e "n3. 디스크 사용량:"
    df -h | grep -v tmpfs | grep -v devtmpfs
    
    # 4. 네트워크 상태
    echo -e "n4. 네트워크 상태:"
    echo "활성 연결 수: $(ss -t state established | wc -l)"
    echo "리스닝 포트: $(ss -tuln | grep LISTEN | wc -l)"
    
    # 5. 프로세스 TOP 10
    echo -e "n5. CPU 사용률 상위 프로세스:"
    ps aux --sort=-%cpu | head -11
    
    echo -e "n6. 메모리 사용률 상위 프로세스:"
    ps aux --sort=-%mem | head -11
    
    # 7. 최근 에러 로그
    echo -e "n7. 최근 1시간 에러 로그 (상위 10개):"
    journalctl -p err --since "1 hour ago" --no-pager | tail -10
    
    # 8. 서비스 상태
    echo -e "n8. 주요 서비스 상태:"
    for service in ssh nginx mysql docker; do
        if systemctl list-unit-files | grep -q "^$service.service"; then
            status=$(systemctl is-active $service 2>/dev/null || echo "inactive")
            echo "$service: $status"
        fi
    done
    
    # 9. 보안 이벤트 요약
    echo -e "n9. 보안 이벤트 요약 (오늘):"
    echo "SSH 로그인 실패: $(grep "Failed password" /var/log/secure 2>/dev/null | grep "$(date +%b %d)" | wc -l)"
    echo "SSH 로그인 성공: $(grep "Accepted" /var/log/secure 2>/dev/null | grep "$(date +%b %d)" | wc -l)"
    echo "sudo 사용: $(journalctl --since today | grep sudo | wc -l)"
    
    echo -e "n=== 리포트 완료 ==="
    echo "리포트 파일: $REPORT_FILE"
    
    # 이전 리포트 정리 (7일 이상 된 것)
    find $REPORT_DIR -name "system_report_*.txt" -mtime +7 -delete

    6. 로그 보안과 컴플라이언스

    로그 무결성 보장

    # 1. 로그 파일 권한 설정
    sudo chmod 640 /var/log/messages
    sudo chown root:adm /var/log/secure
    
    # 2. 로그 변조 방지를 위한 체크섬 생성
    #!/bin/bash
    # log_integrity_check.sh
    
    LOG_CHECKSUM_DIR="/var/log/checksums"
    mkdir -p $LOG_CHECKSUM_DIR
    
    # 중요 로그 파일들의 체크섬 생성
    for logfile in /var/log/messages /var/log/secure /var/log/audit/audit.log; do
        if [ -f "$logfile" ]; then
            checksum_file="$LOG_CHECKSUM_DIR/$(basename $logfile).sha256"
            sha256sum "$logfile" > "$checksum_file.new"
    
            # 이전 체크섬과 비교
            if [ -f "$checksum_file" ]; then
                if ! diff "$checksum_file" "$checksum_file.new" > /dev/null; then
                    echo "경고: $logfile 이 변조되었을 수 있습니다!"
                    logger "LOG_INTEGRITY_WARNING: $logfile checksum mismatch"
                fi
            fi
    
            mv "$checksum_file.new" "$checksum_file"
        fi
    done

    중앙 집중식 로그 수집 (Rsyslog)

    # rsyslog 서버 설정 (/etc/rsyslog.conf)
    # 중앙 로그 서버로 설정
    
    # UDP로 로그 수신 허용
    $ModLoad imudp
    $UDPServerRun 514
    $UDPServerAddress 0.0.0.0
    
    # TCP로 로그 수신 허용 (더 안전)
    $ModLoad imtcp
    $InputTCPServerRun 514
    
    # 클라이언트별로 로그 분리 저장
    $template RemoteLogs,"/var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log"
    *.* ?RemoteLogs
    & stop
    
    # 클라이언트 설정 - 중앙 서버로 로그 전송
    echo "*.* @@log-server:514" >> /etc/rsyslog.conf
    systemctl restart rsyslog

    7. 트러블슈팅 실전 시나리오

    시나리오 1: “사이트가 갑자기 500 에러를 내뿜어요!”

    # 단계별 진단 과정
    echo "=== 웹 서버 500 에러 트러블슈팅 ==="
    
    # 1. 웹서버 에러 로그 즉시 확인
    echo "1. 웹서버 에러 로그:"
    tail -50 /var/log/nginx/error.log
    
    # 2. 애플리케이션 로그 확인
    echo -e "n2. 애플리케이션 로그:"
    journalctl -u myapp -n 50
    
    # 3. 데이터베이스 연결 확인
    echo -e "n3. 데이터베이스 상태:"
    systemctl status mysql
    journalctl -u mysql -n 20
    
    # 4. 시스템 리소스 확인
    echo -e "n4. 시스템 리소스:"
    free -h
    df -h | grep -v tmpfs
    
    # 5. 네트워크 연결 상태
    echo -e "n5. 네트워크 연결:"
    ss -tuln | grep :80
    ss -tuln | grep :3306

    시나리오 2: “서버가 자꾸 멈춰요!”

    # 시스템 행업/프리징 분석
    echo "=== 시스템 행업 분석 ==="
    
    # 1. 커널 메시지 확인
    dmesg | tail -50
    
    # 2. 높은 CPU 사용 프로세스
    echo -e "n2. CPU 사용률 TOP 10:"
    ps aux --sort=-%cpu | head -11
    
    # 3. 메모리 부족 이벤트
    echo -e "n3. OOM 이벤트 확인:"
    dmesg | grep -i "out of memory"
    journalctl --since today | grep -i "oom"
    
    # 4. I/O 대기 상태 프로세스
    echo -e "n4. I/O 대기 프로세스:"
    ps aux | awk '$8 ~ /D/ { print $0 }'
    
    # 5. 시스템 부하 이력
    echo -e "n5. 시스템 부하 이력:"
    sar -q 1 5

    시나리오 3: “데이터가 사라졌어요!”

    # 데이터 손실 원인 분석
    echo "=== 데이터 손실 원인 분석 ==="
    
    # 1. 파일시스템 에러 확인
    echo "1. 파일시스템 에러:"
    dmesg | grep -i "error|fail" | grep -E "(sd[a-z]|nvme|ext4|xfs)"
    
    # 2. 디스크 하드웨어 상태
    echo -e "n2. 디스크 상태:"
    smartctl -a /dev/sda | grep -E "(Health|Error)"
    
    # 3. 백업 관련 로그
    echo -e "n3. 백업 로그:"
    journalctl -u backup -n 20
    
    # 4. 사용자 활동 로그
    echo -e "n4. 최근 사용자 활동:"
    last -10
    journalctl --since today | grep sudo | grep -E "(rm|mv|delete)"
    
    # 5. 애플리케이션 데이터베이스 로그
    echo -e "n5. 데이터베이스 로그:"
    grep -i "drop|delete|truncate" /var/log/mysql/mysql.log

    마치며: 로그로 시스템과 대화하기

    핵심 원칙 정리

    1. 실시간 모니터링: journalctl -ftail -f를 습관화하세요
    2. 패턴 인식: 정상적인 로그 패턴을 먼저 익히세요
    3. 체계적 접근: 문제 발생 시 단계별로 로그를 확인하세요
    4. 자동화: 반복적인 분석 작업은 스크립트로 자동화하세요

    로그 분석가가 되기 위한 일일 습관

    # 매일 아침 실행하는 로그 체크 루틴
    #!/bin/bash
    echo "=== 오늘의 시스템 상태 $(date) ==="
    
    # 1. 어제부터 오늘까지의 에러 요약
    journalctl -p err --since yesterday --no-pager | wc -l
    
    # 2. 새로운 SSH 접속
    grep "Accepted" /var/log/secure | grep "$(date +%b %d)"
    
    # 3. 시스템 리소스 상태
    free -h | grep Mem
    df -h | grep -v tmpfs | grep -E "9[0-9]%|100%"
    
    # 4. 중요 서비스 상태
    systemctl is-active nginx mysql ssh
    
    echo "좋은 하루 되세요! 🚀"

    다음 단계

    초급자라면:

    1. journalctl -f로 실시간 로그 모니터링 연습
    2. 기본 grep 패턴으로 로그 검색 연습
    3. 주요 로그 파일 위치 암기

    중급자라면:

    1. 복잡한 awk/sed 패턴으로 로그 분석
    2. 자동화 스크립트 작성
    3. 중앙 집중식 로그 시스템 구축

    고급자라면:

    1. ELK 스택이나 Grafana와 연동
    2. 머신러닝 기반 이상 탐지
    3. 컴플라이언스 로그 관리

    기억하세요: 로그는 시스템이 우리에게 보내는 메시지입니다. 이 메시지를 잘 읽을 수 있다면, 여러분은 시스템과 진정한 대화를 나눌 수 있는 운영 전문가가 될 것입니다! 📊


    다음 포스트에서는 “Production 환경 구성도 설계법”을 통해 실제 서비스 운영 환경을 어떻게 설계하고 관리하는지 알아보겠습니다. 기대해 주세요!

  • 리눅스_기본_명령어_완전_정복

    개발자를 위한 리눅스 기본 명령어 완전 정복 (실무편)

    안녕하세요, 주니어 개발자 여러분!

    코드를 작성하고 실행하는 것만큼이나 중요한 것이 바로 그 코드가 살아 숨 쉬는 ‘서버 환경’을 이해하는 것입니다. 그리고 대부분의 서버는 리눅스(Linux) 라는 운영체제 위에서 동작하죠.

    처음 검은 화면에 흰 글씨만 깜빡이는 리눅스 터미널을 마주하면 당황스럽고 막막할 수 있습니다. 하지만 걱정 마세요! 마치 우리가 일상 언어를 배우듯, 몇 가지 필수적인 명령어만 익히면 리눅스 환경을 자유자재로 돌아다니며 원하는 작업을 수행할 수 있게 됩니다.

    오늘은 서버에 접속해서 파일을 둘러보고, 간단한 편집 작업을 하며, 시스템 상태를 확인하는 등 실무에서 매일같이 사용하는 핵심 명령어들을 모아 알려드릴게요. 이 가이드만 잘 따라오시면, 더 이상 리눅스 터미널이 두렵지 않을 겁니다!

    1. 탐색과 이동: 서버 안을 자유롭게 돌아다니기

    가장 먼저 배울 것은 파일과 디렉토리(폴더)를 보고, 원하는 위치로 이동하는 방법입니다.

    ls: 현재 위치에 무엇이 있는지 확인하기

    ls (list)는 현재 디렉토리에 있는 파일과 다른 디렉토리들의 목록을 보여줍니다.

    • ls: 가장 기본적인 형태.
    • ls -l: 파일의 상세 정보(권한, 소유자, 크기, 수정 시간 등)를 긴(long) 형식으로 보여줍니다. (가장 많이 사용!)
    • ls -a: 숨김 파일(이름이 .으로 시작하는 파일)까지 모두(all) 보여줍니다.
    • ls -F: 파일의 종류를 표시해 줍니다 (디렉토리는 /, 실행 파일은 *).

    cd: 원하는 곳으로 이동하기

    cd (change directory)는 다른 디렉토리로 이동하는 명령어입니다.

    • cd [디렉토리명]: 지정한 디렉토리로 이동합니다.
    • cd ..: 현재 위치의 바로 위, 즉 상위 디렉토리로 이동합니다.
    • cd ~ 또는 cd: 나의 홈(home) 디렉토리로 바로 이동합니다.
    • cd -: 바로 이전에 있었던 디렉토리로 이동합니다.

    pwd: 현재 위치 확인하기

    pwd (print working directory)는 현재 내가 있는 디렉토리의 전체 경로를 보여줍니다. 길을 잃었을 때 유용하겠죠?

    2. 파일과 디렉토리 관리: 만들고, 복사하고, 옮기고, 지우기

    이제 파일을 직접 다뤄볼 시간입니다.

    touch: 빈 파일 만들기

    touch [파일명]은 내용이 없는 빈 파일을 생성합니다. 주로 간단한 설정 파일이나 임시 파일을 만들 때 사용합니다.

    mkdir: 새로운 디렉토리(폴더) 만들기

    mkdir (make directory)는 새로운 디렉토리를 생성합니다.

    • mkdir [디렉토리명]: 새로운 디렉토리를 만듭니다.
    • mkdir -p dir1/dir2: -p 옵션은 부모(parent) 디렉토리가 없을 경우 자동으로 함께 생성해 줍니다.

    cp: 복사하기

    cp (copy)는 파일이나 디렉토리를 복사합니다.

    • cp [원본 파일] [새 파일 이름]: 파일을 복사합니다.
    • cp -r [원본 디렉토리] [새 디렉토리 이름]: -r (recursive) 옵션은 디렉토리와 그 안의 모든 내용을 재귀적으로 복사합니다.

    mv: 이동하거나 이름 바꾸기

    mv (move)는 파일이나 디렉토리를 다른 위치로 옮기거나, 이름을 변경할 때 사용합니다.

    • mv [원본 파일] [목표 디렉토리]: 파일을 디렉토리로 이동시킵니다.
    • mv [기존 이름] [새 이름]: 파일 또는 디렉토리의 이름을 변경합니다.

    rm: 삭제하기

    rm (remove)는 파일이나 디렉토리를 삭제합니다. (주의! 리눅스에는 휴지통이 없습니다. 삭제하면 영원히 사라집니다!)

    • rm [파일명]: 파일을 삭제합니다.
    • rm -f [파일명]: -f (force) 옵션은 묻지 않고 강제로 삭제합니다.
    • rm -r [디렉토리명]: 디렉토리와 그 안의 모든 내용을 재귀적으로 삭제합니다.

    3. 파일 내용 확인: 열어보지 않고 엿보기

    cat: 파일 내용 전체 출력하기

    cat (concatenate)은 파일의 내용을 터미널에 쭉 출력합니다. 짧은 설정 파일을 확인할 때 유용합니다.

    head & tail: 파일의 앞/뒤 부분만 보기

    • head [파일명]: 파일의 첫 10줄을 보여줍니다.
    • tail [파일명]: 파일의 마지막 10줄을 보여줍니다.
    • tail -f [로그 파일명]: -f (follow) 옵션은 파일에 새로운 내용이 추가될 때마다 실시간으로 보여줍니다. (실시간 로그 확인할 때 필수!)

    less: 파일 내용 스크롤하며 보기

    less [파일명]은 긴 파일의 내용을 위아래로 스크롤하며 편하게 볼 수 있게 해줍니다. cat으로 보기엔 너무 긴 파일에 사용하세요. (나갈 때는 q를 누르세요.)

    4. 강력한 도구들: 리눅스 활용도 200% 높이기

    grep: 원하는 텍스트만 찾아내기

    grep은 파일 안에서 특정 텍스트 패턴을 포함한 줄만 찾아 출력해주는 강력한 검색 도구입니다.

    • grep "찾을 단어" [파일명]: 파일에서 ‘찾을 단어’가 포함된 모든 줄을 보여줍니다.
    • ps -ef | grep "nginx": | (파이프라인) 기호와 함께 사용하면, 다른 명령어의 출력 결과 중에서 원하는 내용만 필터링할 수 있습니다. 위 예시는 현재 실행 중인 프로세스 목록에서 ‘nginx’라는 단어가 포함된 줄만 보여줍니다.

    > & >>: 명령어 결과 저장하기 (Redirection)

    • 명령어 > 파일명: 명령어의 실행 결과를 파일에 덮어씁니다.
    • 명령어 >> 파일명: 명령어의 실행 결과를 파일의 맨 뒤에 추가합니다.

    마치며

    오늘 배운 명령어들은 리눅스 세계로 들어가는 첫걸음입니다. 처음에는 손에 익지 않아 어색하겠지만, 서버에 자주 접속해서 이것저것 만져보며 연습하는 것이 가장 좋은 학습 방법입니다.

    이 명령어들을 자유자재로 사용할 수 있게 되면, 서버 로그를 분석해 에러 원인을 찾고, 배포 스크립트를 작성하며, 시스템을 모니터링하는 등 개발자로서 한 단계 더 성장한 자신을 발견하게 될 것입니다.

    두려워하지 말고, 지금 바로 여러분의 리눅스 터미널을 열어보세요!

  • 리눅스 실전 운영 가이드: 주니어 개발자를 위한 서버 관리 완전정복

    안녕하세요, 성장하는 개발자 여러분!

    “개발만 하면 되는 거 아니야?”라고 생각했던 시절이 있었습니다. 하지만 실무에 발을 들이면서 깨달은 것은, 훌륭한 개발자가 되기 위해서는 내가 만든 코드가 실제로 어떤 환경에서 돌아가는지 이해하는 것이 필수라는 사실이었습니다.

    대부분의 서버는 리눅스 환경에서 동작합니다. 서버에 배포할 때, 로그를 확인할 때, 성능 이슈를 해결할 때… 모든 순간에 리눅스 지식이 필요하죠. 오늘은 제가 실무에서 겪은 시행착오를 바탕으로, 실제로 써먹을 수 있는 리눅스 운영 노하우를 정리해 드리겠습니다.

    1. 사용자 및 권한 관리: 서버 보안의 첫걸음

    왜 사용자 관리가 중요한가?

    서버에는 여러 개발자가 접근하고, 각각 다른 권한이 필요합니다. 신입 개발자에게 root 권한을 주는 것은 위험하고, 반대로 필요한 권한이 없으면 작업을 할 수 없죠.

    실전 사용자 관리

    # 새로운 사용자 생성
    sudo useradd -m -s /bin/bash newdev
    # -m: 홈 디렉토리 생성
    # -s: 기본 쉘 설정
    
    # 비밀번호 설정
    sudo passwd newdev
    
    # 사용자를 특정 그룹에 추가 (예: docker 그룹)
    sudo usermod -aG docker newdev
    
    # 사용자 정보 확인
    id newdev

    sudo 권한 설정

    # visudo 명령으로 안전하게 sudoers 파일 편집
    sudo visudo
    
    # 특정 사용자에게 sudo 권한 부여
    newdev ALL=(ALL) NOPASSWD: /usr/bin/systemctl, /usr/bin/docker

    실무 팁: NOPASSWD를 사용할 때는 특정 명령어만 지정하세요. 모든 명령어에 적용하면 보안상 위험합니다.

    2. 패키지 관리: 소프트웨어 설치와 업데이트

    YUM으로 패키지 관리하기

    # 패키지 검색
    yum search nginx
    
    # 패키지 정보 확인
    yum info nginx
    
    # 패키지 설치
    sudo yum install -y nginx
    
    # 설치된 패키지 목록
    yum list installed
    
    # 업데이트 가능한 패키지 확인
    yum list updates
    
    # 시스템 전체 업데이트
    sudo yum update

    실무에서 자주 사용하는 패키지들

    # 개발 필수 도구들
    sudo yum groupinstall -y "Development Tools"
    sudo yum install -y git vim htop curl wget
    
    # Node.js 설치 (NodeSource repository 사용)
    curl -sL https://rpm.nodesource.com/setup_18.x | sudo bash -
    sudo yum install -y nodejs
    
    # Docker 설치
    sudo yum install -y yum-utils
    sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
    sudo yum install -y docker-ce docker-ce-cli containerd.io

    3. 로그 관리: 문제 해결의 핵심

    로그 파일 위치 이해하기

    # 시스템 전반적인 로그
    /var/log/messages
    
    # 보안 관련 로그 (ssh 접속, sudo 사용 등)
    /var/log/secure
    
    # 웹 서버 로그 (Apache/Nginx)
    /var/log/httpd/  # Apache
    /var/log/nginx/  # Nginx
    
    # 애플리케이션별 로그
    /var/log/[application_name]/

    실시간 로그 모니터링

    # 실시간 로그 확인 (가장 많이 사용!)
    tail -f /var/log/messages
    
    # 특정 패턴 검색하며 실시간 확인
    tail -f /var/log/secure | grep "Failed password"
    
    # 여러 로그 파일 동시 모니터링
    multitail /var/log/messages /var/log/secure

    journalctl로 systemd 로그 확인

    # 전체 시스템 로그 확인
    journalctl
    
    # 특정 서비스 로그만 확인
    journalctl -u nginx
    
    # 실시간 로그 확인
    journalctl -f
    
    # 오늘 발생한 에러만 확인
    journalctl --since today --priority err
    
    # 특정 시간 범위의 로그
    journalctl --since "2025-01-01 00:00:00" --until "2025-01-01 23:59:59"

    실무 팁: 로그 확인은 문제 해결의 80%입니다. 에러가 발생하면 무조건 로그부터 확인하세요!

    4. 원격 접속 및 보안: SSH 마스터하기

    SSH 키 기반 인증 설정

    # 1. 클라이언트에서 키 생성
    ssh-keygen -t rsa -b 4096 -C "your.email@company.com"
    
    # 2. 공개키를 서버에 복사
    ssh-copy-id user@server-ip
    
    # 3. 이제 비밀번호 없이 접속 가능
    ssh user@server-ip

    SSH 설정 최적화

    # /etc/ssh/sshd_config 편집
    sudo vim /etc/ssh/sshd_config
    
    # 보안 강화 설정
    Port 2222                    # 기본 포트 변경
    PermitRootLogin no           # root 직접 로그인 금지
    PasswordAuthentication no    # 키 기반 인증만 허용
    MaxAuthTries 3              # 인증 시도 횟수 제한
    
    # 설정 적용
    sudo systemctl restart sshd

    원격 파일 전송

    # scp로 파일 전송
    scp localfile.txt user@server:/home/user/
    scp -r local_directory/ user@server:/home/user/
    
    # rsync로 동기화 (더 효율적!)
    rsync -avz --progress local_directory/ user@server:/home/user/remote_directory/

    5. 방화벽 관리: 서버 보안 강화

    firewalld 기본 사용법

    # 방화벽 상태 확인
    sudo firewall-cmd --state
    
    # 현재 설정 확인
    sudo firewall-cmd --list-all
    
    # HTTP/HTTPS 허용
    sudo firewall-cmd --permanent --add-service=http
    sudo firewall-cmd --permanent --add-service=https
    
    # 특정 포트 허용
    sudo firewall-cmd --permanent --add-port=3000/tcp
    
    # 특정 IP만 SSH 접근 허용
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" service name="ssh" accept'
    
    # 설정 적용
    sudo firewall-cmd --reload

    실무 보안 설정 예시

    # 개발 서버 기본 설정
    sudo firewall-cmd --permanent --add-service=ssh
    sudo firewall-cmd --permanent --add-service=http
    sudo firewall-cmd --permanent --add-service=https
    sudo firewall-cmd --permanent --add-port=3000/tcp  # Node.js 개발 서버
    sudo firewall-cmd --permanent --add-port=8080/tcp  # 톰캣 등
    
    # 데이터베이스는 특정 서버에서만 접근
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.1.0/24" port protocol="tcp" port="3306" accept'
    
    sudo firewall-cmd --reload

    6. 시스템 모니터링: 성능 문제 미리 발견하기

    실시간 시스템 상태 확인

    # CPU, 메모리, 프로세스 확인
    htop
    
    # 디스크 사용량 확인
    df -h
    
    # 실시간 디스크 I/O 모니터링
    iotop
    
    # 네트워크 연결 상태
    netstat -tulpn
    ss -tulpn  # 더 빠른 대안
    
    # 현재 로그인 사용자
    who
    w

    성능 문제 진단

    # CPU 사용률이 높은 프로세스 찾기
    ps aux --sort=-%cpu | head -10
    
    # 메모리 사용률이 높은 프로세스
    ps aux --sort=-%mem | head -10
    
    # 특정 프로세스의 자세한 정보
    ps -f -p 프로세스ID
    
    # 시스템 리소스 사용량 히스토리
    sar -u 1 10  # CPU 사용률을 1초마다 10번 측정

    7. 자동화와 스케줄링: 반복 작업 효율화

    cron을 이용한 작업 스케줄링

    # crontab 편집
    crontab -e
    
    # 예시: 매일 새벽 2시에 로그 정리
    0 2 * * * /usr/local/bin/cleanup_logs.sh
    
    # 예시: 매 5분마다 애플리케이션 상태 확인
    */5 * * * * /usr/local/bin/health_check.sh
    
    # 등록된 cron 작업 확인
    crontab -l

    시스템 백업 스크립트 예시

    #!/bin/bash
    # /usr/local/bin/backup_db.sh
    
    DATE=$(date +%Y%m%d_%H%M%S)
    BACKUP_DIR="/backup/database"
    DB_NAME="production_db"
    
    # 데이터베이스 백업
    mysqldump -u backup_user -p$DB_PASSWORD $DB_NAME > $BACKUP_DIR/db_backup_$DATE.sql
    
    # 7일 이상 된 백업 파일 삭제
    find $BACKUP_DIR -name "db_backup_*.sql" -mtime +7 -delete
    
    echo "Backup completed: $DATE" >> /var/log/backup.log

    마치며: 리눅스 운영의 핵심은 ‘경험’

    리눅스 서버 운영은 이론보다는 실전 경험이 중요합니다. 오늘 소개한 내용들을 하나씩 직접 테스트해보세요. VM이나 클라우드 인스턴스에서 연습하다 보면, 어느새 리눅스가 친숙해져 있을 겁니다.

    실무에서 기억해야 할 황금률들:

    1. 로그는 모든 문제 해결의 시작점입니다
    2. 백업 없이는 그 어떤 작업도 하지 마세요
    3. 보안은 편의성과 항상 트레이드오프 관계입니다
    4. 자동화할 수 있는 건 최대한 자동화하세요
    5. 문제가 생기면 당황하지 말고 차근차근 로그를 확인하세요

    서버 운영 능력은 하루아침에 늘지 않지만, 꾸준히 쌓아가다 보면 분명 더 나은 개발자로 성장할 수 있을 것입니다. 여러분의 리눅스 여정을 응원합니다! 🚀

  • 리눅스 파일 시스템과 스왑 메모리 완전 정복: 서버 성능 최적화의 핵심

    안녕하세요, 성장하는 개발자 여러분!

    개발을 하다 보면 “디스크 용량이 부족해요”, “메모리가 부족하다고 나오는데요”, “파일이 갑자기 사라졌어요” 같은 말을 자주 듣게 됩니다. 이런 문제들은 모두 파일 시스템메모리 관리에 대한 이해 부족에서 비롯됩니다.

    특히 서버를 운영하게 되면, 파일 시스템의 구조를 이해하고 스왑 메모리를 적절히 설정하는 것은 선택이 아닌 필수입니다. 오늘은 제가 실무에서 겪은 경험을 바탕으로, 리눅스 파일 시스템과 스왑 메모리를 완전히 정복해 보겠습니다!

    1. 리눅스 파일 시스템의 세계: 모든 것은 파일이다

    파일 시스템의 종류와 특징

    리눅스는 “모든 것은 파일이다”라는 철학을 가지고 있습니다. 하드웨어 정보도, 프로세스 정보도 모두 파일로 관리하죠. 이런 파일들을 효율적으로 저장하고 관리하기 위해 다양한 파일 시스템이 존재합니다.

    🗄️ 디스크 기반 파일 시스템

    EXT4 (Fourth Extended Filesystem)

    • 현재 가장 널리 사용되는 파일 시스템
    • 최대 16TB 파일, 1EB 파일 시스템 지원
    • 저널링 기능으로 시스템 크래시 시 데이터 복구 가능
    # EXT4 파일 시스템 생성
    sudo mkfs.ext4 /dev/sdb1
    
    # 파일 시스템 정보 확인
    sudo tune2fs -l /dev/sdb1

    XFS (X File System)

    • 대용량 파일과 파일 시스템에 최적화
    • B+트리 구조로 빠른 파일 검색
    • RHEL/CentOS 7부터 기본 파일 시스템
    # XFS 파일 시스템 생성
    sudo mkfs.xfs /dev/sdb1
    
    # XFS 정보 확인
    xfs_info /mount/point

    💾 메모리 기반 파일 시스템 (Pseudo File System)

    tmpfs (Temporary File System)

    # 메모리에 임시 파일 시스템 마운트
    sudo mount -t tmpfs -o size=1G tmpfs /tmp/ramdisk
    
    # 임시 파일 시스템 확인
    df -h | grep tmpfs

    procfs & sysfs

    # 현재 실행 중인 프로세스 정보
    cat /proc/cpuinfo
    cat /proc/meminfo
    
    # 시스템 하드웨어 정보
    ls /sys/class/

    실무에서 파일 시스템 관리하기

    파일 시스템 생성과 마운트

    # 1. 사용 가능한 디스크 확인
    lsblk
    fdisk -l
    
    # 2. 파티션 생성 (예: /dev/sdb에 새 파티션 생성)
    sudo fdisk /dev/sdb
    # n (new partition) -> p (primary) -> 1 -> Enter -> Enter -> w (write)
    
    # 3. 파일 시스템 생성
    sudo mkfs.ext4 /dev/sdb1
    
    # 4. 마운트 포인트 생성
    sudo mkdir /data
    
    # 5. 임시 마운트
    sudo mount /dev/sdb1 /data
    
    # 6. 영구 마운트를 위한 fstab 등록
    echo "/dev/sdb1 /data ext4 defaults 0 2" | sudo tee -a /etc/fstab
    
    # 7. fstab 테스트
    sudo mount -a

    파일 시스템 상태 모니터링

    # 디스크 사용량 확인
    df -h
    
    # inode 사용량 확인 (중요!)
    df -i
    
    # 디스크 I/O 모니터링
    iostat -x 1
    
    # 특정 디렉토리 크기 확인
    du -sh /var/log/*

    실무 팁: inode가 부족하면 디스크 용량이 남아있어도 파일을 생성할 수 없습니다!

    2. 스왑 메모리: 가상 메모리의 핵심

    스왑 메모리란?

    스왑 메모리는 물리 RAM이 부족할 때 디스크의 일부를 메모리처럼 사용하는 기술입니다.

    전체 가상 메모리 = 물리 RAM + 스왑 공간

    스왑의 동작 원리

    • 페이지 아웃(Page Out): 사용 빈도가 낮은 메모리 페이지를 스왑 영역으로 이동
    • 페이지 인(Page In): 스왑 영역의 데이터를 다시 물리 메모리로 가져옴

    실전 스왑 관리

    현재 스왑 상태 확인

    # 스왑 사용량 확인
    free -h
    swapon -s
    
    # 더 자세한 메모리 정보
    cat /proc/meminfo | grep -i swap

    스왑 파일 생성하기

    # 1. 2GB 스왑 파일 생성
    sudo dd if=/dev/zero of=/swapfile bs=1G count=2
    
    # 2. 파일 권한 설정 (보안상 중요!)
    sudo chmod 600 /swapfile
    
    # 3. 스왑 영역 초기화
    sudo mkswap /swapfile
    
    # 4. 스왑 활성화
    sudo swapon /swapfile
    
    # 5. 영구 설정을 위한 fstab 등록
    echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstab

    스왑 파티션 생성하기

    # 1. 파티션 생성 (fdisk 사용)
    sudo fdisk /dev/sdb
    # n -> p -> 2 -> Enter -> Enter -> t -> 2 -> 82 -> w
    
    # 2. 스왑 파티션 초기화
    sudo mkswap /dev/sdb2
    
    # 3. 스왑 활성화
    sudo swapon /dev/sdb2
    
    # 4. fstab에 등록
    echo "/dev/sdb2 none swap sw 0 0" | sudo tee -a /etc/fstab

    스왑 성능 최적화

    Swappiness 조정

    # 현재 swappiness 값 확인 (기본값: 60)
    cat /proc/sys/vm/swappiness
    
    # 임시로 swappiness 변경 (값이 낮을수록 스왑 사용을 적게 함)
    sudo sysctl vm.swappiness=10
    
    # 영구 설정
    echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf

    실무 가이드라인:

    • 서버용: swappiness 1-10 (메모리 우선 사용)
    • 데스크톱용: swappiness 10-20
    • 기본값: 60

    스왑 우선순위 설정

    # 우선순위와 함께 스왑 활성화
    sudo swapon -p 1 /swapfile        # 높은 우선순위
    sudo swapon -p 0 /dev/sdb2        # 낮은 우선순위
    
    # fstab에서 우선순위 설정
    /swapfile none swap sw,pri=1 0 0
    /dev/sdb2 none swap sw,pri=0 0 0

    3. 실무에서 마주치는 문제와 해결책

    문제 1: “디스크 용량은 있는데 파일을 만들 수 없어요”

    # inode 사용량 확인
    df -i
    
    # 해결: inode가 부족한 경우
    # 방법 1: 불필요한 파일 삭제
    find /var/log -name "*.log" -mtime +30 -delete
    
    # 방법 2: 파일 시스템 재생성 (데이터 백업 후)
    sudo mkfs.ext4 -N 200000 /dev/sdb1  # inode 수 증가

    문제 2: “시스템이 느려져요”

    # 스왑 사용량 확인
    free -h
    
    # I/O 대기 시간 확인
    iostat -x 1
    
    # 해결책
    # 1. 메모리 증설
    # 2. 스왑을 SSD로 이동
    # 3. swappiness 값 조정

    문제 3: “파일 시스템 마운트가 안 돼요”

    # 파일 시스템 체크
    sudo fsck /dev/sdb1
    
    # 강제 체크 (읽기 전용 모드)
    sudo fsck -f -r /dev/sdb1
    
    # 자동 복구 시도
    sudo fsck -y /dev/sdb1

    4. 자동화 스크립트: 시스템 모니터링

    디스크 사용량 모니터링 스크립트

    #!/bin/bash
    # disk_monitor.sh
    
    THRESHOLD=80
    
    df -h | awk '
    NR>1 {
        gsub(/%/, "", $5)
        if ($5 > threshold) {
            print "경고: " $6 " 파티션이 " $5 "% 사용 중입니다!"
            system("logger 디스크 사용량 경고: " $6 " " $5 "%")
        }
    }' threshold=$THRESHOLD
    
    # inode 사용량도 체크
    df -i | awk '
    NR>1 {
        gsub(/%/, "", $5)
        if ($5 > 80) {
            print "경고: " $6 " 파티션의 inode가 " $5 "% 사용 중입니다!"
        }
    }'

    메모리 사용량 모니터링

    #!/bin/bash
    # memory_monitor.sh
    
    TOTAL_MEM=$(free | awk '/^Mem:/ {print $2}')
    USED_MEM=$(free | awk '/^Mem:/ {print $3}')
    SWAP_USED=$(free | awk '/^Swap:/ {print $3}')
    
    MEM_USAGE=$((USED_MEM * 100 / TOTAL_MEM))
    
    if [ $MEM_USAGE -gt 90 ]; then
        echo "메모리 사용량이 ${MEM_USAGE}%입니다!"
    
        # 메모리 사용량이 높은 프로세스 출력
        echo "Top 5 메모리 사용 프로세스:"
        ps aux --sort=-%mem | head -6
    fi
    
    if [ $SWAP_USED -gt 0 ]; then
        echo "스왑이 사용되고 있습니다: $(($SWAP_USED / 1024))MB"
    fi

    Cron으로 자동 모니터링 설정

    # crontab 편집
    crontab -e
    
    # 5분마다 디스크 사용량 체크
    */5 * * * * /usr/local/bin/disk_monitor.sh
    
    # 10분마다 메모리 사용량 체크
    */10 * * * * /usr/local/bin/memory_monitor.sh
    
    # 매일 새벽 3시에 로그 정리
    0 3 * * * find /var/log -name "*.log" -mtime +7 -delete

    마치며: 안정적인 시스템 운영을 위한 체크리스트

    일일 점검 사항

    • [ ] 디스크 사용량 확인 (df -h)
    • [ ] inode 사용량 확인 (df -i)
    • [ ] 메모리 사용량 확인 (free -h)
    • [ ] 스왑 사용량 확인 (swapon -s)

    주간 점검 사항

    • [ ] 파일 시스템 무결성 검사 (fsck)
    • [ ] 로그 파일 정리
    • [ ] 불필요한 파일 삭제
    • [ ] 시스템 성능 지표 분석

    비상 상황 대응

    • [ ] 백업 스크립트 작동 확인
    • [ ] 응급 복구 절차 숙지
    • [ ] 연락망 및 에스컬레이션 프로세스 준비

    파일 시스템과 스왑 메모리 관리는 서버 안정성의 기초입니다. 오늘 배운 내용들을 실제 환경에서 차근차근 실습해 보시고, 모니터링 스크립트를 활용해서 proactive한 시스템 관리자가 되시길 바랍니다!

    기억하세요: 예방이 최고의 해결책입니다. 🛡️

  • 방화벽과 OpenSSH로 서버 보안 강화하기: 실무에서 바로 쓰는 완벽 가이드

    안녕하세요, 성장하는 개발자 여러분!

    “서버 보안”이라고 하면 뭔가 복잡하고 어려운 것처럼 느껴지시나요? 하지만 실제로는 몇 가지 핵심 원칙만 제대로 지키면 90%의 공격을 막을 수 있습니다. 오늘은 가장 기본이면서도 강력한 두 가지 보안 도구인 방화벽과 OpenSSH를 활용해 서버를 안전하게 지키는 방법을 알려드리겠습니다.

    실무에서 제가 직접 겪었던 보안 사고들과 그 해결 과정을 통해 배운 실전 노하우를 함께 공유하니, 끝까지 집중해서 읽어보시길 바랍니다! 🔒

    1. 서버 보안의 기본 원칙: 최소 권한과 다층 방어

    보안의 황금률

    1. 최소 권한 원칙: 꼭 필요한 것만 열어두기
    2. 다층 방어: 하나의 보안 장치에 의존하지 않기
    3. 지속적인 모니터링: 로그를 통한 이상 징후 감지
    4. 정기적인 업데이트: 보안 패치는 최우선

    실무에서 자주 발생하는 보안 위협들

    # 실제 공격 시도 로그 예시
    grep "Failed password" /var/log/secure | tail -5
    # Jan 15 14:32:11 server sshd[1234]: Failed password for root from 192.168.1.100 port 22
    # Jan 15 14:32:13 server sshd[1235]: Failed password for admin from 192.168.1.100 port 22
    # Jan 15 14:32:15 server sshd[1236]: Failed password for user from 192.168.1.100 port 22
    
    # 의심스러운 접속 시도 확인
    journalctl -u sshd | grep "authentication failure" | tail -10

    이런 로그들이 보이시나요? 이미 여러분의 서버가 공격받고 있을 수 있습니다!

    2. Firewalld: 현대적인 방화벽 관리의 핵심

    Firewalld vs iptables: 왜 Firewalld를 써야 할까?

    Firewalld의 장점:

    • 동적 설정 변경: 서비스 재시작 없이 즉시 적용
    • Zone 기반 관리: 네트워크 환경별 정책 분리
    • GUI 지원: 명령어뿐만 아니라 그래픽 도구도 제공
    • XML 설정: 사람이 읽기 쉬운 설정 파일

    기본 설정과 상태 확인

    # 1. Firewalld 상태 확인
    sudo systemctl status firewalld
    sudo firewall-cmd --state
    
    # 2. 현재 설정 확인
    sudo firewall-cmd --list-all
    
    # 3. 활성 영역(Zone) 확인
    sudo firewall-cmd --get-active-zones
    
    # 4. 기본 영역 확인
    sudo firewall-cmd --get-default-zone

    Zone 개념 이해하기

    Firewalld의 가장 강력한 기능 중 하나가 Zone입니다:

    # 사용 가능한 모든 Zone 확인
    sudo firewall-cmd --get-zones
    # block dmz drop external home internal public trusted work
    
    # 각 Zone의 특성
    # - drop: 모든 들어오는 패킷 차단 (가장 엄격)
    # - block: 들어오는 패킷 거부 응답
    # - public: 기본 Zone, SSH와 DHCP 클라이언트만 허용
    # - external: 외부 네트워크용, NAT 환경에서 사용
    # - internal: 내부 네트워크용, 더 많은 서비스 허용
    # - home: 홈 네트워크용, 파일 공유 등 허용
    # - work: 직장 네트워크용
    # - trusted: 모든 패킷 허용 (가장 관대)

    실무 시나리오별 방화벽 설정

    시나리오 1: 웹 서버 보안 설정

    # 기본 Zone을 public으로 설정 (이미 기본값)
    sudo firewall-cmd --set-default-zone=public
    
    # HTTP/HTTPS 서비스 영구 허용
    sudo firewall-cmd --permanent --add-service=http
    sudo firewall-cmd --permanent --add-service=https
    
    # 커스텀 포트 허용 (예: 8080)
    sudo firewall-cmd --permanent --add-port=8080/tcp
    
    # 설정 적용
    sudo firewall-cmd --reload
    
    # 확인
    sudo firewall-cmd --list-services
    sudo firewall-cmd --list-ports

    시나리오 2: 데이터베이스 서버 보안 강화

    # 특정 IP에서만 MySQL 접근 허용
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="3306" accept'
    
    # 특정 서버에서만 PostgreSQL 접근 허용
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="5432" accept'
    
    # 모든 외부 접근 차단하고 내부 네트워크만 허용
    sudo firewall-cmd --permanent --zone=internal --add-source=192.168.1.0/24
    sudo firewall-cmd --permanent --zone=internal --add-service=mysql
    sudo firewall-cmd --permanent --zone=internal --add-service=postgresql
    
    sudo firewall-cmd --reload

    시나리오 3: 개발 서버 임시 포트 열기

    # 임시로 포트 열기 (재부팅 시 삭제됨)
    sudo firewall-cmd --add-port=3000/tcp
    sudo firewall-cmd --add-port=8080/tcp
    
    # 확인
    sudo firewall-cmd --list-ports
    
    # 영구 설정으로 변경 (필요한 경우)
    sudo firewall-cmd --runtime-to-permanent

    Rich Rules: 고급 방화벽 정책

    # 1. 특정 시간대에만 SSH 접근 허용 (고급 설정)
    # 평일 9시-18시에만 특정 IP에서 SSH 접근 허용
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" service name="ssh" log prefix="SSH Access: " level="info" limit value="3/m" accept'
    
    # 2. 무차별 대입 공격 방지
    # 동일 IP에서 5번 이상 실패 시 10분간 차단
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" log prefix="SSH Brute Force: " level="warning" limit value="5/m" drop'
    
    # 3. 포트 스캔 감지 및 차단
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port port="22" protocol="tcp" log prefix="SSH Scan: " level="warning" limit value="1/m" accept'

    방화벽 로그 모니터링

    # 방화벽 로그 실시간 모니터링
    sudo journalctl -u firewalld -f
    
    # 특정 키워드로 로그 필터링
    sudo journalctl -u firewalld | grep "SSH"
    sudo journalctl -u firewalld | grep "DROP"
    
    # 로그 분석 스크립트
    #!/bin/bash
    echo "=== 오늘의 방화벽 로그 요약 ==="
    echo "총 차단된 연결 수:"
    sudo journalctl -u firewalld --since today | grep -c "DROP"
    echo "SSH 접근 시도:"
    sudo journalctl -u firewalld --since today | grep -c "SSH"
    echo "가장 많이 시도한 IP:"
    sudo journalctl -u firewalld --since today | grep -oP 'from K[0-9.]+' | sort | uniq -c | sort -nr | head -5

    3. OpenSSH: 안전한 원격 접속의 모든 것

    SSH 기본 보안 강화

    1. SSH 설정 파일 최적화

    # SSH 설정 파일 백업
    sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup
    
    # 주요 보안 설정
    sudo nano /etc/ssh/sshd_config

    필수 보안 설정들:

    # /etc/ssh/sshd_config 권장 설정
    
    # 1. 기본 포트 변경 (선택사항)
    Port 2222
    
    # 2. Root 로그인 완전 차단
    PermitRootLogin no
    
    # 3. 패스워드 로그인 비활성화 (키 인증만 허용)
    PasswordAuthentication no
    ChallengeResponseAuthentication no
    UsePAM no
    
    # 4. 빈 패스워드 금지
    PermitEmptyPasswords no
    
    # 5. X11 포워딩 비활성화 (필요없는 경우)
    X11Forwarding no
    
    # 6. 로그인 시간 제한
    LoginGraceTime 30
    
    # 7. 최대 동시 세션 제한
    MaxSessions 3
    
    # 8. 특정 사용자만 SSH 접근 허용
    AllowUsers developer admin
    
    # 9. 특정 그룹만 SSH 접근 허용
    AllowGroups ssh-users
    
    # 10. 연결 유지 설정
    ClientAliveInterval 300
    ClientAliveCountMax 2

    설정 후 서비스 재시작:

    # 설정 파일 문법 검사
    sudo sshd -t
    
    # SSH 서비스 재시작
    sudo systemctl restart sshd
    
    # 상태 확인
    sudo systemctl status sshd

    SSH 키 기반 인증: 패스워드보다 1000배 안전한 방법

    1. SSH 키 쌍 생성

    # RSA 키 생성 (4096비트, 더 안전)
    ssh-keygen -t rsa -b 4096 -C "your-email@domain.com"
    
    # 또는 더 최신의 Ed25519 키 (권장)
    ssh-keygen -t ed25519 -C "your-email@domain.com"
    
    # 키 생성 시 옵션들
    # -t: 키 타입 (rsa, ed25519)
    # -b: 키 비트 수
    # -C: 코멘트 (보통 이메일)
    # -f: 키 파일 이름 지정

    2. 공개키 서버에 복사

    # 자동으로 공개키 복사
    ssh-copy-id username@server-ip
    
    # 커스텀 포트 사용 시
    ssh-copy-id -p 2222 username@server-ip
    
    # 특정 키 파일 지정
    ssh-copy-id -i ~/.ssh/custom_key.pub username@server-ip
    
    # 수동으로 복사 (ssh-copy-id 사용 불가 시)
    cat ~/.ssh/id_rsa.pub | ssh username@server-ip "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

    3. SSH 키 관리 및 보안

    # 키 권한 설정 (매우 중요!)
    chmod 700 ~/.ssh
    chmod 600 ~/.ssh/id_rsa
    chmod 644 ~/.ssh/id_rsa.pub
    chmod 600 ~/.ssh/authorized_keys
    
    # 여러 키 관리를 위한 SSH config 설정
    nano ~/.ssh/config

    SSH Config 예시:

    # ~/.ssh/config
    Host prod-server
        HostName 192.168.1.100
        Port 2222
        User developer
        IdentityFile ~/.ssh/prod_server_key
    
    Host dev-server
        HostName 192.168.1.200
        Port 22
        User admin
        IdentityFile ~/.ssh/dev_server_key
    
    Host git-server
        HostName github.com
        User git
        IdentityFile ~/.ssh/github_key
    
    # 모든 서버에 대한 기본 설정
    Host *
        ServerAliveInterval 60
        ServerAliveCountMax 3
        StrictHostKeyChecking ask
        UserKnownHostsFile ~/.ssh/known_hosts

    사용법:

    # 간단하게 접속
    ssh prod-server
    ssh dev-server
    
    # 파일 복사도 편리하게
    scp myfile.txt prod-server:~/

    SSH 터널링: 안전한 포트 포워딩

    로컬 포트 포워딩

    # 원격 서버의 MySQL을 로컬에서 접근
    ssh -L 3306:localhost:3306 username@server-ip
    
    # 원격 서버의 웹 애플리케이션을 로컬에서 접근
    ssh -L 8080:localhost:80 username@server-ip
    
    # 백그라운드 실행
    ssh -f -N -L 3306:localhost:3306 username@server-ip

    리모트 포트 포워딩

    # 로컬의 서비스를 원격에서 접근 가능하게 (주의 필요)
    ssh -R 8080:localhost:3000 username@server-ip
    
    # 백그라운드 실행
    ssh -f -N -R 8080:localhost:3000 username@server-ip

    SOCKS 프록시

    # SOCKS 프록시 생성
    ssh -D 1080 username@server-ip
    
    # 브라우저에서 localhost:1080을 SOCKS 프록시로 설정하면
    # 모든 트래픽이 서버를 통해 전송됨

    4. 실전 보안 모니터링과 자동화

    SSH 접속 로그 분석

    # 성공한 SSH 로그인 확인
    sudo grep "Accepted" /var/log/secure
    
    # 실패한 SSH 로그인 확인
    sudo grep "Failed password" /var/log/secure
    
    # 특정 IP의 접속 시도 분석
    sudo grep "192.168.1.100" /var/log/secure
    
    # 오늘의 SSH 활동 요약
    sudo journalctl -u sshd --since today | grep -E "(Accepted|Failed)"

    자동 보안 모니터링 스크립트

    #!/bin/bash
    # ssh_monitor.sh - SSH 보안 모니터링 스크립트
    
    LOG_FILE="/var/log/ssh_monitor.log"
    SECURE_LOG="/var/log/secure"
    ALERT_THRESHOLD=5
    
    echo "=== SSH 보안 모니터링 시작: $(date) ===" >> $LOG_FILE
    
    # 1. 실패한 로그인 시도 카운트
    FAILED_ATTEMPTS=$(grep "Failed password" $SECURE_LOG | grep "$(date +%b %d)" | wc -l)
    
    if [ $FAILED_ATTEMPTS -gt $ALERT_THRESHOLD ]; then
        echo "⚠️  경고: 오늘 $FAILED_ATTEMPTS 번의 로그인 실패가 발생했습니다!" >> $LOG_FILE
    
        # 가장 많이 시도한 IP 찾기
        TOP_ATTACKERS=$(grep "Failed password" $SECURE_LOG | grep "$(date +%b %d)" | 
                       grep -oP 'from K[0-9.]+' | sort | uniq -c | sort -nr | head -3)
    
        echo "주요 공격 IP들:" >> $LOG_FILE
        echo "$TOP_ATTACKERS" >> $LOG_FILE
    
        # 자동 차단 (선택사항)
        echo "$TOP_ATTACKERS" | while read count ip; do
            if [ $count -gt 10 ]; then
                echo "IP $ip 자동 차단 (시도 횟수: $count)" >> $LOG_FILE
                sudo firewall-cmd --add-rich-rule="rule family='ipv4' source address='$ip' drop"
            fi
        done
    fi
    
    # 2. 새로운 SSH 키 추가 감지
    AUTHORIZED_KEYS="/home/*/.ssh/authorized_keys"
    for auth_file in $AUTHORIZED_KEYS; do
        if [ -f "$auth_file" ]; then
            KEY_COUNT=$(wc -l < "$auth_file")
            echo "$(dirname $auth_file): $KEY_COUNT 개의 SSH 키" >> $LOG_FILE
        fi
    done
    
    # 3. Root 로그인 시도 감지
    ROOT_ATTEMPTS=$(grep "Failed password for root" $SECURE_LOG | grep "$(date +%b %d)" | wc -l)
    if [ $ROOT_ATTEMPTS -gt 0 ]; then
        echo "🚨 위험: Root 계정으로 $ROOT_ATTEMPTS 번의 로그인 시도가 있었습니다!" >> $LOG_FILE
    fi
    
    echo "=== 모니터링 완료: $(date) ===" >> $LOG_FILE
    echo "" >> $LOG_FILE

    Fail2Ban: 자동 침입 차단 시스템

    # Fail2Ban 설치
    sudo dnf install fail2ban -y
    sudo systemctl enable fail2ban
    sudo systemctl start fail2ban
    
    # SSH 보호 설정
    sudo nano /etc/fail2ban/jail.local
    [DEFAULT]
    # 차단 시간 (초)
    bantime = 3600
    # 관찰 시간 (초)
    findtime = 600
    # 최대 시도 횟수
    maxretry = 5

    [sshd]

    enabled = true port = ssh logpath = /var/log/secure maxretry = 3 bantime = 7200

    # Fail2Ban 재시작
    sudo systemctl restart fail2ban
    
    # 상태 확인
    sudo fail2ban-client status
    sudo fail2ban-client status sshd
    
    # 차단된 IP 확인
    sudo fail2ban-client get sshd banned
    
    # 수동으로 IP 차단/해제
    sudo fail2ban-client set sshd banip 192.168.1.100
    sudo fail2ban-client set sshd unbanip 192.168.1.100

    5. 보안 점검 체크리스트와 베스트 프랙티스

    일일 보안 점검 체크리스트

    #!/bin/bash
    # daily_security_check.sh
    
    echo "=== 일일 보안 점검 $(date) ==="
    
    # 1. 시스템 업데이트 확인
    echo "1. 시스템 업데이트 상태:"
    dnf check-update | wc -l
    
    # 2. 방화벽 상태 확인
    echo "2. 방화벽 상태:"
    sudo systemctl is-active firewalld
    
    # 3. SSH 서비스 상태 확인
    echo "3. SSH 서비스 상태:"
    sudo systemctl is-active sshd
    
    # 4. 활성 네트워크 연결 확인
    echo "4. 현재 활성 연결 (상위 10개):"
    sudo ss -tuln | head -10
    
    # 5. 마지막 로그인 확인
    echo "5. 최근 로그인 기록:"
    last -n 5
    
    # 6. 수상한 프로세스 확인
    echo "6. 높은 CPU 사용 프로세스:"
    ps aux --sort=-%cpu | head -5
    
    # 7. 디스크 사용량 확인
    echo "7. 디스크 사용량:"
    df -h | grep -v tmpfs
    
    # 8. 실패한 로그인 시도
    echo "8. 오늘의 실패한 로그인 시도:"
    sudo grep "Failed password" /var/log/secure | grep "$(date +%b %d)" | wc -l
    
    echo "=== 점검 완료 ==="

    월간 보안 리뷰 체크리스트

    • [ ] 사용자 계정 검토: 불필요한 계정 제거
    • [ ] SSH 키 정리: 사용하지 않는 키 제거
    • [ ] 방화벽 규칙 점검: 불필요한 규칙 정리
    • [ ] 로그 분석: 수상한 활동 패턴 확인
    • [ ] 보안 패치 적용: 최신 보안 업데이트
    • [ ] 백업 확인: 설정 파일 백업 상태 점검

    보안 사고 대응 절차

    1. 즉시 대응 (5분 이내)

    # 의심스러운 IP 즉시 차단
    sudo firewall-cmd --add-rich-rule="rule family='ipv4' source address='SUSPICIOUS_IP' drop"
    
    # 모든 SSH 연결 확인
    who
    w
    
    # 의심스러운 세션 강제 종료
    sudo pkill -u suspicious_user
    
    # 긴급 상황 시 SSH 포트 임시 변경
    sudo sed -i 's/Port 22/Port 2222/' /etc/ssh/sshd_config
    sudo systemctl restart sshd

    2. 조사 및 분석 (30분 이내)

    # 상세 로그 분석
    sudo grep -E "($(date +%b %d)|$(date -d yesterday +%b %d))" /var/log/secure > security_incident_$(date +%Y%m%d).log
    
    # 네트워크 연결 상태 저장
    sudo ss -tuln > network_status_$(date +%Y%m%d).log
    
    # 프로세스 상태 저장
    ps aux > process_status_$(date +%Y%m%d).log

    3. 복구 및 강화 (1시간 이내)

    # 패스워드 강제 변경
    sudo passwd username
    
    # SSH 키 교체
    ssh-keygen -t ed25519 -C "incident-response-$(date +%Y%m%d)"
    
    # 방화벽 규칙 강화
    sudo firewall-cmd --set-default-zone=drop
    sudo firewall-cmd --zone=trusted --add-source=ADMIN_IP

    마치며: 보안은 여정이지 목적지가 아닙니다

    핵심 원칙 재정리

    1. 기본을 충실히: 방화벽 + SSH 키 인증만으로도 90% 보안 확보
    2. 지속적인 모니터링: 로그 분석과 이상 징후 감지
    3. 정기적인 점검: 보안 설정과 계정 관리
    4. 빠른 대응: 사고 발생 시 신속한 차단과 분석

    실무에서 기억할 점

    • 편의성 vs 보안: 항상 트레이드오프 관계임을 인식
    • 문서화: 모든 보안 설정과 대응 절차를 문서로 남기기
    • 팀 공유: 보안 지식과 절차를 팀원들과 공유
    • 지속적인 학습: 새로운 공격 기법과 방어 방법 학습

    다음 단계

    오늘 배운 내용을 바탕으로:

    1. 테스트 서버에서 연습: 실제 운영 서버에 적용하기 전에 충분히 연습
    2. 모니터링 시스템 구축: 자동화된 보안 모니터링 환경 구성
    3. 백업 계획 수립: 보안 사고 시 빠른 복구를 위한 백업 전략
    4. 팀 내 보안 문화 조성: 개발팀 전체가 보안을 의식하는 문화 만들기

    기억하세요: 완벽한 보안은 존재하지 않습니다. 하지만 기본적인 보안 수칙을 지키는 것만으로도 대부분의 공격으로부터 서버를 안전하게 지킬 수 있습니다.

    보안은 한 번 설정하고 끝나는 것이 아니라 지속적으로 관리하고 개선해야 하는 여정입니다. 오늘부터 여러분도 이 여정에 함께해주세요! 🛡️


    다음 포스트에서는 “로그 관리와 모니터링 실전 가이드”에서 더 고급 모니터링 기법들을 다뤄보겠습니다. 기대해 주세요!