Remote Desktop: Difference between revisions

Klinger (talk | contribs)
m rustdesk is also available as server package
Line 63: Line 63:
=== Guacamole ===
=== Guacamole ===


Guacamole-server and guacamole-client are in nixpkgs. Some details are in the [https://github.com/NixOS/nixpkgs/issues/17879 package request].
==== Guacamole Server ====
In nixos the guacamole server component is provided by [https://github.com/NixOS/nixpkgs/blob/nixos-24.05/nixos/modules/services/web-apps/guacamole-server.nix guacamole-server]
 
A basic server setup service entry would look like this:
    services.guacamole-server = {
        enable = true;
        host = "127.0.0.1";
        port = 4822;
        userMappingXml = ./user-mapping.xml;
    };
This creates the <code>guacamole-server.service</code> systemd unit.
 
See the [https://search.nixos.org/options?channel=24.05&from=0&size=50&sort=relevance&type=packages&query=services.guacamole-server search.nixos options] for other configuration options.
 
The <code>host</code> entry indicates on which IP the server component listens. The <code>port</code> entry here is the default port of <code>4822</code>.
 
The <code>./user-mapping.xml</code> is a relative path to the file which declares the service. So if the service is in <code>/etc/nixos/configuration.nix</code> then in this example the file would reside at <code>/etc/nixos/user-mapping.xml</code>. Contents of the file are discussed below.
 
==== user-mapping.xml ====
The <code>user-mapping.xml</code> file is how to define the user(s) that are allowed to login to the webportal, as well as the connections available to the user.
 
The file content should look something like this:
 
    <user-mapping>
        <authorize username="USERNAME_HERE" password="ENCRYPTED_PASSWORD_HERE" encoding="sha256">
          <connection name="NAME_OF_THE_CONNECTION">
              <protocol>rdp</protocol>
              <param name="hostname">XXX.XXX.XXX.XXX</param>
              <param name="port">3389</param>
              <param name="ignore-cert">true</param>
          </connection>
          <connection name="NAME_OF_THE_CONNECTION">
              <protocol>ssh</protocol>
              <param name="hostname">XXX.XXX.XXX.XXX</param>
              <param name="port">22</param>
          </connection>
        </authorize>
    </user-mapping>
 
The <code>password=""</code> can be a plain text password, but it is not recommended. An easy way to encrypt a password would be something like:
 
    $  echo -n 'SUPERsecretPASSWORD' | openssl dgst -sha256
    SHA2-256(stdin)= 491cf91d586fb9442db7efe92b7839190206a653971573c23fed0435ceb596e8
 
The [https://guacamole.apache.org/doc/gug/configuring-guacamole.html#configuring-connections upstream documentation] has complete configuration options avaiable.
 
==== Guacamole Client ====
 
In nixos the guacamole client component is provided by the [https://github.com/NixOS/nixpkgs/blob/nixos-24.05/nixos/modules/services/web-apps/guacamole-client.nix guacamole-client] component.
 
This is the part of the service that provides the webportal for end users.
 
A basic client setup service entry would look like this:
 
    services.guacamole-client = {
        enable = true;
        enableWebserver = true;
        settings = {
            guacd-port = 4822;
            guacd-hostname = "localhost";
        };
    };
 
This creates a <code>tomcat.service</code> systemd unit.
 
See the [https://search.nixos.org/options?channel=24.05&from=0&size=50&sort=relevance&type=packages&query=services.guacamole-client search.nixos options] for other configuration options.
 
The webportal this provides is served by the tomcat server, and listens on port <code>8080</code> by default. The <code>settings.guacd-port</code> tells the client software how to communicate with the guacamole-server component.
 
The [https://guacamole.apache.org/doc/gug/configuring-guacamole.html#guacamole-properties upstream documentation] has the list of <code>guacamole.properties</code> options that can be provided for this setting.
 
At this point if you are intending to serve the webportal directly, then the service can be reached at the url <code>http://<your-computer-ip:8080/guacamole</code>.
 
==== Reverse Proxy ====
 
If you want to use <code>nginx</code> as a reverse proxy in front of the webportal, then the below options can serve as an example setup.
 
This example has a virtual host available as <code>https://remote.mydomain.net</code>. It uses the [https://search.nixos.org/options?channel=24.05&from=0&size=50&sort=relevance&type=packages&query=services.nginx nginx] service, and [https://letsencrypt.org/ LetsEncrypt] for SSL. Configuration of a DNS domain and records is outside the scope of this document.
 
    services.nginx = {
        enable = true;
        upstreams."guacamole_server" = {
            extraConfig = ''
                keepalive 4;
            '';
            servers = {
                "127.0.0.1:8080" = {};
            };
        };
        virtualHosts."remote.mydomain.net" = {
            forceSSL = true; # redirect http to https
            enableACME = true;
            locations."/" = {
                extraConfig = ''
                    proxy_buffering off;
                    proxy_set_header Upgrade $http_upgrade;
                    proxy_set_header Connection $http_connection;
                    proxy_set_header X-Real-IP $remote_addr;
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header Host $host;
                    proxy_set_header X-NginX-Proxy true;
                    proxy_pass http://guacamole_server/guacamole$request_uri;
                    proxy_redirect http://guacamole_server/ https://$server_name/;
                '';
            };
        };
    };       
    # this sets up the letsencrypt service to get ssl certs for the above
    security.acme = {
        acceptTerms = true;
        defaults.email = "your.email@server.name";
    };   
 
The <code>upstreams."guacamole_server".servers</code> setting points the to IP:port where the <code>guacamole-client</code> webportal is hosted. In this example <code>nginx</code> and <code>guacamole</code> are on the same host.
 
The <code>virtualHosts."name".forceSSL</code> ensures requests sent to HTTP are redirected to HTTPS. The <code>enableACME</code> sets up LetsEncrypt and nginx to get and renew SSL certs.
 
The <code>proxy_buffering off;</code>, <code>proxy_set_header Upgrade $http_upgrade;</code>, and <code>proxy_set_header Connection $http_connection;</code> settings are required to prevent nginx from buffering traffic, which can prevent guacamole from operating properly.
 
The optional <code>proxy_pass http://guacamole_server/guacamole$request_uri;</code> allows end users to access the service at <code>https://remote.mydomain.net</code> as opposed to <code>https://remote.mydomain.net/guacamole</code>.
 
See the [https://guacamole.apache.org/doc/gug/reverse-proxy.html# upstream documentation] for more details and other proxy examples.
 
==== Firewall ====
 
In the case of the above reverse proxy example, the correct firewall ports will also need to be opened on the server hosting the <code>nginx</code> proxy.
 
    networking.firewall = {
        enable = true;
        allowedTCPPorts = [
            80 # http
            443 # https
            8080 # guacamole
            4822 # guacamole
        ];
    };                                       
 
 
For any systems that will be reached from the guacamole service, the corresponding ports will need to be opened. The below example opens ports that match the connection settings in the above <code>user-mapping.xml</code>.
 
    networking.firewall = {
        enable = true;
        allowedTCPPorts = [
            22 # ssh
            3389 # rdp
        ];
    };                                       
 
==== References ====
 
[https://github.com/NixOS/nixpkgs/issues/17879 The original package request has good discussions as well]


== RDP ==
== RDP ==