레이블이 보안인 게시물을 표시합니다. 모든 게시물 표시
레이블이 보안인 게시물을 표시합니다. 모든 게시물 표시

2015년 4월 1일 수요일

ssh 사용시 암호 대신 SSH key로 인증하기

SSH key 동작방식

SSH 서버는 여러가지 방법으로 클라이언트를 인증할 수 있다. 그 중 가장 기본적인 방법은 패스워드를 사용하는 것으로 사용하기 쉽지만 가장 안전한 인증방법은 아니다.
비록 패스워드는 암호화되어 서버로 보내지지만 꾸준하고 반복적인 해커의 공격에 안전할만큼 복잡하거나 길지 않은 경우가 거의 대부분이다. 컴퓨팅 파워가 비약적으로 발전했기 때문에 자동화 된 스크립트를 사용한 brute-force 공격에 취약할 수 밖에 없다. 다른 추가적인 보안박식들도 있지만 SSH key가 가장 안정적이고 안전한 검증된 인증방식이다.

SSH 키 페어는 두개의 암호키로 SSH 서버가 클라이언트를 인증하는데 사용될 수 있다. 각 키 페어는 public 키와 private 키로 이루어진다.

Private 키는 클라이언트가 가지고 있고, 이 키는 절대적인 비밀(누구에게도 복사해 주거나 공개하면 안됨)로 해야만 한다. 어떤 식으로건 private 키가 알려지는 순간 공격자는 그 쌍이 되는 public 키로 설정된 서버에 아무 추가적인 인증 없이 로그인이 가능해진다. 추가적인 예방조치로 private 키를 passphrase로 암호화 해서 디스크에 저장할 수 있다.

쌍이 되는 public 키는 아무 걱정 없이 자유롭게 누구에게든 공유할 수 있다. Public 키로 메시지를 암호화 할 수 있는데, 그 암호화 된 메시지는 그 쌍이 되는 private 키로만 해석할 수 있다. (암호화에 사용한 public 키로도 암호화 된 메시지를 해석할 수 없다) 이런 특성이 키 페어를 사용한 인증방식에 사용된다.

Public 키는 SSH로 로그인하길 원하는 원격 서버에 업로드된다. 이 키는 사용자 어카운트의 ~/.ssh/authorized_keys 라는 특별한 파일에 추가된다.

클라이언트가 SSH key를 사용해 인증하려고 시도하면, 서버는 클라이언트가 private 키를 가지고 있는지 여부를 테스트 할 수 있다. 클라이언트가 private 키를 가지고 있는걸 증명하면 쉘 세션이 생성되거나 요구된 명령을 실행한다.
이 전체적인 흐름은 다음과 같다.



1. 클라이언트가 서버에 SSH 연결을 요청한다.
2. 서버는 랜덤 챌린지(랜덤 데이터 스트링)를 생성해 클라이언트에게 보낸다.
3. 클라이언트는 서버로 부터 받은 챌린지(C)를 자신이 가지고 있는 private 키로 암호화해서 암호화 된 메시지를 서버로 보낸다.
4. 서버는 클라이언트에서 받은 암호화 된 메시지를 public 키로 해석한 후 그 결과를 2단계에서 자신이 클라이언트에게 보낸 랜덤 챌린지와 일치하는지 확인한다. (public 키로 해석할 수 있는 메시지는 그 쌍이 되는 private 키를 가진 사람만이 만들 수 있기 때문) 일치하면 클라이언트가 인증된 것이다.

SSH 키 만들기

서버가 SSH 키 인증을 사용하도록 설정하려면 가장 먼저 해야 하는 일은 클라이언트에서 키 페어를 만드는 것이다.
키 페어를 만들려면 OpenSSH에 포함되어 있는 ssh-keygen 유틸리티를 사용한다. 디폴트로 2048-bit RSA 키 페어를 만들게 되어 있는데, 대부분의 사용자에게 이 정도면 충분하다.

클라이언트에서 ssh-keygen을 실행해 SSH 키 페어를 만든다.

$ ssh-keygen

Generating public/private rsa key pair.
Enter file in which to save the key (/home/test/.ssh/id_rsa):

