Follow this blog

Software engineering, design, and psychology

Later Ctrl + ↑

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

Shell
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

Shell
curl -v https://example.com

Connect to a website and get a verbose response. Helps to see HTTP response codes and SSL connectivity status.

2. cURL with redirects

Shell
curl -I -L https://example.com

Connect 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

Shell
dig +short example.com

Get an ip for a website. Useful when checking if a website is indeed hosted from a rented server.

4. Show all Letsencrypt certificates

Shell
certbot certificates

List all Letsencrypt certificates on a server with their domains, expiration dates, and paths to private and public keys.

5. Review Apache config

Shell
apache2ctl -S

All 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

Shell
ss -tuln | grep ':443'
lsof -i :443

List 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:

Shell
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

These 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.