2025. 4. 5. 19:49ㆍ42
필수 사항
이 프로젝트는 특정 규칙을 따라 첫 번째 서버를 설정하는 작업입니다. 서버를 설정하는 것이므로 최소한의 서비스만 설치해야 합니다. 이로 인해 그래픽 인터페이스는 필요하지 않습니다. 즉, X.org나 다른 그래픽 서버를 설치하는 것은 금지됩니다. 이를 어기면 점수는 0점이 됩니다.
운영 체제 선택
운영 체제로는 최신 안정 버전의 Debian(테스트나 불안정 버전 제외) 또는 최신 안정 버전의 Rocky 중 하나를 선택해야 합니다. 시스템 관리가 처음이라면 Debian을 추천합니다. Rocky 설정은 복잡하기 때문에, KDump는 설정할 필요가 없습니다. 하지만 SELinux는 시스템 시작 시 활성화되어야 하며, 프로젝트의 요구 사항에 맞게 SELinux 설정을 조정해야 합니다. Debian의 경우에는 AppArmor가 시스템 시작 시 반드시 활성화되어야 합니다.
LVM을 사용한 암호화된 파티션 생성
- 최소한 2개의 암호화된 파티션을 LVM을 사용하여 생성해야 합니다. 아래에 주어진 예시와 같은 방식으로 파티셔닝을 설정해야 합니다.
방어 시 질문 대비
- 방어 시, 선택한 운영 체제에 대해 몇 가지 질문을 받을 수 있습니다. 예를 들어, aptitude와 apt의 차이점이나 SELinux와 AppArmor의 역할에 대해 알아야 합니다. 즉, 자신이 사용하는 도구에 대해 잘 이해하고 있어야 합니다!
SSH 서비스 설정
- SSH 서비스는 필수적으로 포트 4242에서 실행되어야 합니다. 보안상, root 사용자로 SSH 접속이 불가능해야 합니다.
- 방어 시에는 새로운 사용자 계정을 설정하고, SSH 서비스가 어떻게 작동하는지 설명할 수 있어야 합니다.
방화벽 설정
- 운영 체제에 맞는 방화벽 도구를 사용하여, 포트 4242만 열리도록 설정해야 합니다.
- Debian에서는 UFW를 사용하고, Rocky에서는 firewalld를 사용해야 합니다.
- 방화벽은 가상 머신 시작 시 반드시 활성화되어야 합니다.
호스트네임 설정
- 가상 머신의 호스트네임은 자신의 로그인 ID + 42 형식으로 설정해야 합니다. 예를 들어, 로그인 ID가 wil이라면 호스트네임은 wil42가 되어야 합니다.
- 방어 시, 이 호스트네임을 수정해야 합니다.
강력한 비밀번호 정책 설정
- 비밀번호는 30일마다 만료되고, 최소 2일 후에 비밀번호를 변경할 수 있도록 설정해야 합니다.
- 비밀번호가 만료되기 7일 전에 경고 메시지가 사용자에게 전달되어야 합니다.
- 비밀번호는 최소 10자 이상이어야 하며, 대문자, 소문자, 숫자를 포함하고, 3개 이상의 연속된 동일 문자는 금지됩니다.
- 비밀번호는 사용자의 이름을 포함해서는 안 됩니다.
- 루트 계정의 비밀번호는 위의 정책을 따르되, 이전 비밀번호와 상관없이 7자 이상의 새로운 문자로 구성되어야 합니다.
sudo 구성 설정
- sudo 인증 실패 시 최대 3번만 시도할 수 있도록 설정해야 합니다.
- 잘못된 비밀번호로 sudo 명령어를 사용할 때 사용자 정의 오류 메시지가 표시되어야 합니다.
- sudo를 사용할 때 발생하는 모든 입력과 출력은 /var/log/sudo/ 폴더에 저장되어야 합니다.
- 보안을 위해 TTY 모드를 활성화해야 합니다.
- 또한, sudo로 실행할 수 있는 경로를 제한해야 하며, 예를 들어, /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin 경로만 허용되어야 합니다.
모니터링 스크립트 작성
- **monitoring.sh**라는 간단한 bash 스크립트를 작성해야 합니다. 서버가 시작될 때마다 10분마다 특정 정보를 모든 터미널에 표시해야 합니다.
- 스크립트는 아래와 같은 정보를 출력해야 합니다:
- 운영 체제 및 커널 아키텍처
- 물리적 프로세서 수
- 가상 프로세서 수
- 서버의 현재 사용 가능한 RAM과 사용률
- 서버의 현재 사용 가능한 저장소와 사용률
- 프로세서의 현재 사용률
- 마지막 재부팅 시간
- LVM 활성 여부
- 활성 연결 수
- 서버를 사용하는 사용자 수
- 서버의 IPv4 주소와 MAC 주소
- sudo 명령어로 실행된 명령의 수
- 방어 시, 이 스크립트가 어떻게 작동하는지 설명할 수 있어야 하며, 수정 없이 중단하는 방법도 알아야 합니다. 이 작업은 cron을 사용하여 주기적으로 실행될 수 있습니다.
추가 사항
- 모든 계정의 비밀번호를 변경해야 합니다. (루트 계정도 포함)
- 루트 계정의 비밀번호도 위에서 설정한 강력한 비밀번호 정책을 준수해야 합니다.
이 프로젝트는 서버 보안과 기본적인 시스템 관리에 대한 이해를 요구합니다. 각 항목을 설정하고, 방어 시 이를 정확히 설명할 수 있어야 합니다.
가상머신의 동작 원리 : 가상머신은 컴퓨터 안의 컴퓨터라는 느낌으로 하드웨어 같은 물리적 자원을 하이퍼 바이저를 통해서 추상화하여 가상의 운영체제환경에서 독립적으로 컴퓨팅 환경을 구현한 것이다
하이퍼 바이저 : 하드웨어 같은 물리적 요소를 추상화 시키며 추상화한 자원들을 독립된 가상의 환경에 배분하는 역활들을 한다
CentOs 와 Debian의 차이점 : CentOS는 레드햇 계열의 리눅스 배포판으로 기업친화적으로 만들어져서 안정성과 보안이 좋아서 서버환경에서 주로 쓰며 안정적으로 유지보수가 가능해서 기업들이 많이 쓴다
Debian은 커뮤니티적 요소를 띄고 있어서 CentOS만큼 주기적인 유지보수가 이루어지지않고 전세계의 개발자들이 자원해서 유지보수 업데이트를 한다 CentOS보다 보안성은 떨어지나 직관적이고 간단하게 설치할 수 있으며 aptitude같은 텍스트 기반 인터페이스를 지원하는 패키지 관리자 때문에 초보자들이 사용하기 좋다
가상머신의 목적 : 대표적으로 서버 가상화가 있다 가상머신은 하나의 컴퓨터에서 여러개의 가상환경을 만들 수 있다 그렇기 때문에 여러개의 가상 서버를 만들어서 자원의 활용률을 극한으로 끌어올릴 수 있다 또한 여러 운영체제를 동시에 사용하는 것이 가능해서 다양한 테스트 같은 것들을 해볼 수 있다
apt와 aptitude와의 차이점 : 둘 다 패키지 매니저로 업데이트 설치 제거같은 것이 가능하나 apt는 순수하게 명령어를 쳐서(커멘드 라인 기반) 패키지 관리가 가능하나 aptitude는 텍스트 기반의 ui를 지원한다 그래서 aptitude가 좀 더 사용자 친화적이다
Apparmor란 무엇인가? : 데비안에서 쓰는 경로 기반 보안 모듈이다 경로 기반이라는 것은 지정한 경로 이외의 액세스가 발생하면 차단시킨다( 정책 파일을 바탕으로 어떤 어플리케이션이 어떤 파일에 접근가능한지 등 애플리케이션이 실행 전 행동을 검사하고 실행여부를 결정하는 역활을 한다)
ufw 시작되었는지 : ufw status
ssh 시작되었는지 : ss -tunlp
데비안인지 확인 : hostnamectl
ssh는 암호화 된 방식으로 안전하게 다른 컴퓨터 네트워크에 접속할 수 있는 암호화 기반 원격 접속 프로토콜이다 모든 통신이 암호화 되어서 데이터가 중간에 노출될 일도 없고 비밀번호나 인증키를 통한 사용자 인증이 가능하다
ufw는 간단하게 방화벽을 설정하고 관리할 수 있도록 도와주는 사용자 친화적인 인터페이스를 제공하는 도구다 포트 설정이라던가 기본 차단정책 설정들을 하면서 보안을 강화시킬 수 있으며 명령어가 직관적이여서 초보자들도 쉽게 사용할 수 있다
About Sudo
apt-get install sudo // sudo 설치
visudo // sudo 설정으로 들어가기
securepath 경로에 :/snap/bin 추가하기 // sudo를 사용할 때 명령어를 찾는 경로를 /snap/bin으로 제한합니다.
snap 경로를 추가하는 것은 Ubuntu에서 자주 사용하는 패키지 관리 시스템이다
/snap/bin 경로에는 snap으로 설치한 프로그램들의 실행파일이 들어 있다.
즉 sudo 명령 실행시 새로운 쉘을 생성하고 그 안에서 명령을 실행하는데 이 명령을 찾을 경로를 나열한 것이 securepath
Defaults badpass_message="badpass"
Defaults authfail_message="authfail"
Defaults log_input
Defaults log_output
Defaults requiretty // sudo명령어를 실행할 때는 가상의 쉘에서 실행하는데 이때 가상의 쉘이 tty다 (tty는 리눅스 콘솔)
만약 이 설정이 없다면 sudo명령어를 쓰기 위해서 따로 tty를 할당해줘야한다
Defaults passwd_tries=3
Defautls iolog_dir="/var/log/sudo/"
추가하기
usermod -aG sudo [사용자 아이디]하기
AppArmor 적용
dpkg -l apparmor
만약 설치되어있지 않다면
apt-get install apparmor
apt-get install apparmor_utils
aa-enabled // 활성화되어있는지 확인하는 명령어
SSH적용
apt-get install ssh
cd /etc/ssh
vim sshd_cocnfig
port 4242 로 변경
permitlogin no 로 변경
후에
systemctl reload sshd
ss -tunlp로 상태 보기
ufw
apt install ufw // 설치
ufw status (verbose) // 활성화 되어있는지 확인 verbose를 쓰면 더 상세하게 알 수 있다
ufw allow 4242 // 4242포트 허용
ufw enable // 활성화
sudo ufw default deny : incoming policy changed to 'deny' //
systemctl restart ufw // 방화벽 다시 실행
ufw status numbered //
ufw delete number
lvm을 보여주는 명령어
lsblk
비밀번호 정책
vim /etc/login.defs로 들어가서
PASS_MAX_DAYS 30 # 30일마다 만료
PASS_MIN_DATS 2 # 변경 후 2일이 지나야 변경 가능
PASS_WARN_AGE 7 # 만료 7일 전 경고 메세지
이렇게 바꾼다
# 이미 만든 계정에 대해서 수정
# -m = mn_days, -M = max_days, -W = warn_age
chage -m 2 -M 30 -W 7 <username>
chage -l <username> # 확인
# PAM 모듈 사용
apt install libpam-pwquality
vim /etc/pam.d/common-password
# /etc/pam.d/common-password
password requisite pam_pwquality.so retry=3
minlen=10 # 10글자 이상,
dcredit=-1 # 숫자 1개 이상 포함
ucredit=-1 # 대문자 1개 이상 포함
lcredit=-1 # 소문자 1개 이상 포함
maxrepeat=3 # 연속적으로 같은 글자 반복 3글자까지만 가능
reject_username # 유저 이름 포함 안됨
difok=7 # 이전 패스워드와 7글자 이상 달라야 됨
enforce_for_root # 모든 정책이 root 계정에 대해서도 적용됨 (default - 에러 메시지는 나오지만 변경은 가능)
# root에게는 이전 패스워드 묻지 않으므로 difok=7이 적용되지 않음
# 새로 만든 비밀번호 정책에 따라 비밀번호 재설정
passwd -e <username> # 다음 로그인 때 비밀번호 재설정
su <username> # 로그인
리눅스 커널 : 하드웨어와 소프트웨어와의 중개역활을 하는 것 자원을 효율적으로 관리해준다(메모리 관리,프로세스 관리)
사용자가 프로그램을 실행하면 커널이 이에 맞춰 하드웨어 자원을 분배하는 식이다
방화벽 : 들어오는 트래픽을 모니터링하고 제어하는 네트워크 보안 시스템
u_name
#!/bin/bash
printf "#Architecture: "
uname -a
printf "#CPU physical : "
grep "physical id" /proc/cpuinfo | sort -u | wc -l
printf "#vCPU : "
cat /proc/cpuinfo | grep processor | wc -l
printf "#Memory Usage: "
free -m | grep Mem | awk '{printf"%d/%dMB (%.2f%%)\n", $3, $2, $3/$2 * 100}'
printf "#Disk Usage: "
df -a -BM | grep /dev/map | awk '{used+=$3; total+=$2} END {printf "#Disk Usage: %d/%dGb (%d%%)\n", used, total/1024, (used/total)*100}'
printf "#CPU load: "
mpstat | grep all | awk '{printf "%.2f%%\n", 100-$13}'
printf "#Last boot: "
who -b | sed 's/^ *system boot //g'
echo "#LVM use: $(lsblk | grep -q "lvm" && echo "yes" || echo "no")"
printf "#Connections TCP : %s ESTABLISHED\n" "$(ss -tan | grep ESTAB | wc -l)"
printf "#User log: "
who | wc -l
printf "#Network: IP %s (%s)\n" "$(ip -o -4 addr show | awk '!/ lo/ && /inet/ {print $4; exit}' | cut -d/ -f1)" "$(ip link show | awk '/ether/ {print $2; exit}')"
printf "#Sudo : %d cmd\n" "$(journalctl _COMM=sudo | grep COMMAND | wc -l)"
grep "physical id" /proc/cpuinfo | sort -u | wc -l
grep "physical id" /proc/cpuinfo :grep은 문자열을 찾는 명령어로 /proc/cpuinfo에서 "physical id"를 찾는 명령어다
sort -u : 중복을 제거해서 정렬하는 명령어
wc -l :줄을 세어준다
cat /proc/cpuinfo | grep processor | wc -l
cpuinfo를 출력한 뒤 processor가 있는 줄을 찾은 뒤 그 줄들을 센다
free -m | grep Mem | awk '{printf"%d/%dMB (%.2f%%)\n", $3, $2, $3/$2 * 100}'
free -m : 메모리 사용정보를 보여주는 명령어 -m은 MB단위로 보여줌
total used free shared buff/cache available
Mem: 7852 1234 4567 123 2050 5678
Swap: 2048 321 1727
grep을 써서 Mem부분을 끌어와서 $2(total), $3(used) 가져와서 가지고 출력한다
df -a -BM | grep /dev/map | awk '{used+=$3; total+=$2} END {printf "#Disk Usage: %d/%dGb (%d%%)\n", used, total/1024, (used/total)*100}'
df : 디스크 사용량을 보여주는 명령어 -a 모든 파일 시스템 다 포함해서 출력 -BM MB단위로 출력
grep /dev/map 가 들어가는 부분(LVM파티션)만 가져와서
awk '{used+=$3; total+=$2} : $2,$3 열을 가져와서 used하고 total에 더한다
END {printf '#Disk Usage : %d / %d GB (%d %%)\n",used,total/1024,(used/total)*100}' : awk에서 다 계산하고 나서 END는 마지막으로 실해시킬 명령어를 의미한다 |를 안쓰는 이유는 awk에서 실행된건 내부 변수라 다음 파이프로 못넘겨서다
mpstat | grep all | awk '{printf "%.2f%%\n", 100-$13}'
mpstat : cpu 사용률 통계를 보여주는 명령어다
$ mpstat
Linux 5.15.0-91-generic (ubuntu) 2025년 04월 16일 _x86_64_ (8 CPU)
08:50:10 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
08:50:10 all 1.23 0.00 0.87 0.10 0.00 0.05 0.00 0.00 0.00 97.75
grep all을 하면 all이 있는 줄을 가져온다
awk '{printf "%.2f%%\n", 100 - $13}' : awk는 다시 말하지만 한 줄씩 가져오는 명령어다 all이 있는 부분을 가져와 13번째 부분인 idle(유휴)가 있는걸 가져와 100-idle을 빼게 만들어서 cpu 사용률을 구했다
who -b | sed 's/^ *system boot //g'
who는 로그인된 사용자 정보를 출력하는 거고 -b는 마지막 부팅 시간을 출력시켜주는 옵션이다
sed 's/^ *system boot : sed는 치환시켜주는 명령어다 s/패턴/바꿀내용/g 이런 형식인데 공백 + system boot를 그냥 없애라는 명령어다
$(lsblk | grep -q "lvm" && echo "yes" || echo "no")"
lsblk로 디스크와 파티션 정보를 출력한다
grep -q "lvm"을 통해 있으면 1 없으면 0을 리턴 시켜서 yes아니면 no를 출력시키게 한다
- &&는 **"앞의 명령어가 성공했을 때만 다음 명령어를 실행"**하는 역할을 한다
- ||는 **"앞의 명령어가 실패했을 때만 다음 명령어를 실행"**하는 역할을 한다
printf "#Connections TCP : %s ESTABLISHED\n" "$(ss -tan | grep ESTAB | wc -l)"
ss -tan : 네트워크 상태를 보여주는 명령어다 t tcp만 표시 a : 모든 소켓만 표시 n : 네트워크 주소밑 포트 번호 표시
printf "#Network: IP %s (%s)\n" "$(ip -o -4 addr show | awk '!/ lo/ && /inet/ {print $4; exit}' | cut -d/ -f1)" "$(ip link show | awk '/ether/ {print $2; exit}')"
ip -o -4 addr show : ip v4주소를 한줄로 출력한다
awk '!/ lo/ && /inet/ {print $4; exit}' : !/lo 루프백인터페이스를 제외한 inet에만 해당하는 줄에서 $4번째 인자를 출력하고 exit
cut -d/ -f1 : 문자열을 특정 구분자로 나누고 그 중 일부를 출력하는 명령-d/ : 구분자를 /로 지정 -f1 : 첫번째 필드를 출력
ip link show : 시스템에 연결된 네트워크 인터페이스 상태를 보여주는 명령어
그곳에서 ether를 찾고 $2째 인자를 출력
printf "#Sudo : %d cmd\n" "$(journalctl _COMM=sudo | grep COMMAND | wc -l)"
journalctl : 시스템 로그 데이터를 출력하는 명령어다
_COMM : 는 실행된 명령어를 의미한다 = sudo를 넣은것은 sudo랑 관련된 명령어를 필터링 시키는거지
grep COMMAND : 실제 실행된 명령어를 가지고 와서
wc -l 를 통해서 줄 수를 세는거다
Cron
Cron이란 뭔지 : cron은 주기적인 작업을 자동적으로 실행하기 위한 시간기반 작업스케쥴러이다 그러니까 특정시간에 자동으로명령어를 실행할 수 있게 만드는 데몬이다
crontab -e를 통해서 설정한 것을 볼 수 있다
sudo systemctl stop cron
sudo systemctl start cron
데몬?
멀티태스킹 운영 체제에서 데몬은 사용자가 직접적으로 제어하지 않고, 백그라운드에서 돌면서 여러 작업을 하는 프로그램
'42' 카테고리의 다른 글
GET_NEXT_LINE (0) | 2025.03.21 |
---|---|
printf (0) | 2025.02.25 |
LIBFT를 설명 (0) | 2025.02.05 |