프로그램이 생성될 키를 저장할 위치를 선택하도록 물어본다. 디폴트로 ~/.ssh 디렉토리에 저장하게 되어 있다. Private 키는 id_rsa라는 이름이고 public 키는 id_rsa.pub라는 이름을 사용한다.
일반적으로 디폴트를 그대로 사용하는게 좋다. 별도 디렉토리를 사용하려면 원하는 위치를 입력하고, 그냥 디폴트를 사용하려면 엔터를 누르면 된다.

만일 이전에 만들어 놓은 SSH 키가 있다면 다음과 같은 내용을 보게 될 것이다.

/home/test/.ssh/id_rsa already exists.
Overwrite (y/n)?

덮어쓰기를 선택하면 이전 키를 사용하는 인증은 더 이상 사용할 수 없게 된다. 이 단계는 되돌릴 수 없으므로 yes를 선택하려면 매우 주의해야 한다.

Created directory '/home/test/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:

다음으로 키에 대한 passphrase를 물어본다. Passphrase는 옵션으로 private 키를 디스크에 저장할 때 암호화 하는데 사용된다.
어짜피 passphrase를 입력해야 한다면 SSH 키를 사용하는 장점이 무엇인가 궁금할 수 있을 것이다. 몇가지 장점을 나열하자면...

* Private SSH키(passphrase로 보호되는 부분)는 네트웍 상에 절대로 노출되지 않는다. Passphrase는 로컬머신상에서 private 키를 해석하는데만 사용된다. 그러므로 passphrase에 대한 네트웍 기반의 brute-force 공격이 불가능해 진다.
* Private 키는 제한된 디렉토리내에서만 보관된다. SSH 클라이언트는 제한된 디렉토리에 보관되지 않는 private 키는 인식하지 않는다. 또한 키 자체는 제한된 퍼미션을 가져야만 한다. (owner만 rw가 가능) 즉 시스템의 다른 사용자가 볼 수 없다는걸 의미한다.
* Private SSH 키의 passphrase를 탈취하려는 해커는 이미 시스템을 억세스 할 수 있어야 한다. 즉 해커가 이미 시스템의 사용자 어카운트나 루트 어카운트에 억세스 할 수 있다는걸 의미한다. 이 경우 passphrase를 사용하면 해커가 즉각 다른 서버에 로그인 하는걸 막아줄 수 있다. 즉 새로운 SSH key 쌍을 만들고 이미 탈취당한 키는 삭제할 수 있는 시간을 벌어줄 수 있다.

Private 키는 절대 네트웍에 노출되지 않고 파일 퍼미션으로 보호되기 때문에 당신(과 루트유저) 이외에는 이 파일에 접근할 수 없다.
Passphrase는 옵션이기 때문에 입력해주면 이후에는 (SSH agent를 사용하지 않는 한) 이 키를 사용할 때 마다 passphrase를 입력해 줘야 한다. Passphrase를 사용하는걸 권장하지만, 원하지 않는다면 그냥 엔터를 눌러주면 된다.

Your identification has been saved in /home/username/.ssh/id_rsa.
Your public key has been saved in /home/username/.ssh/id_rsa.pub.
The key fingerprint is:
a9:49:2e:2a:5e:33:3e:a9:de:4e:77:11:58:b6:90:26 username@remote_host
The key's randomart image is:
+--[ RSA 2048]----+
|     ..o         |
|   E o= .        |
|    o. o         |
|        ..       |
|      ..S        |
|     o o.        |
|   =o.+.         |
|. =++..          |
|o=++.            |
+-----------------+  

이제 인증에 사용할 수 있는 private 키와 public 키 쌍을 만들었다. 다음 단계는 public키를 서버에 넣어줘 SSH key를 인증에 사용할 수 있게 해 주는 것이다.


서버에 public 키를 카피하기 

- SSH-Copy-ID

