홈 서버 만들기 17. VNC RDP 클라이언트: Guacamole (Docker, Nginx)

May 22, 2018

원격 제어 접속에 사용하는 VNC, RDP 등의 클라이언트 프로그램 중에서 Guacamole은 독특하게 웹브라우저에서 구동되는 HTML5 기반의 프로그램이다 (소개 동영상). 홈 서버에 Guacamole을 설치하면 어디에서든 별도의 클라이언트 프로그램 없이도 웹브라우저로 원격 컴퓨터의 VNC, RDP, SSH, Telnet에 접속할 수 있다. 다음 글 18. 가상 머신에서 설명하는 우분투 서버에 게스트 OS를 설치할 때에도 유용하게 활용할 수 있다. Guacamole은 Docker 이미지로 실행하는 것이 편리하며, DUO 앱을 이용한 2단계 인증도 지원한다. DUO 2단계 인증은 10명의 사용자까지 무료로 이용할 수 있다.

Docker 설치

우분투 서버에 Docker가 설치되어 있지 않다면 Docker를 먼저 설치한다.

sudo apt-get update

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

sudo apt-get update

sudo apt-get install docker-ce

위 명령은 Docker의 패키지 저장소를 통해서 최신 stable 버전의 Docker CE를 설치하는 명령이다. 패키지 저장소 정보를 업데이트하고, Docker의 공식 GPG key를 내려 받고, Docker의 패키지 저장소를 추가하고, 다시 패키지 저장소 정보를 업데이트 한 다음에 docker-ce를 설치한다.

docker --version

이 명령으로 Docker version 18.03.1-ce 등의 Docker 버전이 출력되면 Docker가 설치된 것이다.

만일 홈 서버 컴퓨터를 재시작한 후에 Docker가 자동으로 실행되지 않는다면 아래와 같이 enable 명령을 내려준다.

sudo systemctl enable docker

DUO API 생성

DUO 2단계 인증을 사용하기 위해서는 먼저 API 정보를 생성해야 한다. duo.com에 접속해서 Try it Free 버튼을 클릭해서 무료 사용자로 가입하고, ApplicationsProtect an ApplicationWeb SDKProtect this Application을 클릭한다. Details 항목에 있는 Integration key, Secret key, API hostname을 모두 복사해서 별도로 저장해둔다. 페이지 하단에 SettingsName은 모바일 기기로 푸시 알림이 올 때 표시되는 이름인데 Guacamole 등 적당한 이름을 입력한다. 다 했으면 Save Changes를 클릭해서 저장한다. 저장한 내용은 Applications 메뉴에서 다시 확인할 수 있다. 또한 스마트폰에 Duo Mobile iOS 앱 / 안드로이드 앱을 내려받아서 로그인한다.

Duo Application Key 생성

DUO 2단계 인증에 사용되는 무작위 문자열을 하나 생성한다.

dd if=/dev/random count=1 | sha256sum

우분투 서버에서 이 명령을 실행하면 1034135g45564pyjj05h32t0jb2hjbt4gjb240bj25flsnfo924g4582938gv345 - 이런 형태의 무작위 문자열이 생성된다. - 부분을 제외한 문자열만 복사해서 별도로 저장해둔다.

DUO 2단계 인증 준비

sudo docker volume create guacvol-config

먼저 DUO API 정보가 담길 Docker 볼륨 guacvol-config를 생성한다. guacvol-config는 원하는 이름으로 변경해도 무방하다.

sudo nano /var/lib/docker/volumes/guacvol-config/_data/guacamole.properties

nano 편집기로 DUO API 정보가 기록될 guacamole.properties 파일을 guacvol-config 볼륨에 생성한다. 볼륨 이름을 변경했다면 여기서도 변경한 경로를 입력해야 한다.

duo-integration-key: DGEARB398U3B3G93EQFB
duo-secret-key: D5h15shd935hFHwhsrh852yhDFHsh6sfFJRH20SF
duo-api-hostname: api-adg832fd.duosecurity.com
duo-application-key: 1034135g45564pyjj05h32t0jb2hjbt4gjb240bj25flsnfo924g4582938gv345

앞서 복사해둔 자신의 DUO API 정보를 위의 형식으로 기록한다. 완료했으면 Ctrl키와 x키를 동시에 눌러 nano 편집기를 빠져나오면서 저장한다.

sudo mkdir /var/lib/docker/volumes/guacvol-config/_data/extensions

