Useful Commands to Debug DNS Issues and Redirection Loops (Ubuntu, Apache, Letsencrypt)
Recently I decided to add a blog to my personal website. Now I can regularly share thoughts with everyone! The blog resides at https://mishurovsky.com/blog/, while the main page remains at https://mishurovsky.com.
The path to a working solution, however, was not easy. My website is a Next.js application hosted on Vercel, while the blog engine I chose is a PHP application requiring a separate Linux server with Apache and MariaDB. My initial intent was to lead all traffic through a self-hosted reverse proxy, which would direct /blog requests to the blog engine, and all other requests to the Vercel page. I did not manage to make it work, so I ended up hosting both PHP and Next.js apps from my own server.
But that wasn’t the end of the story. After migration, HTTP connection was OK, but whenever I tried to switch to HTTPS, the response was still served by Vercel, even though I deleted both my domain and project from there! It was not just a failing request, but a redirection loop, 308 to mishurovsky.com again and again and again. I spent two days debugging configs and waiting for DNS caches to clear.
Long story short, the problem was in my use of Letsencrypt: I launched it as
certbot --apache ...# instead of certbot certonly --apache ..., and Certbot created a separate HTTPS virtual host that reused an old configuration pointing to Vercel’s upstream. Apache prioritized this config over mine, causing a persistent redirect loop.
Helpful Commands to Debug DNS Problems and Redirection Loops
During this weekend journey, I discovered a lot of valuable commands to debug connectivity problems, which I want to share. Hopefully, these will help you, my reader, or me myself in some future.
1. Verbose cURL
curl -v https://example.comConnect to a website and get a verbose response. Helps to see HTTP response codes and SSL connectivity status.
2. cURL with redirects
curl -I -L https://example.comConnect to a website and get only headers in response + follow redirects. I used this countless times to examine if redirect loops persist.
3. Get site IP
dig +short example.comGet an ip for a website. Useful when checking if a website is indeed hosted from a rented server.
4. Show all Letsencrypt certificates
certbot certificatesList all Letsencrypt certificates on a server with their domains, expiration dates, and paths to private and public keys.
5. Review Apache config
apache2ctl -SAll the main Apache config details: virtual hosts and structure. The most interesting part is error section in the beginning of the output — this is where I found a reference to an additional config from Letsencrypt.
6. Examine Port Usage
ss -tuln | grep ':443'
lsof -i :443List all listening sockets (TCP/UDP), showing if port 443 is open. Then get a list of all process on port 443 (HTTPS).
7. Flush DNS Cache
Finally, Mac OS specific:
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponderThese two commands flush DNS cache on modern Macs, so DNS could be tested after updates. Requires to quit and re-start a browser after execution.