📚 /42cursus

1. 소개


YOU CAN DO ANYTHING YOU WANT TO DO, VIRTUAL MACHINE, THIS IS YOUR WORLD

42서울 본과정 입과 후 네번째로 수행한 과제로, 가상머신에 리눅스를 설치하고 공부하는 과정이다. 가상머신에 리눅스(Debian or Rocky)를 설치하고, LVM를 통한 파티션 설정과 기타 여러가지 기능을 직접 실습한다. 요구사항이 상당히 많고 처음 접한다면 배워야할 개념도 상당히 많다. 리눅스 설치는 하다보면 10번 넘게 하다보니… 중요한 개념 위주로만 정리했다.



2. 개념 정리


2-1. 운영체제

Operating System은 응용 프로그램 또는 사용자에게 컴퓨터 자원을 사용할 수 있는 인터페이스를 제공하고, 그 결과를 돌려주는 시스템 소프트웨어이다. CPU, Memory, 저장장치 등의 하드웨어를 관리하고 Process 관리, 자원 접근 및 할당, 파일 시스템을 관리한다.


2-2. Virtual Machine(VM)

하나의 컴퓨터 안에서 여러 개의 독립된 환경을 만들어 내는 것으로 물리적 하드웨어 시스템 위에 구축되는 소프트웨어 기반의 컴퓨터이다. 자체적인 OS, CPU, Memory, Network interface, 저장장치 등을 가지고 있고, Hypervisor를 통해 하드웨어에서 VM의 소스를 분리하고 적절히 프로비저닝하여 VM에서 사용할 수 있게 만든다.


2-3. Debian

다양한 환경에서 광범위 하게 사용되는 운영체제로, 다양한 소프트웨어 패키지를 제공한다. 커뮤니티 중심으로 개발되는 프로젝트이며, 자유 소프트웨어 원칙을 강력히 지지하는 것이 특징! 패키지 관리자로 Package management tools, 보안 모듈로 AppArmor를 사용한다.

2-4. Debian과 Rocky의 차이점

기준 Debian Rocky Linux
기반 리눅스 커널 기반 리눅스 커널 기반
목적 범용성, 다양한 환경에 적합 엔터프라이즈급 환경, 서버 및 데이터 센터에 적합
커뮤니티/개발 커뮤니티 중심, 자유 소프트웨어 원칙 강조 Red Hat Enterprise Linux(RHEL)와의 호환성 강조
패키지 관리자 APT 등 dnf 등
보안 모듈 AppArmor, SELinux 옵션 제공 권장 보안 모듈 SELinux
이식성 다양한 하드웨어 아키텍처 지원 주로 x86_64 아키텍처에 초점
사용자 친화성 데스크톱 및 서버 사용에 모두 적합 주로 서버 및 데이터 센터 운영에 초점
라이선스 대부분 GPL 및 다양한 오픈 소스 라이선스 GPL 및 RHEL 호환 라이선스

2-5. Package management tools

Linux의 패키징 시스템을 관리하는 도구 모음으로 패키지 설치, 업그레이드, 제거 등을 자동화하여 쉽게 관리 가능하다. 특정 소프트웨어가 필요로 하는 모든 추가 패키지를 자동으로 파악하고 설치함으로써 의존성 문제를 해결했다. Debian과 Rocky 사이의 Package management tools의 차이점을 더 공부해보자 :)

Debian-APT

Debian은 .deb 패키지 포맷을 사용하며, 패키지 관리 도구로는 주로 **APT (Advanced Package Tool)**를 사용한다. APT는 패키지 설치, 업그레이드, 삭제 등을 쉽게 관리할 수 있도록 도와준다. APT는 의존성 문제를 자동으로 해결하며, 패키지 소스 리스트를 통해 소프트웨어를 중앙 저장소에서 쉽게 설치할 수 있다.

Rocky-dnf

Rocky Linux는 .rpm 포맷을 사용하며, dnf (Dandified YUM) 패키지 관리 도구를 사용한다. dnf는 Red Hat 계열에서 사용되는 패키지 관리 도구로, YUM(Yellowdog Updater, Modified)을 대체하여 더 나은 성능과 의존성 해결 능력을 제공한다.

차이점 요약


2-6. AppArmor

시스템 관리자가 개별 응용프로그램이 엑세스 할 수 있는 시스템 리소스와 권한을 제어 할 수 있게 하는 Linux Kernel 보안 모듈로 MAC(Mandatory Access Control) 방식을 통해 사전에 정의된 규칙(Profile)에 기반하여 권한을 제어한다. 즉, 특정 프로그램이 파일/네트워크/기타 시스템 자원에 접근하는 방식을 경로를 통해 구분한다.

