Overview

Red Hat Virtualization is an open, software-defined platform that virtualizes Linux and Microsoft Windows workloads. Built on Red Hat Enterprise Linux and the Kernel-based Virtual Machine (KVM).
In some cases you would like to hide this platform behind a proxy, as the different services should not be directly reached from the outside network.

In the Blog [1] I explained how to set up Nginx as reverse proxy for all UI of RHV. In this blog we will concentrate on how to reach the console of the VMs, which is best assured with a forward proxy. Unfortunately nginx is not designed to be a forward proxy (some articles try to tweak this anyway). I decided to trust on squid for forward proxying.

The aimed configuration should assure, that the existing reverse proxy is not interfered with and the console “just works” without the need for too much manual adjustments.

Theoretical background

There are different ways to connect to the consoles of the virtual machines. These are

  • serial console
  • spice
  • vnc

We are heading for the spice console. This console will only be reached via proxy. The flow is as follows:

To start a console you need to press the console button of the corresponding VM. This downloads a console.vv file to your local browser.
This console.vv file includes connection details towards the VM console. Typically this console is reached by connecting to the hypervisor host on which the VM runs on. In our case, this connection to the hypervisor host needs to go through a forward proxy.
Both information is included within the console.vv file.
If you your local desktop system is configured properly it will open a console client and open a connection according to the details of the console.vv file.

You therefor need to adjust 3 things.

  • make RHV aware of the spice proxy, so that it includes the proxy -information into the console.vv file
  • configure a forward proxy
  • install a spice client on your local desktop

make RHV aware of the spice proxy

To configure RHV-M to be aware of the spice proxy you need to run following command on your rhv-m engine and restart the ovirt engine afterwards:

engine-config -s SpiceProxyDefault=http://a.b.c.d:3128
systemctl restart ovirt-engine.service

with a.b.c.d being the public/external ip-address of your proxy and with the squid proxy to be listening on port 3128, which is the default port for squid proxy.

Unfortunately the public IP address of my proxy host changes with each start of the environment. So i semi-automated the task of configuring the RHV-M from my console host / management host.

This is the Ansible script I use to (re-)configure RHV-M to be aware of the correct ip of the proxy:

# cat ansible/changeproxy.yml 
- hosts: engine
  gather_facts: true
  become: true
  tasks:
   - set_fact:
       proxyip: "{{ proxyip }}"
     tags:
   - always
  vars_prompt:
   - name: "proxyip"
     prompt: "Please provide the external ip of the control node"
     # default: "1.2.3.4"
     private: no
- hosts: engine
  gather_facts: true
  become: true
  tasks:
   - name: set proxy
     shell: "engine-config -s SpiceProxyDefault=http://{{ proxyip }}:3128"
   - name: restart engine
     systemd:
       state: restarted
       name: ovirt-engine.service
   - name: get proxy
     shell: "engine-config -g SpiceProxyDefault"
     register: command_output
   - debug: msg="{{command_output.stdout}}"

which can be started from my management host like this

[root@control ~]# #ansible-playbook -i ansible/inventory ansible/changeproxy.yml

 

configure a forward proxy

Installation of squid

I’m using the same RHEL 7 host as in [1] with a current subscription attached to it.  Squid is part of the base rhel repository, so no additional repos need to be enabled or disabled. But squid needs to be installed:

yum install squid

Configuration of squid

As squid acts as a normal forward proxy no special configuration needs to be included. We only assure access rights allow the necessary while denying all unhealthy approaches.

I’ve added two destination definitions. One for the rhv-m and one for all rhv-hosts, which would need to be connected to to get access to the console.

acl to_engine dst 192.168.0.99/32     # IP address of the rhvm
acl to_rhvh dst 192.168.0.0/24        # IP network for the hypervisors

I do not want people to connect to other than to safe ports:

http_access deny CONNECT !Safe_ports

Hint: I think the above rule is not adding value as there is already the following rule, which denies everything (including connect) to non-safe ports.

http_access deny !Safe_ports

The relevant rule is the following, which allows access to our engine (aka rhv-m) and to our hypervisors :

http_access allow to_engine
http_access allow to_rhvh

Anything else is denied – as it is the default configuration in squid.conf:

# And finally deny all other access to this proxy
http_access deny all

I did not uncomment the following. As I do not have two allow rules also matching “to” objects it is not possible to reach any local service anyway. Leaving this rule commented enables connection from this host to the rhv-m and rhv-h hosts, which helps troubleshooting.

# http_access deny to_localhost

I also changed the listen statement to assure squid will only listen on ipv4 adresses. As I did not secure ipv6 I prefer to switch it off.

http_port 0.0.0.0:3128

Also some logging configured:

access_log stdio:/var/log/squid/access.log squid

The whole /etc/squid/squid.conf looks as follows:

[root@control ~]# cat /etc/squid/squid.conf
#
# Recommended minimum configuration:
#

# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
acl localnet src 10.0.0.0/8 # RFC1918 possible internal network
acl localnet src 172.16.0.0/12 # RFC1918 possible internal network
acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
acl localnet src fc00::/7 # RFC 4193 local private network range
acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines
# MSI new:
acl to_engine dst 192.168.0.99/32
acl to_rhvh dst 192.168.0.0/24

acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT

