Cross-posted to: https://sh.itjust.works/post/14975166
Solution
I’m still not really sure exactly what the root cause of the issue was (I would appreciate it if someone could explain it to me), but I disabled HTTPS on the Nextcloud server
nextcloud.disable-https
and, all of a sudden, it started working. My Caddyfile simply contains the following:
nextcloud.domain.com {
server-LAN-ip:80
}
Original Post
I am trying to upgrade my existing Nextcloud server (installed as a Snap) so that it is sitting behind a reverse proxy. Originally, The Nextcloud server handled HTTPS with Let’s Encrypt at domain.com
; now, I would like for Caddy to handle HTTPS with Let’s Encrypt at nextcloud.domain.com
and to forward the traffic to the Nextcloud server.
With my current setup, I am encountering an error where it is saying 301 Moved Permanently
. Does anyone have any ideas on how to fix or troubleshoot this?
Caddyfile
:
https://nextcloud.domain.com {
reverse_proxy 192.168.1.182:443
header / Strict-Transport-Security max-age=31536000;
}
And here is the output of curl -v https://nextcloud.domain.com/
:
* Host nextcloud.domain.com:443 was resolved.
* IPv6: (none)
* IPv4: public-ip
* Trying public-ip:443...
* Connected to nextcloud.domain.com (public-ip) port 443
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: none
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_CHACHA20_POLY1305_SHA256 / x25519 / id-ecPublicKey
* ALPN: server accepted h2
* Server certificate:
* subject: CN=nextcloud.domain.com
* start date: Feb 21 06:09:01 2024 GMT
* expire date: May 21 06:09:00 2024 GMT
* subjectAltName: host "nextcloud.domain.com" matched cert's "nextcloud.domain.com"
* issuer: C=US; O=Let's Encrypt; CN=R3
* SSL certificate verify ok.
* Certificate level 0: Public key type EC/prime256v1 (256/128 Bits/secBits), signed using sha256WithRSAEncryption
* Certificate level 1: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* Certificate level 2: Public key type RSA (4096/152 Bits/secBits), signed using sha256WithRSAEncryption
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://nextcloud.domain.com/
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: nextcloud.domain.com]
* [HTTP/2] [1] [:path: /]
* [HTTP/2] [1] [user-agent: curl/8.6.0]
* [HTTP/2] [1] [accept: */*]
> GET / HTTP/2
> Host: nextcloud.domain.com
> User-Agent: curl/8.6.0
> Accept: */*
>
< HTTP/2 301
< alt-svc: h3="public-ip:443"; ma=2592000
< content-type: text/html; charset=iso-8859-1
< date: Wed, 21 Feb 2024 07:45:34 GMT
< location: https://nextcloud.domain.com:443/
< server: Caddy
< server: Apache
< strict-transport-security: max-age=31536000;
< content-length: 250
<
301 Moved Permanently
<h1>Moved Permanently</h1>
<p>The document has moved here.</p>
* Connection #0 to host nextcloud.domain.com left intact
Running
curl --location https://nextcloud.domain.com
results incurl: (47) Maximum (50) redirects followed
More than 50 redirects? Hmm, that looks weird. What is the output when you run
wget --spider https://nextcloud.domain.com
? Could you try enabling cookies for cURL and pasting the contents of thecookiefile
here?curl --cookie cookiefile --cookie-jar cookiefile --location https://nextcloud.domain.com
Here is the output of
wget --spider https://nextcloud.domain.com
:Spider mode enabled. Check if remote file exists. --2024-02-21 09:20:41-- https://nextcloud.domain.com/ Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' Resolving nextcloud.domain.com (nextcloud.domain.com)... public-ip Connecting to nextcloud.domain.com (nextcloud.domain.com)|public-ip|:443... connected. HTTP request sent, awaiting response... 301 Moved Permanently Location: https://nextcloud.domain.com:443/ [following] Spider mode enabled. Check if remote file exists. --2024-02-21 09:20:46-- https://nextcloud.domain.com/ Connecting to nextcloud.domain.com (nextcloud.domain.com)|public-ip|:443... connected. HTTP request sent, awaiting response... 301 Moved Permanently Location: https://nextcloud.domain.com:443/ [following] Spider mode enabled. Check if remote file exists. --2024-02-21 09:20:46-- https://nextcloud.domain.com/ Connecting to nextcloud.domain.com (nextcloud.domain.com)|public-ip|:443... connected. HTTP request sent, awaiting response... 301 Moved Permanently Location: https://nextcloud.domain.com:443/ [following] Spider mode enabled. Check if remote file exists. [...] [I deleted a bunch of repetitions] [...] --2024-02-21 09:20:48-- https://nextcloud.domain.com/ Connecting to nextcloud.domain.com (nextcloud.domain.com)|public-ip|:443... connected. HTTP request sent, awaiting response... 301 Moved Permanently Location: https://nextcloud.domain.com:443/ [following] 20 redirections exceeded.
And here is the contents of the cookie file (it is empty):
# Netscape HTTP Cookie File # https://curl.se/docs/http-cookies.html # This file was generated by libcurl! Edit at your own risk.
Yep, definitely something wrong with the webserver 😅 Can you try this configuration?
https://nextcloud.domain.com { reverse_proxy 192.168.1.182:443 { header_up Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" header_up X-Forwarded-Proto {scheme} header_up X-Forwarded-For {remote} header_up X-Real-IP {remote} } }
You said that “originally, the Nextcloud server handled HTTPS with Let’s Encrypt at
domain.com
” and now you are redirecting to192.168.1.182
on port443
. Is this Nextcloud server still serving HTTPS with Let’s Encrypt fordomain.com
?I’m asking because if you are using Caddy in front of that HTTPS webserver as a reverse-proxy, you will need to override the
Host
header with the configured upstream address. Here’s the documentation. I think it would be something like this (?):https://nextcloud.domain.com { reverse_proxy domain.com:443 { header_up Host {upstream_hostport} header_up Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" header_up X-Forwarded-Proto {scheme} header_up X-Forwarded-For {remote} header_up X-Real-IP {remote} } }
Your first configuration results in the following when I access
nextcluod.domain.com
from both within and outside the LAN:400 Bad Request Bad Request Your browser sent a request that this server could not understand. Reason: You're speaking plain HTTP to an SSL-enabled server port. Instead use the HTTPS scheme to access this URL, please.
This is an interesting response, because it’s what I see when I try to access the server from
192.168.1.182:443
from within the LAN. Which, I assume, is to be expected when a port has TLS enabled – one should access it from192.168.1.182:80
instead; however, when I modify your suggestion to be from port80
, rather than port443
, it results in the usual301 Moved Permanently Moved Permanently The document has moved https://nextcloud.domain.com:443/
Your second configuration results in the following when I access
nextcloud.domain.com
from both within and outside the LAN:Client sent an HTTP request to an HTTPS server.
Side note: I do still have the original HTTPS setup with Let’s Encrypt enabled on the Nextcloud server for
domain.com
. Is that causing the issue? I’d rather not disable that unless I need to, at the moment.