If/else based on ip


(Maciej świć) #1

Hi,
I am trying to invoke authentication only when a request comes from outside my LAN range. I have tried the following which if found somewhere in the documentation but it doesnt work. Unknown directive {{if

{{if not eq .Ip "10.0.0.10"}}
    basicauth / username **********
{{end}}

(dewey hylton) #2

Here are related notes from my testing several months ago; with luck, you may find something useful:

## produce 404 when requested by 10.0.0.36
ipfilter /private/ {
    rule block
    ip 10.0.0.36/32
}

## for non-local requests, returns page at / but does not show / in the address bar
rewrite /localonly/ {
        if {remote} not_starts_with 10.0.0.
        to /
    }

## for non-local requests, redirects to / and shows / in the address bar
redir 307 {
        if {remote} not_starts_with 10.0.0.
        /localonly2/ /
    }

## yes, redundant but shows we can redirect any non-local request anywhere we like
## wanted to test this to prove that caddy would be able to properly obtain a cert
## while blocking any other remote requests - and it worked flawlessly
redir 307 {
        if {remote} not_starts_with 10.0.0.
        / https://google.com
    }

(Matthew Fay) #3

One issue is that basicauth can’t really be scoped inside a site block except by base path.

If I recall correctly, the last time this came up, one recommendation was configuring two sites, e.g. secure.example.com and open.example.com, with a Caddyfile like:

open.example.com {
  # Serve site without auth
  root /var/www/html

  # Redirect non-LAN IPs to secure site
 redir {
    if {remote} not_starts_with "10."
    if {remote} not_starts_with "192.168."
    / https://secure.example.com{uri}
  }
}

secure.example.com {
  # Serve site with basicauth
  basicauth / username password
  root /var/www/html

  # Redirect LAN IPs to open site
 redir {
    if_op or
    if {remote} starts_with "10."
    if {remote} starts_with "192.168."
    / https://open.example.com{uri}
  }
}

(Matt Holt) #4

Also, templates can’t be used inside the Caddyfile, only in pages that are rendered to a client. :+1:


(Maciej świć) #5

What i ended up doing is the following. Each service has its own section after the ###### header. Just copy-paste and replace the values to add new reverse-proxies. This uses namecheap DNS-01 for SSL.

(auth) {
    basicauth / username password
}

(options) {
    gzip
    tls {
        dns namecheap
        wildcard
    }
}

(external) {
    redir 302 {
        if {remote} not_starts_with "10.0.0"
        if {remote} not_starts_with "10.0.1"
        if {remote} not_starts_with "10.0.2"
        if {remote} not_starts_with "10.0.3"
        / https://e-{host}{uri}
    }
}

############################################
# tracer.******.com
############################################

(tracer) {
    proxy / http://10.0.1.18:5800 {
        transparent
        insecure_skip_verify
    }
}

tracer.******.com {
    import options
    import external
    import tracer
}

e-tracer.******.com {
    import auth
    import options

    redir 302 {
        if {remote} starts_with "10.0"
        / https://tracer.******.com{uri}
    }

    import tracer
}