본문 바로가기
정보보안/이론

[KITRI] Day14. Telnet, SSH 구축하기

by 민-Zero 2020. 5. 13.

Telnet, SSH

리눅스에서는 원격으로 리눅스 서버에 접근할수 있도록 다양한 원격접속 프로토콜들을 제공한다.

원격 접속 : Telnet, SSH, VNC, RDP, Wake On Lan(WOL)

이들중 telnet과 보안이 약한 telnet대신 사용하는 ssh를 구축하자.

 

텔넷은 텔넷 클라이언트와 텔넷 서버로 구성되어 진다.

Telnet Client : telnet이라는 이름으로 존재하며 필요한 경우 실행하고 필요가 없는 경우 종료한다.

Telnet Server : telnetd라는 이름으로 존재하며 상시 구동되고 있어야 하며 요청이 들어올 경우 응답을 한다.

웹으로 생각할 경우 Web Client는 Web Browser(IE, Chrome, firefox 등)이 되고 Web server는 apache web, IIS등이 되는 것이다.

 

telnet 서버 구축

텔넷 서버를 구축하기 위해 rpm 명령어를 통해 패키지가 설치되어 있는지 확인한다.

 

만약 텔넷이 설치되어있지 않는다면 yum install -y telnet-server를 통해 설치를 진행하면 된다.

 

rpm -ql 을 통해패키지와 함께 설치된 파일은 무엇인지 확인하면 /etc/xinetd.d/telnet 이라는 파일이 설치되어 있는것을 확인할 수 있다. 

 

해당 파일은 텔넷 서버의 서비스를 설정할수 있는 파일로 현재는 보안성의 문제로 사용되지 않기 때문에 disable이 yes로 설정되어 있기 때문에 no로 변경해야 서버를 동작할 수 있다.

 

텔넷 서버가 동작하는지 확인하기 위해 자기 자신이 클라이언트가 되어 자신의 텔넷 서버에 접속을 시도해보면 된다.

접속 방법은 telnet 접속할IP 라는 명령어를 통해 수행할 수 있다. 만약 접속이 되지 않는다면 오류메세지를 통해 몇 계층에 문제가 있는지 확인할 수 있다.

No Route to host 메세지라면 패킷이 도달할 수 없는 오류이므로 L3, L4 에서 의 오류, Connection Refused면 서비스 에 연결할 수 없는 오류이므로 L7 오류인 것을 알 수 있다.

 

위의 경우 Refused 메세지가 등장했으므로 7계층의 서비스 상에서 문제 즉 disable을 no로 바꾼 설정이 아직 적용이 안되었을 가능성이 가장 크다. 따라서 service xinetd restart로 재시작 하여 설정이 재적용되도록 하면 정상적으로 접속이 된다. 만약 Route to host에러가 등장한다면 방화벽 설정을 변경해야 한다.

 

서비스 재시작과 방화벽 설정법)

centos ~6 StandAlone service 데몬명 start/stop으로 구동및 정지 했고, SuperDaemonservice xinetd start/stop 으로 구동및 정지 했다. 텔넷의 경우 Superdaemon 타입이므로 xinetd의 형태로 구동 및 정지를 수행해야 한다. 자동 동작의 경우 ntsysvchkconfig 데몬명 on/off 로 수행할 수 있다.

centos 7~ 부터는 StandAlone systemctl start/stop 데몬명.service로 구동 및 정지, SuperDaemonsystemctl start/stop 데몬명.socket 으로 구동 및 정지한다. 자동 동작의 경우 systemctl enable/disable 데몬명.service/데몬명.socket으로 수행한다.

 

방화벽은 iptables -I INPUT -p tcp --dport 23 -j ACCEPT 와같이 인바운드 설정을 변경하면 텔넷 서버에 접근할 수 있다.

Centos 7이후부터는 firewall-cmd --add-port=23/tcp 또한 방화벽 설정을 firewall-config를 통해 GUI에서 설정할 수 있다.

 

telnet의 약한 보안성을 확인하기 위해 윈도우에서 리눅스 서버로 user1이라는 계정으로 접속을 해보자 비밀번호는 123으로 수행하며 와이어샤크를 통해 캡쳐할 경우 접속한 아이디와 비밀번호가 모두 노출되게 된다.

원하는 패킷만 확인하기 위해 조건을 걸 수 있다. ip.addr == IP && tcp.port == 23 로 조건을 걸어 원하는 IP와 port가 23번 인 패킷만 확인하도록 수행했다. 좀더 상세하게 패킷을 걸러내려면 ip.dst == IP && tcp.dstport == 23 && telnet같은 방법도 가능할 것이다.

이때 user1 이라는 데이터가 전송되는 것을 확인할 수 있으며

입력한 비밀번호 123도 그대로 노출되는 것을 확인할 수 있다. 이처럼 패킷이 전송될때 암호화 되어 전송되지 않고 그대로 노출되기 때문에 중간에 패킷을 가로채기만 하면 모든 데이터가 유출되기 때문에 telnet은 더이상 사용되지 않고 패킷이 전송될때 암호화를 진행하여 전송하는 SSH가 사용된다.

 

telnet에 원격으로 접속할때 root로 로그인 하지 못하도록 설정하는 파일이 존재하는데 /etc/securetty 이다.

이곳에 접속할 수 있는 가상터미널을 설정할 수 있는데 pts/1 pts/2과 같이 추가하게 되면 해당 설정에 등록된 수만큼 들어올수 있게 된다. 하지만 이곳에 pts가 없으면 외부에서 telnet으로 root 로그인은 막을 수 있다.

 

SSH

putty를 사용해 ssh접속을 시도한후 와이어 샤크를 통해 보게되면 텔넷과는 다르게 내용이 암호화되어 알아볼 수 없다.