서버에 public키를 복사하는 가장 쉬운 방법은 ssh-copy-id 라는 유틸리티를 사용하는 것이다. 간단하기 때문에 가능하다면 가장 권장하는 방법이다. 
ssh-copy-id는 OpenSSH 패키지에 들어있기 때문에 로컬 시스템에 이미 설치되어 있을 가능성이 크다. 이 방식을 사용하려면 먼저 서버에 패스워드로 ssh 억세스가 가능해야만 한다.
이 유틸리티를 사용하려면 연결하려는 원격 호스트 이름과 유저 어카운트를 지정해 주면 된다. 

$ ssh-copy-id test@foo.bar.com

명령을 입력하면 다음과 같은 메시지가 출력된다. 

The authenticity of host 'foo.bar.com (111.111.11.111)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes

메시지의 내용은 로컬 컴퓨터가 원격 컴퓨터를 식별할 수 없다는 의미이다. 새 호스트에 처음으로 접속하는 경우 발생한다. 'yes'와 엔터를 눌러 계속 진행한다.
유틸리티가 로컬 어카운트의 기존에 만들어 놓은 id_rsa.pub 키를 찾는다. 키를 찾으면 원격 컴퓨터의 유저 어카운트 패스워드를 묻는다. (예에서는 foo.bar.com 서버의 test 어카운트의 암호)

/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
test@foo.bar.com's password:

암호를 입력하고 엔터를 누르면 유틸리티는 입력한 암호를 사용해 원격 호스트의 어카운트에 연결한다. 그리고 로컬 어카운트에 있는 ~/.ssh/id_rsa.pub 키파일의 내용을 원격 호스트 어카운트의 ~/.ssh 디렉토리에 있는 authorized_keys 에 복사한다.

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'test@foo.bar.com'"
and check to make sure that only the key(s) you wanted were added.

이제 자신의 id_rsa.pub 파일이 서버에 업로드 된 것이다.

- 수동으로 복사

로컬 머신 어카운트의 id_rsa.pub 키 파일 내용을 SSH로 로그인하길 원하는 서버 어카운트의 ~/.ssh/authorized_keys 파일에 복사해 넣어주면 된다.

먼저 id_rsa.pub 키 파일 내용을 화면에 출력한다.

$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCqql6MzstZYh1TmWWv11q5O3pISj2ZFl9HgH1JLknLLx44+tXfJ7mIrKNxOOwxIxvcBF8PXSYvobFYEZjGIVCEAjrUzLiIxbyCoxVyle7Q+bqgZ8SeeM8wzytsY+dVGcBxF6N4JS+zVk5eMcV385gG3Y6ON3EG112n6d+SMXY0OEBIcO6x+PnUSGHrSgpBgX7Ks1r7xqFa7heJLLt2wWwkARptX7udSq05paBhcpB0pHtA1Rfz3K2B+ZVIpSDfki9UVKzT8JUmwW6NNzSgxUfQHGwnW7kj4jp4AT0VZk3ADw497M2G/12N0PPB5CnhHf7ovgy6nL1ikrygTKRFmNZISvAcywB9GVqNAVE+ZHDSCuURNsAInVzgYo9xgJDW8wUw2o8U77+xiFxgI5QSZX3Iq7YLMgeksaO4rBJEa54k8m5wEiEE1nUhLuJ0X/vh2xPff6SQ1BL/zkOhvJCACK6Vb15mDOeCSq54Cr7kvS46itMosi/uS66+PujOO+xt/2FWYepz6ZlN70bRly57Q06J+ZJoc9FfBCbCyYH7U/ASsmY095ywPsBo1XQ9PqhnN1/YOorJ068foQDNVpm146mUpILVxmq41Cj55YKHEazXGsdBIbXWhcrRf4G2fJLRcGUr9q8/lERo9oxRm5JFX6TCmj6kmiFqv+Ow9gI0x8GvaQ== test@localhost

원격 호스트에 로그인 한 다음 먼저 홈 디렉토리에 .ssh 디렉토리가 만들어 져 있는가 확인한다. 만일 없다면 다음 명령으로 만들어준다.

$ mkdir ~/.ssh

이제 .ssh 디렉토리 안에 authorized_key 파일이 없으면 만들고, 이미 존재하면 파일 내용에 추가해주면 된다.

$ echo [public_key_string] >> ~/.ssh/authorized_keys

