User Tools

Site Tools

This documentation is no longer maintained by the Turris team (although it can be used by the community to share content). The current official documentation is at docs.turris.cz.

Install & Configure Guacamole within LXC

Sorry, this is a work in progress. I have this working on a Turris Omnia, just need to write up the documentation. Please feel free to edit/correct as required.

The goal of this how-to is to have remote access of internal system (themselves exposed via SSH/RDP/etc.) through the internet via HTTPS, with a gateway running withing a LXC-hosted container.

Use-case: Your company firewall doesn't allow outbound RDP/SSH, so you can't connect to your system, which is in the cloud; they do allow outbound HTTPS/SSL.

Part 1: Create the LXC container

Step 1: Install & Configure storage (suggest mSATA)

  • Begin with the LXC containers installation exactly as described in the LXC howto and the containers will be placed on your mSATA drive.
  • TIP: The following commands can be used after you move the 2.5 GHz wifi miniPCI-E card from slot 1 to slot 3: sed '/path/ s/01/03/g' /etc/config/wireless (which should switch the configuration from slot 1 to slot 3), and then wifi (which restarts wireless networking with the new configuration).

Step 2: Create & Configure Ubuntu LXC

This step assumes that a sufficiently large filesystem is mounted on /srv. You'll need to create an LXC container via the Web GUI, as the CLI command doesn't work.

  1. Create a LXC based upon Ubuntu (suggest XX/16.04 LTS):
    ## Can't see why this command doesn't work!
    # lxc-create -n ubuntu -t download -- -d Ubuntu -r Xenial -a armv71  
    
    ## The container needs to auto-start, check:
      uci show | grep lxc-auto
    
    ## start the container, and attach to its console
      lxc-start -n ubuntu  
      lxc-attach -n ubuntu 
  2. Configure the Ubuntu server:
    ## Set an admin password
      (echo "P@ssw0rd"; sleep 1; echo "P@ssw0rd") | passwd root
    
    ## Configure system
    # dpkg-reconfigure tzdata # Optional: set timezone
    
    # Install some updates automatically
      apt -y install unattended-upgrades # best practice
      
    # Change hostname...
      apt -y install dbus # otherwise next cmd fails
      hostnamectl set-hostname vm-server
      
      reboot

Part 2: Install & Configure guacamole server

The following requires root access (suggest using lxc-attach to access the Ubuntu console, rather than via SSH).

Step 1: Install & Configure guacamole server

  1. First, Install guacamole server dependencies…
      apt-get -y install wget
    
    ## The minimum set of packages that a guacamole server requires
      apt-get -y install libcairo2-dev libjpeg-turbo8-dev libpng-dev libossp-uuid-dev
    
    ## Optional (per-protocol) packages for VNC, RDP, SSH and Telnet (and their dependencies)
      apt-get -y install \
            libvncserver-dev libfreerdp-dev libssh2-1-dev libtelnet-dev \
            libpango1.0-dev libssl-dev libpulse-dev libvorbis-dev libwebp-dev
             
    ## Optional packages for guacenc
      apt-get -y install libavcodec-dev libavutil-dev libswscale-dev
  2. Then, Download the latest (stable) release (or the latest version), then build it…
      guac_ver=0.9.13-incubating  # release used...
     
      wget -qO- https://sourceforge.net/projects/guacamole/files/current/source/guacamole-server-${guac_ver}.tar.gz | tar xz
    
      pushd guacamole-server*/
        
    ## Check the build environment, Prepare a startup script, then Build/install the package
      ./configure --with-init-dir=/etc/init.d
    
      make         > /dev/null  # Compile, and...
      make install > /dev/null  # Install
      popd
    
    ## Start Guacamole server (first tell Ubuntu to rescan the libs)
      ldconfig                   # before: service guacd start
      update-rc.d guacd defaults # before: service guacd start
      service guacd start
  3. Finally, check that the Guacamole daemon is running correctly…
      netstat -nltp | grep guac
      ps -ew | grep guac