guacvol-config 볼륨에 DUO 2단계 인증 익스텐션이 위치할 디렉토리를 생성한다. 볼륨 이름을 변경했다면 여기서도 변경한 경로를 입력해야 한다.

wget -P /tmp --content-disposition "http://apache.org/dyn/closer.cgi?action=download&filename=guacamole/0.9.14/binary/guacamole-auth-duo-0.9.14.tar.gz"

/tmp 디렉토리에 DUO 2단계 인증 익스텐션을 내려받는다. 위 예시는 이 글을 작성하는 현재의 최신 버전인 0.9.14 버전을 다운로드 하는 것이며, 다른 버전의 다운로드 주소는 https://guacamole.apache.org/releases/에서 찾을 수 있다.

tar -zxvf /tmp/guacamole-auth-duo-0.9.14.tar.gz -C /tmp/

내려받은 파일의 압축을 해제한다.

sudo mv /tmp/guacamole-auth-duo-0.9.14/guacamole-auth-duo-0.9.14.jar /var/lib/docker/volumes/guacvol-config/_data/extensions

압축을 해제한 내용물 중에서 실제 익스텐션 파일을 앞서 생성한 guacvol-config 볼륨의 익스텐션 디렉토리로 옮긴다. 볼륨 이름을 변경했다면 여기서도 변경한 경로를 입력해야 한다.

rm /tmp/guacamole-auth-duo-0.9.14.tar.gz
rm -r /tmp/guacamole-auth-duo-0.9.14

/tmp에 내려받은 파일과 압축을 해제한 나머지 내용물을 삭제하려면 위 명령을 실행한다.

Guacamole 실행

Guacamole의 Docker 이미지는 guacdguacamole로 구성되어 있고, 추가로 별도의 데이터베이스 이미지가 필요하다. 데이터베이스는 MySQL 또는 PostgreSQL을 사용할 수 있는데, MySQL은 빈 화면을 출력하는 문제가 있어서 PostgreSQL을 선택했다.

sudo docker pull guacamole/guacd
sudo docker pull guacamole/guacamole
sudo docker pull postgres

guacd, guacamole, PostgreSQL의 Docker 이미지를 내려받는다.

sudo docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --postgres > /tmp/initdb.sql

PostgreSQL 데이터베이스 초기화에 사용되는 스크립트를 guacamole 이미지에서 추출해서 /tmp 디렉토리에 저장한다.

sudo docker volume create guacvol-postgres

PostgreSQL이 사용할 Docker 볼륨을 생성한다. guacvol-config는 원하는 이름으로 변경해도 무방하다.

sudo docker run --restart=always --name=guac-postgres \
--mount source=guacvol-postgres,target=/var/lib/postgresql \
-d postgres

PostgreSQL 이미지를 guac-postgres 이라는 이름의 컨테이너로 실행한다. 앞서 PostgreSQL 볼륨의 이름을 guacvol-postgres가 아닌 다른 것으로 변경했다면 이 명령에서도 변경한 것으로 맞춰주어야 한다. 참고로 위의 명령은 한 줄로 작성하기에는 길어서 \를 사용해서 여러 줄로 나눈 것으로, 전체를 한꺼번에 복사해서 PuTTY 등에 붙여넣으면 된다.

sudo docker cp /tmp/initdb.sql guac-postgres:/initdb.sql

/tmp 디렉토리에 추출한 데이터베이스 초기화 스크립트를 guac-postgres 컨테이너에 복사한다.

sudo docker exec -it guac-postgres bash

guac-postgres 컨테이너에 접속한다. root@5fe42bf96d3a:/# 이런 형태의 입력란으로 바뀔 것이다.

su postgres

권한을 postgres로 전환한다.

createdb guacamole_db

guacamole_db 라는 이름의 데이터베이스를 생성한다.

cat /initdb.sql | psql -d guacamole_db -f -

앞서 복사한 데이터베이스 초기화 스크립트를 실행한다.

psql -d guacamole_db

guacamole_db 데이터베이스에 접속한다.

\dt

생성된 테이블이 아래와 같이 출력되는지 확인한다.

			 List of relations
 Schema |                 Name                  | Type  |  Owner
