Linux Upskill 4. 서비스 포트 관리, 반복 작업, 파일 찾기

jiffydev·2021년 4월 4일
0

linux upskill

목록 보기
4/8

본 포스트는 박재호님의 유튜브 강의를 보고 개인적으로 정리한 내용입니다.

1. 서비스 포트 관리

1-1. 명령어 실습

1-1-1. netstat -na

여기서 -a 옵션은 다른 명령어에서도 유추할 수 있듯 모든 목록을 가져오라는 뜻이다. -n 옵션은 dns query를 하지 말고(ip 주소를 해석하려 하지 말고) ip 주소를 그대로 가져오라는 뜻인데, 만약 네트워크에 장애가 생겼을 때 -n 옵션을 넣지 않으면 timeout을 기다리느라 쓸데없이 시간을 소모하게 된다.

ubuntu@ip-172-26-9-205:~$ netstat -na | less


위 이미지에서 연결 상태를 크게 두 가지로 나눌 수 있는데, tcp/udp를 통한 접속과 unix domain socket을 통한 프로세스간의 내부 통신 방식이다.
일반적인 외부와의 통신에서는 tcp/udp 방식으로 사용하므로 이를 중심으로 살펴보자.

State 항목에서 LISTEN은 서버가 접속 요청을 기다리고 있는 상태이고 ESTABLISHED는 연결이 완료된 상태를 뜻한다.

1-1-2. ss -ltp

ss도 netstat과 마찬가지로 서비스 포트의 정보를 보여주는 명령인데, netstat이 예전부터 리눅스를 사용하던 사람이 사용한다면 ss는 최근에 리눅스를 배운 사람들이 사용한다(고한다).
각 옵션에 대해 설명하면, -l은 listening중인 소켓을 표시하라는 뜻이고 -t는 tcp 소켓을 표시하라는 뜻이며, -p는 현재 소켓을 사용중인 프로세스를 표시하라는 뜻이다.

ubuntu@ip-172-26-9-205:~$ ss -ltp

1-1-2. nmap

nmap은 네트워크 보안을 위한 유틸리티로 네트워크를 스캔하여 보안상의 문제점을 찾아주는 강력한 도구이다. 다만 사용시 주의할 점으로, local 서버에 대해서만 테스트해야 한다는 점이다. 만약 그 외 서버에 접근하게 되면 열린 포트에 대한 공격으로 판단할 수 있기 때문이다.

그러면 이제 nmap을 설치해보자

sudo apt install nmap

그리고 localhost에 대해 nmap을 실행해보면 다음과 같은 결과가 나올 것이다.(포트 상태에 따라 결과는 다를 수 있다)

localhost에 nmap을 사용하는 이유는 내가 실수로 어떤 포트를 열었을 경우나, 누군가가 시스템에 침투하여 포트를 열어 악의적 행위를 하려는 경우 이를 찾아내기 위해 사용한다.

1-2. netcat을 사용한 간단한 웹서버 만들기

우선 다음과 같이 간단한 셸 스크립트문을 작성한다.

while true; do echo -e "HTTP/1.1 200 OK\n\n $(date)" | nc -l localhost 8090; done &

셸 스크립트의 내용을 하나씩 살펴보면,
while true; : 무한 반복문이다.
do echo -e "HTTP/1.1 200 OK\n\n $(date)" : 먼저 echo 명령은 큰따옴표 안에 있는 문장을 출력한다. 그리고 e 옵션은 backlash() escape를 적용하라는 뜻으로 여기서는 \n(개행)을 적용하게 된다. $(date)는 현재 날짜를 뜻한다.
nc -l localhost 8090 : netcat의 -l 옵션은 연결되는 것을 listen하고 있으라는 뜻으로, 다음에 주어지는 인자인 주소(여기서는 localhost)와 포트 번호(여기서는 8090)로 오는 요청에만 응답하게 된다.
done : do로 시작하면 반드시 done으로 끝나야 한다.
& : 백그라운드로 작업을 수행하라는 뜻이다. &를 넣지 않으면 프롬프트에서 계속 명령이 실행되므로 다른 작업을 할 수 없다.

정상적으로 수행되고 있는지 판단하기 위해서는 터미널을 두 개 열어야 한다.
한 쪽에는 위의 셸 스크립트를 실행해 놓고, 다른 쪽에서는

curl localhost:8090

curl로 실행해 보자.

listen하는 쪽에서는 200 OK 메시지가 떴고, 요청하는 쪽에서는 현재 날짜를 잘 받은 것을 볼 수 있다.

