Custom YOURLS
Like many people, my teams at work have to deal with a lot of esoteric, computer-generated URLs for various resources. Thanks, Microsoft. Nobody can ever remember them, nobody remembers to bookmark them, and those that do get saved or linked to from elsewhere get broken when someone in another team deletes and then recreates the original file.
That last one is the worst, because there are so many places we may have linked to a resource it's impossible to go back and update them all. It's particularly annoying if they've been turned into a QR code or link on a poster somewhere.
That's why we love YOURLS, the self-hosted URL shortening service. When something breaks we go and fix it in one place, and everything is fine again.
Fallback Redirect
By default, if YOURLS doesn't have a short URL in its database for a request it'll bounce you back to the top level of the domain it's configured on. However, it doesn't do this with the request URI intact. Just the plain jane domain, which is a shame.
But custom plug-ins are supported, so here's yourls-fallback-redirect, my take on solving that problem. Now any unknown URL redirects to the domain of your choosing, with the URI intact so it can be dealt with as you see fit. This is great for shortening long domain names without any other faff required. In fact, you can see it in action with blw.rs/custom-yourls.
Files First
As people got familiar with using our domain we decided to use it to host some static files. The type of files that are rarely update but really important, like insurance certificates, which need to be accessible to anyone outside of the organisation at the drop of a hat, and not locked behind unreliable share links.
For some added fun, I'm an Nginx person and not really up to speed with Apache, so here's how to make this combination work, using the BirdsLikeWires YOURLS installation as an example.
server {
http2 on;
listen 443 ssl;
server_name www.blw.rs;
ssl_certificate /etc/nginx/ssl/blw.rs.cer;
ssl_certificate_key /etc/nginx/ssl/blw.rs.key;
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
return 301 https://blw.rs$request_uri;
}
server {
http2 on;
listen 443 ssl;
server_name blw.rs;
root /var/www/blw/root;
ssl_certificate /etc/nginx/ssl/blw.rs.cer;
ssl_certificate_key /etc/nginx/ssl/blw.rs.key;
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
set $php_sock unix:/var/run/php/php8.4-fpm.sock;
index index.php index.html;
# Redirect /admin to /yourls/admin
location = /admin {
return 301 /yourls/admin/;
}
location ^~ /admin/ {
return 301 /yourls$request_uri;
}
# Explicitly handle /yourls/ to prevent rewrite loop
location ^~ /yourls/ {
try_files $uri $uri/ /yourls/yourls-loader.php$is_args$args;
location ~ \.php$ {
fastcgi_pass $php_sock;
include fastcgi.conf;
}
}
location / {
try_files $uri $uri/ @rewrite_to_yourls;
}
location @rewrite_to_yourls {
rewrite ^/(.*)$ /yourls/$1 last;
}
location ~ \.php$ {
fastcgi_pass $php_sock;
include fastcgi.conf;
}
location ~ /\.ht {
deny all;
}
}
Explanation
The first server block just redirects any traffic from the www subdomain to the apex.
The second block sets up the certificates, then allows me to run YOURLS in a subdirectory. This makes updating the installation far easier, as I just need to drop in the new release, update the plug-ins, and create a new link to it.
ln -s /var/www/blw/root/YOURLS-1.XX.X /var/www/blw/root/yourls
Following all that, Nginx will first attempt to fetch files locally. If this fails, it'll pass the request on to YOURLS to deal with. Due to our plugin, this will either succeed with a short URL, or it'll fail and be passed on to whichever other domain we configured.
The last bit is to not serve .htaccess files, in case there are any lurking which shouldn't be.
Conclusion
Works really well.
You'll notice there's nothing hosted on port 80, the traditional HTTP port. I'm using acme.sh to request certificates based upon DNS entries, so I thought I'd lock off that port in the firewall and not bother with HTTP for this service.