#Linux

[Linux] 보안 조치: 특정 확장자 파일 권한 일괄 변경 (find + chmod 조합)

보안 취약점 조치를 위해 특정 디렉토리 하위의 파일 권한을 일괄 변경하는 방법을 정리합니다. chmod -R로 기본 권한을 잡고, find 명령어를 이용해 설정 파일(xml, properties)이나 로그 파일의 실행 권한을 제거하여 보안을 강화합니다.

0. 배경 및 시나리오 (Context)

일반적으로 웹 애플리케이션(WAS) 디렉토리의 보안 권장 설정은 다음과 같습니다.

  • 디렉토리: 750 (소유자: rwx, 그룹: r-x, 기타: ---) - 이동(x) 가능해야 함
  • 파일: 640 (소유자: rw-, 그룹: r--, 기타: ---) - 실행(x) 권한 제거

단순히 chmod -R 750을 하면 모든 파일에 실행 권한이 붙어버리므로, 특정 확장자 파일들을 찾아 640으로 다시 변경해줘야 합니다.

Test Environment

  • OS: CentOS 7 (3.10.0-957.el7.x86_64)

1. 1단계: 소유권 및 기본 권한 설정

먼저 대상 디렉토리 하위의 모든 파일/폴더의 소유권을 맞추고, 디렉토리 기준 권한(750)을 일괄 적용합니다.

