Hlavní navigace

Apache Guacamole: gateway pro vzdálený desktop (RDP a VNC)

Motivací pro vznik tohoto článku byla nutnost uspokojivě řešit přístup uživatelů na jejich stanice v zaměstnání z domova. Jako odpůrce NATu mne myšlenka na tunelování portů odpuzovala, nasadil jsem tedy Guacamole.
Milan Beneš
Doba čtení: 5 minut

Sdílet

V prvé řadě si povězme, co Guacamole je. Jedná se o bezklientovou gateway pro připojení ke vzdálenému desktopu. Slovem bezklientová chtějí autoři naznačit, že pro používání nepotřebujete specializovanou aplikaci či plugin, bude vám stačit webový prohlížeč s podporou HTML5 a ideálně WebSocketů.

Guacamole se skládá z webové aplikace (serveru), která je napsaná v Javě, klienta v Javascriptu a démona guacd – proxy, která na jedné straně komunikuje s Java servletem a na druhé straně se nativními protokoly připojuje k jednotlivým vzdáleným desktopům. Více napoví schéma z uživatelského manuálu:


V současné době (březen 2020) démon guacd podporuje protokoly RDP a VNC a dále je schopen se připojit k SSH, telnetu a Kubernetes. Stabilní verze nese označení 1.1.0 a závisí na FreeRDP 2.

Instalace

Instalace je popsána v manuálu. Z nabízených možností jsem sáhl po Ubuntu, které bylo zrovna po ruce. Používám ho ve formě LXC kontejneru běžícího na hypervizoru s Gentoo. Zatímco Javový servlet je možno stáhnout, proxy je nutné zkompilovat. Tento proces je sám o sobě bezproblémový, během testování jsem ovšem zjistil, že verze FreeRDP v Ubuntu 18.04 obsahuje bug, jehož důsledkem skončí pokus o připojení k Windows 10 segfaultem. Toto mne donutilo upgradovat kontejner na vývojovou verzi Ubuntu 20.04, kde již FreeRDP touto chybou netrpí. Pro instalaci závislostí nutných pro překlad tedy spusťte:

# apt install libcairo2-dev libpng-dev libjpeg-turbo8-dev libtool-bin libossp-uuid-dev libavcodec-dev libavutil-dev libswscale-dev freerdp2-dev libpango1.0-dev libssh2-1-dev libvncserver-dev libssl-dev libvorbis-dev libwebp-dev
# apt install build-essential make
# apt install tomcat9

Následně si stáhněte guacamole-server-1.1.0.tar.gz, rozbalte ho do /usr/src, přeložte, povolte a spusťte:

# ./configure --with-init-dir=/etc/init.d
# make -j24
# make install
# systemctl enable guacd
# systemctl start guacd

Osobně jsem musel ještě restartovat kontejner, aby si linker natáhl cestu do /usr/local/lib. Povolte a spusťte tomcat9. Stáhněte a rozbalte servlet ( guacamole-1.1.0.war) a přesuňte ho do /var/lib/tomcat9/webapps. Servlet se automaticky rozbalí. Stáhněte a rozbalte guacamole-auth-jdbc-1.1.0.tar.gzguacamole-auth-ldap-1.1.0.tar.gz.

Zde trochu odbočím a osvětlím, proč používám zároveň LDAP i databázi. Guacamole umí držet kompletní konfiguraci spojení v LDAPu, nicméně je poté nutné rozšířit schéma v AD, což může být neprůchozí (například přes našeho správce Windows). V takovém případě můžete použít LDAP čistě pro autentizaci uživatele a všechna ostatní data držet v SQL databázi.

V této fázi již můžete založit adresář v /etc/guacamole  s podadresáři extensions a lib. Do podadresáře extensions okopírujte soubory guacamole-auth-jdbc-mysql-1.1.0.jar a guacamole-auth-ldap-1.1.0.jar. Dále si opatřete soubor mysql-connector-java_8.0.18-1ubuntu19.10_all.deb a prostřednictvím dpkg -i ho nainstalujte. Nyní můžete vyrobit symlink z /usr/share/java/mysql-connector-java-8.0.18.jar  do adresáře  /etc/guacamole/libs.

Root_onlineskoleni

Nyní můžete založit samotnou databázi a naplnit ji daty, potřebné sql soubory jsou přiložené v archivu guacamole-auth-jdbc-1.1.0.tar.gz. Taktéž si v AD vyrobte neprivilegovaného uživatele, pomocí kterého se budete bindovat.