타 모듈에 비해 간단한 설정이 장점이지만, 단순한만큼 복잡한 보안 요구 사항을 충족시키지 못할 수 있으며 Profile 로딩 시간 때문에 시스템 시작 속도에 영향을 미칠 수 있다. 또한 동일 어플리케이션에 대하여 여러 경로가 존재할 수 있기 때문, 한 프로그램에 대하여 여러 보안 Profile이 생성될 수 있다.

그렇다면 AppArmor가 없었던 시절에는 어떻게 관리했을까?**

AppArmor가 도입되기 전에는 Linux 시스템에서 주로 DAC (Discretionary Access Control) 방식으로 권한을 관리했다. DAC는 파일이나 디렉토리의 소유자가 누구에게 접근 권한을 부여할지 결정하는 방식이다. Linux에서 가장 흔한 형태의 DAC는 파일의 소유자, 그룹, 기타 사용자에 대한 파일 권한 (읽기, 쓰기, 실행 권한) 설정이다.

AppArmor가 도입되기 전에는 SELinux와 같은 다른 MAC 방식의 보안 모듈도 존재했지만, 설정이 복잡하고 관리가 어려워 일부 시스템 관리자들에게는 DAC 방식이 여전히 주로 사용되었다.


2-7. Sudo

Sudo(Superuser do)는 Unix 및 Linux 기반 시스템에서 슈퍼유저 또는 root 권한으로 명령을 실행할 수 있게 해주는 프로그램이다. 일반 사용자에게 관리자(루트) 권한으로 명령을 실행할 수 있는 권한을 제한적으로 부여하여 루트 사용자로의 지속적인 로그인을 방지하고, 보안 위험을 줄일 수 있다. 또한 루트 권한으로 실행된 모든 명령과 사용자를 기록 가능해 시스템 관리, 감시 추적 등이 용이하다.

sudo log를 어디서 확인 할 수 있을까?**

sudo 명령어로 실행된 작업에 대한 로그는 보통 /var/log/auth.log 또는 /var/log/secure 파일에서 확인할 수 있다. 사용 중인 배포판에 따라 경로가 약간 다를 수 있지만, 일반적으로 다음 경로에서 sudo 관련 로그를 찾을 수 있다:

로그 파일에서 sudo 명령을 필터링하여 확인하려면 grep 명령을 사용할 수 있다.

grep 'sudo' /var/log/auth.log    # Debian 기반 시스템
grep 'sudo' /var/log/secure      # Red Hat 기반 시스템

2-8. TTY

TTY(Tele Type Writer)는 컴퓨터와 연결된 가상의 터미널로 한 컴퓨터를 여럿이서 사용하기 위해 (물리적 한계 극복) 사용했으며 현재 UNIX 시스템에서 터미널 역할을 수행한다. 텍스트 기반 인터페이스와 다중 터미널 세션 기능, 원격 접속과 시스템 관리 및 표준 입출력 관리가 특징이다. 이때 Sudo가 TTY를 요구한다는 것은 Sudo 명령어를 사용자가 직접 터미널 세션에서 입력해야만 SUdo 권한을 사용할 수 있다는 것을 의미한다.

이것이 왜 필요한지 공부해보자!

sudo가 TTY(Tele Type Writer)를 요구하는 이유는 보안 측면에서 사용자 인증을 강화하고, 비정상적인 사용을 방지하기 위해서이다. TTY는 물리적 또는 가상 터미널로서 사용자가 직접 명령을 입력하는 환경을 제공하는데, 이를 요구함으로써 sudo 명령을 자동화된 스크립트나 백그라운드 프로세스에서 악용하는 것을 막을 수 있다. 이 방식은 다음과 같은 이유로 보안이 강화된다.

  1. 직접 사용자 인증 요구
    TTY를 요구함으로써 sudo 명령이 직접 사용자가 터미널 세션을 통해 입력되었는지 확인할 수 있다. 이 과정에서 사용자의 비밀번호를 묻거나, 사용자가 로그인된 터미널에서 명령이 실행되었는지 확인할 수 있어 인증 절차를 강화한다.

  2. 악성 스크립트 방지
    자동화된 스크립트나 원격 프로세스가 루트 권한을 남용하지 못하게 한다. 만약 TTY 없이 sudo가 허용된다면, 악의적인 사용자가 원격으로 시스템에 접근해 루트 권한을 얻는 데 악용할 수 있다. TTY를 요구함으로써 사용자가 직접 명령을 입력하지 않는 비정상적인 상황에서 sudo 사용을 막는다.

  3. 로그 추적 및 감시 강화
    TTY 환경에서는 사용자가 어떤 터미널에서 어떤 명령을 실행했는지 명확하게 기록할 수 있다. 이를 통해 sudo 사용 내역을 보다 쉽게 추적할 수 있고, 누가 언제 어디서 루트 권한으로 명령을 실행했는지 확인할 수 있어 보안 관리가 용이해진다.

