𝝅번째 알파카의 개발 낙서장

screen

[Ubuntu] Ubuntu 원격 프로토콜 보안 강화하기

posts

Ubuntu

count

개요 🔗

SSH, SFTP와 같은 원격 프로토콜은 서버의 접근성을 향상시켜주지만, 서버의 보안성을 극도로 훼손한다.

공격자가 특정 서버의 IP를 알아냈을 경우, 해당 IP로 SSH 접속 시도를 할 수 있다. 굳이 IP가 아니더라도 해당 IP와 연결된 도메인을 통해서도 얼마든지 가능하다. 특정 도메인의 정보를 DNS서버에 요청하여 IP는 물론 소유자 정보까지 쉽게 취득할 수 있기 때문이다.

따라서 누군가가 내가 접속하려는 서버의 IP 혹은 도메인, SSH 서비스 포트, 계정정보를 알고 있다면 얼마든지 SSH 접속 시도를 하거나 서버에 피해를 줄 수 있다.

외부에 도메인을 공개하는 순간 국내는 물론 외국에서 여러 접속 시도가 들어오기도 한다. 특히 중국에서의 공격이 많이 들어오며, 인터넷에서 이와 관련된 경험담이나 피해사례를 쉽게 찾아볼 수 있다.

단순히 재미삼아 내가 접속한 도메인에 접속시도를 하는 어중이떠중이들도 있겠지만, 그 중 몇몇은 공격자로 취급할 수 있을 정도의 실력을 가지기도 하며, 그 중에서도 극소수의 몇몇은 내 서버의 보안을 우회할 수 있을 정도의 실력을 가지고 있을 수도 있다.

서버의 특성 상 여러 내부 시스템 및 네트워크와 연결되어 있으므로, 서버가 뜷리는 것은 그 서버와 연관된 각종 정보들의 안전을 보장할 수 없음을 의미한다. 심지어 항상 최상의 보안대책을 강구하는 기업에서조차 피해를 입기도 한다. 우스갯소리로 이미 대다수의 자국민 주민등록번호는 인터넷에 나뒹굴고 있을거라고 얘기하기도 할 정도니.

기업처럼 높은 수준의 보안과 수준에 맞는 지식을 가진 담당자가 있을 경우 피해 확인 및 보완이라도 할 수 있겠지만, 보안에 무감각하거나 관련 지식이 미흡한 소규모 사업장이나 개인의 경우 자신의 서버가 피해를 입었다는 사실조차 인지하지 못 하기도 한다. 심할 경우 서버 관리조차 이루어지지 않아 공격자의 개인 서버로 사용되기까지 한다.

그 어떤 보안대첵을 강구해도 보안은 언제나 부족하다. 하지만 간단한 조치만으로도 앞서 언급한 위협의 상당부분을 차단할 수 있다. 말했듯이 대부분은 공격자라고 부르기도 뭐한 장난섞인 시도이며, 상대적으로 낮은 가치의 데이터가 대다수인 개인 서버가 일정 수준의 보안을 갖추고 있을 경우 이를 우회하는 것은 시간낭비이기 때문이다.

간단히 말해 여러분이 게임을 하는데 체력은 많고 패턴도 귀찮은데다, 보상은 잡몹 수준인 보스가 있다고 가정하자. 해당 구간에 도달할 때마다 한숨만 나올 것이며, 게임 커뮤니티엔 해당 보스를 삭제해달라는 요구가 빗발칠 것이다. 유튜브를 보다보면 인기 급상승 5위로 올라온 "역대 최악의 게임 보스 TOP 10" 영상에 당당히 이름이 올라가있다. 또한 DC의 해당 게임 갤러리나 인벤에선 그 보스의 이름을 비하의 의미로 사용하고 있을 것이며, 해당 보스를 스킵할 수 있는 각종 연구들이 활발하게 진행되고 있을 것이다.

이 장에선 우리의 서버를 이런 "보상은 없고 패턴은 귀찮은 체력돼지" 보스로 만들어 공격자들이 드러워서 피하도록 만들어 볼 것이다.

서비스 포트 변경하기 🔗

파일 시스템에 직접적으로 영향을 주는 통신은 SSH, SFTP가 존재한다. 각 프로토콜의 전신인 Telnet과 FTP는 SSL의 미적용으로 OS 설치 시 비활성화 되어있다. 굳이 해당 프로토콜을 쓸 이유조차 없으니, 여기서는 논외로 한다.

