Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -276,3 +276,363 @@ sudo certbot renew --dry-run
```

Your OpenCloud instance is now running securely behind a fully configured external Nginx reverse proxy with HTTPS.


## Optional: HTTP/3 (QUIC) Support

:::info Why use HTTP/3?
HTTP/3 represents a major leap in web performance and reliability by replacing the underlying TCP protocol with QUIC (built on UDP).

**Key benefits for OpenCloud include:**
1. **Faster Connection Establishment:** Zero round-trip time (0-RTT) handshakes mean users connect to your cloud significantly faster, especially on mobile networks.
2. **No Head-of-Line Blocking:** If a single packet is lost during a large file upload or sync, only that specific transfer is delayed. Other concurrent requests (like loading the dashboard) continue instantly.
3. **Better Mobile Experience:** Connection migration allows users to switch between Wi-Fi and mobile data without dropping their active file syncs or video streams.
4. **Improved Security:** Encryption is built directly into the transport layer, reducing overhead and improving privacy.
:::

:::warning Advanced Setup
HTTP/3 over QUIC requires an nginx build with QUIC support. The stock nginx package on most distributions does **not** include QUIC. At the time of writing, Ubuntu 26.04+ ships an nginx version with QUIC enabled out of the box. On older distributions you need to build nginx from source with `--with-http_v3_module` or use the [official nginx QUIC packages](https://nginx.org/en/docs/quic.html).

Verify that your nginx supports QUIC before proceeding:

```bash
nginx -V 2>&1 | grep -o -- '--with-http_v3_module'
```

If this returns nothing, your nginx does not support QUIC.
:::

The following configurations replace the HTTP/2 configurations above. They use `upstream` blocks with keepalive connections and a `map` directive for cleaner WebSocket handling. Pick the configuration that matches your deployment.

### Configuration 1: OpenCloud Only with HTTP/3

```nginx
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

upstream opencloud_backend { server 127.0.0.1:9200; keepalive 32; }

# ── HTTP → HTTPS redirect ──────────────────────────────────
server {
listen 80;
server_name cloud.YOUR.DOMAIN;

root /var/www/certbot;
location ^~ /.well-known/acme-challenge/ { try_files $uri =404; }

location / {
return 301 https://$host$request_uri;
}
}

# ── OpenCloud ───────────────────────────────────────────────
server {
listen 443 quic reuseport;
listen 443 ssl;
http2 on;
server_name cloud.YOUR.DOMAIN;

add_header Alt-Svc 'h3=":443"; ma=86400' always;
ssl_certificate /etc/letsencrypt/live/cloud.YOUR.DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cloud.YOUR.DOMAIN/privkey.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

client_max_body_size 0;
keepalive_requests 100000;
keepalive_timeout 5m;
http2_max_concurrent_streams 512;

root /var/www/certbot;
location ^~ /.well-known/acme-challenge/ { try_files $uri =404; }

location / {
proxy_pass http://opencloud_backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_read_timeout 3600;
proxy_buffering off;
}
}
```

### Configuration 2: OpenCloud + Collabora with HTTP/3

```nginx
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

upstream opencloud_backend { server 127.0.0.1:9200; keepalive 32; }
upstream wopi_backend { server 127.0.0.1:9300; keepalive 16; }
upstream collabora_backend { server 127.0.0.1:9980; keepalive 16; }

# ── HTTP → HTTPS redirect ──────────────────────────────────
server {
listen 80;
server_name cloud.YOUR.DOMAIN collabora.YOUR.DOMAIN wopiserver.YOUR.DOMAIN;

root /var/www/certbot;
location ^~ /.well-known/acme-challenge/ { try_files $uri =404; }

location / {
return 301 https://$host$request_uri;
}
}

# ── OpenCloud ───────────────────────────────────────────────
server {
listen 443 quic reuseport;
listen 443 ssl;
http2 on;
server_name cloud.YOUR.DOMAIN;

add_header Alt-Svc 'h3=":443"; ma=86400' always;
ssl_certificate /etc/letsencrypt/live/cloud.YOUR.DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cloud.YOUR.DOMAIN/privkey.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

client_max_body_size 0;
keepalive_requests 100000;
keepalive_timeout 5m;
http2_max_concurrent_streams 512;

root /var/www/certbot;
location ^~ /.well-known/acme-challenge/ { try_files $uri =404; }

location / {
proxy_pass http://opencloud_backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_read_timeout 3600;
proxy_buffering off;
}
}

# ── Collabora ──────────────────────────────────────────────
server {
listen 443 quic;
listen 443 ssl;
http2 on;
server_name collabora.YOUR.DOMAIN;

add_header Alt-Svc 'h3=":443"; ma=86400' always;
ssl_certificate /etc/letsencrypt/live/cloud.YOUR.DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cloud.YOUR.DOMAIN/privkey.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

keepalive_requests 100000;
keepalive_timeout 5m;
http2_max_concurrent_streams 512;

root /var/www/certbot;
location ^~ /.well-known/acme-challenge/ { try_files $uri =404; }

location / {
proxy_pass http://collabora_backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
proxy_buffering off;
}
}