# 1. 소유권 변경 (하위 포함)
chown -R wasadm:wasadm ./*

# 2. 기본 권한 설정 (일단 모두 750으로 설정)
# 주의: 이 상태에서는 일반 텍스트 파일도 실행 권한(x)을 갖게 됨
chmod -R 750 ./*

2. 2단계: 특정 확장자 권한 강화 (실행 권한 제거)

find 명령어를 사용하여 설정 파일이나 로그 파일 등 실행될 필요가 없는 파일들을 찾아 권한을 640으로 낮춥니다.

명령어 구문

# 구문: find [경로] -name "[패턴]" -exec chmod [권한] {} \;

# XML 설정 파일
find . -name "*.xml" -exec chmod 640 {} \;

# 로그 파일
find . -name "*.log" -exec chmod 640 {} \;

# 프로퍼티 파일
find . -name "*.properties" -exec chmod 640 {} \;

# 쉘 스크립트 제외한 모든 일반 파일 (고급)
# find . -type f ! -name "*.sh" -exec chmod 640 {} \;
주의 (Quotation):
*.xml과 같이 와일드카드를 사용할 때는 반드시 따옴표(" ")로 감싸주어야 합니다. 그렇지 않으면 현재 디렉토리에 xml 파일이 많을 경우 쉘이 먼저 해석해버려 "paths must precede expression" 에러가 발생할 수 있습니다.

3. Tip: 대량 파일 처리 시 성능 최적화

파일이 수만 개 이상일 경우 -exec ... \; 방식은 파일 하나마다 프로세스를 실행하므로 느립니다. xargs를 사용하면 훨씬 빠릅니다.

# xargs를 이용한 고속 처리 방식
find . -name "*.log" -print0 | xargs -0 chmod 640

4. 검증 (Verification)

작업 완료 후 ls -l 명령어로 디렉토리와 파일의 권한이 의도한 대로 분리되었는지 확인합니다.

drwxr-x---  2 wasadm wasadm 4096 ...  logs/       (750, 디렉토리)
-rw-r-----  1 wasadm wasadm 1024 ...  server.xml  (640, 파일)
-rwxr-x---  1 wasadm wasadm  512 ...  start.sh    (750, 스크립트)
Open Stream →
#AIX

[Linux/AIX] 윈도우 파일 업로드 시 발생하는 개행 문자(^M) 제거 방법 (Perl, vi, sed)

Windows(CRLF)에서 작성한 파일을 Unix/Linux(LF) 계열 서버로 업로드하면, 라인 끝에 ^M 특수문자가 붙어 스크립트 실행 에러(bad interpreter)를 유발합니다. AIX 환경에서도 확실하게 동작하는 Perl 명령어를 이용한 일괄 제거 방법을 정리합니다.

0. 원인 및 증상 (Context)

운영체제마다 줄바꿈(New Line)을 처리하는 방식이 다릅니다.

  • Windows: CR(Carriage Return, \r) + LF(Line Feed, \n)
  • Unix/Linux/AIX: LF(\n)

FTP 전송 시 ASCII 모드가 아닌 Binary 모드로 전송하거나, 단순 복사/붙여넣기를 할 경우 Windows의 CR(\r) 문자가 그대로 남아 vi 에디터에서 ^M으로 표시됩니다.

Test Environment

  • OS: AIX (또는 Linux)
  • Shell: sh, ksh, bash

1. 문제 확인 (Issue Identification)

쉘 스크립트 실행 시 에러가 발생하거나, vi로 파일을 열었을 때 라인 끝마다 ^M이 붙어있는 것을 확인할 수 있습니다.

vi 에디터 화면

#!/bin/sh^M
#./startServer.sh server_name^M
#./stopServer.sh server_name -username username -password password^M

2. 해결 방법 A: Perl 명령어 사용 (권장)

AIX의 기본 sed 명령어는 -i(파일 직접 수정) 옵션을 지원하지 않는 경우가 많습니다. 따라서 Perl을 사용하는 것이 가장 호환성이 좋고 간편합니다.

명령어 구문

^M을 직접 입력하기 번거로우므로, 8진수 코드인 \015를 사용하는 것이 안전합니다.

# 구문: perl -pi -e 's/찾을문자/바꿀문자/g' [파일명]
perl -pi -e 's/\015//g' stopWasAll.sh

다중 파일 일괄 처리

와일드카드(*)를 사용하여 여러 파일을 한 번에 변환할 수 있습니다.

# 현재 경로의 모든 .sh 파일에서 CR 제거
perl -pi -e 's/\015//g' *.sh

3. 해결 방법 B: vi 에디터 내부 치환

파일을 열어놓은 상태에서 수정하고 싶을 때 사용합니다.

  1. vi로 파일 열기
  2. 명령 모드(ESC)에서 치환 명령어 입력
:%s/^M//g
Tip: 위 명령어의 ^MShift + 6, M을 타이핑하는 것이 아닙니다.
반드시 Ctrl + V를 누른 상태에서 Ctrl + M을 눌러야 입력됩니다.

4. 해결 방법 C: dos2unix 유틸리티

리눅스(CentOS/Ubuntu) 환경이라면 전용 도구를 설치하여 해결하는 것이 가장 쉽습니다.

# 설치 (CentOS)
yum install -y dos2unix

# 변환
dos2unix stopWasAll.sh

5. 검증 (Verification)

변환 후 다시 vi로 파일을 열어 ^M 문자가 사라졌는지 확인합니다.

test1 root [/was8/bin]# vi stopWasAll.sh

#!/bin/sh
#./startServer.sh server_name
#./stopServer.sh server_name -username username -password password
#PropFilePasswordEncoder.sh
#export LANG=en_us.utf8

깔끔하게 정리된 것을 확인할 수 있습니다.

Open Stream →
#command

[Linux] find 명령어 실무 패턴 3가지: 파일명, 수정 시간, 문자열 검색(grep) 활용

리눅스(CentOS 7) 환경에서 원하는 파일을 빠르고 정확하게 찾기 위한 find 명령어의 필수 옵션을 정리합니다. 대소문자 구분 없는 검색, 최근 변경된 파일 탐색, 그리고 xargs를 조합한 파일 내용 검색 방법을 다룹니다.

Test Environment

  • OS: CentOS 7 (3.10.0-957.el7.x86_64)
  • Shell: Bash

1. 파일명으로 검색 (By Name)

가장 기본적인 사용법입니다. -name 옵션은 정확한 이름을, -iname 옵션은 대소문자를 무시하고 검색합니다.

기본 검색

# 전체 경로(/)에서 Mem.sh 파일 찾기
find /sw -name "Mem.sh"

# 현재 디렉토리(.)에서 찾기
find . -name "Mem.sh"

대소문자 무시 검색 (Insensitive)

파일명의 대소문자가 확실하지 않을 때 유용합니다.

# Mem.sh, MEM.sh 모두 검색됨
find /sw -iname "Mem.sh"
Tip (에러 숨기기):
검색 도중 Permission denied 메시지가 너무 많이 뜬다면 명령어 뒤에 2>/dev/null을 붙여 에러 메시지를 버릴 수 있습니다.
예: find / -name "test" 2>/dev/null

2. 수정 시간으로 검색 (By Time)

장애 발생 시점이나 로그 분석 시, 특정 시간 내에 변경된 파일을 찾을 때 -mtime(Modification Time) 옵션을 사용합니다.

사용 예시

# 최근 1일(24시간) 이내에 수정된 .sh 파일 검색
find /sw -name "*.sh" -mtime -1

옵션 상세 설명

  • -mtime -n: 최근 n일 이내에 변경됨 (Today)
  • -mtime +n: n일 이전에 변경됨 (Old files)
  • -mtime n: 정확히 n일 전에 변경됨

3. 파일 내용 문자열 검색 (With Grep)

find로 찾은 파일들의 내용(Content)을 검색하고 싶을 때, 파이프(|)와 xargs를 사용하여 grep으로 넘겨줍니다.

검색 파이프라인

[파일 찾기][목록 전달][내용 검색]의 흐름입니다.

# 1일 이내 수정된 sh 파일들 중에서 "Mem"이라는 글자가 포함된 라인 출력
find /sw -name "*.sh" -mtime -1 | xargs grep "Mem"

실행 결과 해석

/sw/Mem.sh:MEMINFO=`cat /proc/meminfo...`  <-- 파일명:내용
/sw/Mem1.sh: TOTAL=`free | grep ^Mem...`
/sw/Mem1.sh: USED=`free | grep ^Mem...`

grepfind가 찾아낸 파일들을 하나씩 열어서 "Mem" 키워드가 있는지 확인하고, 해당 라인을 파일명과 함께 출력해 줍니다.


Next Step:
파일을 단순히 찾는 것을 넘어, -exec 옵션을 사용하여 검색된 파일의 권한을 일괄 변경(chmod)하거나 삭제(rm)하는 등의 고급 활용법을 익혀보세요.

Open Stream →
#command

[Linux] 파일/디렉토리 소유권(Owner/Group) 변경: chown 명령어 사용법 및 주의사항

리눅스 환경(CentOS 7)에서 파일 및 디렉토리의 소유자(User)와 그룹(Group)을 변경하는 chown 명령어 사용법을 정리합니다. 하위 경로까지 일괄 변경하는 -R 옵션과 실무 예제를 다룹니다.

0. 배경 지식 (Context)

리눅스의 모든 파일은 특정 사용자와 그룹에 속하게 됩니다. 보통 root 권한으로 설치하거나 복사한 파일은 소유권이 root로 되어 있어, 일반 애플리케이션 계정(예: wasadm, tomcat 등)에서 접근하거나 실행할 때 "Permission denied" 오류가 발생합니다. 이때 chown을 사용하여 소유권을 적절한 계정으로 넘겨주어야 합니다.

Test Environment

  • OS: CentOS 7 (3.10.0-957.el7.x86_64)
  • User: root (명령어 실행 주체), wasadm (대상 계정)

1. 기본 문법 (Syntax)

chown(Change Owner) 명령어의 기본 구조입니다. 루트(Superuser) 권한이 필요합니다.

# 소유자만 변경
chown [USER] [FILE]

# 소유자와 그룹 동시 변경 (가장 많이 사용)
chown [USER]:[GROUP] [FILE]

# 하위 디렉토리까지 재귀적 변경
chown -R [USER]:[GROUP] [DIRECTORY]

2. 실무 사용 예시 (Examples)

제공해주신 로그를 바탕으로 상황별 명령어 사용법을 분석합니다.

Step 1: 전체 초기화 (root 권한으로 설정)

-R 옵션을 사용하여 현재 디렉토리(*)의 모든 파일과 폴더를 root:root 소유로 변경합니다.

[root@localhost sw]# chown -R root:root *

# 확인
[root@localhost sw]# ls -alrt
drwxrwxrwx.  2 root root   6 Feb  5 01:49 img
drwx------.  2 root root   6 Feb  5 01:49 was
...
주의 (Warning):
chown -R은 매우 강력한 명령어입니다. 실수로 루트 디렉토리(/)나 시스템 디렉토리에서 실행할 경우 시스템 부팅이 불가능해질 수 있으므로, 실행 전 현재 경로(pwd)를 반드시 확인하십시오.

Step 2: 특정 서비스 계정으로 이관

WAS나 웹 서버 운영을 위해 특정 디렉토리(img, was)와 스크립트(Mem.sh)의 소유권을 wasadm 계정으로 변경합니다.

# 디렉토리 및 파일 소유권 변경 (wasadm 계정, wasadm 그룹)
[root@localhost sw]# chown wasadm:wasadm img
[root@localhost sw]# chown wasadm:wasadm was
[root@localhost sw]# chown wasadm:wasadm Mem.sh

Step 3: 변경 결과 검증 (Verification)

ls -l 명령어로 변경된 소유권을 확인합니다. 3번째 컬럼(Owner)과 4번째 컬럼(Group)이 변경된 것을 볼 수 있습니다.

[root@localhost sw]# ls -alrt
total 8
# 변경된 항목 (wasadm)
drwxrwxrwx.  2 wasadm wasadm   6 Feb  5 01:49 img
drwx------.  2 wasadm wasadm   6 Feb  5 01:49 was
-rwxr-xr-x.  1 wasadm wasadm 428 Feb  8 01:16 Mem.sh

# 변경되지 않은 항목 (root 유지)
drwx------.  2 root   root     6 Feb  5 01:49 web
drwxr-xr-x.  2 root   root     6 Feb  5 01:49 bin
...

Next Step:
소유권 변경이 완료되었다면, 해당 사용자가 파일에 대해 어떤 작업을 할 수 있는지 결정하는 권한(Permission) 설정(chmod) 단계로 넘어가야 합니다.

Open Stream →
#command

[Linux] CentOS 7 메모리 사용률 분석 완벽 가이드: free 명령어 변화와 실질 사용량 계산

CentOS 7(RHEL 7)부터 free 명령어의 출력 형식이 변경되었습니다. 기존의 buffers/cache 라인이 사라지고 available 컬럼이 추가된 배경을 이해하고, 정확한 메모리 사용률을 계산하는 방법을 정리합니다.

0. 배경 지식: CentOS 6 vs 7 차이점

리눅스는 남는 메모리를 적극적으로 캐시(Cache)로 사용하여 성능을 높입니다. 따라서 'Used'가 높다고 해서 반드시 메모리가 부족한 것은 아닙니다.

  • CentOS 6 이하: -/+ buffers/cache 행을 통해 실질 사용량을 확인했습니다.
  • CentOS 7 이상: 커널이 직접 계산한 available 컬럼을 통해 "즉시 사용 가능한 메모리"를 판단합니다.

Test Environment

  • OS: CentOS 7 (Kernel 3.10.0-957.el7.x86_64)

1. 메모리 확인 명령어 (free)

가장 기본적인 확인 방법입니다. -m 옵션은 Megabyte 단위로 출력합니다.

[root@localhost sw]# free -m
              total        used        free      shared  buff/cache   available
Mem:           7803         892        4686         263        2224        6277
Swap:          8064           0        8064

실시간 모니터링 및 상세 보기

-w(wide) 옵션을 주면 buffer와 cache를 분리해서 볼 수 있고, -s(seconds) 옵션으로 반복 조회가 가능합니다.

# 1초 간격으로 buffer/cache를 분리하여 출력
free -mw -s 1

2. 메모리 사용률 계산 공식 (Calculation)

단순히 used / total로 계산하면 캐시 메모리까지 사용량에 포함되어 수치가 과도하게 높게 나옵니다. 목적에 따라 계산 방식을 달리해야 합니다.

공식 A: OS 관점의 사용률 (캐시 포함)

메모리가 실제로 얼마나 할당되어 있는지(반납되지 않은 상태) 확인할 때 사용합니다.

$$ Usage(\%) = \frac{used}{total} \times 100 $$

공식 B: 애플리케이션 관점의 실질 사용률 (권장)

"실제로 메모리가 부족한가?"를 판단할 때는 available 값을 기준으로 해야 합니다.

$$ Usage(\%) = \frac{total - available}{total} \times 100 $$

Tip: sar -r 1 명령어를 통해서도 %memused(메모리 사용률)를 확인할 수 있습니다.

3. 주요 파라미터 설명 (Parameters)

CentOS 7 free 명령어의 각 컬럼이 의미하는 바는 다음과 같습니다.

파라미터 설명
total 설치된 전체 물리 메모리 크기
used 현재 할당되어 사용 중인 메모리 (total - free - buff/cache)
free 아무 용도로도 사용되지 않는 완전한 유휴 메모리
shared tmpfs(램디스크) 등 프로세스 간 공유되는 메모리
buff/cache 커널 버퍼 및 파일 시스템 캐시 (필요시 즉시 반환 가능)
available (핵심) 스와핑(Swapping) 없이 새로운 프로세스 실행에 즉시 할당 가능한 메모리 추정치

Next Step:
메모리 사용률이 비정상적으로 높다면(available 부족), top 명령어로 메모리 누수(Leak)가 의심되는 프로세스를 찾거나, echo 3 > /proc/sys/vm/drop_caches 명령어로 캐시를 강제 반환하여 가용 공간을 확보하는 방법을 검토해 보세요.

Open Stream →
#command

[Linux] Java 실제 설치 경로 확인 방법: which vs readlink 차이점 및 JAVA_HOME 설정

리눅스 환경에서 java 명령어의 실제 설치 위치(Absolute Path)를 찾는 방법을 정리합니다. 단순 경로 확인용인 which와 심볼릭 링크의 원본을 찾아주는 readlink -f의 차이점을 이해하고, 이를 통해 JAVA_HOME을 설정하는 팁을 다룹니다.

0. 배경 지식 (Context)

리눅스(특히 CentOS/RHEL 계열)는 alternatives 시스템을 사용하여 여러 버전의 프로그램을 관리합니다. 때문에 /usr/bin/java는 실제 실행 파일이 아니라, 여러 단계의 바로가기(Symbolic Link)로 연결된 껍데기일 확률이 높습니다.

Test Environment

  • OS: CentOS 7 (3.10.0-957.el7.x86_64)
  • Package: OpenJDK 1.8

1. 명령어 경로 확인 (which)

가장 기본적으로 사용하는 명령어입니다. 환경 변수 $PATH에 등록된 경로 중 어디에 있는 명령어가 실행되는지 알려줍니다.

[wasadm@localhost ~]$ which java
/usr/bin/java
한계점: 위 결과인 /usr/bin/java는 실제 파일이 아닌 심볼릭 링크일 가능성이 높아서, 이 경로를 JAVA_HOME으로 설정하면 오류가 발생합니다.

2. 원본 경로 추적 (readlink -f)

심볼릭 링크가 아무리 여러 단계로 꼬여 있어도, 최종 원본 파일의 절대 경로를 한 번에 찾아주는 가장 확실한 명령어입니다.

# 구문: readlink -f [심볼릭_링크_경로]
[wasadm@localhost ~]$ readlink -f /usr/bin/java

# 출력 결과 (실제 설치 위치)
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-7.b13.el7.x86_64/jre/bin/java

위 결과에서 마지막 /bin/java를 제외한 앞부분이 바로 JAVA_HOME이 됩니다.


3. 링크 구조 단계별 확인 (ls -l)

readlink가 어떻게 동작하는지 ls -l 명령어로 한 단계씩 추적해보면 리눅스의 alternatives 구조를 이해할 수 있습니다.

Step 1: 실행 파일 확인

[wasadm@localhost ~]$ ls -l /usr/bin/java
lrwxrwxrwx 1 root root 22 Feb  5 01:36 /usr/bin/java -> /etc/alternatives/java

/usr/bin/java/etc/alternatives/java를 가리키고 있습니다.

Step 2: alternatives 확인

[wasadm@localhost ~]$ ls -l /etc/alternatives/java
lrwxrwxrwx 1 root root 71 Feb  5 01:36 /etc/alternatives/java -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-7.b13.el7.x86_64/jre/bin/java

/etc/alternatives/java가 비로소 실제 JDK가 설치된 경로를 가리키고 있습니다. readlink -f는 이 과정을 한 번에 수행해 줍니다.


4. 활용: JAVA_HOME 환경 변수 설정

위에서 찾은 경로를 활용하여 환경 변수를 등록합니다. (/etc/profile 또는 ~/.bash_profile)

# 원본 경로: /usr/lib/jvm/java-1.8.0-.../jre/bin/java
# bin/java 앞부분까지만 복사

export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-7.b13.el7.x86_64/jre
export PATH=$JAVA_HOME/bin:$PATH

Next Step:
만약 서버에 여러 버전의 Java가 설치되어 있어 기본 실행 버전을 변경하고 싶다면, alternatives --config java 명령어를 사용하여 간편하게 스위칭할 수 있습니다.

Open Stream →
#command

[Linux] 파일/디렉토리 권한 관리 완벽 가이드: chmod 명령어와 755, 777의 의미

리눅스 환경(CentOS 7)에서 파일 및 디렉토리의 접근 권한을 제어하는 chmod 명령어 사용법을 정리합니다. 숫자 모드(755, 644)와 문자열 모드(u+x)의 차이를 이해하고, -R 옵션을 통해 하위 경로까지 일괄 적용하는 실무 예제를 다룹니다.

0. 배경 지식: 권한의 구조 (Permission Structure)

리눅스의 파일 권한은 소유자(User), 그룹(Group), 기타(Other) 세 가지 대상에 대해 읽기(r), 쓰기(w), 실행(x) 권한을 부여하는 구조입니다.

권한 확인 (ls -l)

ls -l
# 결과 예시: drwxr-xr-x (755)
# d(디렉토리) | rwx(소유자) | r-x(그룹) | r-x(기타)

1. 권한 변경 (chmod)

chmod(Change Mode) 명령어를 사용하여 파일이나 디렉토리의 권한을 변경합니다. 이미 생성된 파일의 현재 상태를 변경하는 명령어입니다.

옵션 설명

  • -R (--recursive): 디렉토리 내부의 모든 파일과 하위 디렉토리까지 재귀적으로(일괄) 변경합니다. (가장 많이 사용)

실무 사용 예시

# 1. WAS 디렉토리: 소유자만 모든 권한(7), 나머지는 접근 불가(0)
chmod -R 700 ./was

# 2. 웹 루트 및 바이너리: 소유자(7), 그룹/기타는 읽기/실행만(5) - 일반적인 설정
chmod -R 755 ./web
chmod -R 755 ./bin

# 3. 이미지 업로드 폴더: 누구나 쓰고 읽기 가능 (보안 주의!)
chmod -R 777 ./img

2. 권한 설정 방식 A: 숫자 모드 (Octal Mode)

가장 직관적이고 많이 사용되는 방식입니다. 각 권한에 할당된 점수(4, 2, 1)를 더해서 표현합니다.

권한 (Permission) 기호 (Symbol) 숫자 값 (Octal)
Read (읽기) r 4
Write (쓰기) w 2
Execute (실행) x 1

조합 예시

  • 7 (rwx): 4 + 2 + 1 (모든 권한)
  • 6 (rw-): 4 + 2 (읽기/쓰기 - 일반 파일)
  • 5 (r-x): 4 + 1 (읽기/실행 - 실행 파일, 디렉토리)
  • 0 (---): 권한 없음

3. 권한 설정 방식 B: 문자열 모드 (Symbolic Mode)

특정 대상의 권한만 콕 집어서 추가(+)하거나 제거(-)할 때 유용합니다.

대상 (Who) 연산자 (Op) 권한 (Permission)
u: User (소유자)
g: Group (그룹)
o: Other (기타)
a: All (전체, ugo)
+: 추가
-: 제거
=: 지정
r: 읽기
w: 쓰기
x: 실행

사용 예시

# run.sh 파일에 실행(x) 권한 추가 (모든 사용자에게)
chmod +x run.sh

# 그룹(g)에게 쓰기(w) 권한 제거
chmod g-w file.txt

# 기타 사용자(o)에게 읽기(r) 권한만 할당
chmod o=r file.txt

Next Step:
파일의 권한뿐만 아니라 소유권을 변경해야 할 때는 chown(Change Owner) 명령어를 사용해야 합니다. chown user:group filename 형식을 함께 익혀두세요.

Open Stream →
#command

[Linux] 서버 관리 필수 명령어 모음: 로그 정리(find), 네트워크(netstat), 메모리 점검

리눅스 시스템 운영 중 로그 파일 정리, 디스크 용량 확보, 네트워크 연결 상태 점검, 메모리 사용률 확인을 위해 자주 사용하는 명령어 패턴(One-Liner)을 정리합니다. RedHat/CentOS 7 환경을 기준으로 작성되었습니다.

Test Environment

  • OS: CentOS 7, RedHat 7.2
  • Shell: Bash

1. 파일 검색 및 정리 (File Management)

서버 운영 중 가장 흔한 이슈는 로그 파일로 인한 디스크 풀(Disk Full)입니다. find 명령어를 사용하여 오래된 파일을 검색하고 삭제하는 패턴입니다.

최근 수정된 파일 찾기

설정 파일(xml 등)이 최근에 변경되었는지 확인할 때 사용합니다.

# 최근 7일 이내(-7)에 수정된 xml 파일 검색
find . -type f -name "*.xml" -mtime -7 -print

오래된 로그 파일 삭제

로그 디렉토리 관리를 위해 일정 기간이 지난 파일을 삭제합니다. 삭제 명령(rm)을 실행하기 전, 반드시 조회(ls)를 먼저 수행하여 대상을 검증해야 합니다.

# 1. 대상 확인 (7일이 지난 로그 파일 조회)
find /log/server1 -name "*.log" -mtime +7 -print

# 2. 삭제 실행 (방법 A: -delete 옵션 사용)
find /log/server1 -name "*.log" -mtime +7 -delete

# 2. 삭제 실행 (방법 B: -exec rm 사용, 가장 범용적)
find /log/server1 -name "*.log" -mtime +7 -exec rm -f {} \;

# 3. 30일 이상 된 로그 파일만 강제 삭제
find /log/server1 -type f -name "*.log" -ctime +30 -exec rm -rf {} \;

대용량 파일 검색

디스크 용량을 많이 차지하는 파일을 찾습니다.

# 3GB 이상인 파일을 찾아 용량과 함께 출력
find . -size +3000000k -exec ls -lh {} \+

날짜순 파일 정렬 보기

기본 ls -l의 날짜 포맷이 보기 힘들 때 ISO 포맷으로 변환하여 확인합니다.

ls --time-style="+%Y-%m-%d %H:%M:%S" -altr | grep ^- | more

2. 네트워크 상태 점검 (Network Monitoring)

웹 서버나 DB 서버의 현재 연결 상태를 확인하여 트래픽 스파이크나 연결 누수(Leak)를 점검합니다.

동시 접속자 수 확인 (Web Server)

ESTABLISHED 상태는 현재 연결이 수립되어 데이터를 주고받는 상태를 의미합니다.

# 80 포트 동시 접속자 수 카운트
netstat -nap | grep :80 | grep ESTABLISHED | wc -l

# 8080 포트(WAS) 동시 접속자 수 카운트
netstat -nap | grep :8080 | grep ESTABLISHED | wc -l

DB 연결 풀(Connection Pool) 확인

WAS에서 DB로 맺은 연결 개수를 확인합니다. 포트 번호로 grep하여 정렬합니다.

# 특정 포트와 연결된 소켓 정보 확인
netstat -anp | grep {port_number}

# 연결 개수 카운트
netstat -anp | grep {port_number} | wc -l

3. 메모리 사용률 점검 (Memory Check)

리눅스의 free 명령어는 버퍼/캐시 메모리를 포함하여 보여주기 때문에, 실제 애플리케이션이 사용하는 메모리(Actual Used)를 계산하기 위해서는 별도의 연산이 필요할 때가 있습니다.

메모리 계산 스크립트 (Shell)

전체 메모리 대비 실제 사용률을 백분율(%)로 계산하는 스크립트입니다.

#!/bin/sh
# free 명령어의 출력 컬럼 위치는 OS 버전에 따라 다를 수 있으므로 확인 필요 (awk $2, $3...)

# Total Memory
TOTAL=`free | grep ^Mem | awk '{print $2}'`

# Used Memory (OS 관점)
USED1=`free | grep ^Mem | awk '{print $3}'`

# Used Memory (Buffer/Cache 제외, CentOS 6 이하 구버전 방식)
# USED2=`free | grep ^-/+ | awk '{print $3}'`

# CentOS 7 이상 (available 컬럼 등 고려 필요하나 단순 계산 시)
# 버퍼/캐시를 포함한 단순 사용률
NOMINAL=$((100*USED1/TOTAL))

echo "Memory Usage: ${NOMINAL}%"

One-Liner (간편 계산)

awk를 사용하여 한 줄로 메모리 사용률을 출력합니다.

# 전체 메모리 대비 사용량(Used) 비율
awk '/^Mem/ {printf("Used: %u%%", 100*$3/$2);}' <(free -m)

# (참고) 버퍼/캐시를 제외한 실 사용률 계산은 free -m의 available 컬럼을 활용하는 것이 정확합니다.
free -m | awk 'NR==2{printf "Memory Usage: %.2f%%\n", ($3/$2)*100 }'

Next Step:
반복적으로 사용하는 위 명령어들을 ~/.bash_profilealias로 등록해두면, 긴 명령어를 타이핑하는 수고를 덜고 오타로 인한 사고를 방지할 수 있습니다.

Open Stream →
#command

[Linux] CentOS 7 호스트네임(Hostname) 영구 변경 및 필수 후속 조치 (hostnamectl)

CentOS 7 및 systemd 기반 리눅스 시스템에서 hostnamectl 명령어를 사용하여 호스트네임을 영구적으로 변경하는 방법을 정리합니다. 변경 후 쉘 프롬프트에 즉시 반영하는 방법과 /etc/hosts 파일 수정의 중요성을 포함합니다.

0. 배경 지식 (Context)

호스트네임은 네트워크 상에서 서버를 식별하는 이름입니다. 과거에는 /etc/sysconfig/network 파일을 수정하고 재부팅해야 했으나, CentOS 7부터는 hostnamectl 명령어를 통해 재부팅 없이 즉시 설정을 영구 반영할 수 있습니다.

Test Environment

  • OS: CentOS 7.2
  • System: systemd based

1. 호스트네임 변경 (hostnamectl)

hostnamectl 명령은 커널 호스트네임 설정과 /etc/hostname 파일 수정을 동시에 수행합니다.

현재 상태 확인

hostnamectl status

변경 명령어

# 구문: hostnamectl set-hostname [새로운_이름]
hostnamectl set-hostname web-server-01

2. 변경 사항 확인 및 적용 (Verification)

명령어 실행 즉시 시스템 설정은 변경되지만, 현재 로그인된 터미널의 프롬프트(Shell Prompt)에는 반영되지 않을 수 있습니다.

변경 확인

# 1. 설정값 확인
hostname

# 2. 상세 확인
hostnamectl status

터미널 프롬프트 갱신

로그아웃 후 다시 로그인(Reconnect)하면 프롬프트가 변경됩니다. 재접속 없이 바로 확인하려면 아래 명령어를 사용하세요.

# 현재 쉘 세션 갱신
exec bash

결과: [root@old-name ~]# 에서 [root@web-server-01 ~]# 로 변경됨.


3. 필수 후속 조치: /etc/hosts 수정

호스트네임을 변경했다면, 서버 자신이 자신의 이름을 찾아갈 수 있도록 로컬 DNS 설정 파일인 /etc/hosts도 반드시 수정해야 합니다. 이를 누락하면 sudo 명령어 실행이 느려지거나 일부 애플리케이션 기동 시 에러가 발생할 수 있습니다.

파일 수정

vi /etc/hosts

수정 내용

기존 호스트네임이 적힌 부분을 새로운 이름으로 변경하거나 추가합니다.

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

# 변경된 호스트네임 추가 (자신의 IP 또는 Loopback에 매핑)
127.0.0.1   web-server-01
Tip: 클러스터링(Cluster) 환경이나 WAS(WebSphere, JBoss) 환경에서는 127.0.0.1 대신 실제 서버의 공인 IP(또는 사설 IP)에 호스트네임을 매핑하는 것이 좋습니다.
Open Stream →
#Linux

[Linux/Java] High CPU 트러블슈팅: OS 스레드와 Java 스레드 매핑 분석 가이드

Java 프로세스(JVM)가 고부하 상태일 때, CPU를 점유하고 있는 범인(특정 스레드)을 찾아내는 방법을 정리합니다. OS 명령어(ps, top)로 문제의 스레드 ID(TID)를 식별하고, 이를 16진수로 변환하여 Java Thread Dump와 매핑하는 과정을 다룹니다.

Test Environment

  • OS: RedHat Linux (CentOS 호환)
  • Target: Java Process (WebSphere/Tomcat 등)

1. 프로세스 및 스레드 식별 (Identify Usage)

먼저 CPU를 많이 사용하는 Java 프로세스의 PID(Process ID)를 찾고, 그 내부에서 실제로 리소스를 소모하는 스레드(LWP, Light Weight Process)를 식별해야 합니다.

전체 프로세스 확인

# Java 프로세스 PID 확인
ps -ef | grep java

스레드별 CPU 점유율 확인 (top)

-H 옵션을 사용하여 프로세스 내부의 스레드 단위로 리소스를 모니터링합니다.

# PID가 12345인 경우
top -H -p 12345

출력 화면에서 PID(실제로는 TID/LWP) 컬럼과 %CPU 컬럼을 확인하여 가장 상단에 있는 번호를 기록합니다.

스레드별 CPU 점유율 확인 (ps)

ps 명령어를 통해서도 스레드 정보를 확인할 수 있습니다. -lmT 옵션이나 -L 옵션을 사용합니다.

# LWP(Light Weight Process) 확인
ps -lmT [PID]

# 또는 커스텀 포맷 사용
ps -eLo pid,lwp,pcpu,comm | grep [PID]

2. 스레드 ID 변환 (Decimal to Hex)

OS에서 확인한 스레드 ID는 10진수(Decimal)이지만, Java Thread Dump 파일(Javacore 등)에서는 스레드 ID가 16진수(Hexadecimal)로 기록됩니다. 따라서 매핑을 위해 변환 과정이 필요합니다.

변환 예시

  • OS TID: 9091 (10진수)
  • Hex TID: 0x2383 (16진수)

변환 명령어

# 쉘에서 바로 변환하기 (예: 9091 -> 2383)
printf '%x\n' 9091

3. 스레드 덤프 생성 및 분석 (Thread Dump)

현재 JVM의 상태를 스냅샷으로 남기기 위해 스레드 덤프를 생성합니다.

덤프 생성 (Kill -3)

kill -3 시그널은 프로세스를 종료하지 않고 표준 출력(stdout)이나 로그 파일로 스레드 정보를 출력합니다.

kill -3 [PID]
  • IBM JDK (WebSphere): javacore.YYYYMMDD.HHMMSS.pid.txt 파일 생성
  • Oracle/Open JDK: catalina.out 또는 지정된 로그 파일에 출력

로그 매핑 분석

생성된 덤프 파일에서 앞서 변환한 16진수 값(예: 0x2383)을 검색합니다. IBM JDK의 경우 nid(Native ID) 또는 native_thread_id 항목과 매칭됩니다.

/* Javacore 예시 */
"WebContainer : 5" (TID:0x12345600, sys_thread_t:0x789abc00, state:R, native ID:0x2383) prio=5
    at com.example.MyClass.infiniteLoop(MyClass.java:45)
    at ...