2. 특정 시각에 반복적으로 작업하기

2-1. 명령어 실습

2-1-1. crontab

주기적인 작업에 일반적으로 많이 사용되는 crontab명령이다. 일단은 /etc/crontab에서 파일을 출력해보자.

ubuntu@ip-172-26-9-205:~$ less /etc/crontab

이처럼 미리 설정돼있는 작업들이 보일 것이다.
daily 작업에서는 무엇을 하는지 보려면 /etc/cron.daily 디렉토리를 확인하면 된다.

우리는 그 중에서 패스워드 관련(passwd)파일을 확인해 볼 것이다.

ubuntu@ip-172-26-9-205:/etc/cron.daily$ vi passwd


셸 스크립트에 익숙하지는 않지만, 간단히 설명하면 /var/backups 디렉토리에서 4개의 파일(passwd, group, shadow, gshadow)를 대상으로 반복문을 도는데, /var/backups 밑의 파일과 /etc 밑의 파일을 비교(cmp)해서 차이가 있으면, /etc 밑의 파일을 파일명.bak로 /var/backups에 복사한 후 권한을 600(소유주만 write, read)로 변경한다.

/var/backups를 보면 *.bak 파일이 있는 것을 알 수 있다.

2-1-2. list-timers

list-timers는 crontab보다 좀 더 자세한 정보를 제공한다. 직접 눈으로 확인해보자.

ubuntu@ip-172-26-9-205:~$ systemctl list-timers

crontab과의 차이점은 crontab이 파일 하나에 특정 시각 패턴과 실행 명령을 같이 넣어놓은 반면, list-timers는 이를 분리해 놨다는 점이다. 이로 인해 list-timers 테스트나 시각을 변경하기 용이할뿐만아니라 일회성 작업을 하기도 편하다.

이번에는 apt-daily.timer에 대해 알아보고자 하는데 그 전에 이 타이머가 어떤 상태인지 알아보자.

ubuntu@ip-172-26-9-205:~$ systemctl status apt-daily.timer


이 타이머는 현재 active 상태이며 실행되기 전까지 대기중인 것을 알 수 있다.
그리고 음영처리된 디렉토리 안에 .service 파일이 있어 설정된 주기로 그 파일을 실행하리라는 것을 예상할 수 있다. 실제로 맞는지 확인하기 전에, 활성화된 파일을 확인해 보자.
활성화된 파일은 /etc/systemd/system/timers.target.wants 디렉토리 안에 존재한다.
해당 디렉토리 안에서 apt-daily.timer 파일을 확인해 보면 아래와 같이 심볼릭 링크를 걸어 놓은 것을 알 수 있다.

여기서 우리는 /lib/systemd/system/apt-daily.timer 밑에 여러 타이머가 있지만 그 중에 활성화 된 것만 /etc/systemd/system/timers.target.wants 아래에 심볼링 링크가 걸려 있으리라는 것을 추론할 수 있다.

이제 타이머에 어떤 내용이 있는지를 잠깐 보면 다음과 같다.

그리고 한 가지 특기할 만한 점은 apt-daily-upgrade.timer파일에서 볼 수 있는데,

After 부분을 보면 apt-daily.timer라고 되어 있다.
이는 apt-daily.timer를 먼저 실행한 후 실행하라는 뜻으로, 의존성을 기술할 수 있다.
crontab은 이런 의존성 처리가 어렵기 때문에 순서대로 일어나야 하는 작업임에도 앞선 작업이 오래 걸리게 되면 다음 작업이 이를 기다리지 않고 먼저 처리되는 불상사가 발생할 수 있다.

다음으로, 실제로 어떤 명령이 실행되는지를 service 파일에서 확인해보자.

ubuntu@ip-172-26-9-205:/lib/systemd/system$ cd /lib/systemd/system

디렉토리를 이동한 후 apt-daily.service 파일을 편집기로 열어보면 다음과 같이 실행되는 명령을 볼 수 있다.

3. 특정 조건으로 파일 찾기

3-1. 명령어 실습

