2015년 12월 27일 일요일

임베디드 시스템에서 ssh 설정 및 사용하기

임베디드 시스템에 원격 연결을 위해서 시리얼 통신 다음으로 많이 사용되는 telnet은 사용이 편리하고 설정이 간단 하지만 데이터 전송이 암호화되지 않기 때문에 보안 문제를 가지고 있다. 제품 출시 후 이더넷 포트를 통한 리버스 엔지니어링을 막아야 하거나 연결 상태에서 통신 데이터가 외부에 노출되지 않도록 하기 위해서는 telnet 대신 ssh 연결을 사용하여야 한다. (알려진 바로는 미국 NSA에서는 ssh도 뚫을 수 있다고 하는데 어떤 방법을 사용하는지는 공개가 되지 않았다.  )

ssh는 telnet에 비해서 설정이 조금 복잡해서 제대로 설정을 하기 위해서는 약간의 지식이 필요하다. ssh는 인증을 위해서 한쌍의 public/private keys로 이루어진 SSH key-pairs를 사용하는데, 아래 글이 public/private key pair를 이해하는데 도움이 될 것이다.

공개키 암호와 안드로이드 서명


패스워드 인증 방식

일단 연결하고자 하는 target 임베디드 장치가 server(혹은 Host)가 되며 target 장치에 연결하고자 하는 시스템(주로 사용자 pc)이 client가 된다. 먼저 server는 client가 접속을 시도할 때 자신의 public keys를 client에게 전달된다. 이때 client에서는 Host의 RSA key fingerprint라고 부르는 값이 출력되며 접속 진행 여부를 사용자에게 묻는다. 이 key값이 server에서 생성한 key의 fingerprint와 일치한다면 yes를 선택하면 된다.  yes 선택 시 client는 Host의 public key를 가져다 보관한다.  (일반적으로 ~/.ssh/known_hosts 에 보관됨) fingerprint값은  ssh-keygen를 사용해서 확인할 수 있다.  서버의 공개키 전달 및 이에 따른 fingerprint 확인은 최초 접속 시에만 수행된다. 이 fingerprint값을 통하여 client는 자신이 접속하는 서버를 확인하게 된다.

임베디드 시스템에서는 client와 server가 보통 바로 연결되어 있고,  두장치 모두 동일 사용자가 관리하므로 fingerprint확인이 바로 가능하며, 대부분의 경우 그렇게 중요하지도 않다.

client는 공유키 생성(접속시마다 변경됨)하여 이를 server의 public key를 사용하여 암호화한 후 이를 server에 전달하고, 이후 통신은 이 공유키를 사용하여 암호화 된다.

공유키를 전달한 후 첫번째 통신은 사용자가 입력한 패스워드가 될 것이다. 패스워드는 공유키로 암호화 하여 서버에 전달되므로 중간에 누군가가 패킷을 가로채어도 패스워드가 노출되지 않는다.  - 패스워드 이후의 모든 통신도 이 공유키를 통하여 암호화 된다.

여기서 굳이 기 공유된 server의 공개키를 사용하지 않고, 별도의 공유키를 사용하는 이유는 공유키를 사용하여 암호화 하는것이 공개키를 사용하여 암호화하는 것보다 연산처리의 부담이 적기 때문이라고 한다.

한줄 정리:  패스워드 인증 방식에서는 server가 공개키 생성, client가 공유키 생성

공개키 인증방식

공개키 인증방식을 사용하면 매번 접속시 비밀번호를 입력하지 않고 접속이 가능하다.  이를 위해서 server가 아닌 client에서 SSH key-pairs를 생성해야 한다. 생성한 key중 공개키를 server로 전달하여 저장하여 놓으면(최초 1회) 이후 client 접속 시 server는 이를 사용하여 공유키를 생성하여 client에 공유키를 전달하고, 향후 통신을 이 공유키를 통하여 암호화 한다.  client의 공개키를 통하여 암호화된 공유키(client 접속시마다 server에서 난수를 사용하여 생성함)는 해당 공개키의 pair인 비밀키로만 복호화 가능하기 때문에 매번 접속시마다 비밀번호를 사용하지 않고도 client를 인증할 수 있다.

아래 명령으로 client에서 생성한 공개키를 server에 등록할 수 있다. (key 생성 방법은 이후 설명함) 이 과정에서는 server의 sshd_config 파일의 "PasswordAuthentication" 가 일단 "yes"로 설정되어 있어야 한다. (변경 시 설정이 반영되려면 sshd가 재시작되어야 한다.)

$ cat ~/.ssh/id_rsa.pub | ssh user@192.168.11.14 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys”

보통 임베디드 시스템 개발을 위해서 접속 시에는 root로 접속하므로 위에서 user 대신 root를, 123.45.56.78 대신 target 시스템의 ip를 넣으면 된다.  ssh-copy-id를 사용하는 방법도 있지만, ssh-copy-id를 지원하지 않는 시스템도 많으므로 여기서는 소개하지 않는다.

참고 사이트 : How To Set Up SSH Keys

이후 "PasswordAuthentication" 를 "no"로 변경하고 sshd를 재실행시키면 client에서 비밀번호 대신 SSH key-pairs을 사용해서 로그인하게 된다.

아래는 SSH key-pairs을 사용해서 root로 로그인하기 위한 명령이다.

$  ssh -v -i ~/.ssh/id_rsa root@192.168.11.14

key 파일의 위치는 위에서와 같이 ssh 실행 시 -i 옵션으로 지정하거나 아래와 같이 ~/.ssh/config 파일에 지정하면 된다.