--------+---------------------------------------+-------+----------
 public | guacamole_connection                  | table | postgres
 public | guacamole_connection_group            | table | postgres
 public | guacamole_connection_group_permission | table | postgres
 public | guacamole_connection_history          | table | postgres
 public | guacamole_connection_parameter        | table | postgres
 public | guacamole_connection_permission       | table | postgres
 public | guacamole_sharing_profile             | table | postgres
 public | guacamole_sharing_profile_parameter   | table | postgres
 public | guacamole_sharing_profile_permission  | table | postgres
 public | guacamole_system_permission           | table | postgres
 public | guacamole_user                        | table | postgres
 public | guacamole_user_history                | table | postgres
 public | guacamole_user_password_history       | table | postgres
 public | guacamole_user_permission             | table | postgres
(14 rows)
CREATE USER guacamole_user WITH PASSWORD '비밀번호';

데이터베이스 사용자 guacamole_user를 원하는 비빌번호로 생성한다.

GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA public TO guacamole_user;
GRANT SELECT,USAGE ON ALL SEQUENCES IN SCHEMA public TO guacamole_user;

데이터베이스 사용자 guacamole_user 에게 권한을 부여한다.

\q

guacamole_db 데이터베이스 접속을 종료한다.

exit

postgres 권한에서 빠져나온다.

exit

guac-postgres 컨테이너 접속을 종료한다. varins@myserver: 이런 형태의 원래의 입력란으로 돌아올 것이다.

sudo docker run --restart=always --name=guacd \
-d guacamole/guacd

guacd 이미지를 guacd 이라는 이름의 컨테이너로 실행한다.

sudo docker run --restart=always --name=guacamole -p 9884:8080 \
--link guacd:guacd \
--link guac-postgres:postgres \
--mount source=guacvol-config,target=/config \
-e POSTGRES_DATABASE=guacamole_db \
-e POSTGRES_USER=guacamole_user \
-e POSTGRES_PASSWORD=비밀번호 \
-e GUACAMOLE_HOME=/config \
-d guacamole/guacamole

guacamole 이미지를 guacamole 이라는 이름의 컨테이너로 실행한다. 9884는 Guacamole 접속에 사용할 포트 번호인데 원하는 것으로 바꾸어도 무방하다. 앞서 DUO API 정보가 담기는 Docker 볼륨 이름을 guacvol-config가 아닌 다른 것으로 변경했다면 이 명령에서도 변경한 것으로 맞춰주어야 한다. 비밀번호에는 앞서 생성한 데이터베이스 사용자 guacamole_user의 비밀번호를 입력한다.

Guacamole 접속

내부 네트워크에서 접속

http://홈.서버.내부.IP주소:9884/guacamole/

이와 같이 http 프로토콜을 사용해서 홈 서버의 내부(사설) IP 주소와 앞서 지정한 접속 포트를 조합해서 접속하면 Guacamole 로그인 화면이 나타난다. 초기 접속 ID는 guacadmin 이고 비밀번호도 guacadmin 이다. 2단계 인증 설정 화면이 나타나면 진행한 후에, 우측 상단의 메뉴에서 SettingsUsers 로 이동해서 비밀번호를 변경한다.

외부 네트워크에서 접속

인터넷 공유기에서 Guacamole 접속 포트를 홈 서버 컴퓨터로 포워딩 한다면 공인 IP 주소나 도메인으로도 접속할 수 있는데, http 프로토콜을 사용해야 하므로 해당 도메인에 https로 리턴하는 설정이 적용되어 있다면 접속이 안 될 수 있다. 이때에는 인터넷 공유기에서 포트 포워딩을 하지 말고, 우분투 서버에서 운영 중인 웹 서버을 이용해서 프록시를 구성하면 https 프로토콜로 어디에서든 접속할 수 있다. 여기서는 기존에 운영 중인 Nginx 웹 서버가 있다고 가정하고 설명한다.

	location /abc/ {
		proxy_pass http://127.0.0.1:9884/guacamole/;
		proxy_buffering off;
		proxy_http_version 1.1;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection $http_connection;
		proxy_cookie_path /guacamole/ /abc/;
		access_log off;
	}

	location /abc {
		return https://example.com/abc/;
	}

이 내용을 Nginx 서버 블록에 추가하면 된다. 4곳의 abc는 접속 주소가 되는 https://example.com/abc 의 abc 부분으로, 원하는 대로 바꾸면 된다. Guacamole에 접속할 때는 항상 마지막에 /가 붙어야 하기 때문에 /abc 로 접속하면 /abc/ 로 리턴하는 설정을 추가했다. 9884는 자신의 접속 포트로 바꾸고 example.com은 자신의 도메인으로 바꾼다.

서버 블록에 이 내용을 추가하는 위치는 listen 443 영역이다. 앞선 글 08. 웹 서버에서 설정한 example.com의 서버 블록을 기준으로 보면,