분석 포인트:

  1. 16진수 ID로 검색하여 해당 스레드를 찾습니다.
  2. 해당 스레드의 상태(Runnable, Waiting 등)를 확인합니다.
  3. Stack Trace를 통해 현재 어떤 코드(메소드)가 실행 중인지 파악하여 병목 지점을 수정합니다.

Next Step:
주기적인 모니터링이 필요하다면 top -Hjstack을 결합한 쉘 스크립트를 작성하여, CPU 임계치 초과 시 자동으로 덤프를 남기도록 자동화해 보십시오.

Open Stream →
#command

[Linux] FTP CLI 명령어 완벽 가이드 및 상태 코드(Response Code) 정리

리눅스 쉘 환경에서 FTP 서버에 접속하여 파일을 업로드/다운로드하는 필수 명령어와 주요 옵션을 정리합니다. 또한 트러블슈팅 시 유용한 FTP 응답 코드(Response Code)의 의미를 설명합니다.

[Image of FTP client server data transfer diagram]

1. 서버 접속 및 로그인 (Connection)

FTP 클라이언트를 실행하여 원격 서버에 접속하는 과정입니다. open 명령어를 사용하거나 실행 시 인자로 IP를 전달합니다.

[test@zeroTest]$ ftp 210.xxx.xxx.xxx
Connected to 210.xxx.xxx.xxx.
220 web17 FTP server (Version 5.60) ready.
Name (210.xxx.xxx.xxx:test): [아이디 입력]
331 Password required for user.
Password: [패스워드 입력]
230 User test logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>

