Information Security Management System(ISMS) / 한국 정보보호 관리체계 인증(K-ISMS)
사실 처음 공부를 시작할때 개발자 vs 엔지니어 로 고민 했던 사람들이 많았다.
그런 우리의 고민을 모든 날려버린 직업이 발생하는데 바로 DevOps 이다.
개발자에게 엔지니어의 역할을 맞기거나 엔지니어에 개발을 요구 하는…
그래서 숙련 되지 않는 엔지니어를 위해서(혹은 개발자지만 엔지니어 역량이 요구되는 직무인 사람) 서버 기본 보안 설정에 대한 글을 포스팅 하게 되었다.
(ISMS 혹은 K-ISMS 에 필요한 포스팅을 했을때 블로그에 해당 링크를 통해 유입 되는 사람이 많다.)
사실 한국 과학기술정보통신부에서 발행하는 문서 “201712_주요정보통신기반시설_기술적_취약점_분석평가_가이드” 에 따라
centos 7 에서 설정해줘야 하는 부분만 스크립트로 작성 하였다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
#!/bin/bash ### 루트 권한 check U=$(env | grep "^SUDO_USER=" | cut -d"=" -f2) if [[ x$U == "x" ]];then echo "should get super user permition with ( sudo -i )" exit 1 fi ## root 계정의 원격 접속 제한 TARGET=/etc/ssh/sshd_config CHECK=$(grep -n ^PermitRootLogin $TARGET) if [[ -n $CHECK ]];then TNUM=$(cut -d':' -f1 <<< $CHECK) TSTR=$(cut -d':' -f2 <<< $CHECK) if [[ $(echo $CHECK | grep -i yes$) ]];then sed -i "${TNUM}s/$TSTR/PermitRootLogin no/g" $TARGET fi else echo "PermitRootLogin no" >> $TARGET fi unset TARGET CHECK TNUM TSTR ## 계정 잠금 임계값 설정 if [[ -z $(grep "pam_tally2.so" /etc/pam.d/password-auth-ac) ]];then sed -i '5 i\auth required pam_tally2.so deny=5 magic_root unlock_time=600; 11 i\account required pam_tally2.so' /etc/pam.d/password-auth-ac fi if [[ -z $(grep "pam_tally2.so" /etc/pam.d/system-auth-ac) ]];then sed -i '5 i\auth required pam_tally2.so deny=5 magic_root unlock_time=600; 11 i\account required pam_tally2.so' /etc/pam.d/system-auth-ac fi ## 패스워드 복잡성 설정 - 패스워드 최소 길이 설정 TARGET=/etc/login.defs CHECK=$(grep -n ^PASS_MIN_LEN $TARGET) if [[ -n $CHECK ]];then TNUM=$(cut -d':' -f1 <<< $CHECK) TSTR=$(cut -d':' -f2 <<< $CHECK) TVELUE=$(awk '{print $2}' <<< $TSTR) if [ $TVELUE -lt 8 ];then sed -i "${TNUM}s/$TSTR/PASS_MIN_LEN\t8/g" $TARGET fi else echo "PASS_MIN_LEN\t8" >> $TARGET fi ## 패스워드 복잡성 설정 - 패스워드 최대 사용 기간 설정 TARGET=/etc/login.defs CHECK=$(grep -n ^PASS_MAX_DAYS $TARGET) if [[ -n $CHECK ]];then TNUM=$(cut -d':' -f1 <<< $CHECK) TSTR=$(cut -d':' -f2 <<< $CHECK) TVELUE=$(awk '{print $2}' <<< $TSTR) if [ $TVELUE -gt 90 ];then sed -i "${TNUM}s/$TSTR/PASS_MAX_DAYS\t90/g" $TARGET fi else echo "PASS_MAX_DAYS\t90" >> $TARGET fi ## 패스워드 복잡성 설정 - 패스워드 최소 사용 기간 설정(0 일 설정 금지) TARGET=/etc/login.defs CHECK=$(grep -n ^PASS_MIN_DAYS $TARGET) if [[ -n $CHECK ]];then TNUM=$(cut -d':' -f1 <<< $CHECK) TSTR=$(cut -d':' -f2 <<< $CHECK) TVELUE=$(awk '{print $2}' <<< $TSTR) if [ $TVELUE -eq 0 ];then sed -i "${TNUM}s/$TSTR/PASS_MIN_DAYS\t1/g" $TARGET fi else echo "PASS_MIN_DAYS\t1" >> $TARGET fi ## ssh - Session Timeout 설정 if [[ -z $(grep "^TMOUT=600" /etc/profile) ]];then echo "TMOUT=600" >> /etc/profile fi ## UMASK 설정 관리 TARGET=/etc/login.defs CHECK=$(grep -n ^UMASK $TARGET) if [[ -n $CHECK ]];then TNUM=$(cut -d':' -f1 <<< $CHECK) TSTR=$(cut -d':' -f2 <<< $CHECK) TVELUE=$(awk '{print $2}' <<< $TSTR) if [ $TVELUE -lt 22 ];then sed -i "${TNUM}s/$TSTR/UMASK\t\t22/g" $TARGET fi else echo "UMASK\t\t22" >> $TARGET fi ## cron 파일 소유자 및 권한 설정 (권한 제한(only root)) echo root > /etc/cron.allow ## 패스워드 파일 보호 / /etc/passwd 파일 소유자 및 권한 설정 chmod 400 /etc/shadow chown root:root /etc/shadow ## 로그온시 경고 메세지 제공 echo -e "\e[31;1m o o O o o o o o-O-o o o o-o | | / \ |\ | |\ | | |\ | o o o o o---o | \ | | \ | | | \ | | -o \ / \ / | | | \| | \| | | \| o | o o o o o o o o o-O-o o o o-o \e[32;1m This Server useable to Authorization User Only. if you not of that. go away! \e[0m" > /etc/motd ### 어드민 그룹(wheel) 현재 접속한 ID 설정 ADMINGROUP="wheel" if [[ ! -z $U ]];then ACID=$U fi ## 어드민 그룹이 없을 경우 생성한다. if [[ ! -z $(id $ACID 2>/dev/null) ]];then if [[ -z $(grep ^$ADMINGROUP: /etc/group) ]];then groupadd -r $ADMINGROUP fi ## root 계정 su 제한 chgrp $ADMINGROUP $(which su) chmod 4750 $(which su) ## SUID, SGID, Sticky bit 설정 파일 점검 chgrp $ADMINGROUP $(which newgrp) chmod 4750 $(which newgrp) $(which unix_chkpwd) ## 불필요한 계정 제거 ID_LIST=( adm lp sync shutdown halt news uucp operator games gopher nfsnobody squid ftp www-data list ) for a in ${ID_LIST[@]} do if [[ ! -z $(id $a 2>/dev/null) ]];then userdel $a DELLIST="$DELLIST $a" fi done if [[ ! -z $DELLIST ]];then echo -e "\e[31;1m"$DELLIST" art deleted.\e[0m";fi unset ID_LIST DELLIST ADMINGROUP ## 홈 디렉토리의 존재 관리 echo "아래 리스트는 계정별 홈디렉토리를 나타낸다. / 홈디렉토리가 없는 계정이 존재해서는 안된다." for b in $(awk -F: '!/^#/&&$6!~/^\/dev\/null$/&&$6!~/^\/$/{print $1":"$6}' /etc/passwd) do USERNAME=$(cut -d: -f1 <<< $b) USERHOME=$(cut -d: -f2 <<< $b) if [ ! -d $USERHOME ];then echo "$USERNAME" else if [[ -z $(ls -dal $USERHOME|grep ^d......--.) ]];then echo -en "\e[31;1m$USERNAME" ls --time-style=long-iso -dal $(readlink -f $USERHOME)|awk '{print "\t"$1"\t"$3"\t"$4"\t"$8}' fi;fi done echo -e "\e[0m" ## 계정이 존재하지 않는 GID 금지 echo "아래 리스트는 그룹별 속한 아이디를 보여 준다. / 속한 아이디가 없는 그룹은 삭제해야 한다." for a in $(cat /etc/group|grep -v ^#) do GROUPNAME=$(cut -d: -f1 <<< "$a") GROUPNUM=$(cut -d: -f3 <<< "$a") ACCHECK=$(awk -F: '!/^#/&&$4~/^'$GROUPNUM'$/{print $1}' /etc/passwd) if [[ -z $ACCHECK ]];then if [[ $GROUPNAME == "cdrom" ]] || [[ $GROUPNAME == "floppy" ]] || [[ $GROUPNAME == "tape" ]] || [[ $GROUPNAME == "dialout" ]];then echo -e "\e[34;1m$GROUPNAME group for default devices\e[0m" #> /dev/null elif [[ $GROUPNAME == "disk" ]] || [[ $GROUPNAME == "sys" ]] || [[ $GROUPNAME == "mem" ]] || [[ $GROUPNAME == "kmem" ]] || [[ $GROUPNAME == "man" ]] || [[ $GROUPNAME == "systemd-journal" ]] || [[ $GROUPNAME == "lock" ]] || [[ $GROUPNAME == "man" ]] || [[ $GROUPNAME == "input" ]];then echo -e "\e[34;1m$GROUPNAME group for Linux kernel\e[0m" #> /dev/null elif [[ $GROUPNAME == "man" ]];then echo -e "\e[34;1m$GROUPNAME group for manual\e[0m" #> /dev/null else if [[ -z $(groupmems -l -g $GROUPNAME) ]];then if [[ -z $(find / -xdev -group $GROUPNAME) ]];then echo -e "\e[31;1m$GROUPNAME group is empty\e[0m" else echo -e "\e[34;1m$GROUPNAME group has some file and folder.\e[0m" fi else echo -e "\e[32;1m$GROUPNAME group has [ $(groupmems -l -g $GROUPNAME) ]\e[0m" fi;fi else echo -e "\e[32;1m$GROUPNAME group has [ "$ACCHECK" ]\e[0m" fi unset ACCHECK GROUPNUM GROUPNAME done fi |
“계정이 존재하지 않는 GID 금지 / 홈 디렉토리의 존재 관리” 항목은 보여줄뿐 수동으로 맞추어야 한다.
1 2 3 |
~]# usermod 유져명 -d /홈/디렉토리 ~]# groupdel 그룹명 |
가이드 라인 문서중 apache / NFS / ftp / sendmail 은 사용 여부에 따라 추가적인 보안 조치를 해야 한다.
아래는 가이드 라인 문서에 따른 점검 항목 및 centos 에서의 처리 방법 예제 이다.(hwp 로 제작된 pdf 라서 복사가 안됨….)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
계정 관리 root 계정 원격 접속 제한 (상) 스크립트 패스워드 복잡성 설정 (상) 서버관리자 숙지 계정 잠금 임계값 설정 (상) 스크립트 패스워드 파일 보호 (상) 스크립트 root 이외의 UID가 '0' 금지 (상) 일반적으로 문제 없음 root 계정 su 제한 (하) 스크립트 패스워드 최소 길이 설정 (상) 스크립트 패스워드 최대 사용 기간 설정 (상) 스크립트 패스워드 최소 사용 기간 설정 (상) 스크립트 불필요한 계정 제거 (하) 스크립트(list 수동) 관리자 그룹에 최소한의 계정 포함 (하) 스크립트(list 수동) 계정이 존재하지 않는 GID 금지 (하) 일반적으로 문제 없음 동일한 UID 금지 (상) 일반적으로 문제 없음 사용자 shell 점검 (하) 일반적으로 문제 없음 Session Timeout 설정 (하) 스크립트 파일 및 디렉터리 관리 root 홈, 패스 디렉터리 권한 및 패스 설정 (상) 일반적으로 문제 없음 파일 및 디렉터리 소유자 설정 (상) 일반적으로 문제 없음 /etc/passwd 파일 소유자 및 권한 설정 (상) 스크립트 /etc/shadow 파일 소유자 및 권한 설정 (상) 스크립트 /etc/hosts 파일 소유자 및 권한 설정 (상) *위험수용* /etc/(x)inetd.conf 파일 소유자 및 권한 설정 (상) 일반적으로 문제 없음 /etc/syslog.conf 파일 소유자 및 권한 설정 (상) 일반적으로 문제 없음 /etc/services 파일 소유자 및 권한 설정 (상) 일반적으로 문제 없음 SUID. SGID, Stick bit 설정 파일 점검 (상) 일반적으로 문제 없음 사용자, 시스템, 시작파일 및 환경 파일 소유자 및 권한 설정 (상) 일반적으로 문제 없음 world writable 파일 점검 (상) 일반적으로 문제 없음 /dev에 존재하지 않는 device 파일 점검 (상) 일반적으로 문제 없음 HOME/.rhosts, hosts.equiv 사용 금지 (상) 일반적으로 문제 없음 접속 IP 및 포트 제한 (상) *서비스에 따라 개별설정 필요* hosts.lpd 파일 소유자 및 권한 설정 (하) 일반적으로 문제 없음 NIS 서비스 비활성화 (상) 일반적으로 문제 없음 UMASK 설정 관리 (상) 스크립트 홈디렉토리 소유자 및 권한 설정 (상) 스크립트(list 수동) 홈디렉토리로 지정한 디렉토리의 존재 관리 (상) 스크립트(list 수동) 숨겨진 파일 및 디렉토리 검색 및 제거 (하) 일반적으로 문제 없음 서비스 관리 finger 서비스 비활성화 (상) 일반적으로 문제 없음 Anonymous FTP 비활성화 (상) 일반적으로 문제 없음 r 계열 서비스 비활성화 (상) 일반적으로 문제 없음 cron 파일 소유자 및 권한 설정 (상) 스크립트 Dos 공격에 취약한 서비스 비활성화 (상) 일반적으로 문제 없음 NFS 서비스 비활성화 (상) 일반적으로 문제 없음 NFS 접근 통제 (상) 일반적으로 문제 없음 automountd 제거 (상) 일반적으로 문제 없음 RPC 서비스 확인 (상) 일반적으로 문제 없음 NIS, NIS+ 점검 (상) 일반적으로 문제 없음 tftp, talk 서비스 비활성화 (상) 일반적으로 문제 없음 Sendmail 버전 점검 (상) *서비스에 따라 개별설정 필요* 스팸 메일 릴레이 제한 (상) *서비스에 따라 개별설정 필요* 일반사용자의 Sendmail 실행 방지 (상) *서비스에 따라 개별설정 필요* DNS 보안 버전 패치 (상) *서비스에 따라 개별설정 필요* DNS Zone Transfer 설정 (상) *서비스에 따라 개별설정 필요* Apache 디렉토리 리스팅 제거 (상) *서비스에 따라 개별설정 필요* Apache 웹 프로세스 권한 제한 (상) *서비스에 따라 개별설정 필요* Apache 상위 디렉토리 접근 금지 (상) *서비스에 따라 개별설정 필요* Apache 불필요한 파일 제거 (상) *서비스에 따라 개별설정 필요* Apache 링크 사용 금지 (상) *서비스에 따라 개별설정 필요* Apache 파일 업로드 및 다운로드 제한 (상) *서비스에 따라 개별설정 필요* Apache 웹 서비스 영역의 분리 (상) *서비스에 따라 개별설정 필요* ssh 원격접속 허용 (상) 일반적으로 문제 없음 ftp 서비스 확인 (하) *서비스에 따라 개별설정 필요* ftp 계정 shell 제한 (상) 일반적으로 문제 없음 Ftpusers 파일 소유자 및 권한 설정 (하) 일반적으로 문제 없음 Ftpusers 파일 설정 (상) 일반적으로 문제 없음 at 파일 소유자 및 권한 설정 (상) 일반적으로 문제 없음 SNMP 서비스 구동 점검 (상) 일반적으로 문제 없음 SNMP 서비스 커뮤니티스트링의 복잡성 설정 (상) 일반적으로 문제 없음 로그온 시 경고 메시지 제공 (하) 스크립트 NFS 설정 파일 접근 권한 (상) 일반적으로 문제 없음 expn, vrfy 명렁어 제한 (상) 일반적으로 문제 없음 Apache 웹 서비스 정보 숨김 (상) *서비스에 따라 개별설정 필요* 패치 관리 최신 보안패치 및 벤더 권고사항 적용 (상) 서버관리자 숙지 로그 관리 로그의 정기적 검토 및 보고 (상) 서버관리자 정기 점검 정책에 따른 시스템 로깅 설정 (하) 일반적으로 문제 없음 |
일반적으로 문제 없음 = centos 7 기본 설치 상태에서 문제가 이미 없거나 설치 되지 않는 서비스 및 명령어
스크립트 = 올려둔 스크립트로 패치가 되는 경우
스크립트(list 수동) = 올려둔 스크립트 실행시 관리자가 인지 할 수 있도록 리스트 출력 (관리자 개입 수정 필요)
서버 관리자 숙지 = 일회성이 아닌 지속 적으로 관리자가 신경 써야 하는 부분
위험 수용 = 사이드 라인을 따라 갈 경우 서버에 장애 발생
서비스에 따라 개별 설정 필요 = 서버 목적에 따라 설치시 별도로 보안 점검이 필요로 하는 부분
감사합니다. 개발자로서 엔지니어의 역량을 요구받아, 모르는 내용 인터넷 서핑하다가 들어왔습니다. 잘 참고하겠습니다.
방문 감사드립니다.
저는 엔지니어지만 python 개발을 하고 있습니다 🙂