각 서비스 포트는 동일하게 SSH 데몬에서 관리하므로 22다. 기본 프로토콜의 포트는 기본 포트가 고정적이므로, 대부분의 공격 시도는 이런 불변성을 악용하여 이루어진다. 반대로 말하자면, 서비스 포트를 변경하는 것만으로도 간단한 공격 시도를 손쉽게 차단할 수 있다.

기본으로 설정된 포트와 달리, 서버 담당자가 임의로 바꾼 포트는 추적할 방법이 없기 때문. 포트의 최대값은 65,535개이므로, 임의의 포트로 변경했다면 공격자는 모든 포트에 통신을 시도하여 SSH 포트를 찾아내야만 한다.

SSH와 SFTP의 서비스 포트를 변경하거나, iptables이나 공유기 설정을 통해 포트포워딩을 시켜 임의의 외부 포트와 22번 포트를 매칭시켜줄 수도 있다.

서비스 포트 변경을 통한 접근 제어 🔗

BASH

0sudo vi /etc/ssh/sshd_config

파일 내용을 보면 #Port 22로 주석처리된 구문을 확인할 수 있는데, 해당 주석을 제거하여 원하는 포트로 입력해준 뒤 저장하면 된다.

BASH

0systemctl restart ssh

SSH 서비스를 재시작함을 잊지 말자.

포트포워딩을 통한 접근 제어 🔗

SSH의 포트 변경이 꺼려진다면, 포트포워딩을 통해 외부에서 접속하는 임의의 포트 하나와 매칭하자. iptables를 활용하여 구성할 수 있다.

BASH

0# 포트포워딩 추가
1iptables -t nat -A PREROUTING -p tcp --dport 22 -j REDIRECT --to-port [PORT NUMBER]
2
3# 포트포워딩 삭제
4iptables -t nat -D PREROUTING -p tcp --dport 22 -j REDIRECT --to-port [PORT NUMBER]
5
6# 포트포워딩 상태 확인
7iptables -L

공유기를 사용하고 있다면 공유기에서 포트포워딩을 진행할 수도 있다.

iptables를 활용하면 특정 IP만 해당 포트에 접근할 수 있도록 제한할 수도 있다. geoIP 플러그인과 연동하면 국가별 IP 대역별로 관리할 수도 있으니, 관심이 있다면 찾아보길 바란다. 적용이 마냥 간단하지는 않으니 참고할 것.

RSA Key 파일로만 접근 허용하기 🔗

공격자가 꽤나 근성이 있어서, 혹은 운이 좋아서 내가 임의로 변경한 SSH 서비스 포트를 알아내어 공격을 시도한다고 가정해보자.

계정정보의 경우 보통 Brute Force 기법을 통해 가능한 모든 조합의 계정정보를 입력하여 로그인을 시도할 것이다. 이를 막기 위해 일정량의 로그인 실패가 감지되면 잠시 동안 접근을 제한하거나, 계정을 잠궈 관리자가 해제해야 다시 활성화되게끔 시스템을 구성하기도 한다.

위 방법도 충분히 좋은 방법이지만, 오로지 RSA Key로만 로그인할 수 있도록 서버 설정을 구성하면 로그인의 보안을 대폭 강화할 수 있다.

내가 사용자의 계정정보, 심지어 비밀번호까지 알고 있더라도 서버에 등록된 공개키와 매칭되는 개인키가 없을 경우 로그인을 시도할 수 없다.


절차는 아래와 같다.

  1. RSA 키쌍 생성
  2. 서버에 공개키 등록
  3. SSH, SFTP 프로토콜 접속 시 개인키 파일을 제공하여 로그인 수행

RSA 키 생성 시 키 파일에 암호를 설정할 수 있다. 이 경우, 로그인 시 해당 키 파일에 설정된 비밀번호를 요구한다. 키 파일의 비밀번호는 서버의 계정정보와 별개이므로, 키 파일이 유출되었다 하더라도 키 파일의 사용을 막아 실질적인 피해를 방지할 수 있다.

RSA 키쌍 생성하기 🔗

BASH

0ssh-keygen -t rsa

위 명령어를 사용하여 RSA 비대칭키를 생성하자. 생성 과정에서 키 파일의 비밀번호를 요구하는데, 빈 칸인 채로 Enter를 누르면 비밀번호 없이 생성된다. 이 경우, 키 파일만 획득하면 키 파일을 사용할 수 있다. 반대로 비밀번호를 입력하면 해당 키 파일을 사용하기 위해 지정한 비밀번호를 입력하여 디코딩해야한다.

  • 개인키 /home/username/.ssh/id_rsa
  • 공개키 /home/username/.ssh/id_rsa.pub