2. 디렉토리 탐색 (Navigation)

FTP는 원격(Remote) 서버와 로컬(Local) 클라이언트의 디렉토리를 동시에 제어해야 합니다. 로컬 명령어 앞에는 주로 l(local)이 붙습니다.

원격 서버 (Remote) 제어

  • pwd : 원격 서버의 현재 경로 확인
  • ls (또는 dir) : 원격 서버의 파일 목록 출력
  • cd [path] : 원격 서버의 디렉토리 이동
  • cdup : 원격 서버에서 상위 디렉토리로 이동

로컬 클라이언트 (Local) 제어

  • !pwd : 로컬 클라이언트의 현재 경로 확인
  • lcd [path] : 로컬 클라이언트의 작업 디렉토리 변경 (다운로드/업로드 위치 변경 시 필수)
# 로컬 다운로드 경로를 /bin으로 변경 예시
ftp> lcd /bin
Local directory now /bin

3. 파일 전송 설정 (Transfer Settings)

파일 전송 전, 전송 모드와 시각적 피드백 옵션을 설정하는 것이 중요합니다.

전송 모드 (Transfer Mode)

바이너리 파일(이미지, 실행파일, 압축파일 등) 전송 시 반드시 binary 모드를 사용해야 파일 깨짐을 방지할 수 있습니다.

  • ascii (또는 as) : 텍스트 파일 전송 모드
  • binary (또는 bi) : 바이너리 전송 모드 (권장)

