Google OTP(Authenticator) 이용한 SSH 로그인 보안 강화

일반적으로 서버의 SSH 접속하기 위해 사용자의 아이디와 비밀번호가 필요하다. 이 말은 즉슨 대충 ID만 알아도 Brute Force Attack 할 수 있다는 얘기가 된다. 서버 관리자 입장에서 생각해보면 여간 짜증나는 일이 아니다. 로그인이 안 된다 할지라도 해킹이 시도되는 동안 소모되는 서버 자원은 어쩔 것인가 ㄷㄷㄷㄷ

이를 방지하기 위해 Fail2Ban 과 같은 Python 기반의 스크립트를 이용하여 지정된 횟수 이상으로 로그인을 실패하면 해킹으로 판단하여 일정시간 접근을 차단시키는 방법도 있다. 하지만 이 방법도 지정된 횟수 이내로.. 예를 들면 로또보다 더한 확률로 1~2번 시도만에 로그인이 성공하면 낭패다. (그러니 유저들을 추가할 땐 비밀번호 정책을 빡세게 합시다 ㄷㄷㄷ)

하지만 OTP를 이용하게 되면 약간은 안심이 될 것 같다. 1분마다 6자리의 숫자가 갱신이 되고 그 이전의 숫자조합은 무용지물이 되어버리니 이 얼마나 짱짱한가. 몇가지 OTP 서비스들이 있긴 하지만 Google OTP(정확히 말하면 Google Authenticator) 를 이용하기로 했다. 별 거 없다. 왜냐면 구글신이니까..

말머리에서 언급한 바와 같이 SSH 접속하기 위해선 사용자의 아이디와 비밀번호가 필요하지만 Google Authenticator 를 이용하면 그 중간에 OTP 번호를 입력하는 절차가 추가된다.

예를 들면 다음과 같다.

일반적인 SSH 로그인

일반적인 SSH 로그인

 

OTP 이용한 SSH 로그인

OTP 이용한 SSH 로그인

 

세팅하는 방법을 순서대로 나열하겠다. 기존의 타 블로그들에서 작성된 대부분의 Google Authenticator 세팅 방법들은 크게 문제가 없지만 중요한 부분이 빠져있다. 이 글에선 빠지지 않고 모두 작성해놨으니 그대로 차근차근 실행만 한다면 될 것이다.

  • CentOS 6.8 & 7 기준으로 작성
  • root (최고관리자) 권한 기준으로 작성
  • 작업시작 전 모든 패키지들을 업데이트 (하지 않아도 크게 상관 없음)
  1. .ssh 디렉토리 권한 변경
    * 필수 작업 – 0700으로 맞추지 않으면 로그인이 제대로 작동하지 않는다.
  2. Google OTP 패키지 설치에 필요한 필수 패키지 설치
  3. Git 으로 Google OTP 다운로드
  4. 소스 컴파일 작업
  5. Google Authenticator 설정
  6. y 누르고 엔터 (일반적으로 2번)
  7. 스마트 폰에 Google Authenticator 앱 설치 후, 모니터에 나타나는 QR코드 촬영 또는 Secret Key 작성으로 OTP 추가
  8. PAM 설정

    8.1. %PAM-1.0 바로 밑에 다음 내용 추가 (한 줄임)

    8.2 저장
  9. SSH 설정

    9.1. 다음 설정사항들을 모두 yes로 변경

    9.2 저장
  10. SSH 재시작
  11. (옵션) 모든 유저에게 OTP 부여가 완료되었고 더이상 유저 추가 계획이 없을 경우 8.1. 에서 추가된 내용 중 nullok 를 삭제한다.
    nullok 삭제시 해당 서버 SSH에 접근하는 모두가 OTP를 거쳐야 함.

 

위 과정을 모두 마치면 Google Authenticator 를 거쳐 로그인을 할 수 있다. 이렇게 되면 어제 작성했던 Root 비밀번호 자동 변경 쉘 스크립트에서 비밀번호를 좀 더 약하게 생성시켜도 괜찮을 듯 하다.

약 2주간 적용하고 싶은 마음에 수많은 삽질을 했고 결국 성공했다. 별 거 아닌데 뿌듯하다.

 

CentOS 서버 동기화 Step by Step! (feat. Rsync)

