Nextcloud backup failed, problem with routing?

Started by pascal585, August 21, 2023, 09:27:59 PM

Previous topic - Next topic
Hey guys,

I installed on my new OPNsense the Nextcloud backup plugin and tried to configure it. The backup failed.

Following error messages are in General logs:

2023-08-21T20:48:27 Error php-cgi{"url":"https:\/\/cloud.xyz\/remote.php\/dav\/files\/opnsense\/","content_type":null,"http_code":0,"header_size":0,"request_size":0,"filetime":-1,"ssl_verify_result":0,"redirect_count":0,"total_time":60.023131,"namelookup_time":10.073269,"connect_time":0,"pretransfer_time":0,"size_upload":0,"size_download":0,"speed_download":0,"speed_upload":0,"download_content_length":-1,"upload_content_length":-1,"starttransfer_time":0,"redirect_time":0,"redirect_url":"","primary_ip":"","certinfo":[],"primary_port":0,"local_ip":"","local_port":0,"http_version":0,"protocol":0,"ssl_verifyresult":0,"scheme":"","appconnect_time_us":0,"connect_time_us":0,"namelookup_time_us":10073269,"pretransfer_time_us":0,"redirect_time_us":0,"starttransfer_time_us":0,"total_time_us":60023131,"effective_method":"PROPFIND"}

2023-08-21T20:48:27 Error php-cgi Error while fetching filelist from Nextcloud '/.' path

2023-08-21T20:47:27 Error php-cgi {"url":"https:\/\/cloud.xyz\/ocs\/v1.php\/cloud\/user","content_type":null,"http_code":0,"header_size":0,"request_size":0,"filetime":-1,"ssl_verify_result":0,"redirect_count":0,"total_time":60.025292,"namelookup_time":10.192918,"connect_time":0,"pretransfer_time":0,"size_upload":0,"size_download":0,"speed_download":0,"speed_upload":0,"download_content_length":-1,"upload_content_length":-1,"starttransfer_time":0,"redirect_time":0,"redirect_url":"","primary_ip":"","certinfo":[],"primary_port":0,"local_ip":"","local_port":0,"http_version":0,"protocol":0,"ssl_verifyresult":0,"scheme":"","appconnect_time_us":0,"connect_time_us":0,"namelookup_time_us":10192918,"pretransfer_time_us":0,"redirect_time_us":0,"starttransfer_time_us":0,"total_time_us":60025292,"effective_method":"GET"}

2023-08-21T20:47:27 Error php-cgi Cannot get real username


The nextcloud instance is behind a reverse proxy in my home lab that is reachable over the WAN IP address, port 443. The reverse proxy has a trusted letsencrypt certificate for the Nextcloud instance.

Port forwarding and NAT reflection are enabled, clients are able to communicate with Nextcloud and all other services behind reverse proxy.

The OPNsense is unable to ping the Nextcloud domain. nslookup works with dnsmasq and Unbound DNS. Traceroute without result, no hops. Same problem with my other public services behind the reverse proxy. All other websites of the internet are reachable, firmware updates are no problem for example.

In my opinion it must be a routing problem. Maybe because destination IP is same to the IP of WAN interface?

I would be very happy to get some tips or solutions for my problem.

Best regards
Pascal

August 22, 2023, 08:04:11 AM #1 Last Edit: October 26, 2023, 03:46:00 PM by Monviech
Maybe this can help you?

https://forum.opnsense.org/index.php?topic=34925.0

I have the same Setup with reverse Proxy and Nextcloud Backup, so I know it should work if Hairpinning is configured right.

EDIT:
It seems the packet hits the loopback interface of the opnsense. And when I DNAT on the loopback interface there is Destination Host Unreachable. So what was missing is an additional SNAT to masquerade the traffic from loopback to WAN.

An alternative pragmatic option would be to force the opnsense to use the internal IP Address by using split DNS.

EDIT EDIT:
Got ICMP to work with the loopback interface of the opnsense to the NATed destination. So I'm sure these rules should work if you create additional ones for TCP:

ICMP Rules:

Firewall: NAT: Outbound
Interface: Loopback
TCP/IP Version: IPv4
Protocol: ICMP
Source address: 127.0.0.1/32
Source port: any
Destination address: WAN address
Destination port: any
Translation / target: WAN address

Firewall: NAT: Port Forward
Interface: Loopback
TCP/IP Version: IPv4
Protocol: ICMP
Source address: This Firewall
Source port: any
Destination address: WAN address
Destination port: any
Redirect target IP: Internal IP of Reverse proxy (e.g. 10.0.0.203)


TCP Rules:

Firewall: NAT: Outbound
Interface: Loopback
TCP/IP Version: IPv4
Protocol: TCP
Source address: 127.0.0.1/32
Source port: any
Destination address: WAN address
Destination port: 443
Translation / target: WAN address

Firewall: NAT: Port Forward
Interface: Loopback
TCP/IP Version: IPv4
Protocol: TCP
Source address: This Firewall
Source port: any
Destination address: WAN address
Destination port: 443
Redirect target IP: Internal IP of Reverse proxy (e.g. 10.0.0.203)

EDIT Again:

Nope the above also doesn't work. I can't get the DNAT rules to match on the Loopback interface. I recommend split DNS or IPv6.
Hardware:
DEC740

August 22, 2023, 03:39:03 PM #2 Last Edit: August 23, 2023, 07:48:43 AM by Monviech
I recommend doing it like this with a host override to circumvent this problem: https://forum.opnsense.org/index.php?topic=35540.0

The root of the problem seems to be the following:

In the code
https://github.com/opnsense/plugins/tree/master/sysutils/nextcloud-backup/src/opnsense/mvc/app/library/OPNsense/Backup
            array(
                "name" => "url",
                "type" => "text",
                "label" => gettext("URL"),
                "help" => gettext("The Base URL to Nextcloud without trailing slash. For example: https://cloud.example.com"),
                "value" => null
            ),

the $url is getting defined.

Down lower the curl request is made:
$result = $this->curl_request(
            "$url/remote.php/dav/files/$internal_username$directory",


This curl request results in the Opnsense resolving the URL to the A record of the cloud.example.com. If this results in an external IP Address that's bound to the Opnsense, the routing table sends the request to loopback lo0. The source IP is "$external_ip" and the destination IP is also "$external_ip". This results in the packet not being routed any further.

If the code would have the option to use the "--header" trigger in curl, it could be passed directly to the internal IP and there would be no routing problem.
curl --header "Host: cloud.example.com" -k https://192.168.178.10


Hardware:
DEC740