Skip to content
Snippets Groups Projects
Commit 07311cb4 authored by Stefano Alberto Russo's avatar Stefano Alberto Russo
Browse files

Add https proxy for tasks mechanism stub.

parent 15bdf157
No related branches found
No related tags found
No related merge requests found
......@@ -518,10 +518,10 @@ def hash_string_to_int(string):
#================================
# Tunnel setup
# Tunnel (and proxy) setup
#================================
def setup_tunnel(task):
def setup_tunnel_and_proxy(task):
# Importing here instead of on top avoids circular dependencies problems when loading booleanize in settings
from .models import Task, KeyPair, TaskStatuses
......@@ -545,9 +545,108 @@ def setup_tunnel(task):
task.tcp_tunnel_port = tcp_tunnel_port
task.save()
# Setup the proxy now.
# Some info about the various SSL switches: https://serverfault.com/questions/577616/using-https-between-apache-loadbalancer-and-backends
# Esnure conf directory exists
if not os.path.exists('/shared/etc_apache2_sites_enabled'):
os.makedirs('/shared/etc_apache2_sites_enabled')
# Set conf file name
apache_conf_file = '/shared/etc_apache2_sites_enabled/{}.conf'.format(task.uuid)
# Check if proxy conf exists
if not os.path.exists(apache_conf_file):
# Write conf file
logger.debug('Writing task proxy conf to {}'.format(apache_conf_file))
websocket_protocol = 'wss' if task.container.interface_protocol == 'https' else 'ws'
task_proxy_host = os.environ.get('TASK_PROXY_HOST', 'localhost')
apache_conf_content = '''
#---------------------------
# Task interface proxy
#---------------------------
#<Location /desktop/{0}/>
#AuthType Basic
#AuthName "Restricted area"
#AuthUserFile /shared/reyns/etc_apache2_sites_enabled/'''+str(task.uuid)+'''.htpasswd
#Require valid-user
#ProxyPass http://desktop-{0}:8590/
#ProxyPassReverse http://desktop-{0}:8590/
#</Location>
#<Location /sessions/{1}>
#ProxyPass ws://desktop-{0}:8590/websockify
#ProxyPassReverse ws://desktop-{0}:8590/websockify
#</Location>
Listen '''+str(task.tcp_tunnel_port)+'''
<VirtualHost _default_:'''+str(task.tcp_tunnel_port)+'''>
ServerName '''+task_proxy_host+'''
ServerAdmin admin@rosetta
SSLEngine on
SSLCertificateFile /root/certificates/rosetta_platform/rosetta_platform.crt
SSLCertificateKeyFile /root/certificates/rosetta_platform/rosetta_platform.key
SSLCACertificateFile /root/certificates/rosetta_platform/rosetta_platform.ca-bundle
SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
# Use RewriteEngine to handle websocket connection upgrades
RewriteEngine On
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule /(.*) '''+str(websocket_protocol)+'''://webapp:'''+str(task.tcp_tunnel_port)+'''/$1 [P,L]
<Location "/">
# preserve Host header to avoid cross-origin problems
ProxyPreserveHost on
# proxy to the port
ProxyPass '''+str(task.container.interface_protocol)+'''://webapp:'''+str(task.tcp_tunnel_port)+'''/
ProxyPassReverse '''+str(task.container.interface_protocol)+'''://webapp:'''+str(task.tcp_tunnel_port)+'''/
</Location>
</VirtualHost>
'''
with open(apache_conf_file, 'w') as f:
f.write(apache_conf_content)
# Now check conf exist on proxy
logger.debug('Checking if conf is enabled on proxy service')
out = os_shell('ssh -o StrictHostKeyChecking=no proxy "[ -e /etc/apache2/sites-enabled/{}.conf ]"'.format(task.uuid), capture=True)
if out.exit_code == 1:
logger.debug('Conf not enabled on proxy service, linkig it and reloading Apache conf')
# Link on proxy since conf does not exist
out = os_shell('ssh -o StrictHostKeyChecking=no proxy "sudo ln -s /shared/etc_apache2_sites_enabled/{0}.conf /etc/apache2/sites-enabled/{0}.conf"'.format(task.uuid), capture=True)
if out.exit_code != 0:
logger.error(out.stderr)
raise ErrorMessage('Somthing went wrong when activating the task proxy conf')
# Reload apache conf on Proxy
out = os_shell('ssh -o StrictHostKeyChecking=no proxy "sudo apache2ctl graceful"', capture=True)
if out.exit_code != 0:
logger.error(out.stderr)
raise ErrorMessage('Somthing went wrong when loading the task proxy conf')
# Check if the tunnel is active and if not create it
# Check if the tunnel is (still) active and if not create it
logger.debug('Checking if task "{}" has a running tunnel'.format(task))
out = os_shell('ps -ef | grep ":{}:{}:{}" | grep -v grep'.format(task.tcp_tunnel_port, task.interface_ip, task.interface_port), capture=True)
......
......@@ -10,7 +10,7 @@ from django.contrib.auth.models import User
from django.shortcuts import redirect
from django.db.models import Q
from .models import Profile, LoginToken, Task, TaskStatuses, Container, Computing, KeyPair, ComputingSysConf, ComputingUserConf, Text
from .utils import send_email, format_exception, timezonize, os_shell, booleanize, debug_param, get_tunnel_host, random_username, setup_tunnel, finalize_user_creation
from .utils import send_email, format_exception, timezonize, os_shell, booleanize, debug_param, get_tunnel_host, random_username, setup_tunnel_and_proxy, finalize_user_creation
from .decorators import public_view, private_view
from .exceptions import ErrorMessage
......@@ -341,7 +341,7 @@ def tasks(request):
elif action=='connect':
# First ensure that the tunnel is setu up
setup_tunnel(task)
setup_tunnel_and_proxy(task)
# Then, redirect to the task through the tunnel
tunnel_host = get_tunnel_host()
......@@ -972,16 +972,25 @@ def direct_connection_handler(request, uuid):
raise ErrorMessage('You do not have access to this task.')
# First ensure that the tunnel is setu up
setup_tunnel(task)
setup_tunnel_and_proxy(task)
# Set task proxy host
task_proxy_host = settings.TASK_PROXY_HOST
# Then, redirect to the task through the tunnel
tunnel_host = get_tunnel_host()
if task.requires_proxy_auth and task.auth_token:
user = request.user.email
password = task.auth_token
return redirect('{}://{}:{}@{}:{}'.format(task.container.interface_protocol, user, password, tunnel_host, task.tcp_tunnel_port))
if task.requires_proxy:
if task.requires_proxy_auth and task.auth_token:
user = request.user.email
password = task.auth_token
redirect_string = 'https://{}:{}@{}:{}'.format(user, password, task_proxy_host, task.tcp_tunnel_port)
else:
redirect_string = 'https://{}:{}'.format(task_proxy_host, task.tcp_tunnel_port)
else:
return redirect('{}://{}:{}'.format(task.container.interface_protocol, tunnel_host,task.tcp_tunnel_port))
redirect_string = '{}://{}:{}'.format(task.container.interface_protocol, tunnel_host,task.tcp_tunnel_port)
logger.debug('Task direct connect redirect: "{}"'.format(redirect_string))
return redirect(redirect_string)
......@@ -999,7 +1008,7 @@ def sharable_link_handler(request, short_uuid):
raise ErrorMessage('You do not have access to this task.')
# First ensure that the tunnel is setu up
setup_tunnel(task)
setup_tunnel_and_proxy(task)
# Then, redirect to the task through the tunnel
tunnel_host = get_tunnel_host()
......
......@@ -230,6 +230,8 @@ LOCAL_USER_DATA_DIR = os.environ.get('LOCAL_USER_DATA_DIR', '/data')
# Invitation code if any
INVITATION_CODE = os.environ.get('INVITATION_CODE', None)
# Task proxy host (WARNING: direct use of the env var in utils.py)
TASK_PROXY_HOST = os.environ.get('TASK_PROXY_HOST', 'localhost')
#===============================
# Auth
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment