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

May 22, 2018Updated on December 8, 2018

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

Docker 설치

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

Duo Application Key 생성

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

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

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

DUO 2단계 인증 준비

sudo docker volume create guacvol-config

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

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

nano 편집기로 DUO API 정보가 46wrth3w기록될 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 정보를 te4j6yt위의 형식으로 기록한다. 완료했으면 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단계 yur46인증 익스텐션을 내려받는다. 위 예시는 이 글을 작성하는 현재의 최신 버전인 0.9.14 버전을 다운로드 하는 것이며, 다른 버전의 다운로드 주소는 https://guacamole.apache.org/releases/에서 찾을 수 있는데, 원하는 Version의 숫자를 클릭해서 이동한 th4+r4h뒤 guacamole-auth-duo- 로 시작하는 이름의 파일을 내려받으면 된다.

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

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

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

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

Guacamole 실행

Guacamole의 r16u3Docker 이미지는 guacdguacamole로 구성되어 있고, 추가로 별도의 데이터베이스 이미지가 필요하다. 데이터베이스는 MySQL 또는 PostgreSQL을 사용할 수 있는데, MySQL은 빈 화면을 출력하는 46yr문제가 있어서 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 et46y132데이터베이스 초기화에 사용되는 스크립트를 guacamole 이미지에서 추출해서 /tmp 디렉토리에 저장한다.

sudo docker volume create guacvol-postgres

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

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

PostgreSQL 이미지를 guac-postgres 이라는 이름의 컨테이너로 실행한다. 46ry앞서 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 컨테이너에 6tyjdf접속한다. root@5fe42bf96d3a:/# 이런 형태의 입력란으로 바뀔 것이다.

su postgres

권한을 postgres로 전환한다.

createdb guacamole_db

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

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

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

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 '비밀번호';

데이터베이스 yu43사용자 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;

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

\q

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

exit

postgres 권한에서 sr64h531빠져나온다.

exit

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

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

guacd 4rsh35이미지를 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 접속에 사용할 4s6fh포트 번호인데 원하는 것으로 바꾸어도 무방하다. 앞서 DUO API 정보가 담기는 Docker 볼륨 이름을 guacvol-config가 아닌 다른 것으로 변경했다면 이 명령에서도 변경한 것으로 맞춰주어야 한다. 비밀번호에는 앞서 d64f53생성한 데이터베이스 사용자 guacamole_user의 비밀번호를 입력한다.

Guacamole 접속

내부 네트워크에서 접속

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

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

외부 네트워크에서 접속

인터넷 공유기에서 Guacamole 접속 포트를 홈 서버 컴퓨터로 포워딩 한다면 공인 IP 주소나 도메인으로도 접속할 수 있는데, http 프로토콜을 사용해야 하므로 해당 도메인에 https로 6f4g5h리턴하는 설정이 적용되어 있다면 접속이 안 될 수 있다. 이때에는 인터넷 공유기에서 포트 포워딩을 하지 말고, 우분투 서버에서 운영 중인 웹 서버을 이용해서 프록시를 구성하면 https 프로토콜로 어디에서든 64s5gfh접속할 수 있다. 여기서는 기존에 운영 중인 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 6gh4d서버 블록에 추가하면 된다. 4곳의 abc는 접속 주소가 되는 https://example.com/abc 의 abc 부분으로, 원하는 대로 바꾸면 된다. Guacamole에 접속할 때는 6g4fd13항상 마지막에 /가 붙어야 하기 때문에 /abc 로 접속하면 /abc/ 로 리턴하는 설정을 추가했다. 9884는 자신의 접속 포트로 바꾸고 example.com은 자신의 도메인으로 바꾼다.

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

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 영역에 추가하고, d6h453완료했으면 Ctrl키와 x키를 동시에 눌러 nano 편집기를 빠져나오면서 저장한다.

sudo nginx -t
sudo systemctl restart nginx

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

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

 

Guacamole 사용

 

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

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

 

본 글의 저작권은 작성자 Varins에게 있습니다.
Varins의 사전 서면 동의 없이는 본 글의 전부 또는 일부를 무단으로 전재, 게시, 배포하는 것을 금지합니다.

 