편의 옵션

  • hash : 파일 전송 진행 상황을 #(Hash Mark)로 표시 (대용량 파일 전송 시 유용)
  • prompt : 다중 파일 전송(mget/mput) 시 파일마다 확인하는 과정을 On/Off
ftp> binary
200 Type set to I.
ftp> hash
Hash mark printing on (1024 bytes/hash mark).

4. 파일 업로드 및 다운로드

단일 파일 처리와 다중 파일(Wildcard * 사용) 처리 명령어가 구분됩니다.

다운로드 (Server -> Local)

  • get [filename] : 단일 파일 다운로드
  • mget [pattern] : 다중 파일 다운로드 (예: mget *.pdf)
ftp> get thinkinjava.pdf
local: R389.PDF remote: R389.PDF
200 PORT command successful.
150 Opening BINARY mode data connection for R389.PDF (44028 bytes).
#######################
226 Transfer complete.

업로드 (Local -> Server)

  • put [filename] : 단일 파일 업로드
  • mput [pattern] : 다중 파일 업로드 (예: mput *.html)

5. 기타 관리 명령어

  • delete [filename] / mdelete [pattern] : 원격 파일 삭제
  • mkdir [dirname] / rmdir [dirname] : 원격 디렉토리 생성 및 삭제
  • chmod [mode] [file] : 원격 파일 권한 변경 (예: chmod 755 run.sh)
  • rename [old] [new] : 파일 이름 변경
  • size [filename] : 파일 크기(Byte) 확인
  • bye, quit, exit : 접속 종료

