1. Caddy version (caddy version
):
v2.5.0 h1:eRHzZ4l3X6Ag3kUt8nj5IxATprhqKq/wToP7OHlXWA0=
2. How I run Caddy:
Nothing fancy, just the Caddy packages for Ubuntu. Currently on 20.04
a. System environment:
I use systemd to run Caddy (i.e. systemctl start/stop/restart caddy
)
b. Command:
See above
c. Service/unit/compose file:
I don’t know where this is unfortunately. I know I haven’t changed it though.
d. My complete Caddyfile or JSON config:
{
admin off
}
(logging) {
log {
output file /var/log/caddy/caddy.log {
roll_size 15mb
roll_keep 20
}
}
}
(errors) {
handle_errors {
root * /var/www/internal/errors
rewrite * /{http.error.status_code}.html
file_server
}
}
(php) {
php_fastcgi unix//run/php/php8.1-fpm.sock
}
www.telesphoreo.me {
import logging
redir https://telesphoreo.me{uri}
}
telesphoreo.me {
import logging
import errors
import php
root * /var/www/telesphoreo.me
file_server browse
encode gzip zstd
@denied path /assets/ /old_html/* /new_html/* /recyclebin/* /nitrogen/ /wave/
respond @denied 403
}
blog.telesphoreo.me {
import logging
import php
root * /var/www/blog.telesphoreo.me
file_server
encode gzip
}
db2.telesphoreo.me {
import logging
import php
root * /usr/share/phpmyadmin
file_server
}
nexus.telesphoreo.me {
reverse_proxy http://localhost:8082
}
panel.telesphoreo.me {
import logging
php_fastcgi unix//run/php/php8.0-fpm.sock
root * /var/www/pterodactyl/public
file_server
header X-Content-Type-Options nosniff
header X-XSS-Protection "1; mode=block"
header X-Robots-Tag none
header Content-Security-Policy "frame-ancestors 'self'"
header X-Frame-Options DENY
header Referrer-Policy same-origin
request_body {
max_size 100m
}
respond /.ht* 403
}
pictochat.telesphoreo.me {
import logging
reverse_proxy http://localhost:8080
}
wordle.telesphoreo.me {
import logging
root * /var/www/wordle.telesphoreo.me/games/wordle
file_server
encode gzip
}
ci.plex.us.org {
reverse_proxy http://localhost:8081
}
docs.plex.us.org {
import logging
redir https://plex.us.org{uri}
}
httpd.plex.us.org {
import logging
reverse_proxy 172.18.0.1:27192
}
plex.us.org {
import logging
root * /var/www/plexus.org/build
respond /updater/check/ "1.0.3"
file_server
}
forum.plex.us.org {
import logging
import php
root * /var/www/forum.plexus.org/public
file_server
header /assets {
+Cache-Control "public, must-revalidate, proxy-revalidate"
+Cache-Control "max-age=25000"
Pragma "public"
}
respond /.ht* 403
}
www.smokes-crystal.rocks {
import logging
redir https://smokes-crystal.rocks{uri}
}
smokes-crystal.rocks {
import logging
import errors
root * /var/www/smokes-crystal.rocks
file_server
}
3. The problem I’m having:
Basically, Error 404 codes are working, but Error 403 codes aren’t. I have it setup so it should return the error pages I’ve made instead of the default Chome. If you go to https://telesphoreo.me/404 for example, this is a page that does not exist. It correctly shows the error 404 page. However, if I go to a URL I’ve restricted such as https://telesphoreo.me/recyclebin, it will show the Chrome error 403 page. I can’t figure out why the same code for handling 404 doesn’t work on 403. It’s also important to note that if you add a directory to respond to 403 that doesn’t exist, it will actually (correctly) return 404. It’s technically correct that something that doesn’t exist is 404, but it ignores that I told it specifically to return 403.
4. Error messages and/or full log output:
Here’s a log of a 403 occuring
{"level":"error","ts":1651467493.0210693,"logger":"http.log.access.log1","msg":"handled request","request":{"remote_ip":"X.X.X.X","remote_port":"21212","proto":"HTTP/2.0","method":"GET","host":"telesphoreo.me","uri":"/recyclebin/","headers":{"Cf-Ipcountry":["US"],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Safari/537.36"],"Sec-Ch-Ua":["\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"101\", \"Google Chrome\";v=\"101\""],"Sec-Ch-Ua-Platform":["\"macOS\""],"Cf-Connecting-Ip":["45.79.1.27"],"Accept-Encoding":["gzip"],"Sec-Fetch-User":["?1"],"Cookie":[],"Cdn-Loop":["cloudflare"],"Sec-Fetch-Mode":["navigate"],"Sec-Ch-Ua-Mobile":["?0"],"Upgrade-Insecure-Requests":["1"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"],"X-Forwarded-Proto":["https"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"Sec-Fetch-Site":["none"],"Sec-Fetch-Dest":["document"],"Accept-Language":["en-US,en;q=0.9"],"X-Forwarded-For":["X.X.X.X"],"Cf-Ray":["704e2e35284e93d9-DFW"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"telesphoreo.me"}},"user_id":"","duration":0.00009629,"size":0,"status":403,"resp_headers":{"Server":["Caddy"],"Content-Type":[]}}
Here’s one of a 404
{"level":"error","ts":1651467413.3765965,"logger":"http.log.access.log1","msg":"handled request","request":{"remote_ip":"X.X.X.X","remote_port":"53448","proto":"HTTP/2.0","method":"GET","host":"telesphoreo.me","uri":"/404","headers":{"Cf-Ray":["704e2c436b8aa9f7-DFW"],"X-Forwarded-Proto":["https"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"Accept-Encoding":["gzip"],"Cdn-Loop":["cloudflare"],"Cf-Ipcountry":["US"],"X-Forwarded-For":["X.X.X.X"],"User-Agent":["curl/7.79.1"],"Accept":["*/*"],"Cf-Connecting-Ip":["X.X.X.X"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"telesphoreo.me"}},"user_id":"","duration":0.00014789,"size":946,"status":404,"resp_headers":{"Server":["Caddy"],"Etag":["\"rahx6rqa\""],"Content-Type":["text/html; charset=utf-8"],"Last-Modified":["Sun, 17 Apr 2022 18:11:15 GMT"],"Accept-Ranges":["bytes"],"Content-Length":["946"]}}
5. What I already tried:
I don’t have a good idea on where to start unfortunately. What I used to do before having the error handling code was actually remove the read permission for everyone on the folder itself. Part of the reason it’s sort of confusing is because I want people to have access to specific files if they know the URL, but not be able to list the whole directory. It’s also a problem if I remove the permission because if it’s asset files or something, it refuses to load on the webpage itself. So right now all the permissions are “normal” where everyone has read access to the folder. If the permissions are removed, it still returns the Chrome default error 403 page. While I would never go back to Apache, I preferred their granular control of limiting indexing / viewing of specific directories with .htaccess. I unfortunately don’t know how to test different error codes to see if it’s specifically 403 that doesn’t return the page.
ls -la
total 64
drwxr-xr-x 2 root root 4096 Jun 22 2021 .
drwxr-xr-x 3 root root 4096 Jun 22 2021 ..
-rw-r--r-- 1 root root 881 Jun 22 2021 400.html
-rw-r--r-- 1 root root 869 Jun 22 2021 401.html
-rw-r--r-- 1 root root 866 Jun 22 2021 403.html
-rw-r--r-- 1 root root 946 Apr 17 13:11 404.html
-rw-r--r-- 1 root root 891 Jun 22 2021 405.html
-rw-r--r-- 1 root root 941 Jun 22 2021 415.html
-rw-r--r-- 1 root root 785 Jun 22 2021 418.html
-rw-r--r-- 1 root root 861 Jun 22 2021 423.html
-rw-r--r-- 1 root root 886 Jun 22 2021 426.html
-rw-r--r-- 1 root root 911 Jun 22 2021 451.html
-rw-r--r-- 1 root root 864 Jun 22 2021 500.html
-rw-r--r-- 1 root root 868 Jun 22 2021 503.html
-rw-r--r-- 1 root root 917 Jun 22 2021 505.html
-rw-r--r-- 1 root root 926 Jun 22 2021 507.html
Here’s a listing of all the errors that are currently set up. I can’t think of anything to rename it to to yield different results. If I rename the working 404.html
to something invalid (like test.html
), it will return the default Chrome page. This leads me to believe a similar thing is happening here, but I genuinely can’t figure out what to name it to.
Appreciate any help. I seriously appreciate Caddy and the people behind it. You guys are awesome and have saved me an insane amount of trouble and time with Linux administration.
6. Links to relevant resources:
https://telesphoreo.me/404 ← should return 404
https://telesphoreo.me/recyclebin ← should return 403