SSH는 공개키 방식을 통해 키를 교환한뒤 보내는 내용을 서로 암호화 하여 전송하기 때문이다.

패킷을 확인하면 디피헬만 키교환 방식을 통해 서버와 클라이언트가 서로 공개키를 주고받는 것을 확인할 수 있다.

 

SSH Server의 비밀키와 공개키는 /etc/ssh 위치에 존재한다. 

여기서 rsa, dsa 등이 보이는데 이는 비대칭키 알고리즘을 나타낸다.

비밀키(private) /etc/ssh/ssh_host_rsa

공개키(Public) /etc/ssh/ssh_host_rsa.pub

 

ssh구축하기 위해 설치 확인을 먼저 하면 ssh관련 서버 클라이언트 패키지가 존재하는 것을 확인할 수 있다. 만약 설치되어 있지 않다면 yum을 통해 다운받으면 되지만 ssh의 경우 기본적으로 설치가 되어있다.

ps aux | grep sshd 로 프로세스에서 동작중인지 확인 가능하다. standalone 형태의 데몬들은 service sshd status로도 확인 가능하다.

 

ssh -l 계정명 서버IP, ssh 계정명@서버IP 과 같은 형태로 리눅스에서 접속할 수 있다. 이때 맨처음 접속하게 되면 공개키 방식으로 암호화된 데이터를 서로 전송해야 하므로 공개키를 받을지 물어보며 공개키를 받지 않으면 접속이 수행되지 않는다.

 

telnet과 마찬가지로 접속시 에러가 발생하면 메세지를 통해 몇계층 에러인지 확인하고 조치하면 된다.

방화벽은 ~6 까지는 iptables -I INPUT -p tcp --dport 22 -j ACCEPT

7~ firewall-cmd --add-port=22/tcp 또는 firewall-cmd --add-service=ssh

 

vi /etc/ssh/sshd_config 를 통해 서버의 설정을 변경할 수 있다. 주석처리 된 부분이 default 값으로 해당 내용을 참고로 변경하면 된다.

portdefault가 아닌 임의의 포트로 변경하도록 #Port 22 밑에 Port 2020 이런식으로 추가하면 접속 포트를 변경할 수 있다. 변경하는 이유는 22번 포트는 ssh의 포트로 잘알려진 포트임으로 누구든 일단 로그인을 시도할 수 있게 되어 Brute force나 Dictionary attack 과 같은 공격을 시도해볼 가능성을 열어주기 때문에 임의의 포트로 변경하여 운영하는것이 바람직 하다.

 

포트를 변경하고 service sshd restart를 통해 적용하면 22번 으로 접근할 수 없는 것을 확인할 수 있다.

 

ListenAddress 는 요청을 들어주는 ip로 외부와 연결할 아이피를 ListenAddress에 설정하지 않는다면 외부에서 요청이 들어와도 듣지 않기 때문에 외부에서 내부 서비스에 접근할 수 없다.

ListenAddress 에 설정한 IP만 허용하겠다는 뜻이 되므로 클라이언트는 ListenAddress에 설정된 아이피를 통한 서비스 접근 이외에는 접근이 불가능하게 된다. (ListenAddress :: 부분은 ipv6 주소를 설정하는 부분이다.)

 

테스트를 위해 /etc/sysconfig/network-scripts 밑에 있는 랜카드 설정파일을 .1 .2로 추가하여 가상의 랜카드를 생성하자. 그리고 새롭게 생성한 가상의 랜카드에 임의의 ip를 할당해 주면 서버에 총 3개의 랜카드가 존재하게 된다. 해당 설정을 적용하기 위해 service network restart를 수행해야 한다.

그럼 Listen Address에 설정한 가상의 랜카드 192.168.252.16 이외에는 ssh접근을 수행할 수 없는것을 확인할 수 있다.

 

SSH 키 생성

서버에서 사용하는 공개키와 비밀키를 새롭게 생성할 수 있다. 키가 노출되지 않았더라도 주기적으로 키값을 바꿔주는것이 보안성을 좀더 높일 수 있는 방법이다.

사용법)

ssh-keygen -b bits -t 알고리즘 -c 설명 -f [경로]키이름

-b 비트 : 768 ~ (기본값 : 2048)

-t 알고리즘 : rsa1, rsa, dsa (기본값: rsa)

-f [경로]키이름 : ~/.ssh/id_rsa (기본값 : 유저 비밀키)

 

ssh-keygen -b 2048 -t rsa -f /etc/ssh/ssh_host_rsa_key 로 입력하게 되면 서버의 키값을 변경할 수 있다.

이때 새롭게 생성하면 passphrase 를 물어보는데 이는 해당 공개키를 받아 서버에 접근할때 사용할 암호를 설정하는 부분이며 키값을 갱신한뒤 다시 로그인해보면 키가 바뀌었기 때문에 공격의 가능성이 있어 경고 문구가 뜨는것을 확인할 수 있다. 

 

추가 보안설정

PermitRootLogin 부분을 yes가 아닌 no로 수정하면 ssh를 사용한 root 계정 로그인을 막을 수 있다.

PermitRootLogin without-password 로 변경하면 패스워드를 제외하고 rsa를 사용한 인증서 로그인은 가능하도록 설정할 수 있다. 이처럼 보안성이 약한 아이디, 비밀번호를 통한 로그인을 막고 공인인증서와 같은 방법으로만 로그인 할 수 있게 변경할 수 있다.

 

공인 인증서에 관한 설정은 아래의 설정을 통해 변경한다.

44 #RSAAuthentication yes RSA 인증방식을 사용하고

45 #PubkeyAuthentication yes 공개키 방식을 사용하도록

46 AutorizedKeysFile .ssh/autorized_keys 인증서 위치

 

댓글