TTY 요구의 비활성화
때로는 sudo가 TTY 없이도 작동해야 하는 경우가 있다. 예를 들어, 특정 자동화 작업이나 데몬 프로세스에서 sudo 명령이 필요할 때 TTY 요구를 비활성화할 수 있다. 이를 위해서는 /etc/sudoers 파일에 다음과 같은 규칙을 추가한다:

Defaults !requiretty

그러나, 이 설정은 보안 위험을 초래할 수 있으므로 매우 신중하게 사용해야 한다. TTY 요구는 사용자가 터미널을 통해 직접 인증할 수 있게 하고, 시스템의 보안을 강화하기 위한 중요한 요소이다.


2-9. UFW

UFW(Uncomlicted FireWall)은 사용자 친화적인 방화벽 관리 인터페이스로 기존 iptables의 복잡성을 단순화 시켰으며 주로 입출력 트래픽을 제어하고, 원하지 않는 네트워크 접근을 차단하기 위해 사용한다.


2-10. SSH

SSH(Secure SHell) 이란 컴퓨터가 같은 public network를 통해 통신 시 보안적으로 안전하게 통신을 하기 위한 프로토콜으로 보안적으로 안전한 채널을 구축한 뒤 정보를 교환하는 방식(키 기반의 인증 / 암호화)이다.

SSH의 작동원리를 공부해보자!

SSH(Secure SHell)는 결국 안전한 원격 접속을 가능하게 하는 프로토콜로, 대칭키 암호화비대칭키 암호화를 결합하여 작동하며, 이 과정을 통해 안전한 통신을 보장한다. SSH는 또한 키 검증을 통해 통신 상대방의 신뢰성을 확인한다. 각 암호화 방식과 키 검증 방법을 이해하면 SSH의 작동 원리를 잘 이해할 수 있다.

SSH의 초기 연결 과정에서, 클라이언트는 서버의 공개키를 사용하여 세션을 설정하고 대칭키를 암호화하여 전송한다. 서버는 이 대칭키를 자신의 개인키로 복호화하고, 그 후에는 대칭키를 사용해 암호화된 데이터 통신을 계속한다. 이 과정에서 대칭키는 보안이 강화된 상태로 안전하게 전달된다.

SSH 작동 과정 요약

  1. 세션 설정: 클라이언트는 서버와 연결을 시도하고, 서버는 자신의 공개키를 클라이언트에 제공한다.
  2. 세션 키 교환: 클라이언트는 비대칭키 암호화를 사용해 서버의 공개키로 대칭키(세션 키)를 암호화하여 전송한다.
  3. 세션 시작: 서버는 개인키로 대칭키를 복호화하고, 이제부터 대칭키를 사용해 빠르고 효율적인 암호화 통신이 시작된다.

키 검증 방식

SSH는 호스트 키 검증을 통해 클라이언트가 서버의 신뢰성을 확인할 수 있도록 한다. 클라이언트가 서버에 처음 연결할 때 서버는 자신의 공개키를 제공하고, 클라이언트는 이를 기록한다. 이후 연결 시 클라이언트는 다음 방법을 통해 서버의 신뢰성을 검증한다:

요약

이러한 SSH의 작동 방식은 클라이언트와 서버 간의 안전한 통신을 보장하며, 네트워크 상의 다양한 보안 위협으로부터 보호할 수 있게 한다.


2-11. Linux Partition


2-12. MBR

MBR은 하드 디스크의 첫 번째 섹터(512바이트)에 위치한 데이터로, 하드 디스크의 전체 구조와 운영 체제(OS)의 부팅 정보를 저장하는 영역이다.

MBR 구성

  1. 부트 로더: 운영 체제를 부팅하기 위한 작은 프로그램이 포함되어 있다. 이 부트 로더는 운영 체제가 설치된 파티션으로의 부팅을 초기화한다.
  2. 파티션 테이블: 디스크의 파티션 정보를 저장하는 테이블로, 최대 4개의 기본(primary) 파티션 또는 확장 파티션을 관리할 수 있다.
  3. 디스크 시그니처: 디스크를 고유하게 식별하는 ID로 사용된다.

