User Tools

Site Tools


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'