Step 2: Install & Configure guacamole server

  1. Check that the Guacamole daemon is running correctly…
    ### Download the (pre-built) client (1/2)...
      wget -N https://sourceforge.net/projects/guacamole/files/current/binary/guacamole-${guac_ver}.war
    
      apt-get -y install tomcat7 # not required: tomcat7-admin tomcat7-docs
    
    ### ???  
      GUACAMOLE_HOME=/usr/share/tomcat7/.guacamole
    
      mkdir -p ${GUACAMOLE_HOME}/extensions      # for: guacamole-auth-jdbc-*sql-*.jar
      mkdir -p ${GUACAMOLE_HOME}/lib             # for: the RDMS' JDBC driver .jar files
    
      mkdir -p /etc/guacamole                    # for: guacamole.properties
      mkdir -p /var/lib/guacamole                # for: guacamole.war
    # mkdir -p /var/lib/guacamole/classpath      #
    
    
    ### Make the Guacamole Client available to Tomcat (symbolic links are best practice)
      cp       guacamole/target/guacamol*.war /var/lib/guacamole/guacamole.war
      ln -sf /var/lib/guacamole/guacamole.war /var/lib/tomcat7/webapps/guacamole.war

Step 3: Install & Configure guacamole server

  1. Check that the Guacamole daemon is running correctly…
    ### Download the (pre-built) client (2/2)...
      wget -N https://sourceforge.net/projects/guacamole/files/current/extensions/guacamole-auth-jdbc-${guac_ver}.tar.gz
    
    ### Install MySQL RDMS...
      sql_root_passwd=P@ssw0rd
    
    # Install (2/3) MySQL (RDBMS) (and provide MySQL with a root password to allow scripted installation)
      debconf-set-selections <<< "mysql-server mysql-server/root_password       password ${sql_root_passwd}"
      debconf-set-selections <<< "mysql-server mysql-server/root_password_again password ${sql_root_passwd}"
    
      apt-get -y install mysql-server
    
    
    ### Create the Guacamole database and an account for the authentication provider
      mysql -u root --password=${sql_root_passwd} <<EOF4
    # MySQL script to create Guacamole DB & Auth provider credentials
      CREATE DATABASE guacamole_db;
      CREATE USER 'guacamole_user'@'localhost' IDENTIFIED BY 'guac_P@ssw0rd';
      GRANT SELECT,INSERT,UPDATE,DELETE ON guacamole_db.* TO 'guacamole_user'@'localhost';
      FLUSH PRIVILEGES;
      quit
    EOF4
    
    
    ### Create the schema and admin account (guacadmin) for the Guacamole DB (2 scripts)
    # pushd extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql
      pushd guacamole-auth-*/mysql
      cat schema/*.sql | mysql -u root --password=${sql_root_passwd} guacamole_db
    
    # Copy the corresponding PostgreSQL or MySQL authentication module to its directory
    # cp target/guacamole-auth-*.jar  ${GUACAMOLE_HOME}/extensions/  # /usr/share/tomcat7/extensions
      cp guacamole-auth-*.jar  ${GUACAMOLE_HOME}/extensions/  # /usr/share/tomcat7/extensions
      popd
    
      mysql_j_ver=5.1.41
    
    # Download either the MySQL Java connector and copy to their directories
      wget -N https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-${mysql_j_ver}.tar.gz | tar xz
    
      cp mysql-connector*/*.jar        ${GUACAMOLE_HOME}/lib/         # /usr/share/tomcat7/lib

Step 4: Install & Configure guacamole server

  1. Check that the Guacamole daemon is running correctly…
      sudo tee /etc/guacamole/guacamole.properties >/dev/null <<EOF5
    # Hostname and port of guacamole proxy
    # guacd-hostname: localhost
    # guacd-port:     4822
    
    # Authentication provider class
    # auth-provider: net.sourceforge.guacamole.net.auth.mysql.MySQLAuthenticationProvider
    
    # Properties used by MySQLAuthenticationProvider
      mysql-hostname: localhost
      mysql-port:     3306
      mysql-database: guacamole_db
      mysql-username: guacamole_user
      mysql-password: guac_P@ssw0rd
    
    # mysql-disallow-simultaneous-connections: false
      mysql-disallow-duplicate-connections:    false
    
    EOF5
    
      ln -s /etc/guacamole/guacamole.properties ${GUACAMOLE_HOME} # is: /usr/share/tomcat7/.guacamole
    
    
    ### Step 4: Finally: Restart Guacamole weblet (i.e. TomCat)
    # sudo service guacd      restart  ## Not needed
    # sudo service mysql      restart
      sudo service tomcat7    restart  ## Is needed

Part 3: Install & Configure nginx proxy

Step 1: Install & Configure nginx proxy

### 0: First, establish remote access via SSH...
    apt-get install -y nginx

    ufw allow 'Nginx Full'  ## allows 80,443/tcp
#   ufw status verbose