3-1-1. locate, find, which

  • locate
    시스템 전체를 대상으로 인자로 주어진 파일명과 일치하는 파일을 검색한다.

    다만 강의에는 나오지 않았으나 개인적으로 발생한 문제가 있었는데, locate access.log를 해도 아무것도 나오지 않는 경우가 있었다.(파일은 존재함에도)
    검색한 결과 locate의 데이터베이스가 업데이트 되지 않아서 발생한 문제로, sudo updatedb 명령으로 업데이트 해주면 해결된다.

  • find
    특정 디렉토리 계층 안에 있는 파일을 검색한다. locate와 다른 점은 특정 디렉토리부터 시작하여 재귀적으로 탐색해 나간다는 점이며, 검색 시 조건을 부여할 수 있다는 점이다.
    먼저 간단하게 find /var -name access.log | less 명령으로 파일 이름으로 검색해보면

    Permission denied가 대부분인 것을 볼 수 있다.
    이 경우 ctrl+l을 눌러주면 거부된 것들은 제외하고 출력할 수 있다.
    또한 와일드카드도 적용이 가능하므로 위의 access.log"access.log*"로 바꾸면 .log 뒤에 내용이 있는 파일도 같이 검색 결과에 나타난다.
    다른 조건으로는 시간과 관련된 조건으로, x시간 전에 변경된 내용을 다음과 같이 검색할 수도 있다. find /var -mtime 3 | less

    여기서 숫자3은 24*3으로 검색일 3일 이전에 변경된 내용을 보여달라는 뜻이다.

  • which
    이번에는 실행파일의 위치를 찾아보고자 한다. 물론 find 명령으로도 위치를 찾을 수 있지만, 실행 경로($PATH)에 걸리지 않는 파일도 모두 나온다는 단점이 있다. 따라서 실행 경로에 있는 파일만 찾기 위해서는 which명령을 사용한다.

3-1-2. 복잡한 조건으로 파일 찾기(grep, zcat)

  • grep
    "PermitRootLogin"이라는 파일을 찾고 싶다고 가정하자. 이 파일이 /etc디렉토리 밑에 있다는 것까지만 알고 대소문자도 저게 맞는지 확실하지 않다.
    그렇다면 grep을 사용해 grep -R -i "PermitRootLogin" /etc/* | less 검색할 수 있다.
    여기서 -R 옵션은 재귀적으로 탐색해서 하위 디렉토리까지 탐색하는 옵션이고, -i옵션은 case insensitive 즉 대소문자를 구별하지 않는 옵션이다.
    실행해 보면 다음과 같이 파일 위치를 알 수 있다.

  • zcat
    파일을 검색하다보면 우리가 찾는 파일이 압축된 파일(.gz 등)일 경우도 있다. 이를 보기 위해 압축을 풀고 파일을 열고 다시 지우는 과정은 매우 번거롭다.
    이 때 사용하는 것이 zcat 명령으로, 이름처럼 압축(zip)된 파일을 보여(cat)준다.
    예를 들어 필자의 /var/log/에는 syslog.2.gz파일이 있다.
    이를 zcat /var/log/syslog.2.gz | less 처럼 실행하면, 압축된 파일의 내용을 보여준다.
    그리고 zcat | less를 합쳐놓은 것이 zless 명령으로 같은 기능을 한다.
    .
    마지막으로, 사실은 less 만으로도 압축된 파일의 내용을 볼 수 있다 ㅎㅎ
    다만 less로 내용을 보는 것은 ubuntu에서는 가능하지만 다른 리눅스 계열 운영체제에서는 작동하지 않을 가능성도 있음에 주의하자.
    이는 ubuntu에서 $LESSOPEN에 명령을 지정해 놓았기 때문으로, echo로 출력해 보면 다음과 같이 나온다.

    내용을 보면 lesspipe로 pipe를 거는데, 이 lesspipe는 압축된 파일이 있다면 less 실행 전에 압축을 풀라는 명령이 담겨있다.

3-1-3. 특정 확장자를 찾아 지우기

우선 다음과 같이 테스트용 파일과 디렉토리를 생성하자.

여기서 *.tmp는 모두 삭제하고 싶은데, 이를 일일이 지우기에는 귀찮은 것도 귀찮은 것이지만 양이 많아지면 빼먹을 가능성도 충분히 있다.
이를 한번에 해결하기 위해 find 명령을 사용할 수 있다.
그리고 이번에는 -exec 옵션을 붙여서, 출력이 아니라 뒤에 나오는 명령을 바로 실행하도록 하는 것이 핵심이다.
다음과 같이 입력하면 tmp 파일이 모두 지워진 것을 확인할 수 있다.


여기서 {}는 find로 찾은 결과의 이름을 뜻하고(그러므로 rm 명령의 인자로 파일 이름을 넘겨주는 것과 같은 효과) \;-exec 옵션의 끝을 나타낸다.(-exec 옵션을 사용하면 반드시 끝에 붙여야 함)

profile
잘 & 열심히 살고싶은 개발자

0개의 댓글