CopyDisable

Wednesday, 10 January 2018

TUSD server on Production

TUS (https://tus.io/protocols/resumable-upload.html) is HTTP based protocol used for resumable file upload. TUSD (https://github.com/tus/tusd) is official implementation of the TUS protocol.
For one of our project, we have decided to use TUSD for uploading large number of files from many locations over unreliable internet connection.
For running TUSD on production, first thing came to our mind was how to make it secure. TUSD does not accept HTTPS connection, neither it has any built in layer for verification/authentication checks. Authentication can be done using the hooks system of TUSD.
So we decided to move the security layer out of TUSD and let it focus on its primary task of resumable file uploading.
Accordingly we introduced HAProxy in front of TUSD server.

  • TUSD server will run as normal user on default port 1080 and HAProxy will listen on default HTTP/HTTPS ports and proxy pass the requests to TUSD server.
  • SSL Security certificate will be deployed on HAProxy and HAProxy will do the SSL offloading. TUSD will receive plain HTTP traffic from HAProxy.
  • We will enable basic HTTP authentication in HAProxy and HAProxy will authenticate the incoming connections before forwarding it to TUSD server.
  • HAProxy will only proxy a specific URL traffic to the backend TUSD server. It will not forward the whole traffic to TUSD server, so any connection attempt to the default HTTP/HTTPS port on the public IP will not be forwarded to TUSD.

For this document I used Ubuntu 16.04, TUSD Version: 0.9.0 and HAProxy Version 1.7.
As we will run TUSD behind HAProxy, so have to add -behind-proxy flag while starting TUSD to inform TUSD that it is running behind a proxy and have to give attention to the special headers sent by the proxy.


Let’s see the configs for this setup


TUSD service:

[Unit]
Description= TUSD File Upload Server
After=network.target

[Service]
User=tusd
Group=tusd
WorkingDirectory=/app/tusd
ExecStart=/bin/bash -ce "exec /app/tusd/tusd -dir /data/tusupload  -hooks-dir /app/tusd/hooks -behind-proxy  >> /logs/tusd/tusd.log 2>&1"
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=infinity
# processes/threads
LimitNPROC=infinity
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false


[Install]
WantedBy=multi-user.target






HAProxy config file:

userlist UL1
                user httpuser insecure-password abcdefghijklmnop

global
                log /dev/log       local0
                log /dev/log       local1 notice
                chroot /var/lib/haproxy
                stats socket /run/haproxy/admin.sock mode 660 level admin
                stats timeout 30s
                user haproxy
                group haproxy
                daemon

                # Default SSL material locations
                ca-base /etc/ssl/certs
                crt-base /etc/ssl/private

                # Default ciphers to use on SSL-enabled listening sockets.
                # For more information, see ciphers(1SSL). This list is from:
                #  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
                # An alternative list with additional directives can be obtained from
                #  https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy
                ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
                ssl-default-bind-options no-sslv3

defaults
                log          global
                mode    http
                option   httplog
                option   dontlognull
                timeout connect 5000
                timeout client  50000
                timeout server  50000
                errorfile 400 /etc/haproxy/errors/400.http
                errorfile 403 /etc/haproxy/errors/403.http
                errorfile 408 /etc/haproxy/errors/408.http
                errorfile 500 /etc/haproxy/errors/500.http
                errorfile 502 /etc/haproxy/errors/502.http
                errorfile 503 /etc/haproxy/errors/503.http
                errorfile 504 /etc/haproxy/errors/504.http



frontend localhost
    bind *:80
    bind *:443 ssl crt /etc/ssl/my_certs/my_cert.pem
    redirect scheme https if !{ ssl_fc }
    mode http

    acl tusdsvr hdr(host) -i tusdserver.example.com   
    use_backend tus-backend if tusdsvr

#########################Backend Settings##########################
backend tus-backend
#HTTP basic Authentication check
      acl AuthOkay_UsersAuth http_auth(UL1)
      http-request auth realm UserAuth if !AuthOkay_UsersAuth

#Setting X-Forwarded-Proto header to https to let TUSD know that it is behind HTTPS proxy and should return https URLs.   
     http-request set-header X-Forwarded-Proto "https"
     http-request add-header X-Forwarded-For %[src]

     mode     http      

    server   server1 localhost:1080  check fall 3 rise 2