# ── Collabora WOPI Server ──────────────────────────────────
server {
listen 443 quic;
listen 443 ssl;
http2 on;
server_name wopiserver.YOUR.DOMAIN;

add_header Alt-Svc 'h3=":443"; ma=86400' always;
ssl_certificate /etc/letsencrypt/live/cloud.YOUR.DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cloud.YOUR.DOMAIN/privkey.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

keepalive_requests 100000;
keepalive_timeout 5m;
http2_max_concurrent_streams 512;

root /var/www/certbot;
location ^~ /.well-known/acme-challenge/ { try_files $uri =404; }

location / {
proxy_pass http://wopi_backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_read_timeout 3600;
proxy_buffering off;
}
}
```

### Configuration 3: OpenCloud + Euro Office with HTTP/3

```nginx
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

upstream opencloud_backend { server 127.0.0.1:9200; keepalive 32; }
upstream wopi_backend { server 127.0.0.1:9300; keepalive 16; }
upstream euroffice_backend { server 127.0.0.1:9900; keepalive 16; }

# ── HTTP → HTTPS redirect ──────────────────────────────────
server {
listen 80;
server_name cloud.YOUR.DOMAIN euro-office.YOUR.DOMAIN wopiserver.YOUR.DOMAIN;

root /var/www/certbot;
location ^~ /.well-known/acme-challenge/ { try_files $uri =404; }

location / {
return 301 https://$host$request_uri;
}
}

# ── OpenCloud ───────────────────────────────────────────────
server {
listen 443 quic reuseport;
listen 443 ssl;
http2 on;
server_name cloud.YOUR.DOMAIN;

add_header Alt-Svc 'h3=":443"; ma=86400' always;
ssl_certificate /etc/letsencrypt/live/cloud.YOUR.DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cloud.YOUR.DOMAIN/privkey.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

client_max_body_size 0;
keepalive_requests 100000;
keepalive_timeout 5m;
http2_max_concurrent_streams 512;

root /var/www/certbot;
location ^~ /.well-known/acme-challenge/ { try_files $uri =404; }

location / {
proxy_pass http://opencloud_backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_read_timeout 3600;
proxy_buffering off;
}
}

# ── Euro Office Document Server ────────────────────────────
server {
listen 443 quic;
listen 443 ssl;
http2 on;
server_name euro-office.YOUR.DOMAIN;

add_header Alt-Svc 'h3=":443"; ma=86400' always;
ssl_certificate /etc/letsencrypt/live/cloud.YOUR.DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cloud.YOUR.DOMAIN/privkey.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

client_max_body_size 100M;
keepalive_requests 100000;
keepalive_timeout 5m;
http2_max_concurrent_streams 512;

root /var/www/certbot;
location ^~ /.well-known/acme-challenge/ { try_files $uri =404; }

location / {
proxy_pass http://euroffice_backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
proxy_buffering off;
}
}

# ── Euro Office WOPI Server ────────────────────────────────
server {
listen 443 quic;
listen 443 ssl;
http2 on;
server_name wopiserver.YOUR.DOMAIN;

add_header Alt-Svc 'h3=":443"; ma=86400' always;
ssl_certificate /etc/letsencrypt/live/cloud.YOUR.DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cloud.YOUR.DOMAIN/privkey.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

keepalive_requests 100000;
keepalive_timeout 5m;
http2_max_concurrent_streams 512;

root /var/www/certbot;
location ^~ /.well-known/acme-challenge/ { try_files $uri =404; }

location / {
proxy_pass http://wopi_backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_read_timeout 3600;
proxy_buffering off;
}
}
```

### Key differences from the HTTP/2 configuration

| Detail | HTTP/2 config | HTTP/3 config |
|---|---|---|
| Listen directives | `listen 443 ssl http2;` | `listen 443 quic;` + `listen 443 ssl;` + `http2 on;` |
| `reuseport` | Not needed | Required on the **first** `listen 443 quic` directive only |
| `Alt-Svc` header | Not needed | Required to advertise HTTP/3 to browsers |
| Upstream blocks | Inline `proxy_pass` to `127.0.0.1` | Named `upstream` blocks with `keepalive` |
| WebSocket upgrade | Per-location `Connection` / `Upgrade` | Global `map` directive |
| Firewall | TCP 443 only | TCP 443 **and** UDP 443 |

:::warning Firewall
HTTP/3 uses UDP port 443. Make sure your firewall allows **both** TCP and UDP traffic on port 443:

```bash
sudo ufw allow 443/tcp
sudo ufw allow 443/udp
```
:::