####################################################################################################################################
# Define variables
  ssl_country=UK
  ssl_state=England
  ssl_city=London
  ssl_org=IT
  ssl_certname=vm-server.dtdns.net
  ssl_altname='DNS.1=vm-server.home,DNS.2=vm-server'

# Create a self-signed certificate
  mkdir -p   /etc/nginx/ssl

  openssl req -x509 -subj "/C=$ssl_country/ST=$ssl_state/L=$ssl_city/O=$ssl_org/CN=$ssl_certname/subjectAltName=$ssl_altname" -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/bonnes_me.key -out /etc/nginx/ssl/bonnes_me.crt -extensions v3_ca

# need to do chmod /etc/nginx/ssl/*.key

### Proxy parameters

    sh -c 'cat > /etc/nginx/proxy.conf <<"EOF"
###############################################################################
### Proxy parameters

  proxy_set_header        Host               $host;
  proxy_set_header        X-Real-IP          $remote_addr;
  proxy_set_header        X-Forwarded-For    $proxy_add_x_forwarded_for;
# proxy_set_header        X-Forwarded-Server $host;

client_max_body_size    10m;
client_body_buffer_size 128k;
proxy_connect_timeout   90;
proxy_send_timeout      90;
proxy_read_timeout      90;
proxy_buffers           32 4k;
proxy_redirect          off;

EOF'

### Proxy parameters for WebSockets

    sh -c 'cat > /etc/nginx/proxy-websocket.conf <<"EOF"
###############################################################################
### Proxy parameters for WebSockets

  proxy_set_header        Host               $host;
  proxy_set_header        X-Real-IP          $remote_addr;
  proxy_set_header        X-Forwarded-For    $proxy_add_x_forwarded_for;
  proxy_set_header        X-Forwarded-Server $host;

proxy_http_version      1.1;
proxy_set_header        Upgrade            $http_upgrade;
proxy_set_header        Connection         "Upgrade";
proxy_set_header        Authorization      "";
proxy_read_timeout      86400;
proxy_redirect          off;

EOF'

### Proxy parameters for SSL

    sh -c 'cat > /etc/nginx/ssl-config.conf <<"EOF"
###############################################################################
### Configuration for SSL

    ssl_certificate              /etc/nginx/ssl/vm-server.crt;
    ssl_certificate_key          /etc/nginx/ssl/vm-server.key;
    ssl_protocols                TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers                  HIGH:!aNULL:!MD5;

EOF'

### HTTPS listener parameters

    sh -c 'cat > /etc/nginx/sites-available/https << EOF
###############################################################################
### SERVER block - HTTPS listener parameters
server {
#   access_log /var/log/nginx/access_https_vm-server.log;
    access_log off;                                   ## default: ??

    listen                       443 ssl;    # 433, or (say) 8443 if using sslh/openvpn
    server_name                  vm-server.dtdns.net vm-server.home vm-server;

    include /etc/nginx/ssl-config.conf;

    port_in_redirect             off;
    
# http://www.nginxtips.com/nginx-optimization-the-definitive-guide/
    client_header_buffer_size     1k;
    client_header_timeout        12;
    large_client_header_buffers   2 1k;

    client_body_buffer_size      10K;
    client_body_timeout          12;
    client_max_body_size          8m;


### LOCATION blocks...
    location /guac/ {
#       proxy_pass        http://vm-server.home:8080/guacamole/;
        proxy_pass        http://localhost:8080/guacamole/;
        proxy_cookie_path /guacamole/ /guac/;           ## because we have location: /guac/, instead of: /guacamole/
        proxy_buffering   off;                          ## guacamole will not work if this is on (default: on)

        include /etc/nginx/proxy-websocket.conf;
    }

  }
EOF'

XXX

    rm    /etc/nginx/sites-enabled/default                                >/dev/null 2>&1
	ln -s /etc/nginx/sites-available/https /etc/nginx/sites-enabled/https >/dev/null 2>&1

    service nginx restart 

Step 5: Configure firewall rules

firewall.@redirect[1]=redirect
firewall.@redirect[1].target='DNAT'
firewall.@redirect[1].src='wan'
firewall.@redirect[1].dest='lan'
firewall.@redirect[1].proto='tcp'
firewall.@redirect[1].src_dport='443'
firewall.@redirect[1].name='HTTPS'
firewall.@redirect[1].dest_ip='172.27.0.100' ## This is the Ip-address of vm-server
firewall.@redirect[1].dest_port='443'