6. FTP 응답 코드 (Response Codes)

서버가 반환하는 3자리 숫자를 통해 트러블슈팅이 가능합니다. 주요 코드는 다음과 같습니다.

Code Description (의미)
150 파일 상태 정상. 데이터 연결을 엽니다. (전송 시작)
200 명령어 성공 (OK)
220 서비스 준비 완료 (접속 초기 메시지)
226 데이터 연결 닫힘. 요청 작업 성공 (전송 완료)
230 사용자 로그인 성공
331 사용자 이름 확인됨. 패스워드 필요
421 서비스 사용 불가. 연결 종료
425 데이터 연결을 열 수 없음 (방화벽, Passive 모드 이슈 등)
530 로그인 실패 (ID/PW 오류)
550 요청 작업 실패 (파일 없음, 권한 부족 등)

Next Step:
FTP는 데이터를 암호화하지 않아 보안에 취약합니다. OpenSSH에 포함된 sftp 명령어를 사용하여 암호화된 파일 전송 환경을 구성하는 방법을 검토해보십시오.

Open Stream →
#command

[Linux] zip/unzip 설치 및 명령어 사용법 (Password 설정, Legacy Unix 수동 설치)

Linux 및 Unix 환경에서 zip 포맷을 다루기 위한 설치 방법과 명령어 사용법을 정리합니다. yum을 이용한 간편 설치부터 패스워드 설정 방법, 그리고 패키지 매니저를 사용할 수 없는 Legacy Unix 환경(AIX, Solaris 등)에서의 수동 설치 절차를 포함합니다.