위의 명령에서 빨간색 [public_key_string] 부분은 위의 cat 명령에서 출력된 결과로 바꿔줘야 한다.  (위에서 노란색으로 칠해진 부분)

SSH 키를 사용해 서버에 로그인하기

서버에 public 키를 카피해 놓았다면 원격 호스트에 로그인 할 어카운트의 암호 없이 로그인이 가능하다. 로그인 절차는 완전 동일하다.

$ ssh test@foo.bar.com

만일 이 호스트에 SSH로 첫번째 접속하는 것이면 다음과 같은 메시지를 보게 될 것이다.

The authenticity of host 'foo.bar.com (111.111.11.111)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes
  
메시지의 내용은 로컬 컴퓨터가 원격 컴퓨터를 식별할 수 없다는 의미이다. 새 호스트에 처음으로 접속하는 경우 발생한다. 'yes'와 엔터를 눌러 계속 진행한다.
Private 키에 passphrase를 지정해 주지 않았다면 곧바로 로그인이 된다. 만일 키 쌍을 만들 때 private 키에 passphrase를 지정해 주었다면 passphrase를 물어본다. 인증이 성공되면 쉘 세션이 열리게 된다.

2011년 2월 28일 월요일

구글 2단계 인증 사용하기 (Using Google 2-step verification)

구글에서 새로 시작한 서비스이다.
비밀번호 유출이 걱정되거나 계정이 해킹당한거 같다고 걱정하는 사람들은 이 서비스를 이용하면 구글을 훨씬 안심하고 사용할 수 있게 된다.


사용하려면 먼저 구글 어카운트 설정으로 가서 Using 2-step verification을 선택한다.
 

아래와 같이 2-step verification 설정이 시작된다.

먼저 어떤 스마트폰을 사용할건지 선택한다.


플랫폼을 선택하면 해당 플랫폼에 필요한 앱을 설정하는 법이 나온다. 그대로 따라해서 폰에 필요한 앱을 설치해준다.


 설치가 완료된 다음 next를 누르면 아래와 같이 화면에 QR코드가 나타난다.


폰에 설치한 앱을 실행한다. 여기서는 안드로이드에 설치된 경우이다.


Scan account barcode를 선택한 다음 컴퓨터 화면의 QR코드를 인식시킨다.

정상적으로 QR 코드가 인식되면 화면에 위와 같은 확인 코드가 나오게 된다.
PC에 위의 확인코드를 넣어주면 된다.


모든게 정상적으로 되었다면 아래와 같은 화면이 나오게 된다.
여기까지 오면 일단 설정은 끝난건데 문제는 암호를 잊어버리고 폰도 없어지거나 분실되는 경우 사용할 수 있는 수단이 필요하게 된다. 

은행의 보안카드같이 화면에 아래와 같은 코드들이 나타나게 된다. 이 코드들은 별도로 잘 보관해 두어야 한다. 만일 암호도 기억이 나지 않고 스마트폰도 없는 경우는 이 코드를 알고 있어야만 자신을 확인시켜줄 수 있게 된다.

꼼꼼하게 확인하기 위해 저 표를 인쇄하건 어딘가에 잘 보관해 두었다는걸 체크해 주지 않으면 next버튼이 활성화 되지 않는다.


다음으로 넘어가면 마지막 수단으로 문자메시지나 음성으로 확인할 수 있도록 하기 위해 휴대폰 번호를 등록한다.

여기까지 왔으면 이제 설정이 끝난것이다. 아래와 같은 최종 확인 화면이 나오게 되고 여기서 Turn on 2-step verification 버튼을 눌러주면 이 기능이 활성화되어 바로 적용된다.


 자동으로 로그아웃되고 다시 로그인하도록 암호를 물어본다.

암호를 넣으면 이전과 다르게 바로 로그인이 되는게 아니고 아래와 같은 화면이 나와 인증코드를 물어보게 된다. 자신의 폰에 설치한 앱을 실행하면 화면에 나오는 인증코드를 넣어주면 된다.

 
 정상적으로 로그인이 되면 다음과 같은 화면을 볼 수 있다.

