Hey TeddyCloud Fellows,
I want to share something I’ve been working on with the flying around configs here in the forum. I’ve created a personal GitHub repository for TeddyCloud using Docker. It’s all set up to make it super easy to get TeddyCloud and NGINX running with Docker. The Webpanel uses Let’s Encrypt Certificates and Basic Authentication for securing the access.
Check it out here:
I would appreciate any feedback, issues, or anything else you might have.
The first line is the path to the cert of your own, self-signed CA, created with openssl or XCA (X - Certificate and Key management ). The second line only allowsclients, with a signed cert from this specific CA to connect. Important to know, that this is fully independent from the server cert for TLS
@henryk@Teddy,
Thanks for your request. I also had certificate based authentication in mind. But it is not possible with the actual configuration. When using nginx ssl_preread for SNI-based routing, you cannot use SSL client verify. Dumb NGINX .
So, I stayed with a simple version. However, I could implement it in a more complex way. This would involve using a second nginx container. The first nginx is just for the SNI-based routing. The second one then can handle the client-cert and proxy-forward to the teddycloud web interface.
I just want to get rid of the basic auth. Just for the frontend. (You could also disable basic auth if opened from certain IPs, but usually you do not have a fixed ip for ll your devices)
I’ve made some modifications and added optional IP filtering for the server/backend and the web interface. If there’s no htpasswd file, basic auth will be disabled as well. To implement IP filtering and disable basic auth, remove the existing .htpasswd file and add the following lines to your .env file: ALLOWED_IPS_WEB= ALLOWED_IPS_BACKEND=
The README should be up to date.
I’m fiddling around with an additional scenario for cert authentication.
@Quentendo64 you are correct, sni would not work, therefore I have published the webinterface on a different port e.g. 4443 and use cert based authentication there, while 443 will be used by the tonieboxes
If I understand the docker compose yams correctly, you only use port 80 and 443. But teddycloud supports an additional port 8443 for https webfrontend, shouldn’t you support that also? And if I got the thread correctly, would it be possible to add only on the port 8443 the cert authentication and leave port 80 with basic authentication?
No, I do 4443 with cert based authentication only. It should be possible to try cert based authentication first and fall back to basic, on the same port. Let me do some tests over the next days and I will post my nginx config
@Teddy, thank you for your configuration. @henryk, I will implement the approach as well.
Currently, I am working on another Tonie-related project regarding .TAF conversion. As soon as I am on a clean state there, I will invest time for implementing the other nginx approach.
Hello guys,
as discussed on Telegram, i will share my configuration for teddycloud setup with NGINX. Its running for 2 months now in “production”, i only faced some upload-timeout issues, i hope i fixed the most of them but maybe i didnt catched all I will also review the setup of @Quentendo64 , looks quite similar to mine.
In general: I use a config based on the following idea:
As i have several other applications up and running, its the best solution for me, but that does not mean its the best solution for you if you dont have other services up and running on that machine
Basically, all traffic (toniebox, web-accesses to all your domains) will be forwarded to one port to NGINX-STREAM module. The stream module routes the traffic based on the SNI (Server Name Indication) to your dedicated NGINX-SERVER modules. If no SNI is provided, traffic will be forwarded to teddycloud:443 port, so authentification for toniebox can be done there direclty. If you access the page tc.example.com with a browser, SNI will be provided and it will be forwarded to the dedicated NGINX-Server module, where you can also configure Letsencrypt-certificates and do a certificate-based authentification (thats what i did) or password-prompt.
upstream backend {
server 127.0.0.1:9443; # Replace with the host for teddycloud.example.com
}
upstream no_sni {
server 127.0.0.1:443; # Replace with the host for traffic without SNI
}
map $ssl_preread_server_name $upstream_name {
tc.example.com backend; # Match specific SNI
cloud.example.com backend;
apps.example.com backend;
default no_sni; # Default upstream for other cases
}
# Configure the server block
server {
listen 8443;
ssl_preread on;
proxy_connect_timeout 36000s;
proxy_pass $upstream_name;
}
Config for NGINX-Server module:
server {
listen 9443 ssl http2;
listen [::]:9443 ssl http2;
ssl_certificate /etc/letsencrypt/live/tc.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tc.example.com/privkey.pem;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.2 TLSv1.3;
server_name tc.example.com;
server_tokens off;
error_page 497 https://$host:$server_port$request_uri;
#Eigene Zertifikat-Authentifizierung, bitte abschalten, wenn nicht selbst implementiert
ssl_client_certificate /opt/easy-rsa/keys/ca.crt;
ssl_crl /opt/easy-rsa/keys/crl.pem;
ssl_verify_client optional;
client_max_body_size 4096M;
location / {
proxy_pass http://127.0.0.1:5020;
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-Host $server_name;
proxy_set_header X-Forwarded-Proto https;
proxy_max_temp_file_size 4096M;
proxy_connect_timeout 36000s;
proxy_read_timeout 36000s;
proxy_send_timeout 36000s;
send_timeout 36000s;
proxy_buffers 6 16k;
proxy_buffer_size 32k;
#if client-side certificate failed - show error message
#Eigene Zertifikat-Authentifizierung, bitte abschalten, wenn nicht selbst implementiert
if ($ssl_client_verify != SUCCESS) {
return 403;
}
if ($scheme != "https") {
return 301 https://$host$request_uri;
} # Macht einen Redirct auf HTTPs, falls Schema nicht https ist.
access_log /var/log/nginx/teddy.access.log;
error_log /var/log/nginx/teddy.error.log;
}
location /web/favicon.ico {
alias /var/www/html/web/favicon.ico;
}
location /.well-known/acme-challenge {
alias /var/www/tc.example.com/.well-known/acme-challenge;
location ~ /.well-known/acme-challenge/(.*) {
add_header Content-Type application/jose+json;
}
}
}
Main Benefit, if you do it with the stream-config:
you can flash you’re tonie box with same URL as you access it via browser (example: tc.example.com)