1. 패키지 설치 (Installation)

CentOS, RHEL 등 일반적인 리눅스 배포판에서는 패키지 매니저를 통해 손쉽게 설치할 수 있습니다.

설치 확인 및 설치

# 설치 여부 확인
rpm -qa | grep zip

# 패키지 설치 (root 권한 필요)
yum install zip unzip

2. zip 명령어 (압축하기)

파일이나 디렉토리를 .zip 포맷으로 압축합니다.

기본 구문

# 형식
zip [옵션] [생성할파일명.zip] [대상파일_또는_디렉토리]

사용 예시

# 1. 디렉토리 재귀적 압축 (-r 옵션 필수)
# directory 폴더 하위의 모든 파일을 name.zip으로 압축
zip -r name.zip directory

# 2. 패스워드 설정 압축 (-P 옵션)
# 보안상 주의: 명령어 히스토리에 패스워드가 남을 수 있음
zip -P [password] -r name.zip directory

3. unzip 명령어 (압축 해제)

.zip 파일의 압축을 해제합니다.

기본 구문

# 형식
unzip [파일명.zip]

사용 예시

# 1. 기본 압축 해제
unzip filename.zip

# 2. 특정 디렉토리에 압축 해제 (-d 옵션)
unzip filename.zip -d /target/path

# 3. 패스워드가 걸린 파일 해제
# 방법 A: 명령어 입력 시 패스워드 입력 (히스토리 노출 위험)
unzip -P [password] filename.zip

# 방법 B: 명령어 실행 후 인터랙티브하게 입력 (권장)
unzip filename.zip
# (Enter password 프롬프트 출력 시 입력)

4. Legacy Unix 수동 설치 (Manual Installation)

인터넷 연결이 제한적이거나 패키지 매니저가 없는 Unix 환경(AIX, HP-UX, Solaris 등)에서는 Oracle 등에서 제공하는 바이너리를 수동으로 설치해야 합니다.

바이너리 다운로드

각 플랫폼에 맞는 unzip 유틸리티를 다운로드합니다. (Oracle Data Server 9i Release 2 기준 레거시 자료)

  • Compaq Tru64 UNIX
  • Compaq OpenVMS (Alpha)
  • HP-UX 11.0
  • IBM RS/6000 AIX
  • LINUX Intel
  • Sun SPARC Solaris

Note: 최신 버전의 소스 코드는 Info-ZIP 공식 홈페이지에서 확인할 수 있습니다.

UNIX 플랫폼 설치 절차

  1. 바이너리 파일을 다운로드하여 Binary Mode로 서버에 전송합니다.
  2. 파일 압축을 해제합니다.
    % uncompress unzip_<os>
  3. 실행 파일을 PATH 환경변수가 잡힌 경로(예: /usr/bin, /usr/local/bin)로 이동합니다.
  4. 실행 권한을 부여합니다.
    % chmod 751 unzip_<os>
  5. 설치된 명령어로 압축을 해제합니다.
    % unzip_<os> filename.zip

Compaq OpenVMS (Alpha) 추가 설정

OpenVMS 환경에서는 유틸리티에 대한 심볼(Symbol) 정의가 필요합니다.

unzip == $disk:[dir]unz550xV-axp.exe

Next Step:
대용량 로그 파일 관리 등을 위해 tar 명령어와 cron을 결합하여 주기적인 백업 스크립트를 작성하는 방법을 학습해 보시길 권장합니다.

Open Stream →
#command

[Linux] find 명령어 완벽 가이드: 파일 검색부터 일괄 처리까지

리눅스 시스템 관리에서 가장 강력한 도구 중 하나인 find 명령어의 옵션과 사용법을 정리합니다. 파일명, 권한, 시간, 크기 등 다양한 조건으로 파일을 검색하고 -execxargs를 통해 후처리하는 방법을 다룹니다.

Test Environment

  • OS: CentOS 7
  • Shell: Bash

1. 기본 구문 (Syntax)

find 명령어는 지정된 경로 하위의 모든 트리를 탐색하므로 검색 범위 설정에 주의해야 합니다.

find [경로] [조건] [동작]

주요 검색 조건 (Predicates)

  • -name [pattern]: 파일 이름으로 검색 (와일드카드 사용 가능)
  • -type [d/f]: 파일 타입 (d: 디렉토리, f: 일반 파일)
  • -user [name]: 소유자 이름으로 검색
  • -group [name]: 그룹 이름으로 검색
  • -perm [mode]: 파일 권한으로 검색
  • -size [n]: 파일 크기로 검색 (+n: 이상, -n: 이하, 단위: k, M, G)
  • -empty: 빈 파일 또는 빈 디렉토리 검색

시간 관련 조건 (Time Stamps)

시간 옵션에서 +n은 n일 이전(Old), -n은 n일 이내(New)를 의미합니다.

  • -atime [n]: Access Time (마지막 접근 시간, 일 단위)
  • -mtime [n]: Modify Time (마지막 수정 시간, 일 단위)
  • -ctime [n]: Change Time (메타데이터 변경 시간, 일 단위)

2. 기본 사용 예제

파일명 및 타입 검색

# 1. 현재 디렉토리(.)에서 이름에 'test'가 포함된 파일 찾기
find . -name "*test*" -print

# 2. 시스템 전체(/)에서 'foobar'라는 이름의 파일 찾기
find / -name "foobar" -print

# 3. 디렉토리만 찾기
find . -type d

# 4. 숨겨진 파일(점으로 시작하는 파일) 찾기
find . -name ".*" -print

권한(Permission) 및 소유자 검색

# 1. 권한이 700인 파일 찾기
find . -perm 700 -print

# 2. 권한이 400 이거나 200인 파일 찾기 (논리 연산 OR 사용)
# 괄호 앞에는 반드시 escape(\) 처리가 필요합니다.
find . \( -perm 400 -o -perm 200 \) -print

# 3. 특정 사용자(foobar) 소유의 파일 찾기
find / -user foobar -print

# 4. 소유자나 그룹이 없는(삭제된 계정 등) 파일 찾기 (고아 파일)
find / \( -nouser -o -nogroup \) -print

# 5. 실행 권한이 있는 파일 찾기 (Others에게 쓰기 권한이 있는 경우 등 보안 점검 시 유용)
find / -perm -2 -print

3. 고급 활용 및 일괄 처리 (Actions)

검색된 파일에 대해 -exec 또는 xargs를 사용하여 추가 명령을 수행할 수 있습니다.

-exec 옵션 사용

{}는 검색된 파일명을 의미하며, \;로 명령을 종료합니다.

# 1. 이름이 core인 파일을 찾아 상세 정보 출력(ls -l)
find . -name core -exec ls -l {} \;

# 2. *.bak 파일을 찾아 즉시 삭제
find . -name "*.bak" -exec rm -f {} \;

# 3. *.txt 파일 내에서 특정 문자열 치환 (Perl 이용)
find / -name "*.txt" -exec perl -pi -e 's/OldString/NewString/g' {} \;