Konfigurace

Poslední věcí, která zbývá je vytvoření konfiguračního souboru  /etc/guacamole/guacamole.properties:

# Hostname and port of guacamole proxy
guacd-hostname: localhost
guacd-port: 4822

ldap-hostname: pdc.firma.cz
ldap-port: 389
ldap-user-base-dn: ou=OU2,ou=OU1,dc=firma,dc=cz

ldap-search-bind-dn: cn=guac,ou=ServiceAccnts,dc=firma,dc=cz
ldap-search-bind-password: dlouheheslo
ldap-encryption-method: starttls
ldap-username-attribute: sAMAccountName
ldap-user-search-filter: (&(objectCategory=Person)(sAMAccountName=*)(memberOf=CN=SKUPINA,OU=Groups,OU=OU1,DC=firma,DC=cz)(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))

# MySQL properties
mysql-hostname: mysql.firma.cz
mysql-port: 3306
mysql-database: guac_db
mysql-username: guac
mysql-password: jinedlouheheslo
mysql-user-required: true

Zde bych dodal jen pár vysvětlivek. Podmínka !(UserAccountControl:1.2.840.113556.1.4.803:=2) v ldap-user-search-filter  odfiltruje neaktivní účty; mysql-user-required: true zajistí, že bez ohledu na to, zda-li se uživatel úspěšně autentizuje v LDAPu, bude dále připuštěn pouze tehdy, existuje-li odpovídající uživatel v SQL databázi.

Pokud potřebujete zvednout úroveň logování, vytvořte /etc/guacamole/logback.xml s tímto obsahem:

<configuration>
    <!-- Appender for debugging -->
    <appender name="GUAC-DEBUG" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <!-- Log at DEBUG level -->
    <root level="debug">
        <appender-ref ref="GUAC-DEBUG"/>
    </root>
</configuration>

Nyní můžete restartovat Tomcat a zkusit se připojit na IP adresu serveru na portu 8080 do umístění

/guacamole-1.1.0/

. Pokud všechno dopadlo dobře, měli byste se být schopni přihlásit jako uživatel guacadmin s heslem guacadmin.

Administrace

V administraci můžete vytvářet uživatele, uživatelské skupiny a spojení na jednotlivé počítače. Spojení na vzdálenou plochu můžete organizovat do stromu. Jednotlivým uživatelům či skupinám můžete přidělovat práva k užívání jednotlivých spojení. Zde jsem narazil na jednu záludnost: pokud máte spojení v nějaké stromové struktuře, musíte uživateli či skupině přidělit i práva k předkům onoho spojení. Uživatele v databázi zakládáme bez hesla.

V ostatních aspektech je administrační rozhraní přímočaré, vypíchl bych možnost nastavení ignorování kontroly certifikátu u RDP a dále možnost předání přihlašovacích údajů z Guacamole přímo do Windows – je možné použít tokeny ${GUAC_USERNAME}${GUAC_PASSWORD}.

Na následujících snímcích je domovská obrazovka aplikace, editor spojení a editor skupin.




Reverzní proxy

V produkčním prostředí nejspíš budete chtít schovat Guacamole server za proxy. V tomto případě je dobré v souboru /etc/tomcat9/server.xml nastavit RemoteIpValve, například:

        <Valve className="org.apache.catalina.valves.RemoteIpValve"
               remoteIpHeader="x-forwarded-for"
               remoteIpProxiesHeader="x-forwarded-by"
               protocolHeader="x-forwarded-proto" />

abychom do Tomcatu dostali skutečnou IP adresu klienta. Na proxy je dále nutné vypnout bufferování, takto mám nastaven náš Nginx:

server {
    listen 80;
    server_name  xxx.firma.cz;

    access_log  /var/log/nginx/xxx.firma.cz.access.log;

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

server {
    listen 443 ssl http2;
    server_name  xxx.firma.cz;

    ssl_certificate   /etc/ssl/xxx.firma.cz/fullchain.pem;
    ssl_certificate_key  /etc/ssl/xxx.firma.cz/privkey.pem;

    include ssl.conf;

    location / {
        proxy_pass      http://xxx.internal:8080/guacamole-1.1.0/;
        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;
        access_log off;
    }
}

Závěr

Cílem tohoto dokumentu bylo čtenáře seznámit s úskalími, na která jsem narazil během nasazení Guacamole v naší organizaci a taktéž poskytnout již hotovou konfiguraci.