서버 및 시스템 보안 개요
1. 서버 시장 및 보안 개요
- 대형 서버 시장: Unix 기반, 클라우드 환경에서는 Linux 사용
- 시스템 보안 주요 요소
- 계정관리: ID/PW, OTP, 생체 인증 등
- 세션 관리: 일정 시간 후 세션 종료
- 접근 제어: 네트워크 내 보호
- 권한 관리: 사용자별 적절한 권한 부여
- 로그 관리: 시스템 활동 기록
- 취약점 관리: 보안 결함 관리
- 2. 계정 관리
- 인증 방법 (4가지)
- 알고 있는 것 → ID/PW
- 가지고 있는 것 → OTP, 출입카드
- 자신의 모습 → 지문, 홍채 인식
- 위치하는 곳 → 콜백 인증
- 리눅스 계정 관리
- 관리자(root) 계정
- 시스템 전체 관리 가능 → 엄격한 보안 필요
- 원격 접속 금지, 복잡한 비밀번호 사용
- 일반 사용자 계정
- 제한된 권한, 그룹을 통해 권한 관리
- 관리자(root) 계정
- 원격 접속(root 계정 보안)
- 기본적으로 root 원격 로그인 금지
- SSH 서버 설정 방법
- 인증 방법 (4가지)
- 2. 계정 관리
sudo apt update
sudo apt install openssh-server
systemctl status ssh
SSH 보안 설정 파일: /etc/ssh/sshd_config
- 기본 포트(22) 변경
- PermitRootLogin no 설정
2. 비밀번호 및 계정 파일 관리
- 비밀번호 파일 보호 (shadow 파일 사용)
- /etc/passwd → 계정 정보 저장
- /etc/shadow → 암호화된 비밀번호 저장 (root만 접근 가능)
- 비밀번호 관리 명령어
adduser [계정명] # 사용자 추가
passwd [계정명] # 비밀번호 변경
deluser [계정명] # 사용자 삭제 (root 권한 필요)
- 그룹 관리 명령어
addgroup [그룹명] # 그룹 추가
delgroup [그룹명] # 그룹 삭제
groups # 현재 그룹 확인
3. 계정 전환 및 대리 실행
- 사용자 전환 (su 명령어)
- su [계정명] → 계정 전환 (디렉토리 유지)
- su - [계정명] → 홈 디렉토리 변경 (새 로그인처럼)
- 대리 실행 (sudo 명령어)
- 특정 사용자 권한으로 명령 실행
- 예시:
sudo -u user 명령어
- sudoers 파일 수정 필요: /etc/sudoers
4. 패스워드 정책 및 보안
- 좋은 패스워드 정책
- 8자 이상, 숫자/대소문자/특수문자 포함
- 60~90일마다 변경
- 5회 이상 로그인 실패 시 계정 잠금
- 6. 기타 계정 관리
- 데이터베이스 계정 관리
- MS-SQL 관리자 계정: sa
- Oracle 관리자 계정: sys, system
- system 계정은 DB 생성 불가
- 응용 프로그램 계정 관리
- 보안이 취약한 프로그램(TFTP) 대신 SFTP 사용
- 네트워크 장비 계정 관리
- 기본적으로 패스워드만 있으면 접근 가능
- 사용자 모드 vs 관리자 모드 (enable 명령어 필요)
- 데이터베이스 계정 관리
- 예시)
# 사용자 추가
sudo adduser aa # 'aa'라는 새 사용자 생성
# 비밀번호 변경
sudo passwd aa # 'aa' 사용자의 비밀번호 변경
# 사용자 삭제 (홈 디렉토리는 유지)
sudo deluser aa # 'aa' 사용자 삭제
# 사용자 삭제 (홈 디렉토리까지 삭제)
sudo deluser --remove-home aa # 'aa' 사용자 및 홈 디렉토리 삭제
# 그룹 추가
sudo addgroup developers # 'developers' 그룹 생성
# 그룹 삭제
sudo delgroup developers # 'developers' 그룹 삭제
# 현재 사용자의 그룹 확인
groups # 현재 로그인한 사용자가 속한 그룹 확인
# 특정 사용자의 그룹 확인
groups aa # 'aa' 사용자가 속한 그룹 확인
# 사용자 계정 전환 (현재 디렉토리 유지)
su aa # 'aa' 계정으로 전환
# 사용자 계정 전환 (홈 디렉토리로 이동)
su - aa # 'aa' 계정으로 전환하며 홈 디렉토리로 이동
1. 세션 관리
클라이언트와 서버 간의 연결 상태 유지
-세션이 필요한 이유
- HTTP는 stateless(상태 저장 X), connectionless(1회성 연결) → 세션으로 해결
- 일정 시간이 지나면 자동 종료하여 비인가자가 세션을 탈취하지 못하도록 보호
2. 패치 관리
보안 취약점 해결 및 시스템 안정성 유지
-패치가 필요한 이유
-
- 운영체제도 소프트웨어 → 새로운 버그 & 취약점 발생
- 보안 공격(예: 해킹) 방지
- (예시) Ubuntu LTS의 보안 업데이트로 19개 취약점 해결 (2023년)
3. 로그 관리
시스템 활동 기록 & 보안 점검
-로그의 역할
-
- 시스템의 성능, 오류, 보안 정보 기록
- 서버 관리자는 정기적으로 로그 분석
- 해킹 시도 파악 및 대응
-로그 저장 규칙 (syslog.conf 예시)
*.emerg * # 긴급(emergency) 로그는 모든 곳에 기록
*.alert /var/adm/syslog.log # 심각한(alert) 오류는 특정 파일에 저장
authpriv.none /var/log/messages # 보안 관련 로그는 남기지 않음
authpriv.* /var/log/messages # 보안 관련 로그를 저장
-syslog의 로그 수준
- 모든 로그를 남기는 것은 성능과 부하 측면에서 현실적으로 불가능
- 어느 이상의 심각한 수준에 대해 선별적으로 로그를 남기는 것을 권장
-syslog로그 파일의 종류 및 경로
대부분 로그 파일의 경로가 미리 약속되어 있음
-로그 관리 주의사항
- 로그 파일 용량 정기 점검
- 보관 주기 설정 (오래된 로그 삭제 or 백업)
- 보안 침입 시도 감지 & 분석
4. 서비스 관리
불필요한 서비스 차단 & 보안 강화
-이메일 서비스 (sendmail) 보안
- 보안 공격의 주요 대상 (예: 버퍼 오버플로 공격)
- 가능하면 비활성화
systemctl stop sendmail # 서비스 정지
systemctl disable sendmail # 부팅 시 자동 실행 비활성화
- 대체 서비스 추천: Postfix (SMTP) + Dovecot (IMAP/POP3) + 스팸 필터
- 반드시 sendmail을 사용해야 하면 최신 버전 유지 (KISA 참고)
5. 안전한 소프트웨어 개발 (시큐어 코딩)
소스코드에서 보안 취약점 제거
-대표적인 시큐어 코딩 가이드
- CERT (국제 표준)
- 행정안전부 소프트웨어 보안 개발 가이드 (boho.or.kr 참고)
6. 주요 보안 공격 & 대응 방법
① 메모리 버퍼 오버플로 공격
-개념
- 허용된 크기보다 더 큰 데이터를 입력하여 메모리를 침범
- 악성 코드 실행 가능
-취약한 C 코드 예제
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[]) {
char buffer[10]; // 크기가 10인 버퍼
strcpy(buffer, argv[1]); // 버퍼 크기 체크 X (보안 취약)
printf("%s\n", buffer);
}
-대응 방법
입력값 크기 검증 (strlen 사용)
if (argv[1] != NULL && strlen(argv[1]) < sizeof(buffer)) {
strcpy(buffer, argv[1]);
}
-보안 라이브러리 사용 (strncpy 등)
-정적 분석 도구 활용 (valgrind, cppcheck 등)
② 포맷 스트링 공격
-개념
- printf() 등에서 포맷 문자열(%x, %n 등)을 악용하여 메모리 조작
-취약한 C 코드 예제
#include <stdio.h>
int main(int argc, char* argv[]) {
printf(argv[1]); // 보안 취약 (사용자가 직접 입력값을 전달)
}
-대응 방법
printf("%s", argv[1]); // 안전한 코드
-%n 등 위험한 포맷 스트링 사용 제한
- 정적 분석 도구 활용하여 취약점 검사
③ 경쟁 조건 (Race Condition) 공격
-개념
- 여러 프로세스가 동시에 같은 파일/자원에 접근하여 보안 문제 발생
- 예) 하나의 파일을 두 개의 프로세스가 동시에 수정하려고 할 때
-대응 방법
동기화 기법 사용 (Mutex, Lock)
파일 접근 시 순서 강제 설정
실습
vi로 test.c 생성 후 컴파일 방법
vi test.c //vi [편집 하려는 file의 경로]
i //현재 커서가 있는 곳에 글자 추가
#include<stdio.h>
int main(int argc, char* gray[])
{
int a = 100;
printf("%x \n", a);
printf("%d \n", a);
return 0;
}
//esc키
:wq // 현재 편집하는 파일을 저장하고 vi에디터 종료
gcc test.c -o test
./test
//출력결과
//60
//100