여기서 모든 설정은 끝난 셈이지만 남은 문제는 웹 브라우져로 로그인 할 때는 인증코드를 물어볼 수 있지만 전용 클라이언트(구글계정에 연동되는 메일이나 웹 서비스 클라이언트들) 은 인증코드를 물어볼 수 없기 때문에 제대로 동작을 하지 않게 된다. 그 경우를 위해 Application-specific passwords 기능을 제공한다. 아래에서 Manage application-specific passwords를 선택한다.


여러 클라이언트마다 별도로 관리할 수도 있다. 그걸 위해 각 application-specific passwords마다 이름을 붙여준다. 아래에 원하는 이름을 정해주고 Generate password버튼을 누르면 된다.


그럼 아래 노란색 박스에 암호가 만들어진다. 클라이언트에 자신의 원래 암호 대신 저 암호를 넣어주면 클라이언트들도 정상적으로 동작하게 된다. 이 암호는 랜덤하게 생성된 길고 복잡한 암호이기 때문에 brute-force 방식의 password cracker들에게는 거의 깨질일이 없는 안전한 암호이다. 이 암호는 클라이언트에 한번만 넣어주면 되고 따로 암기할 필요는 없는 암호이다.

이렇게 하면 스마튼 폰을 통해 구글의 2단계 인증 기능을 사용할 수 있고 훨씬 더 안전하게 구글을 사용할 수 있게 된다. 특히 PC방이나 공공장소에서 구글에 로그인 할 때 혹시라도 키로깅을 당하더라도 OTP 코드는 계속 바뀌기 때문에 설사 암호가 로깅되어도 계정이 뚤릴까봐 걱정할 필요가 없어진다.

2009년 10월 10일 토요일

Safelock: Biometric Typing Security

IEEE Student Innovation Contest의 first prize 수상작인데 패스워드의 문제점을 상당부분 해결한 수작이다.
패스워드의 문제점은 다른 사람이 어떤 방법으로건 패스워드를 알아낸 경우 그 사람의 시스템에 불법적인 억세스를 막을 방법이 없다는 것이다. 그 대안으로 지문/홍채인식등의 방법을 사용하기도 하지만 그 경우 별도의 하드웨어가 필요하기 때문에 추가적인 비용이 필요하게 된다.
그에 비해 Safelock은 별도의 하드웨어를 사용하지 않고 현재의 패스워드를 사용하는 시스템에도 소프트웨어만으로 기능을 추가할 수 있다.



동작 원리는 사람마다 키보드를 사용하는 입력 스타일이 다른 점을 이용하는 것이다. 사람마다 키를 누르고 다음 키를 누를때까지의 간격, 키를 누르고 있는 시간, 키를 누르는 압력등이 다 다르다. 그렇기 때문에 사용자의 패스워드 뿐 아니고 이 추가정보를 같이 기록해 놓고 사용자가 패스워드를 입력하면 타이핑에서 이 정보들을 추출한 다음 normalize해서 기록되어 있는 정보와 비교하는 것이다.
이 입력 스타일이 해당 오차범위 이내에 들어가지 않으면 설사 정확한 패스워드를 입력했다 하더라도 시스템에 로그인 할 수 없다.
또한 Safelock은 사용자가 반복적으로 잘못된 패스워드를 입력하는 경우 그 사용자의 입력 스타일을 기록하고 분석해서 정해진 횟수 이상 잘못된 패스워드를 입력하면 그 사람은 '잠재적으로 위험한 사용자'로 기록해서 아예 시스템을 잠궈 버린다.
그렇기 때문에 실수로 패스워드가 유출되었거나 키로그 소프트웨어등을 사용해서 다른 사람이 암호를 알게 되었다 하더라도 입력 스타일이 다르기 때문에 시스템에 로그인 할 수 없게 된다.
특히 최근에는 컴퓨터에 키로그 소프트웨어를 설치하거나 별도의 하드웨어를 연결하지 않더라도 옆방에서 키보드가 눌릴 때 발생되는 아주 미약한 전자기파를 받아 분석해서 어느 키가 눌렸는지 확인할 수 있기 때문에 이 기술은 시스템의 security를 획기적으로 강화시켜 줄 수 있다.