#
# Recommended minimum Access Permission configuration:
#
# Deny requests to certain unsafe ports
http_access deny !Safe_ports

# Deny CONNECT to other than secure SSL ports
# MSI changed:
##http_access deny CONNECT !SSL_ports
http_access deny CONNECT !Safe_ports

# Only allow cachemgr access from localhost
http_access allow localhost manager
http_access deny manager

# We strongly recommend the following be uncommented to protect innocent
# web applications running on the proxy server who think the only
# one who can access services on "localhost" is a local user
# http_access deny to_localhost

#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#

# Example rule allowing access from your local networks.
# Adapt localnet in the ACL section to list your (internal) IP networks
# from where browsing should be allowed
# MSI changed:
#http_access allow localnet
#http_access allow localhost
http_access allow to_engine
http_access allow to_rhvh

# And finally deny all other access to this proxy
http_access deny all

# Squid normally listens to port 3128
# MSI changed:
# http_port 3128
http_port 0.0.0.0:3128

# Uncomment and adjust the following to add a disk cache directory.
#cache_dir ufs /var/spool/squid 100 16 256

# Leave coredumps in the first cache dir
coredump_dir /var/spool/squid

#
# Add any of your own refresh_pattern entries above these.
#
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320


# MSI: added
access_log stdio:/var/log/squid/access.log squid

start squid

We also need to start and enable squid:

systemctl start squid.service 
systemctl enable squid.service

Spice Client

The easiest way is to get the right Virt-viewer is to follow the link of your rhv-manager start page:
On the start page you find a link “Console Client Resources” underneath the header “Downloads”. For Windows you will find several msi -files to install on 32 or 64 bit. For Linux you find the command to install Virt-viewer:

yum install virt-viewer

There is an option for Browser-Based Console Clients (SPICE-HTML5 and noVNC) mentioned as well. But I did not look into this.

For MAC-Users I found [3], which describes a solution, working for me.

If you installed a Virt-viewer, you will also need to assure, your browser (or you OS) knows that .vv files need to be open with Virt-viewer. If this is not configured properly,  you can start the Virt-viewer manually.

after clicking “console” on your VM in RHV-M.

console.vv is downloaded and will most likely reside in your Downloads folder. then run:

remote-viewer Downloads/console.vv

… and your console should open as expected.

Troubleshooting

There are quite some things you might want to review, if things do not work as intended:

Log files

Look at

  • /var/log/messages on all nodes involved.
  • /var/log/squid/access.log on the proxy node.

VM console settings

In RHV-M before starting the console review the console options. They should look similar to the following:

RHV - Console Options

console.vv content

Review the console.vv file with your favourite editor. It should look similar to the following:

[virt-viewer]
type=spice
host=192.168.0.40                 ####### <<< hypervisor host
port=5901
password=GysH6p/M67CL
# Password is valid for 120 seconds.
delete-this-file=1
fullscreen=0
title=HostedEngine:%d
toggle-fullscreen=shift+f11
release-cursor=shift+f12
secure-attention=ctrl+alt+end
tls-port=5902
enable-smartcard=0
enable-usb-autoshare=1
usb-filter=-1,-1,-1,-1,0
tls-ciphers=DEFAULT
host-subject=O=example.com,CN=rhvh1.example.com
ca=-----BEGIN CERTIFICATE-----\nMIIDvTCCAqWgAwIBAgICEAAwDQYJKoZIhv....\n-----END CERTIFICATE-----\n
proxy=http://129.146.213.55:3128  ####### <<< public IP of proxy  
secure-channels=main;inputs;cursor;playback;record;display;smartcard;usbredir
versions=rhev-win64:2.0-160;rhev-win32:2.0-160;rhel7:2.0-6;rhel6:99.0-1
newer-version-url=https://129.146.213.55/ovirt-engine/rhv/client-resources

[ovirt]
host=129.146.213.55:443             ####### <<< public IP of proxy
vm-guid=b9e88694-42e1-4614-bc41-2282be851e4e
sso-token=rT4uGrYjmzAbslOFVWqiGEOTCPno_ObiWEIZ_u8p3rtJgpEdWjWC8dhDXzqzc0P7PyersrLM5chdDPExW8SSwQ
admin=1
ca=-----BEGIN CERTIFICATE-----\nMIIDvTCCAqWgAwIBAgICEAAwDQYJK.........\n-----END CERTIFICATE-----\n

Note: The bold written comments at the end of the lines do NOT belong to the file.

Assure the ip-adresses you find in this file are correct.

connection possible

If the IP-Adresses look correct, you can try to connect to each end-point with your favourite network connection testing tool (e.g netcat).

From the proxy host, you should be able to connect to the hypervisor host (host in the console.vv) at port 5901. If this is not possible, look at the host, wether some service is listening. Also review host firewall rules (on both hosts).

From your client try to connect to the proxy on port 3128. You can also try this connection with curl or alike.

Also review the logs of the proxy.

Conclusion

With this second step you can run a RHV-environment within a private area only connected to the outside via proxies. The connection towards the Web-UIs was already dealt with. Now the console for the VMs is usable as well.

Links

I came across following links.

[1] Using nginx as reverse proxy in front of Red Hat Virtualization 4.2

[2] RHV Administration Guide – SPICE Proxy

[3] Virt-viewer on MAC