기본적으로 위 경로에 바로 생성된다.

RSA 키를 서버에 등록하기 🔗

BASH

0ssh-copy-id username@xxx.xxx.xxx.xxx

위 명령어를 입력하여 키 파일을 서버에 등록하자. /home/username/.ssh/id_rsa.pub를 자동으로 등록한다.

키 파일로 SSH 접속하기 🔗

BASH

0ssh -i [PRIVATE KEY] username@xxx.xxx.xxx.xxx

위 명령어를 입력하여 SSH를 접속할 수 있다. -i 옵션으로 개인키 경로를 입력할 수 있다. 키 생성 시 비밀번호를 입력했다면 비밀번호 입력이 필요하며, 따로 생성하지 않았을 경우 즉시 로그인이 된다.

저 Windows에서 쓰고있는데, 개인키 사용시 오류떠요! 🔗

아마 대부분 Ubuntu에서 RSA 키를 생성하고, 생성한 개인키를 Windows로 전송하여 SSH 접근하는데 사용할 것이다.

OUTPUT

0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
2@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
3Permissions for 'C:\\id_rsa' are too open.
4It is required that your private key files are NOT accessible by others.
5This private key will be ignored.
6Load key "C:\\id_rsa": bad permissions

하지만 막상 Windows에서 키 파일 사용 시, 키 파일이 너무 많은 유저에게 허용되면 보안 상의 이유로 키 파일의 사용을 제한한다. 해결책은 하나다. 해당 키 파일을 사용할 유저에게만 권한을 부여해주면 된다.

문제는 Windows의 편의성으로 인해, 파일 전송 완료 시 필요한 권한을 자동으로 부여해주기 때문에, 수동으로 제거해야한다.

image

키 파일의 [속성] - [보안] 탭에서 파일에 부여된 접근권한을 확인할 수 있다. 보다시피 현재는 너무 많은 사용자에게 접근이 허가되어 있으므로, 오직 나만 접근할 수 있도록 변경한다. 안타깝게도 파일에 상속이 적용되어있어서 그냥 삭제되지 않는다. 하단의 [고급] 탭을 누르자.

image

하단의 [상속 사용 안 함] 버튼을 클릭하여 상속 관계를 제거한다. 메시지 하나가 뜰텐데, [명시적 사용 권한으로 변환]을 선택한다. 제거하면 사용자를 직접 지정해야해서 번거롭다.

이후 내 계정을 제외한 모든 권한 항목은 제거한다. 이후 저장하고 다시 시도하면 정상적으로 로그인을 수행할 수 있다.

SSH 접근 시 키 파일 방식만 허용하기 🔗

여기까지 왔다면 로그인은 잘 됐다는 뜻인데, 키 파일로 로그인할 수 있는 건 좋지만, 문제는 그냥 계정 정보를 입력해도 로그인이 된다.

이래서야 키 파일의 높은 보안성을 활용하기 어렵다. 로그인 시 반드시 키 파일 로그인만을 허용하여, 내 서버의 개인키를 가진 인원만 접속할 수 있도록 제한해보자.

※ 무턱대고 설정했다간 본인조차 SSH에 접속하지 못하는 상황이 생기기도 하니 주의할 것

BASH

0sudo vi /etc/ssh/sshd_config

SSH 설정 파일을 열어 아래의 값을 수정하자. 비밀번호 입력 로그인 방식을 사용하지 않도록 설정하는 것이다.

  • PasswordAuthentication yes -> PasswordAuthentication no

BASH

0systemctl restart ssh

재부팅 후 로그인을 수행해보자.

BASH

0# 일반 로그인 방식의 SSH
1ssh username@xxx.xxx.xxx.xxx
2
3# 키 파일 방식의 SSH
4ssh -i [PRIVATE KEY] username@xxx.xxx.xxx.xxx

일반로그인은 계정 정보를 제대로 입력했다 하더라도 로그인에 실패할 것이다.

정리 🔗

SSH와 SFTP를 반드시 개인키로만 로그인할 수 있도록 구성을 변경했다.

생각보다 간단한 수준의 보안 작업이라도, 실제로 이루어지는 공격의 대다수를 무력화시킬 수 있다.

키를 통해 더욱 안전하게 서버의 보안을 지킬 수 있지만, 키 파일을 분실하지 않도록 주의하자.