xargs 파이프 연계

많은 수의 파일을 처리할 때는 -exec보다 xargs가 성능상 유리할 수 있습니다.

# 1. 파일 내용에서 특정 문자열 검색 (grep)
find . -type f | xargs grep "검색어"

# 2. 100MB 이상인 파일을 찾아 크기순 보기
find / -size +100M -print | xargs ls -lh

# 3. 최근 30일 동안 수정되지 않은 파일 목록 저장
find / -mtime +30 -print > old_files.txt

4. 실무 유용한 패턴 정리

디스크 정리 및 관리

# 1. 빈 파일(0 byte) 찾기
find / -empty -print
# 또는
find / -size 0 -print

# 2. 최근 30일간 접근하지 않은 파일 리스트 추출
# ! (NOT) 연산자와 -a (AND) 연산자 조합
find / ! \( -atime -30 -a \( -type d -o -type f \) \) | xargs ls -l > not_access.txt

# 3. 특정 디렉토리 하위의 *.bak 파일을 백업 폴더로 이동
# (주의: 백틱 ` 사용 시 파일명이 너무 많으면 에러 발생 가능성 있음)
mv `find . -name "*.bak"` /home/bak/

보안 점검

# 1. Root 권한으로 실행되는 SetUID 파일 찾기 (+4000)
find / \( -user root -a -perm +4000 \) -print

# 2. Others에게 쓰기 권한이 있는 파일을 찾아 쓰기 권한 제거
find / -perm -2 -exec chmod o-w {} \;

Next Step:
find 명령어로 파일을 찾은 뒤, 로그 분석이나 텍스트 처리가 필요하다면 grep, awk, sed 명령어의 정규표현식(Regex) 활용법을 학습해 보시길 권장합니다.

Open Stream →
#Linux

[Linux] OS 기본 계정 관리 및 권한 설정 완전 정복 (chmod, chown)

Linux(CentOS/RHEL) 환경에서의 기본적인 사용자 계정 생성, 비밀번호 설정, 그리고 파일 권한(Permission) 및 소유권(Ownership) 관리를 위한 필수 명령어 정리 노트입니다.

1. 사용자 계정 관리 (User Management)

리눅스 시스템에서 사용자를 추가하고, 비밀번호를 설정하며, 계정 정보를 확인하는 방법입니다. 모든 작업은 root 권한이 필요합니다.

계정 생성 및 비밀번호 설정

useradd 명령어로 계정을 생성하고 passwd로 비밀번호를 설정합니다. (CentOS 계열에서 adduseruseradd의 심볼릭 링크입니다.)

  • useradd [옵션] [계정명]: 계정 생성
  • passwd [계정명]: 비밀번호 설정 (생략 시 현재 로그인된 계정의 비밀번호 변경)
# 1. 기본 생성 예시
[root@localhost ~]# useradd testuser
[root@localhost ~]# passwd testuser
Changing password for user testuser.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.

# 2. 옵션을 지정하여 상세 생성 예시
# -d: 홈 디렉토리 지정
# -u: UID 지정 (500번대 이상 권장)
# -g: GID 지정 (기존 그룹)
# -c: Comment (사용자 설명)
# -s: 쉘 지정 (/bin/bash 등)
[root@localhost ~]# useradd -d /home/was -u 510 -g 500 -c "WAS Admin" -s /bin/bash wasadmin

계정 관련 주요 파일 경로

  • /etc/passwd: 사용자 계정 정보가 저장됨 (형식: User:PWD:UID:GID:Comment:Home:Shell)
  • /etc/group: 그룹 정보가 저장됨

기타 유용한 명령어

  • su - [계정명]: 해당 계정으로 로그인 (환경변수 로드 포함)
  • usermod: 계정 속성 수정 (옵션은 useradd와 유사)
  • userdel -r [계정명]: 계정 및 홈 디렉토리까지 완전 삭제

2. 권한 관리 (Permission - chmod)

리눅스는 다중 사용자 시스템이므로 파일과 디렉토리에 대해 읽기(r), 쓰기(w), 실행(x) 권한을 엄격히 구분합니다.

권한 표기법 (Octal vs Symbolic)

  • r (Read, 4): 파일 읽기 / 디렉토리 목록 확인
  • w (Write, 2): 파일 수정 / 디렉토리 내 파일 생성 및 삭제
  • x (Execute, 1): 파일 실행 / 디렉토리 진입(cd)

권한 합산 예시:

  • 7 (rwx) = 4 + 2 + 1 : 모든 권한
  • 5 (r-x) = 4 + 0 + 1 : 읽기 및 실행
  • 6 (rw-) = 4 + 2 + 0 : 읽기 및 쓰기

chmod 사용 예제

# 1. 심볼릭 모드 (u:소유자, g:그룹, o:기타)
chmod u+x run.sh      # 소유자에게 실행 권한 추가
chmod g-w data.txt    # 그룹에게 쓰기 권한 제거

# 2. 8진수 모드 (실무에서 가장 많이 사용)
chmod 755 script.sh   # 소유자(rwx), 그룹(rx), 기타(rx)
chmod 644 config.conf # 소유자(rw), 그룹(r), 기타(r) - 일반적인 설정 파일
chmod 600 private.key # 소유자(rw)만 접근 가능 - 보안 중요 파일

# 3. 재귀적 변경 (-R 옵션)
chmod -R 755 /var/www/html # 하위 디렉토리 및 파일 전체 적용

3. 소유권 관리 (Ownership - chown)

파일이나 디렉토리의 소유자(Owner)와 소유 그룹(Group)을 변경할 때 사용합니다. 주로 파일 전송 후 권한을 맞출 때 사용됩니다.

# 소유자만 변경
chown user1 file.txt

# 소유자와 그룹을 동시에 변경 (소유자:그룹)
chown was:wasgroup app.log

# 디렉토리 하위 모든 파일의 소유권 변경 (-R)
chown -R apache:apache /var/www/html

4. 파일 정보 확인 및 해석 (ls -al)

ls -al 명령어를 통해 현재 권한 상태를 정확히 파악하는 것이 중요합니다.

drwxr-xr-x  2  root  root  4096  Dec 9 10:00  etc
----------  -  ----  ----  ----  -----------  ---
    (1)    (2)  (3)   (4)   (5)      (6)      (7)
  1. 파일 타입 및 권한: 첫 글자가 d면 디렉토리, -면 파일. 이후 3자리씩 소유자/그룹/기타 권한.
  2. 링크 수: 하드 링크의 개수.
  3. 소유자(User): 파일의 소유 계정 ID.
  4. 소유 그룹(Group): 파일의 소유 그룹 ID.
  5. 파일 크기: Byte 단위 크기.
  6. 수정 시간: 마지막 수정 날짜.
  7. 파일 이름: 파일명.

Next Step:
기본적인 권한 관리에 익숙해졌다면, SetUID, SetGID, Sticky Bit와 같은 특수 권한 설정을 학습하여 보안 레벨을 한 단계 높여보시기 바랍니다.

Open Stream →