Feasibility of hosting Teddycloud

With release 0.5.2 hosting TeddyCloud becomes a thing :slight_smile:

The only technical challenge is running the SSL backend without a second public IP address. If you use NGINX as a reverse proxy you’ll find a way to do it above.
In case of HAProxy I am using the following snippet:

global
...
    crt-base /usr/local/etc/haproxy/certs
...
defaults
    log     global
    mode    http
    option  httplog
    option  dontlognull
    option  forwardfor
...
userlist TeddyCloudUsers
    user teddy insecure-password SomeStrongPasswordHerePlease
...
frontend tcp-in
    bind *:443,[::]:443 v6only
    mode tcp

    tcp-request inspect-delay 5s
    tcp-request content accept if { req_ssl_hello_type 1 }

    use_backend tcp2http if { req.ssl_sni -i tc.example.org }
    use_backend tcp2http if { req.ssl_sni -i regular.site1.com }
    use_backend tcp2http if { req.ssl_sni -i regular.site2.com }
...
    use_backend tcp2http if { req.ssl_sni -i final.regular.site.com }

    default_backend teddycloud


frontend http-in
    bind *:80,[::]:80 v6only
    bind 127.0.0.1:10443 alpn h2,http/1.1 ssl crt /usr/local/etc/haproxy/certs accept-proxy
...
    acl teddycloud hdr(host) tc.example.org
    acl teddycloud_auth http_auth(TeddyCloudUsers)
    http-request auth if teddycloud !teddycloud_auth
    use_backend teddycloud_web if teddycloud
...
    default_backend internalserver


backend tcp2http
    mode tcp
    server haproxy-loopback 127.0.0.1:10443 check send-proxy-v2


backend teddycloud
    mode tcp
    server teddycloud teddycloud:443 no-check


backend teddycloud_web
    mode http
    server teddycloud_web teddycloud:80 no-check
 

backend internalserver
    server internalserver apache:80
    http-request set-header X-Forwarded-Port %[dst_port]
    http-request add-header X-Forwarded-Proto https if { ssl_fc }
    http-request add-header X-Forwarded-Host %[hdr(Host)] if { ssl_fc }

The cool thing about HAProxy is that it can act as a TCP proxy. The benefit of which is that it does not have to terminate the SSL connection (no unsafe legacy renegotiation with the actual backend, no need to share any certificates). Unfortunatly the only piece of information passed at layer 4 is the SSL connection setup (no certificates or anything here) - the only useful thing is the SNI though.

It would be easy to route to the Teddycloud backend based on the SNI, but here of all things the box does NOT pass an SNI.

Hence, the setup needs to tediously document all hosted domains and route them based on SNI to the actual internal server.
The default routing will be applied to all SSL traffic WITHOUT SNI (= our TonieBoxes) or without specified SNI.

As a bonus I included BasicAuth authentication for the TeddyCloud frontend.