$ cat ~/.ssh/config
IdentityFile ~/.ssh/id_rsa

서버에 등록하는 파일은 public key(id_rsa.pub)이며 접속 시 사용하는 파일은 private key(id_rsa)임에 주의한다.

~/.ssh/config 파일은 ssh client의 개인 설정 파일로 전체 시스템에 적용되는 /etc/ssh/ssh_config 파일보다 우선하여 적용된다.  따라서 설정 변경이 필요하다면 /etc/ssh/ssh_config을 직접 수정하지 말고 ~/.ssh/config을 수정하도록 한다.

Server에서 Private/Public key pair 생성하기 (QNX 시스템에서 예)

ssh-keygen을 사용한다. 아래는 server(target)에서 key 생성 예이다. (Tested on QNX OS)

# ssh-keygen -t dsa -b 1024 -f /etc/ssh/ssh_host_dsa_key -N ''
# ssh-keygen -t rsa -b 1024 -f /etc/ssh/ssh_host_rsa_key -N ''

위와 같이 실행 시 SSH key-pairs는 /etc/ssh/ 아래에 생성된다.

생성된 Private/Public key의 fingerprint 확인하기
아래와 같이 생성된 SSH key-paris의 fingerprint를 확인할 수 있다.

# ssh-keygen -l   <== 소문자 el
Enter file in which the key is (/root/.ssh/id_rsa): /etc/ssh/ssh_host_rsa_key
1024 1e:f7:b2:e2:ec:9d:b9:e4:bd:51:ea:d9:26:65:c0:0b  root@localhost (RSA)


Client 에서 Private/Public key pair 생성하기

ssh-keygen을 사용한다. 아래는 client( 개발자 pc : Linux or Mac)에서 key를 생성하는 방법이다.

$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/dooeui/.ssh/id_rsa): [Enter]
Enter passphrase (empty for no passphrase): [Enter]
Enter same passphrase again: [Enter]
Your identification has been saved in test.
Your public key has been saved in test.pub.
The key fingerprint is:
...


key pair는 default로 ~/.ssh/ 아래에 생성된다. (id_rsa, id_rsa.pub) 이름에서 유추 가능하듯이 id_rsa 는 private key이며, id_rsa.pub가 publick key이다.


Server 설정( QNX OS )

client로 부터 접속 요청이 들어 올 경우 inetd이 sshd를 실행한다. Server쪽 sshd 설정은 /etc/ssh/sshd_config 파일에 저장된다. 최초 로그인 시에는 client의 비밀번호 접속을 허용해야 한다. 계속해서 비밀번호를 사용해서 접속해도 되지만, 보안을 위해서는 비밀번호 로그인을 disable하고 SSH key-pairs를 사용한 로그인을 사용하는 것이 좋다. 비밀번호 로그인 on/off는 아래와 같이 PasswordAuthentication을 yes나 no로 설정하여 제어할 수 있다.

/etc/ssh/sshd_config
------------------------------------------------------
...
PasswordAuthentication yes
...
------------------------------------------------------


서버에는 최소한 아래 파일들이 필요하다.
  • libcrypto.so.2
  • libz.so.2
  • sshd
  • ssh-keygen
  • sftp-server

ssh접속을 위해서 서버에서는아래 파일이 실행되어고 있어야 한다. 
  • inetd
  • random -p

inetd가 ssh접속 요청을 받아 sshd를 실행시키도록 하기 위해서 inetd.conf에 아래 내용이 추가되어야 한다.

/etc/inetd.conf
------------------------------------------------------
...
ssh stream tcp nowait root /usr/sbin/sshd in.sshd -i
------------------------------------------------------

포트 번호 및 프로토콜 설정

/etc/services
------------------------------------------------------
...
ssh 22/tcp
------------------------------------------------------

sshd 설정

/etc/ssh/sshd_config
------------------------------------------------------
Protocol 2
LoginGraceTime 600
PermitRootLogin yes
PasswordAuthentication yes
PermitEmptyPasswords yes
Subsystem    sftp    /usr/libexec/sftp-server
------------------------------------------------------
 
  • / 아래에 쓰기 가능한 파일 시스템이 mount되어있는지 확인
  • 아래 폴더 생성 (없으면)
# mkdir /etc    (to create writeable /etc directory for /etc/passwd and /etc/ssh/)
# mkdir /etc/ssh (for the keys to be generated)
# mkdir /root
  • /etc/passwd에 내용 추가
echo root::0:0::/root:/bin/sh > /etc/passwd (now root user "exists" from rights management
perspective and can create keys)
  • passwd 설정
# passwd   (give a password)

  •  /etc/passwd에 내용 추가
echo sshd:x:15:6:sshd:/var/chroot/sshd:/bin/false >> /etc/passwd (creates entry for "privilege separation user sshd", appends to passwd file)
  • 디렉토리 설정 및 소유권 설정

# mkdir /var
# mkdir /var/chroot
# mkdir /var/chroot/sshd
# chmod 700 /var/chroot/sshd



Client 설정 ( Linux or MAC OS X )

일반적으로 /etc/ssh/ssh_config 파일에 시스템 전체적으로 적용되는 설정파일이 있으며, 이 파일의 내용중 변경하고 싶은 항목이 있을 경우 ~/.ssh/config 파일에 변경된 내용을 적으면 된다. (동일 항목에 대해서는 ~/.ssh/config의 값이 우선하여 적용된다. )

참고 사이트

Understanding the SSH Encryption and Connection Process





댓글 1개:

Hong, Doo Eui :

잘못된 내용이 있어 2017년 3월 4일 수정/보완함.