홈 서버 만들기 목차 
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
21. Dynamic DNS: CloudFlare + ddclient
22. SSL/TLS 인증서: Let's Encrypt + CloudFlare (Wildcard + 자동갱신)

Comments (6)

  • DongHyeon

    July 11, 2018 at 3:13 am

    안녕하세요. varins님 덕분에 서버 구축이 수월하게 되고 있습니다.

    다름이 아니라 guacamole 접속 에러가 뜹니다. SSH는 접속이 잘 되는데
    VNC, RDP가 아래 에러가 뜨면서 접속이 되지 않습니다. 혹시 어떤 문제인지 짐작이 가시나요?
    settings->connections 설정을 제대로 했는지는 모르겠지만,
    varins님은 어떤식으로 설정하셨는지 알 수 있을까요?

    The remote desktop server is currently unreachable.
    If the problem persists, please notify your system administrator,
    or check your system logs.
    연결할 수 없다 뜨고, 로그 확인해보라는데 로그 파일 경로도 어디있는지 모르겠고…
    구글링 해도 제가 잘 못 찾는건지 안보이네요.

    1. Varins

      July 11, 2018 at 9:11 am

      안녕하세요,
      SSH 이외의 프로토콜이 접속이 안 된다면 대부분 포트와 관련된 문제일 가능성이 많습니다.

      VNC와 RDP가 사용하는 포트가 인터넷 공유기에서 포트 포워딩 설정되어야 하고, VNC와 RDP가 홈 서버 컴퓨터 내부의 가상 머신 등에서 실행된다면 경우에 따라 iptables에서 해당 포트를 열어주어야 합니다. 또한 물론, VNC와 RDP가 확실하게 작동하고 있어야 합니다. 윈도우 OS에서 RDP 허용 옵션이 적용되어 있는지 확인도 필요합니다.

      Guacamole 자체의 설정은 별것 없이 본문의 스크린샷이 전부입니다. 좌측이 RDP, 우측이 VNC입니다.

    2. DongHyeon

      July 14, 2018 at 5:07 pm

      vnc를 사용하려고 해서 공유기에 5900,5901번 포트를 포트포워딩을 해줬습니다.
      마찬가지로 서버로 사용하는 PC에서도 아래 명령어를 입력해서 포트를 열어줬습니다.
      sudo iptables -A INPUT -p tcp -m tcp –dport 5900 -j ACCEPT
      sudo iptables -A INPUT -p tcp -m tcp –dport 5901 -j ACCEPT
      하지만 현상은 같습니다…

      그리고 댓글에서 VNC와 RDP가 확실하게 작동되고 있어야 한다고 하셨는데,
      어떤 느낌인지 잘 모르겠어요. guacamole 설치만 완료하면 VNC와 RDP가 알아서 설치가 되는건가요?
      아니면 따로 VNC와 RDP를 설치해줘야 하나요?

    3. Varins

      July 15, 2018 at 12:05 am

      Guacamole는 단지 클라이언트 프로그램입니다. 우분투 서버 컴퓨터에서 SSH 서버가 작동하고 있으므로 클라이언트 Guacamole에서 SSH접속 가능한 것이지요. 마찬가지로 클라이언트 Guacamole를 이용해서 VNC / RDP로 접속하려는 대상 컴퓨터에서 VNC / RDP가 작동하고 있어야 합니다.

      예를 들어서 Guacamole를 이용해서 윈도우10 pro가 설치된 컴퓨터에 RDP로 접속하려면, 윈도우10 pro 컴퓨터에 RDP 사용함 옵션이 켜져 있어야 합니다.

  • DongHyeon

    July 19, 2018 at 4:17 pm

    감사합니다. 드디어 성공했습니다.
    Guacamole만 설치하면 될거라는 생각에 원격을 할 PC에 VNC나 RDP를 실행하지 않아서 안된 문제였습니다.
    다시 한 번 이렇게 좋은 경험을 할수 있도록 도움주셔서 감사합니다.

    1. Varins

      July 25, 2018 at 8:49 am

      잘 작동한다니 저도 기쁩니다.
      좋은 말씀 감사드립니다. 즐거운 시간 보내세요.

Leave a comment

댓글은 관리자의 승인 이후에 게시됩니다.

Prev Post Next Post