2015.03.25 기준 CentOS 최신 버전은 7.0.1406 이지만 무한한 삽질로 인한 빡침으로 14년 10월 20일에 릴리즈된 6.6 버전으로 진행한다.

(7.0.1406 버전으로 정신적 데미지 많이 받음… 하아…)

– 일단 휘리릭 휘갈겨 쓴 후, 시간을 두고 글 정리를 해야겠음.. 이쁘게 다듬으려니 귀찮..OTL

[일반 PC 에서의 작업]

별도 준비물 : FAT32 형식으로 포맷된 4GB 이상의 USB 메모리 (본체에 꽂아 놓은 상태로 진행 ㄱㄱ)


1. CentOS 6.6 넷인스톨 iso 파일을 다운로드 한다. (64bit 기준)

( http://ftp.daum.net/centos/6.6/isos/x86_64/CentOS-6.6-x86_64-netinstall.iso )

2. iso2usb 유틸리티를 다운로드 한다. (2015.03.25 기준 최신 : v0.7)

( http://sourceforge.net/projects/iso2usb/files/latest/download )

3. 2에서 다운받은 압축파일을 압축해제하고 나온 실행 파일을 실행한다. ( iso2usb.exe )

4. 1에서 다운받은 iso 파일을 선택하고 하단의 USB 드라이브 명을 확인한 후 OK

5. 약 2~3분이 지나면 부팅가능한 USB 메모리가 된다. 본체에서 안전하게 제거하고 (전원이 꺼져있는) 설치할 서버 본체 USB 포트에 꽂는다.

A 서버에서 B 서버로 파일들을 동기화 또는 백업 하려고 함!

[A & B서버에서의 공통 작업]

# OS 설치작업 시작 #

1. 서버를 켜고 BIOS 메뉴에 들어가서 USB 메모리를 첫번째 부팅 장치로 설정한다. 그리고 저장 후 재시작.

2. ‘Install CentOS 6.6 뭐시기 블라블라~’ 선택하고 좀 기다리면 시퍼런 배경의 설정 창이 뜬다.

3. 일단 랜카드부터 설정을 해준다. IP / 게이트웨이 / DNS 등

4. 설정이 잘 되면 어느 CentOS 미러서버의 파일을 다운받아 설치를 계속 진행할 건지 설정하는 창이 뜬다.

( http://ftp.daum.net/centos/6.6/os/x86_64/images/install.img ) – 다음서버가 제일 속도 준수하더라..

5. 주소를 올바르게 입력하면 혼자 다운로드 받고 GUI 설치화면으로 넘어간다. (여기서부터가 리얼 설치)

6. 시간대 설정하고 Root 비번 설정하고 파티션 설정하고 소프트웨어 뭐 설치할지 설정하고 나면 실제 설치가 진행된다.

(아직 익숙치 않은데 호기롭게 Minimal 로 설치했다가 무한삽질로 인해 눈물을 머금으며 다시 재설치 했다.)

7. 설치의 마지막 과정인 재시동이 되고 나면 엄청나게 많은 설정사항들이 [ OK ] 를 내뱉으며 서버 관리자의 로그인 직전 상태가 된다.

8. 관리자 로그인 후 랜카드가 제대로 잡혔는지 여기저기 ping 날려준다. 문제 없길 바라자. (문제 있으면 구글링해서 해결하자.. 그것까지 적으려니 귀찮다.)

# OS 설치작업 끝 #

9. SSH 자동 로그인 작업

[root@localhost ~]# ssh-keygen -t rsa

# 그 후 입력하는 것들 뜨면 일단 엔터 연타 #

그럼 root 폴더 밑에 .ssh 디렉토리와 그 하위에 id_rsa, id_rsa.pub 파일이 생성될 것이다. (뭐가 문제인지 강제로 .ssh 폴더 생성후 퍼미션 설정해도 자동 로그인이 안 될 수 있다.)

(원래 서버 작업시 최고관리자/root 로 작업하는 걸 보안상의 이유로 추천하지 않는다. 이 글에서는 귀차니즘으로 인해 이렇게 처리한다는 걸 보여주기 위함!)

A 서버 정보 : 1.2.3.4

B 서버 정보 : 5.6.7.8

B 서버 SSH 포트 : 20000

[A 서버에서의 작업]

SSH 공개키 작업 시작#


1. 9에서 생성된 id_rsa.pub 파일을 B 서버로 보내야한다.

[root@localhost ~]# cat ~/.ssh/id_rsa.pub | ssh -p 20000 root@5.6.7.8 ‘cat >> ~/.ssh/authorized_keys’

# B서버의 root 비밀번호를 물을 것이다. (위 명령어에서 root 로 B 서버 ssh 로그인 시도하니까!)

그리고 퍼미션도 한 번 설정해준다.

[root@localhost ~]# ssh -p 20000 root@5.6.7.8 ‘chmod 0600 ~/.ssh/authorized_keys’

2. 1의 작업으로 B서버로의 ssh 로그인은 비밀번호 입력할 필요 없이 바로 할 수 있다.

[root@localhost ~]# ssh -p 20000 root@5.6.7.8

SSH 공개키 작업 끝#

# rsync 세팅 시작 #

1. 테스트겸해서 A 서버의 작은 디렉토리(/test)를 B 서버로 보내본다.

[root@localhost ~]# rsync -avzh /test -e “ssh -p 20000” root@5.6.7.8:/backup


2. 첫 동기화라서 해당 A 서버 경로의 파일을 모조리 체크하고 전송하기 시작할 것이다.

(B 서버의 /backup/test 경로로 파일 전송)

Unison 동기화 프로그램

 Unison 

http://www.cis.upenn.edu/~bcpierce/unison/

2대 이상의 서버(1대일 경우 폴더)를 동기화(Sync) 시켜주는 프로그램이다.

간단히 /bin/unison /경로A /경로B 로 동기화 가능함.

(원격서버에 연결해야 할 경우 /bin/unison /경로A ssh://계정@아이피//경로B 와 같이 실행)

동기화를 하다보면 마스터 서버에서 삭제된 파일이 다른 모든 슬레이브 서버에서도 마찬가지로 삭제되는 경우가 있다.

필요없는 파일이라면 상관없지만 실수로 중요한 파일을 삭제했다면…

…그리고 cron 으로 빡세게 분단위 동기화를 걸어놨다면

N분 0초가 되기 전에 슬레이브 서버에 있는 파일을 다른 곳으로 복사시켜놔야 할 것이다.

(마스터 서버 : 주로 사용되는 서버 / 슬레이브 서버 : 백업용 서버)

서버 용량이 넉넉하다면 슬레이브 서버의 파일을 그대로 유지하는게 좋을 수 있다.

이럴 경우 unison 실행시 옵션이 필요한데, 2가지 유형이 있다.



마스터 서버에서 파일이 삭제되더라도

A) 슬레이브 서버에 있는 파일로 다시 복원(복사)

    /bin/unison /경로A /경로B -ignorearchives

B) 슬레이브 서버의 특정 경로에는 삭제된 파일이 적용되지 않음 (파일 유지, 마스터 서버에만 파일이 삭제됨)

    /bin/unison /경로A /경로B nodeletion=/경로



본인의 경우, A 방법을 이용하다가 B 방법으로 옮겼다.

A 방법은 정말 쓸모 없어서 완전히 삭제시켜야 하는 파일인데 unison 실행시 슬레이브 서버로부터

매번 삭제된 파일들이 복사되어 엄청 짜증나는 경험이 있었다.

그렇다고 매번 파일 삭제할 때마다 마스터&슬레이브 서버들을 돌아다니며 하나씩 지울 수도 없는 노릇이고..

(타이밍 잘못 맞추면 분명 삭제했는데도 다시 살아난다..)


B 방법으로 옮겼는데 불만 없이 잘 사용하고 있다.

마스터 서버에서 삭제한 파일 중 꼭 다시 확인해야 하는 것이 있을 땐 슬레이브 서버로 들어가서 확인하면 된다.

물론 정말 쓸모없는 파일들은 슬레이브 서버에서 직접 삭제를 시켜줘야 마스터&슬레이브 서버 모두에서 사라지게 된다.


아.. 더 작성하기 귀찮다..

이 정도면 귀차니즘 이겨내고 잘 쓴듯 ㅇㅇ..

ㅂㅂ