sudo 설정
visudo
를 사용해 sudoers 파일의 아래 내용 편집
1
2
3
4
5
6
7
8
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
Defaults authfail_message="Authenticate failed."
Defaults badpass_message="Password failed."
Defaults log_input
Defaults log_output
Defaults requiretty
Defaults iolog_dir="/var/log/sudo/"
Defaults passwd_tries=3
- authfail_message : sudo 인증 실패 시 출력 메시지
- badpads_message : sudo 인증에서 비밀번호 불일치 시 출력 메시지
- log_input : log에 sudo로 사용한 input 내용 저장
- log_output : log에 sudo로 출력된 output 내용 저장
- requiretty : 현재 shell이 tty 인지 아닌지에 따라 sudo의 허가여부 결정
- iolog_dir : sudo log 저장 경로 설정
- passwd_tries : sudo 실행 횟수 설정
사용자 설정
유저 관리
1
2
3
4
5
sudo useradd -m [username] # 새유저 및 해당 홈디렉토리 생성
passwd [username] # 패스워드 설정
grep /bin/bash /etc/passwd | cut -f1 -d:# useradd로 추가했던 유저 목록
userdel [username] [groupname] # 유저를 해당 그룹에서 제거
userdel -r [username] # 유저의 모든 정보 삭제
그룹 관리
1
2
3
4
5
6
groupadd user42 # user42그룹을 추가
groupdel [groupname] # 그룹 삭제
usermod -G user42,sudo [username] # 유저를 user42, sudo그룹에 추가.(나머지 그룹에서는 제거)
usermod -aG user42,sudo [username] # 유저를 user42, sudo그룹에 추가. (나머지 그룹에서도 유지)
usermod -g user42 [username] # user42를 유저의 primary group으로 만듦.
id [username] # 유저의 그룹 정보를 보여줌
- 계정을 sudo그룹에 넣으면 sudo 권한이 부여된다.
사용자 정보
/etc/passwd
- 시스템 관리자가 유저를 생성할때마다 관련 정보를 저장
- 각 필드별로 아래와 같은 의미를 가진다.
1
[user_account]:[user_pw]:[user_id]:[group_id]:[comment]:[home_dir]:[login_shell]
cut -f1 -d: /etc/passwd
: 사용자 계정만 출력.
내가 생성하지 않았는데 보이는 다양한 계정(daemon, bin, sys, man 등) → 시스템 계정
- 시스템 계정
시스템의 필요에 의해 생성된 계정
리눅스는 파일이나 프로세스 생성 시 반드시 소유자를 명시하게 되는데 모든 시스템에 대해 root 권한을 부여할 시에 생길 수 있는 시스템 손상의 문제를 시스템 계정을 통해 방지 할 수 있다.
호스트 정보
1
2
3
4
hostname # hostname 확인
hostname [new name] # 임시 hostname 변경
sudo hostnamectl set-hostname [new name] # static hostname 변경
sudo systemctl reboot # 시스템 reboot
패스워드 정책 설정
설정 1
sudo vim /etc/login.defs
로 아래 내용 수정
1
2
3
PASS_MAX_DAYS 30 # 최대 30일까지 사용
PASS_MIN_DAYS 2 # 최소 2일 이상 사용
PASS_WARN_AGE 7 # 7일전부터 경고 메시지 출력
설정 2
sudo apt install libpam-pwquality
: 비밀번호 정책 설정을 위한 패키지 설치
sudo vim /etc/pam.d/common-password
: 중간에 위치한 per-package modules를 아래와 같이 변경
1
password requisite pam_pwquality.so retry=3 minlen=10 difok=7 ucredit=-1 lcredit=-1 dcredit=-1 reject_username enforce_for_root maxrepeat=3
각 항목의 의미는 아래와 같다.
1
2
3
4
5
6
7
8
9
retry=3 # 비밀번호 최대 3회까지 입력 가능
minlen=10 # 최소 10자
difok=7 # 이전 비밀번호와 최소 7글자는 다르게 설정
ucredit=-1 # 대문자 최소 1자 이상
lcredit=-1 # 소문자 최소 1자 이상(이 조건이 있는 이유?)
dcredit=-1 # 숫자 최소 1자 이상
reject_username # username을 그대로 or 뒤집어서 암호로 사용 불가
enforce_for_root # 해당 비밀번호 정책을 root에도 적용
maxrepeat=3 # 3자까지 중복 가능
설정 적용
위의 두가지 설정은 모두 새로 생성되는 유저에 적용된다. 따라서 아래와 같이 추가적인 설정 적용 과정을 거쳐야 한다.
chage -m 2 -M 30 -W 7 [username]
: 비밀번호 기간 적용(2~30일 유효, 7일전 경고)
passwd -e [username]
: 다음 로그인시 비밀번호 변경
chage -l [username]
: 유저별로 설정된 내용 확인
sudo vim /etc/shadow
: 설정된 내용 한번에 확인
위 내용 중 root와 username(taehooki)의 4, 5, 6번 필드(각각 2, 30, 7)를 보면 설정이 적용된 것을 알 수 있다.
AppArmor 설정
1
2
3
4
5
6
sudo apt --installed list apparmor # 설치 확인
apt install apparmor apparmor-profiles apparmor-utils # 설치
sudo apparmor_status # 상태 확인
aa-enabled # 활성화 여부 확인
sudo aa-status # 현재 상태 확인 가능(enforced, complain, unconfined)
ps auxZ | grep -v '^unconfined' # apparmor가 실행제한한 파일 확인
- enforce 모드 : 허가되지 않은 파일에 접근을 거부한다.
- complain 모드 : 어플리케이션이 해야 할 일이 아닌 일을 했을 때 로그를 기록한다.
SSH 설정
1
2
3
4
apt --installed list openssh-server # openssh 설치 확인(보통 설치되어있다.)
ssh -V # openssh 버전 확인
apt install openssh-server # openssh 설치(없다면)
sudo ufw allow 4242 # 4242 포트 ufw 허용
sudo vim /etc/ssh/sshd_config
내용 수정1 2
Port 4242 # SSH포트를 4242로 변경 PermitRootLogin no # 외부에서 root로의 로그인 차단
설정 적용
1 2 3
sudo systemctl restart ssh # 수정 후, 다시 시작해서 설정 적용 systemctl status ssh # openssh 실행 상태 확인 ss -tunpl # 포트번호 확인
systemctl : 서비스 관리 명령어
1 2 3 4 5 6 7 8
systemctl start [서비스이름] # 시작 systemctl stop [서비스이름] # 종료 systemctl restart [서비스이름] # 재시작 systemctl try-restart [서비스이름] # 재시작(시작된 서비스) systemctl reload [서비스이름] # 설정 reload systemctl status [서비스이름] # 상태 확인 systemctl is-active [서비스이름] # 상태 확인(1) systemctl list-units --type service --all # 모든 서비스 상태확인
service
와systemctl
의 차이
service 명령어는 /etc/init.d 를 실행한다.
systemctl 명령어는 /lib/systemd 의 파일을 실행하고 만약 없으면 위의 service의 경로의 파일을 실행한다.
UFW 설정
1
2
3
4
5
6
7
8
9
$ sudo apt install ufw # ufw 방화벽 설치
$ sudo ufw status verbose # 상태 확인(디폴트는 inactive)
$ sudo ufw enable # 부팅시 ufw 활성화 하기
$ sudo ufw disable # 비활성화
$ sudo ufw default deny # 기본 incoming deny
$ sudo ufw default allow # 기본 incomig allow
$ sudo ufw allow 4242 # 4242port로 ssh 연결 허용
$ sudo ufw status numbered # 규칙번호 확인
$ sudo ufw delete [규칙번호] # 해당 규칙 삭제
TTY로 VM 접근
tty
리눅스 디바이스 드라이버 중에서 콘솔이나 터미널을 의미
명칭은 과거에 사용하던 Teletypewriter에서 유래하였다.
여러 개의 터미널이 존재할 경우 tty0, tty1, …. , tty6로 번호를 붙혀 사용한다.
Port Forwarding
로컬에서 tty를 통해 가상머신에 접근하기 위해서는 포트 포워딩 작업이 추가적으로 필요하다.
sudo apt-get install net-tools
: 넷툴즈 설치 (ifconfig 사용을 위해)
VirtualBox 설정
[Settings]-[Network]-[Advanced]-[Port Forwarding] 에서 Rule 추가하기
HOST IP
: 127.0.0.1 (localhost, 자기 자신) 또는ifconfig | grep inet
의 값HOST PORT
: 5000 (임의의 값)GuestIP
: 10.0.2.15 (hostname -I
의 값)GUEST PORT
: 4242- 호스트 포트 : 외부에서 연결할 때 이용하고자 하는 포트
- 게스트 포트 : 내가 지정한 서비스의 포트
cmd에서 아래 내용 입력해서 가상환경에 접속
1
ssh taehooki@127.0.0.1 -p 5000 # ssh [username]@[HOST IP] -p [HOST PORT]
VirtualBox의 포트 포워딩 설정에서 호스트 포트를 22(ssh 기본포트)로 지정했다면 ssh로 접속할 때 포트부분을 제외하고 ssh [username]@[HOST IP]
만 입력해도 된다.
exit
: 가상환경 접속 종료
SSH를 사용해 접속할때 root로는 접속을 막았기 때문에 연결되지 않는다.
쉘 스크립트 작성
관련 명령어
- OS 아키텍쳐, 커널 버전(Architecture)
uname -a
- 물리 프로세서 개수(CPU physical)
- cat /proc/cpuinfo(CPU 코어 개별적인 세부사항이 담겨있다.) 파일 참고
cat /proc/cpuinfo | grep "physical id" | sort -u | wc -l
- physical id : 0은 프로세서가 0개라는 의미가 아닌, 0번 id를 갖는 프로세서라는 의미이다.(0, 1, 2, … 으로 증가한다.)
- 해당 line을 추출한 뒤
- -u (unique) 옵션(정렬 후 중복된 내용을 제거)으로 정렬 후
- 행의 수를 세어 출력한다.
- 가상 프로세서 개수(vCPU)
cat /proc/cpuinfo | grep processor | sort -u | wc -l
- 현재 서버에 여유있는 RAM과 사용률(Memory Usage)
free
: 메모리 사용량, 여유량과 캐싱으로 사용되는 메모리의 현황- [total] : 설치된 총 메모리 크기 / 설정된 스왑 총 크기
- [used] : total에서 free, buff/cache를 뺀 사용중인 메모리. / 사용중인 스왑 크기
- [free] : total에서 used와 buff/cahce를 뺀 실제 사용 가능한 여유 있는 메모리량 / 사용되지 않은 스왑 크기
- [shared] : tmpfs(메모리 파일 시스템), ramfs 등으로 사용되는 메모리. 여러 프로세스에서 사용할 수 있는 공유 메모리
- [buffers] : 커널 버퍼로 사용중인 메모리
- [cache] : 페이지 캐시와 slab으로 사용중인 메모리
- slab : 커널이 내부적으로 사용하는 영역
- [buff/cache] : 버퍼와 캐시를 더한 사용중인 메모리
- [available] : swapping 없이 새로운 프로세스에서 할당 가능한 메모리의 예상 크기. (예전의 -/+ buffers/cache이 사라지고 새로 생긴 컬럼)
free -m | grep Mem | awk '{printf "%d/%dMB (%.2f%%)", $3, $2, $3/$2*100}'
- free의 내용을 MB단위로 받아서
- Mem이 포함된 행의 내용을
[used]/[total]MB ([used]/[total]x100%)
형태로 출력
- 현재 서버에 여유있는 메모리와 사용률(Disk Usage)
df
: 디스크메모리의 전체 현황- BM, BG: MB, GB로 결과 출력
df -BM | grep /dev/map | awk '{sum+=$3}END{print sum}' | tr -d
df -BM | grep /dev/map | awk '{sum+=$4}END{print sum}' | tr -d
- 현재 프로세서의 사용률(CPU load)
mpstat
: 사용가능한 CPU와 core별 사용률 현황sudo apt-get install sysstat
: mpstat 명령어가 포함된 패키지 설치mpstat | grep all | awk '{printf "%.2f%%\n", 100-$NF}'
- NF: 필드의 총 개수($NF=마지막 필드)
- 마지막 reboot 일시(Last boot)
who
: 호스트에 로그인한 사용자 정보를 /var/run/utmp 파일에서 가져옴- [b] : 마지막 시스템 부팅 시간
who -b | awk '{printf $3" "$4"\n"}'
- LVM 활성화 여부(LVM use)
lsblk
: 현재 디바이스의 스토리지 정보를 출력- 모든 블럭 장치에 대한 정보를 알 수 있다.
lsblk | grep LVM | wc -l | awk '{if($1>0) print "yes"; else print "no"}'
- 활성화 된 연결의 수(Connections TCP)
ss
: Socket Statistics. 네트워크 상태 확인 (netstat
로도 가능)- [a] : 모든 포트 확인
- [t] : TCP 포트 확인
- [u] : UDP 포트 확인
- [l] : LISTEN 상태 포트 확인
- [p] : 프로세스명을 표시
- [n] : 호스트 / 포트 / 사용자이름을 숫자로 표시
ss -t | grep ESTAB | wc -l | tr -d '\n'
- ss : socket의 상태 확인(socket statistics)
- ss를 옵션없이 사용하면 listening socket(서버)을 제외한 연결된 소켓만을 출력한다.
- [t] : TCP socket 표시
- tr : 문자 변환/삭제
- 사용법 :
tr [옵션][문자열1][문자열2]
- [d] : 문자열1에서 특정 문자를 삭제
- [s] : 문자열2에서 반복되는 문자를 삭제
- [t] : 문자열 1을 문자열2의 길이로 자름
- [옵션x] : 문자열1을 문자열2로 변경
- ss : socket의 상태 확인(socket statistics)
- 서버를 사용중인 유저의 수(User log)
who | wc -l
- 서버의 IPv4 주소와 MAC주소(Network)
hostname -I
: 서버의 IPv4 주소ip link | grep link/ether | awk '{print "("$2")"}'
: 서버의 MAC 주소ifconfig | grep ether | awk '{print "("$2")"}'
로도 MAC 주소 확인 가능
- sudo를 통해 실행된 명령의 횟수(Sudo)
monitoring.sh
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
#!/bin/bash
printf "#Architecture: "
uname -a
printf "#CPU physical : "
cat /proc/cpuinfo | grep "physical id" | 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 -BM | grep /dev/map | awk '{sum+=$3}END{print sum}' | tr -d '\n'
printf "/"
df -BM | grep /dev/map | awk '{sum+=$4}END{print sum}' | tr -d '\n'
printf "MB ("
df -BM | grep /dev/map | awk '{sum1+=$3 ; sum2+=$4 }END{printf "%d", sum1 / sum2 * 100}' | tr -d '\n'
printf "%%)\n"
printf "#CPU load: "
mpstat | grep all | awk '{printf "%.2f%%\n", 100-$NF}'
printf "#Last boot: "
who -b | awk '{printf $3" "$4"\n"}'
printf "#LVM use: "
lsblk | grep LVM | wc -l | awk '{if($1>0) print "yes"; else print "no"}'
printf "#Connections TCP : "
ss -t | grep ESTAB | wc -l | tr -d '\n'
printf " ESTABLISHED\n"
printf "#User log: "
who | wc -l
printf "#Network: IP "
hostname -I | tr -d '\n'
ip link | grep link/ether | awk '{print "("$2")"}'
printf "#Sudo : "
journalctl _COMM=sudo | grep COMMAND | wc -l | tr -d '\n'
printf " cmd\n"
exit 0
cron
특정 시간에 특정 작업을 자동으로 수행하는 스케쥴러
crontab
cron 작업을 설정하고 수행하는 프로그램 /etc/crontab
파일에 기록된 내용대로 작업을 수행
기본 사용법
1
2
3
sudo crontab -e # crontab 편집
sudo crontab -l # crontab 작업내용 확인
sudo crontab -r # crontab 전체작업 삭제
사용 예시
1
2
3
4
5
6
7
8
9
10
11
0 * * * * {실행 명령} # 매시 정각
0 0 14 * * {실행 명령} # 매일 14시
0 0 * * 1 {실행 명령} # 매주 월요일 자정
0 0 2 * * {실행 명령} # 매달 2일 자정
20,50 * * * * {실행 명령} # 매시 20분, 50분
*/15 * * * * {실행 명령} # 15분 주기로
0 3 * * * {실행 명령} # 매일 3시
30 */6 * * * {실행 명령} # 매 6시간마다(00:30, 06:30, 12:30, 18:30)
30 1-23/6 * * * {실행 명령} # 1시 반부터 매 6시간마다
0 6 * * 1-5 {실행 명령} # 평일 6시
0 7 * * 6 {실행 명령} # 토요일 7시
crontab 설정
1
2
3
sudo chmod +x monitoring.sh # 실행권한 부여
sudo crontab -e # sudo를 사용해서 crontab 파일 수정
*/10 * * * * /root/monitoring.sh | wall # 10분마다 wall 실행
cron 30초마다 실행하는 법
crontab 옵션은 최소 분단위이다. 초단위로 적용하고자 한다면 sleep을 사용하면 된다.
(default가 1분이라 앞부분 시간설정은 안해도 된다.)1
* * * * * /root/monitoring.sh | wall && sleep 30; /root/monitoring.sh | wall
관련 명령어
1
2
3
4
5
sudo service cron start # 시작
sudo service cron stop # 일시적 중단(재부팅하면 시작된다.)
sudo systemctl disable cron # 재부팅시 중단(아예 중단된다.)
sudo service cron restart # 재시작
sudo service cron status # 작동확인
Ref.
https://m.blog.naver.com/snazzy79/70148845500
https://bono915.tistory.com/entry/VirtualBox-Linux-포트포워딩-설정-및-ssh-연결-방법
https://www.whatap.io/ko/blog/37/
https://zidarn87.tistory.com/137
https://www.cyberciti.biz/tips/linux-investigate-sockets-network-connections.html
https://jdm.kr/blog/2