sudo nano /etc/nginx/sites-available/example.com

example.com 서버 블록을 nano 편집기로 열어서

server {
	listen 80;

	server_name example.com www.example.com;

	return 301 https://$server_name$request_uri;
}

server {
	listen 443 ssl http2;

	server_name example.com www.example.com;

	root /var/www/example.com/html;

	ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
	ssl_dhparam /etc/ssl/certs/dhparam.pem;

	ssl_protocols TLSv1.2;
	ssl_prefer_server_ciphers on;
	ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256;
	ssl_ecdh_curve secp384r1;
	ssl_session_timeout 10m;
	ssl_session_cache shared:SSL:10m;
	ssl_session_tickets off;
	ssl_stapling on;
	ssl_stapling_verify on;
	resolver 8.8.8.8 8.8.4.4 valid=300s;
	resolver_timeout 5s;

	add_header Strict-Transport-Security max-age=31536000;
	add_header X-Frame-Options SAMEORIGIN;
	add_header X-Content-Type-Options nosniff;
	add_header X-XSS-Protection "1; mode=block";

	index index.html index.htm;

	location / {
		try_files $uri $uri/ =404;
	}

	location /abc/ {
		proxy_pass http://127.0.0.1:9884/guacamole/;
		proxy_buffering off;
		proxy_http_version 1.1;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection $http_connection;
		proxy_cookie_path /guacamole/ /abc/;
		access_log off;
	}

	location /abc {
		return https://example.com/abc/;
	}
}

이렇게 listen 443 영역에 추가하고, 완료했으면 Ctrl키와 x키를 동시에 눌러 nano 편집기를 빠져나오면서 저장한다.

sudo nginx -t
sudo systemctl restart nginx

변경한 서버 블록이 적용되도록 Nginx 기본 문법을 검사한 뒤 Nginx를 재시작한다.

이제 어디에서든 https://example.com/abc 에 접속하면 Guacamole을 이용해서 VNC, RDP, SSH, Telnet에 접속할 수 있다.

 

Guacamole 사용

 

우측 상단의 메뉴에서 SettingsConnections으로 이동하면 새로운 연결을 생성할 수 있다. 주요 접속 정보는 PARAMETERS 항목에서 설정하는데, RDP 연결의 경우 UsernamePassword를 모두 입력하고 Ignore server certificate 항목을 체크해야 접속이 가능하다. 그밖의 내용은 원격 접속 대상 컴퓨터에 설정 된 것을 적절히 입력한다.

접속 되면 아래처럼 웹브라우저 상에서 원격 컴퓨터를 사용할 수 있다. RDP 접속시 Internet Explorer와 Edge에서 사운드 재생이 원활하지 않을 경우에는 크롬 등의 다른 웹브라우저를 이용하면 된다. 한/영 전환은 작업 표시줄의 한/영 전환 버튼을 클릭한다. Ctrl Alt Shift 키를 동시에 누르면 좌측에 메뉴가 나타나는데 클립보드 기능이 있어서 원격 컴퓨터에 텍스트를 붙여 넣을 수 있다. 그밖의 사용법은 Guacamole 웹사이트의 설명을 참고한다.

 

홈 서버 만들기 목차 
https://varins.com/category/server

01. 하드웨어 구성과 전기 요금
02. 우분투 서버 18.04 LTS 설치
03. 우분투 서버 18.04 LTS 기본 설정
04. 파일 복원: Btrfs 스냅샷
05. 네트워크 파일 공유: Samba (SMB)
06. Dynamic DNS: 구글 도메인 + ddclient
07. SSL/TLS 인증서: Let's Encrypt (Wildcard)
08. 웹 서버: Nginx, 서버 블록, https 보안연결
09. 웹사이트: php + MariaDB + WordPress
10. 서버 모니터링: Monitorix + Nginx Proxy
11. FTPS: vsftpd
12. VPN: IKEv2 (strongSwan)
13. Torrent: Transmission
14. 클라우드 스토리지: Nextcloud (Nginx, MariaDB)
15. 온라인 오피스: 온리오피스 (Docker, Nginx)
16. 트랜스코딩: Plex
17. VNC RDP 클라이언트: Guacamole (Docker, Nginx)
18. 가상 머신: QEMU-KVM + libvirt + virt-install
19. 시스템 업그레이드: i3 8300T, 970 EVO 전력 사용량
20. 서버 모니터링: netdata + Nginx Proxy
Prev Post Next Post