반응형
회사에서 정상적으로 운영하던 서비스에 문제가 생겼다. 돌이켜보면 매우 간단한 이슈였지만, 해결과정이 재밌었고 비슷한 상황에 도움이 될 수 있을 것 같아서 기록으로 남기게 되었다.
문제
- 며칠 전부터 서버 간의 SSH 연결이 매우 늦어지는 상황이 일어났다. 특히, 특정일 10:00:00을 기준으로 특정 대역대 서버가 모두 영향을 받게 되었다.
- 특히, expect를 이용한 명령어 수행이 기본 1분 내외의 수행시간에서 30분이 지나도 해결되지 않는 문제가 발생하였다.
- 당장 서비스 중인 서버이기 때문에, 해당 대역대가 아닌 다른 서버로 연결을 바꾸어, 해결했지만 특정 대역대의 서버 전체의 "SSH"가 느려져서, 빠른 해결이 필요하였다.
가설 & 시도
- 처음으로 의심한 것은 서버 자체의 부하이다.
- 하지만, ps와 top으로 확인해 보았을 때, H/W 리소스는 충분하였고, 특히 특정 대역대의 서버 전체의 SSH가 다 늦어졌다는 점이 서버 자체의 부하의 가설이 아닌 것을 의미했다.
- 다음 의심한 점은 해당 대역대의 서버들을 물고 있는 Switch의 문제였다. 하지만, SSH 연결 외에 다른 연결을 정상적으로 수행된다는 점이 이상하였다.
로그 확인
- SSH 연결에서는 verbose 옵션을 통해 SSH 연결 과정을 debugging 할 수 있다.
$ time ssh -v {ip주소}
- 나의 경우에는 SSH 연결 대상 서버에서 msg를 응답받는 구간에서, 응답을 받는 데까지 매우 오랜 시간이 걸리는 것을 확인했다.
- 따라서, SSH 대상 서버를 들어가서 로그를 확인하였다.
- 별도의 SSH 모니터링 툴을 사용하지 않는다면 Linux 서버에서 SSH 관련 로그를 확인해 볼 방법은 2가지이다.
- /var/log/audit : Linux 자체에서 audit에 관한 로그를 저장하는 곳이다. 시스템에서 발생하는 이벤트와 활동을 추적하기 때문에, SSH 연결등의 정보가 이곳에 기록된다.
- /var/log/secure : 보안 이벤트와 사용자 인증에 대한 로그가 기록된다. sshd(SSH 데몬)에 의한 로그인 시도, 계정 관련 이슈 등이 기록된다. SSH 연결을 위한 보안의 시간이 기록되기 때문에, 확인해야 한다.
<audit log 예시 - ChatGPT가 만들어줌>
type=USER_AUTH msg=audit(1603989582.198:304): pid=1234 uid=1000 auid=1000 ses=1 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='op=login id=jsmith exe=/usr/sbin/sshd (hostname=?, addr=192.168.1.100, terminal=sshd res=success)'
<secure log 예시 - ChatGPT가 만들어줌>
Nov 20 10:15:30 server sshd[1234]: Accepted publickey for jsmith from 192.168.1.100 port 22 ssh2
Nov 20 10:15:30 server sshd[1234]: pam_unix(sshd:session): session opened for user jsmith by (uid=0)
Nov 20 10:15:30 server systemd-logind[567]: New session 1234 of user jsmith.
- 로그를 확인해 보았을 때, audit log에 정상적으로 success가 찍혀있고, secure log를 확인해 보니, 연결 시도부터까지의 시간이 느린 것을 발견하였다.
방법 발견
- 최초에 SSH가 느려지는 상황을 구글링 하였을 때, 가장 많이 나오는 방법이 /etc/ssh/sshd_config 파일의 UseDNS 옵션을 "no"로 바꾸는 것이다.
- 사실 이 방법이 효과적일 것으로 생각했지만, 회사의 엄격한 보안 정책과 운영 중인 시스템에서 변경점을 가하기 어려워(sshd restart가 필요하기 때문), 운영 중이지 않은 서비스로 실험을 해보았다.
- /etc/ssh/sshd_config에 아래 내용을 추가한다. (만약 UseDNS yes로 되어 있으면 no로 변환한다) 그러고 나서, sshd를 재시작해준다.
$ sudo vim /etc/ssh/sshd_config
---------------------------------
UseDNS no
---------------------------------
$ sudo systemctl restart ssh
- 원리를 알아보니, server에서 SSH로 연결을 시도할 때, SSH 데몬에 DNS를 사용하도록 설정되어 있으면, target 서버에서 /etc/resolv.conf 파일을 읽어서, 해당 파일에 명시된 DNS 서버에, hostname을 묻는 DNS query를 날리고, 이 결과를 통해, 현재 SSH 연결을 시도한 서버에 해당하는 서버가 있으면 해당 hostname으로 연결을 진행한다.
- 이 과정을 reverse DNS lookup이라고 하는데, resolve.conf의 각 서버와 통신하여, hostname을 묻는 과정이 포함되기 때문에 conf 파일 내의 모든 서버와의 연결이 정상적이어야 한다.
- UseDNS를 no로 변경하니, 이슈 전처럼 정상적인 속도로 SSH가 진행되었다. 하지만, 단순히 DNS connection 몇 개가 추가되었다고, 이렇게 오랜 속도가 걸리는 것은 많이 이상하였다.
이슈 해결
- 결론부터 말하면, resolv.conf에 해당한 서버 중, 특정 서버가 IP를 변경하여 생긴 문제였다. 문제가 되는 대역대는 VM 서버를 사용하는 서버들이었고, 하나의 서버를 copy 하는 방식으로 서버를 setup 했기 때문에, 이 대역대의 모든 서버에 대해 동일 현상이 발생하였다.
- resolv.conf에서 문제가 되는 IP들을 제거해 주니, UseDNS 옵션을 다 시켜도, 예전처럼 빠른 속도로 SSH를 붙을 수 있게 되었다.
- 특히, 문제가 발생한 서비스의 경우, shell script 상에 expect 명령어를 이용하도록 되어 있는데, DNS와의 연결이 되지 않으니, Target Server에서 적절한 response를 주지 못하고, 이로 인해 Target 서버와의 연결이 안 되는 것처럼 느껴진 것이었다.
- 돌이켜보니, 매우 간단하고, 황당한 이슈였지만, 원인을 찾는 과정에서 많은 것을 배운 것 같다.
교훈
- 최근 SSH에서는 UseDNS의 default 설정이 no라고 한다. 다만, 예전 버전을 사용하는 경우에는 UseDNS의 기본 옵션은 yes이다. 만약 보안적 문제가 없다면, UseDNS를 끄는 것이 더 좋을 것 같다.
- 하지만, 불가피하게 사용하는 경우에는 꼭 DNS 설정을 잘 관리해야 한다. 해당 DNS도 현재는 거의 사용하지 않지만, History 및 영향도 파악이 불가하여, 별도의 삭제를 하지 않다가 이슈를 맞이하게 된 상황이다.
- Linux 명령어를 단순 사용하기만 했는데, 동작 원리를 알아야겠다!
'Linux' 카테고리의 다른 글
[이슈 해결] Airflow에서 cx_Oracle 관련 에러 (dpi-1047) (24) | 2024.02.19 |
---|