Need assistance with http.matchers.remote_ip usage

1. Output of caddy version:

v2.5.2 h1:eCJdLyEyAGzuQTa5Mh3gETnYWDClo1LjtQm2q9RNZrs=

2. How I run Caddy:

Runs as a service, primary config is /etc/caddy/Caddyfile which contains

import /etc/caddy/redirects/*.cnf

The purpose of this server is redirects and all of the files in the redirects directory are created by a script and are in this form:

fromDomain.tld www.fromDomain.tld {
	redir https://toDomain.tld{uri} permanent
}

We have no issues with this setup, it is an exception to this setup I am writing about.

a. System environment:

OS: AlmaLinux release 8.6 (Sky Tiger)
Kernel: 4.18.0-348.23.1.el8_5.x86_64
Headless server instance running in a VPC on AWS - EC2 instance t3a.medium
systemd 239 (239-58.el8_6.3)
No Docker, no desktop, no anything else really except for some custom created scripts for managing Route 53 zones and the redirects.

b. Command:

I don’t type anything to run it, it is a service. Service status is as follows

Alias tip: S status caddy
● caddy.service - Caddy
   Loaded: loaded (/usr/lib/systemd/system/caddy.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2022-08-09 06:16:45 PDT; 6 days ago
     Docs: https://caddyserver.com/docs/
 Main PID: 899223 (caddy)
    Tasks: 12 (limit: 12008)
   Memory: 57.2M
   CGroup: /system.slice/caddy.service
           └─899223 /usr/bin/caddy run --environ --config /etc/caddy/Caddyfile

If I add or remove a redirect my script either creates a new config file from a template or deletes the config file and then restarts the caddy service.

c. Service/unit/compose file:

N/A

d. My complete Caddy config:

As above

import /etc/caddy/redirects/*.cnf

and a sample config, because I am not going to post over 350 almost identical files

fromDomain.tld www.fromDomain.tld {
	redir https://toDomain.tld{uri} permanent

3. The problem I’m having:

I have a need to have one of the redirects behave differently, but only if the remote IP is a certain IP. I want it to act normally otherwise. I have read the documentation but I am still unsure how to go about this. So for this particular config file I have appended a line I got from (Request matchers (Caddyfile) — Caddy Documentation) to the top of the file, but then I don’t know what to do with it, and how to have any other IPs that doesn’t match just do the redirect.

Here is as far as I got before I got lost.

@pinger remote_ip 203.0.113.14

fromDomain.tld www.fromDomain.tld {
	redir https://toDomain.tld{uri} permanent

Once I have defined @pinger, then what do I do? What does the config file then look like. For example, if I wanted that one IP to serve a static web page on the file system, and all other IPs to just do the redirect, how would that look?

4. Error messages and/or full log output:

N/A

5. What I already tried:

Not much. I have read the following:
I’m new and can’t post links - /docs/caddyfile/matchers#remote-ip
I’m new and can’t post links - /docs/modules/http.matchers.remote_ip
I’m new and can’t post links - /docs/caddyfile/patterns
I’m new and can’t post links - /docs/caddyfile/directives

and I have no better idea how to proceed than I did before I read those pages.

6. Links to relevant resources:

Matchers must go inside of a site block. See the Caddyfile Concepts doc to understand the structure of a Caddyfile:

Then, you apply the matcher to a directive to make it do something when that matcher matches. You can also use the not matcher in front of any other matcher to invert the result.

Keep in mind directives are sorted according to predetermined order. The redir directive is high on the order, so if you use a directive with a lower order, it’ll be sorted after, so the redirect will always trigger anyways. There’s a bunch of ways to work around this, but it depends on your specific needs. Please elaborate on what you’re trying to do when the matcher does match, and we can probably help further.

What I am attempting to do is have the domain this config file belongs to behave normally (a 301 status redirect to another domain) unless the single IP address of a monitoring server makes the request. In that case I would like it to instead serve a static webpage which basically looks like this:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="refresh" content="1; URL='https://toDomain.tld/'">
    <title>Redirect to https://toDomain.tld/</title>
  </head>
  <body>
    <h1>Off to https://toDomain.tld/</h1>
  </body>
</html>

If you are really astute you will recognize that is just a client side redirect using meta refresh. The main difference is that to the monitoring server it is a Status 200 and load completion and not a Status 301 redirect. We need to do some code testing on the monitoring server, which is why I want that server to get the Status 200 and think it is done rather than follow the 301 redirect.

For the sake of this example the static file could be stored at /usr/share/www/toDomain.tld/index.html

Caddy supports doing an HTML redirect, btw, with the html option for redir.

But AFAIK it is broken in the current release, but a fix is coming for the next release. We never noticed it was broken until recently because we didn’t even know anyone still used it :rofl:

So you could just use the HTML redirect all the time for that one domain instead of doing a remote_ip match? Or if you must have different redirects for those IPs, you can use a matcher like this:

from-domain.tld {
	@pinger remote_ip 203.0.113.14
	redir @pinger https://toDomain.tld{uri} html
	redir https://toDomain.tld{uri} permanent
}

So basically this will return an html redirect for requests from that one IP, and a permanent redirect otherwise.

Thank you, that example is probably exactly what I am looking for.

We do want a 301 Permanent Redirect in almost every case. From an SEO perspective using an html redirect doesn’t carry any “link juice” and can actually hurt SEO performance if the client has more than one domain, but only one website. Also, Google can downrank you for html redirects as they are used heavily by bad websites to keep you from using the back button. So really the html redirect must be the exception and not the rule here.

Thank you very much.

This topic was automatically closed after 30 days. New replies are no longer allowed.