sda5

sda5는 디스크의 특정 파티션을 나타낸다. 이를 좀 더 구체적으로 살펴보면:

MBR과 sda5의 관계

MBR의 파티션 테이블은 최대 4개의 기본(primary) 파티션 또는 3개의 기본 파티션과 1개의 확장 파티션을 기록할 수 있다. 확장 파티션은 여러 논리(logical) 파티션을 포함할 수 있으며, sda5는 이러한 확장 파티션 내에 위치한 첫 번째 논리 파티션이다.

부트 프로세스에서의 역할

MBR은 부트 로더를 통해 운영 체제를 로드할 파티션을 결정한다. 만약 운영 체제가 sda5에 설치되어 있다면, MBR의 부트 로더는 sda5로 부팅을 진행하게 된다. 이 과정에서 MBR은 파티션 테이블을 참조해 sda5의 시작 위치를 찾아 운영 체제가 위치한 논리 파티션으로 부팅을 넘긴다.

요약

이처럼 MBR과 sda5는 디스크의 부트 프로세스와 파티션 구조에서 중요한 역할을 하며, MBR은 부팅 시 운영 체제가 위치한 논리 파티션(sda5)을 식별하고 부팅을 진행하게 된다.


2-13. LVM

LVM(Linux Volume Manager)은 Linux에서 복잡한 스토리지 구성을 효율적으로 관리하기 위한 시스템으로 물리적 디스크를 하나의 논리적 볼륨으로 결합할 수 있고, 볼륨의 크기를 쉽게 조정 가능하다.

LVM 단위 구성


2-14. Cron

Cron이란 OS Time-based job scheduling으로 demon의 일종이다. /etc/crontab 에 위치해 있다. Cron 코드 작성 시 Sudo 명령어의 갯수를 잘 카운트해야한다!

cron code
# The architecture of your operating system and its kernel version.
printf "#Architecture: "
uname -a

# The number of physical processors
printf "#CPU physical : "
cat /proc/cpuinfo | grep "physical id" | sort -u | wc -l

# The number of virtual processors
printf "#vCPU : "
cat /proc/cpuinfo | grep processor | wc -l

# The current available RAM on your server and its utilization rate as a percentage
printf "#Memory Usage: "
m_total=$(free -m | awk '$1 == "Mem:" {print $2}')
m_used=$(free -m | awk '$1 == "Mem:" {print $3}')
m_usage=$(awk "BEGIN {printf \"%.2f\", ($m_used/$m_total)*100}")
printf "%s/%s MB (%s%%)\n" "$m_used" "$m_total" "$m_usage"

# The current available memory on your server and its utilization rate as a percentage.
printf "#Disk Usage: "
d_total=$(df -Bg | grep '^/dev/' | grep -v '/boot$' | awk '{ft += $2} END {print ft}')
d_used=$(df -Bm | grep '^/dev/' | grep -v '/boot$' | awk '{ut += $3} END {print ut}')
d_per=$(df -Bm | grep '^/dev/' | grep -v '/boot$' | awk '{ut += $3} {ft += $2} END {printf("%d%%", ut/ft*100)}')
printf "%s/%sGb (%s)\n" "$d_used" "$d_total" "$d_per"


# The current utilization rate of your processors as a percentage
printf "#CPU load: "
mpstat | grep all | awk '{printf "%.1f%%\n", 100-$13}'

# The date and time of the last reboot
printf "#Last boot: "
last_boot=$(who -b | awk '{print $3, $4}')
printf "%s\n" "$last_boot"

# Whether LVM is active or not
if lsblk | grep -q "lvm"; then
    printf "#LVM use: yes\n"
else
    printf "#LVM use: no\n"
fi

# The number of active connections
printf "#Connections TCP : "
ss | grep 'ESTAB' | wc -l | tr -d '\n'
printf " ESTABLISHED\n"

# The number of users using the server
printf "#User log: "
who | wc -l

# The IPv4 address of your server and its MAC (Media Access Control) address
ip=$(hostname -I)
mac=$(ip link show | awk '$1 == "link/ether" {print $2}')
printf "#Network: IP %s (%s)\n" "$ip" "$mac"

# The number of commands executed with the sudo program
printf "#Sudo : "
grep 'COMMAND=' /var/log/auth.log | wc -l | tr -d '\n'
printf " cmd\n"