<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0"
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
  xmlns:atom="http://www.w3.org/2005/Atom">

<channel>

<title>Blog — George Mishurovsky: posts tagged devops</title>
<link>https://mishurovsky.com/blog/?go=tags/devops/</link>
<description>A blog by George Mishurovsky — a senior software engineer with a medical degree. Drawing from both engineering and scientific thinking, he explores software, architecture, design, psychology, and product thinking.</description>
<author></author>
<language>en</language>
<generator>Aegea 11.3 (v4134e)</generator>

<itunes:owner>
<itunes:name></itunes:name>
<itunes:email>george@mishurovsky.com</itunes:email>
</itunes:owner>
<itunes:subtitle>A blog by George Mishurovsky — a senior software engineer with a medical degree. Drawing from both engineering and scientific thinking, he explores software, architecture, design, psychology, and product thinking.</itunes:subtitle>
<itunes:image href="https://mishurovsky.com/blog/pictures/userpic/userpic-square@2x.jpg?1753619610" />
<itunes:explicit>no</itunes:explicit>

<item>
<title>Bookshelf update — September 2026</title>
<guid isPermaLink="false">54</guid>
<link>https://mishurovsky.com/blog/?go=all/bookshelf-update-september-2026/</link>
<pubDate>Thu, 10 Sep 2026 14:10:52 +0200</pubDate>
<author></author>
<comments>https://mishurovsky.com/blog/?go=all/bookshelf-update-september-2026/</comments>
<description>
&lt;p&gt;I haven’t updated my book list for half a year. So, here is what I’ve read recently and can recommend — there are some gems in the list.&lt;/p&gt;
&lt;h3&gt;1. Unit Testing Principles, Practices, and Patterns — V. Khorikov&lt;/h3&gt;
&lt;p&gt;Of all the titles in the list, this impresses me the most. Despite the name, it covers all types of automated behavioural tests: unit, integration, and end-to-end. It changed my approach to code organization and my view of which tests deserve a place in a codebase. The book is also helpful in today’s drift towards agentic coding, guided by spec-driven development and TDD.&lt;br /&gt;
&lt;a href="https://www.oreilly.com/library/view/unit-testing-principles/9781617296277/"&gt;Link to the book&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;2. Fundamentals of Software Architecture — N. Ford&lt;/h3&gt;
&lt;p&gt;Software engineering is often described as a craft. One reason is the many decisions developers make based on what they once saw, heard, or practiced. I believe that proficiency comes with awareness of all possible tools. Awareness turns choices into deliberate informed decisions. This book explains software architecture methodology and provides the starting set of tools for architects.&lt;br /&gt;
&lt;a href="https://www.oreilly.com/library/view/fundamentals-of-software/9781492043447/"&gt;Link to the book&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;3. C# 12 in a Nutshell — J. Albahari&lt;/h3&gt;
&lt;p&gt;A great source for exhaustive knowledge of C#. It reads better than I could expect from a book focused on details of a complex language. Still took me more than a month to complete. Again, awareness of internal functioning and available options leads to elegant solutions, efficient and maintainable code. Definitely a must read for senior-level C# developers. I also tried ‘Pro C#’ by A. W. Troelsen, but its 1600 pages found my head to be too small for comfortable living.&lt;br /&gt;
&lt;a href="https://www.oreilly.com/library/view/c-12-in/9781098147433/"&gt;Link to the book&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;4. ASP.NET Core in Action — A. Lock&lt;/h3&gt;
&lt;p&gt;This book is much harder to read than the previous one. It is not supposed to be read from start to end — and I had to shortcut my reading process and skip some sections. For those starting with ASP.NET, selective reading provides a good explanation of how things work and many code snippets ready for use as starting points.&lt;br /&gt;
&lt;a href="https://www.manning.com/books/asp-net-core-in-action-third-edition/"&gt;Link to the book&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;5. Accelerate — N. Forsgren&lt;/h3&gt;
&lt;p&gt;My science-inclined heart fills with joy when I see a properly designed longitudinal study with a powerful sample size in the tech industry. The study is a solid justification of DevOps practices in software development. A logical relation is the one between software delivery performance and performance-focused organizational culture. The interesting part is that implementation of DevOps is highly likely to transform the culture as well, despite the latter is a much broader concept.&lt;br /&gt;
&lt;a href="https://www.oreilly.com/library/view/accelerate/9781457191435/"&gt;Link to the book&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;6. On Writing Well — W. Zinsser&lt;/h3&gt;
&lt;p&gt;Clarity of writing means clarity of thought. This book does not provide exact writing instructions, but enables freedom and desire for writing — in any style, about any subject. It is a relaxing, slow, and amusing read, breaking the line of a tech reading list. Although it put my vocabulary to work: many words come from non-fiction world of American literature, which I rarely encounter in technical media.&lt;br /&gt;
&lt;a href="https://www.goodreads.com/book/show/53343.On_Writing_Well"&gt;Link to the book&lt;/a&gt;&lt;/p&gt;
</description>
</item>

<item>
<title>How to View Past Terminal Commands — from Simple to Robust</title>
<guid isPermaLink="false">5</guid>
<link>https://mishurovsky.com/blog/?go=all/how-to-quickly-retrieve-past-terminal-commands/</link>
<pubDate>Sun, 03 Aug 2025 14:18:24 +0200</pubDate>
<author></author>
<comments>https://mishurovsky.com/blog/?go=all/how-to-quickly-retrieve-past-terminal-commands/</comments>
<description>
&lt;p&gt;Suppose you want to re-run a shell command you used ten days ago. It was complex one; you do not remember exact flags and arguments, so it is going take a long time to reconstruct an exact text. What can you do?&lt;/p&gt;
&lt;h2&gt;1. The upwards arrow&lt;/h2&gt;
&lt;p&gt;Majority of devs know it. Press “up” to see the previous command, press “down” for the next command, press “Ctrl+C” to drop whatever is in the prompt and start fresh.&lt;/p&gt;
&lt;p&gt;This approach works, but gets tedious when you need to find a line you used last month. Once more than ten or twenty commands have passed, scrolling becomes no better than writing a command from scratch.&lt;/p&gt;
&lt;h2&gt;2. Terminal history file&lt;/h2&gt;
&lt;p&gt;All the commands you enter into a terminal get stored in &lt;span class="inline-code"&gt;.bash_history&lt;/span&gt; file (or &lt;span class="inline-code"&gt;.zsh_history&lt;/span&gt; if you are on Mac) up to a certain limit. Thus, you can run:&lt;/p&gt;
&lt;div class="e2-code-block" data-language="shell"&gt;&lt;div class="e2-code-header"&gt;&lt;span class="e2-code-language"&gt;Shell&lt;/span&gt;&lt;button class="e2-code-copy" type="button" aria-label="Copy code to clipboard" data-copy-text="Copy" data-copied-text="Copied!" data-failed-text="Failed"&gt;&lt;span class="e2-svgi"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"&gt;&lt;mask id="cutout"&gt;&lt;rect width="100%" height="100%" fill="white"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" stroke-width="1.33" rx="1" fill="black" stroke="black"/&gt;&lt;/mask&gt;&lt;rect x="5.25" y="1.75" width="9" height="9" rx="1" stroke-width="1.33" fill="none" mask="url(#cutout)"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" rx="1" stroke-width="1.33" fill="none"/&gt;&lt;/svg&gt;
&lt;/span&gt;Copy&lt;/button&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class="hljs language-shell"&gt;cat ~/.bash_history # output all into the terminal
less ~/.bash_history # or use any text viewer
tail -n 20 ~/.bash_history # or observe only the most recent n lines
cat ~/.bash_history | grep whatever # to search for specific patterns&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This method gives you full access to your history file and lets you see context around commands of interest, plus now you can search for them.&lt;/p&gt;
&lt;h2&gt;3. &lt;span class="inline-code"&gt;history&lt;/span&gt; command&lt;/h2&gt;
&lt;p&gt;Almost the same as using the history file directly: you get a list commands, but now it is &lt;i&gt;numbered&lt;/i&gt;.&lt;/p&gt;
&lt;div class="e2-code-block" data-language="shell"&gt;&lt;div class="e2-code-header"&gt;&lt;span class="e2-code-language"&gt;Shell&lt;/span&gt;&lt;button class="e2-code-copy" type="button" aria-label="Copy code to clipboard" data-copy-text="Copy" data-copied-text="Copied!" data-failed-text="Failed"&gt;&lt;span class="e2-svgi"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"&gt;&lt;mask id="cutout"&gt;&lt;rect width="100%" height="100%" fill="white"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" stroke-width="1.33" rx="1" fill="black" stroke="black"/&gt;&lt;/mask&gt;&lt;rect x="5.25" y="1.75" width="9" height="9" rx="1" stroke-width="1.33" fill="none" mask="url(#cutout)"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" rx="1" stroke-width="1.33" fill="none"/&gt;&lt;/svg&gt;
&lt;/span&gt;Copy&lt;/button&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class="hljs language-shell"&gt;history -20 # show the last 20 commands
history -500 | grep ssh # search for a specific patter in a command
!780 # execute command with order number 780&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But there is one important difference from direct usage of &lt;span class="inline-code"&gt;.bash_history&lt;/span&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="inline-code"&gt;history&lt;/span&gt; command uses the last &lt;span class="inline-code"&gt;HISTSIZE&lt;/span&gt; history entries (default 1000)&lt;/li&gt;
&lt;li&gt;&lt;span class="inline-code"&gt;.bash_history&lt;/span&gt; file uses the last &lt;span class="inline-code"&gt;HISTFILESIZE&lt;/span&gt; entries (default 2000)&lt;br /&gt;
It means that if your command was run a really long time ago, &lt;span class="inline-code"&gt;history&lt;/span&gt; may not find it. The line though, is still persisted, so direct inspection of &lt;span class="inline-code"&gt;.bash_history&lt;/span&gt; will help.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;4. &lt;span class="inline-code"&gt;fc -l&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;This command behaves very similar to &lt;span class="inline-code"&gt;history&lt;/span&gt;, with an additional ability to display ranges of command numbers::&lt;/p&gt;
&lt;div class="e2-code-block" data-language="shell"&gt;&lt;div class="e2-code-header"&gt;&lt;span class="e2-code-language"&gt;Shell&lt;/span&gt;&lt;button class="e2-code-copy" type="button" aria-label="Copy code to clipboard" data-copy-text="Copy" data-copied-text="Copied!" data-failed-text="Failed"&gt;&lt;span class="e2-svgi"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"&gt;&lt;mask id="cutout"&gt;&lt;rect width="100%" height="100%" fill="white"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" stroke-width="1.33" rx="1" fill="black" stroke="black"/&gt;&lt;/mask&gt;&lt;rect x="5.25" y="1.75" width="9" height="9" rx="1" stroke-width="1.33" fill="none" mask="url(#cutout)"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" rx="1" stroke-width="1.33" fill="none"/&gt;&lt;/svg&gt;
&lt;/span&gt;Copy&lt;/button&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class="hljs language-shell"&gt;fc -l -20 # show the last 20 commands
fc -l 100 150 # show commands 100 to 150&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2&gt;5. Reverse-i-search&lt;/h2&gt;
&lt;p&gt;This is the most powerful approach. Press “Ctrl+R” to enter &lt;i&gt;reverse incremental search&lt;/i&gt; mode. Initially you get no output; start writing any part of a command you remember, e. g. &lt;span class="inline-code"&gt;ssh&lt;/span&gt; or &lt;span class="inline-code"&gt;input.json&lt;/span&gt; or &lt;span class="inline-code"&gt;-n 10&lt;/span&gt; — and you will see the first full command entry with that match!&lt;/p&gt;
&lt;p&gt;From there, you can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Press “Enter” to execute the command immediately&lt;/li&gt;
&lt;li&gt;Use left/right arrow keys to move within a command to edit it, then press “Enter” to execute&lt;/li&gt;
&lt;li&gt;Press “Ctrl+R” again to go to the next, older match&lt;/li&gt;
&lt;li&gt;Press “Ctrl+S” to go to the previous, newer match (note a comment below)&lt;/li&gt;
&lt;li&gt;Press up-down arrows to view to nearby entries in history around the match&lt;/li&gt;
&lt;li&gt;Press “Ctrl+C” or “Ctrl+G” to exit the search&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On many systems “Ctrl+S” shortcut will not work, as it is prioritized to pause terminal output (if that happens to you, press “Ctrl+Q” to resume). To make it work for reverse-i-search, add &lt;span class="inline-code"&gt;stty -ixon&lt;/span&gt; to your shell config. This incantation disables terminal flow control with “Ctrl+S” / “Ctrl+Q” shortcuts:&lt;/p&gt;
&lt;div class="e2-code-block" data-language="shell"&gt;&lt;div class="e2-code-header"&gt;&lt;span class="e2-code-language"&gt;Shell&lt;/span&gt;&lt;button class="e2-code-copy" type="button" aria-label="Copy code to clipboard" data-copy-text="Copy" data-copied-text="Copied!" data-failed-text="Failed"&gt;&lt;span class="e2-svgi"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"&gt;&lt;mask id="cutout"&gt;&lt;rect width="100%" height="100%" fill="white"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" stroke-width="1.33" rx="1" fill="black" stroke="black"/&gt;&lt;/mask&gt;&lt;rect x="5.25" y="1.75" width="9" height="9" rx="1" stroke-width="1.33" fill="none" mask="url(#cutout)"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" rx="1" stroke-width="1.33" fill="none"/&gt;&lt;/svg&gt;
&lt;/span&gt;Copy&lt;/button&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class="hljs language-shell"&gt;echo &amp;quot;stty -ixon&amp;quot; &amp;gt;&amp;gt; ~/.bashrc
source ~/.bashrc&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Happy command line manipulation!&lt;/p&gt;
&lt;p&gt;💡 This post has a second part: &lt;a href="https://mishurovsky.com/blog/all/shell-configs-for-better-command-history-search/"&gt;Shell Configs for Better Command History Search&lt;/a&gt;&lt;/p&gt;
</description>
</item>

<item>
<title>Useful Commands to Debug DNS Issues and Redirection Loops (Ubuntu, Apache, Letsencrypt)</title>
<guid isPermaLink="false">1</guid>
<link>https://mishurovsky.com/blog/?go=all/diagnosing-dns-and-redirection-issues-ubuntu-apache-letsencrypt/</link>
<pubDate>Sun, 27 Jul 2025 20:32:29 +0200</pubDate>
<author></author>
<comments>https://mishurovsky.com/blog/?go=all/diagnosing-dns-and-redirection-issues-ubuntu-apache-letsencrypt/</comments>
<description>
&lt;p&gt;Recently I decided to add a blog to my personal website. Now I can regularly share thoughts with everyone! The blog resides at &lt;a href="https://mishurovsky.com/blog/,"&gt;https://mishurovsky.com/blog/,&lt;/a&gt; while the main page remains at &lt;a href="https://mishurovsky.com."&gt;https://mishurovsky.com.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Long story short, the problem was in my use of Letsencrypt: I launched it as&lt;/p&gt;
&lt;div class="e2-code-block" data-language="shell"&gt;&lt;div class="e2-code-header"&gt;&lt;span class="e2-code-language"&gt;Shell&lt;/span&gt;&lt;button class="e2-code-copy" type="button" aria-label="Copy code to clipboard" data-copy-text="Copy" data-copied-text="Copied!" data-failed-text="Failed"&gt;&lt;span class="e2-svgi"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"&gt;&lt;mask id="cutout"&gt;&lt;rect width="100%" height="100%" fill="white"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" stroke-width="1.33" rx="1" fill="black" stroke="black"/&gt;&lt;/mask&gt;&lt;rect x="5.25" y="1.75" width="9" height="9" rx="1" stroke-width="1.33" fill="none" mask="url(#cutout)"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" rx="1" stroke-width="1.33" fill="none"/&gt;&lt;/svg&gt;
&lt;/span&gt;Copy&lt;/button&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class="hljs language-shell"&gt;certbot --apache ...# instead of certbot certonly --apache ...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;, 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.&lt;/p&gt;
&lt;h2&gt;Helpful Commands to Debug DNS Problems and Redirection Loops&lt;/h2&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;1. Verbose cURL&lt;/h3&gt;
&lt;div class="e2-code-block" data-language="shell"&gt;&lt;div class="e2-code-header"&gt;&lt;span class="e2-code-language"&gt;Shell&lt;/span&gt;&lt;button class="e2-code-copy" type="button" aria-label="Copy code to clipboard" data-copy-text="Copy" data-copied-text="Copied!" data-failed-text="Failed"&gt;&lt;span class="e2-svgi"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"&gt;&lt;mask id="cutout"&gt;&lt;rect width="100%" height="100%" fill="white"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" stroke-width="1.33" rx="1" fill="black" stroke="black"/&gt;&lt;/mask&gt;&lt;rect x="5.25" y="1.75" width="9" height="9" rx="1" stroke-width="1.33" fill="none" mask="url(#cutout)"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" rx="1" stroke-width="1.33" fill="none"/&gt;&lt;/svg&gt;
&lt;/span&gt;Copy&lt;/button&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class="hljs language-shell"&gt;curl -v https://example.com&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Connect to a website and get a &lt;b&gt;verbose&lt;/b&gt; response. Helps to see HTTP response codes and SSL connectivity status.&lt;/p&gt;
&lt;h3&gt;2. cURL with redirects&lt;/h3&gt;
&lt;div class="e2-code-block" data-language="shell"&gt;&lt;div class="e2-code-header"&gt;&lt;span class="e2-code-language"&gt;Shell&lt;/span&gt;&lt;button class="e2-code-copy" type="button" aria-label="Copy code to clipboard" data-copy-text="Copy" data-copied-text="Copied!" data-failed-text="Failed"&gt;&lt;span class="e2-svgi"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"&gt;&lt;mask id="cutout"&gt;&lt;rect width="100%" height="100%" fill="white"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" stroke-width="1.33" rx="1" fill="black" stroke="black"/&gt;&lt;/mask&gt;&lt;rect x="5.25" y="1.75" width="9" height="9" rx="1" stroke-width="1.33" fill="none" mask="url(#cutout)"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" rx="1" stroke-width="1.33" fill="none"/&gt;&lt;/svg&gt;
&lt;/span&gt;Copy&lt;/button&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class="hljs language-shell"&gt;curl -I -L https://example.com&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Connect to a website and get only &lt;b&gt;headers&lt;/b&gt; in response + &lt;b&gt;follow redirects&lt;/b&gt;. I used this countless times to examine if redirect loops persist.&lt;/p&gt;
&lt;h3&gt;3. Get site IP&lt;/h3&gt;
&lt;div class="e2-code-block" data-language="shell"&gt;&lt;div class="e2-code-header"&gt;&lt;span class="e2-code-language"&gt;Shell&lt;/span&gt;&lt;button class="e2-code-copy" type="button" aria-label="Copy code to clipboard" data-copy-text="Copy" data-copied-text="Copied!" data-failed-text="Failed"&gt;&lt;span class="e2-svgi"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"&gt;&lt;mask id="cutout"&gt;&lt;rect width="100%" height="100%" fill="white"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" stroke-width="1.33" rx="1" fill="black" stroke="black"/&gt;&lt;/mask&gt;&lt;rect x="5.25" y="1.75" width="9" height="9" rx="1" stroke-width="1.33" fill="none" mask="url(#cutout)"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" rx="1" stroke-width="1.33" fill="none"/&gt;&lt;/svg&gt;
&lt;/span&gt;Copy&lt;/button&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class="hljs language-shell"&gt;dig +short example.com&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Get an ip for a website. Useful when checking if a website is indeed hosted from a rented server.&lt;/p&gt;
&lt;h3&gt;4. Show all Letsencrypt certificates&lt;/h3&gt;
&lt;div class="e2-code-block" data-language="shell"&gt;&lt;div class="e2-code-header"&gt;&lt;span class="e2-code-language"&gt;Shell&lt;/span&gt;&lt;button class="e2-code-copy" type="button" aria-label="Copy code to clipboard" data-copy-text="Copy" data-copied-text="Copied!" data-failed-text="Failed"&gt;&lt;span class="e2-svgi"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"&gt;&lt;mask id="cutout"&gt;&lt;rect width="100%" height="100%" fill="white"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" stroke-width="1.33" rx="1" fill="black" stroke="black"/&gt;&lt;/mask&gt;&lt;rect x="5.25" y="1.75" width="9" height="9" rx="1" stroke-width="1.33" fill="none" mask="url(#cutout)"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" rx="1" stroke-width="1.33" fill="none"/&gt;&lt;/svg&gt;
&lt;/span&gt;Copy&lt;/button&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class="hljs language-shell"&gt;certbot certificates&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;List all Letsencrypt certificates on a server with their domains, expiration dates, and paths to private and public keys.&lt;/p&gt;
&lt;h3&gt;5. Review Apache config&lt;/h3&gt;
&lt;div class="e2-code-block" data-language="shell"&gt;&lt;div class="e2-code-header"&gt;&lt;span class="e2-code-language"&gt;Shell&lt;/span&gt;&lt;button class="e2-code-copy" type="button" aria-label="Copy code to clipboard" data-copy-text="Copy" data-copied-text="Copied!" data-failed-text="Failed"&gt;&lt;span class="e2-svgi"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"&gt;&lt;mask id="cutout"&gt;&lt;rect width="100%" height="100%" fill="white"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" stroke-width="1.33" rx="1" fill="black" stroke="black"/&gt;&lt;/mask&gt;&lt;rect x="5.25" y="1.75" width="9" height="9" rx="1" stroke-width="1.33" fill="none" mask="url(#cutout)"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" rx="1" stroke-width="1.33" fill="none"/&gt;&lt;/svg&gt;
&lt;/span&gt;Copy&lt;/button&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class="hljs language-shell"&gt;apache2ctl -S&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;6. Examine Port Usage&lt;/h3&gt;
&lt;div class="e2-code-block" data-language="shell"&gt;&lt;div class="e2-code-header"&gt;&lt;span class="e2-code-language"&gt;Shell&lt;/span&gt;&lt;button class="e2-code-copy" type="button" aria-label="Copy code to clipboard" data-copy-text="Copy" data-copied-text="Copied!" data-failed-text="Failed"&gt;&lt;span class="e2-svgi"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"&gt;&lt;mask id="cutout"&gt;&lt;rect width="100%" height="100%" fill="white"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" stroke-width="1.33" rx="1" fill="black" stroke="black"/&gt;&lt;/mask&gt;&lt;rect x="5.25" y="1.75" width="9" height="9" rx="1" stroke-width="1.33" fill="none" mask="url(#cutout)"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" rx="1" stroke-width="1.33" fill="none"/&gt;&lt;/svg&gt;
&lt;/span&gt;Copy&lt;/button&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class="hljs language-shell"&gt;ss -tuln | grep &amp;#039;:443&amp;#039;
lsof -i :443&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;List all listening sockets (TCP/UDP), showing if port 443 is open. Then get a list of all process on port 443 (HTTPS).&lt;/p&gt;
&lt;h3&gt;7. Flush DNS Cache&lt;/h3&gt;
&lt;p&gt;Finally, Mac OS specific:&lt;/p&gt;
&lt;div class="e2-code-block" data-language="shell"&gt;&lt;div class="e2-code-header"&gt;&lt;span class="e2-code-language"&gt;Shell&lt;/span&gt;&lt;button class="e2-code-copy" type="button" aria-label="Copy code to clipboard" data-copy-text="Copy" data-copied-text="Copied!" data-failed-text="Failed"&gt;&lt;span class="e2-svgi"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"&gt;&lt;mask id="cutout"&gt;&lt;rect width="100%" height="100%" fill="white"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" stroke-width="1.33" rx="1" fill="black" stroke="black"/&gt;&lt;/mask&gt;&lt;rect x="5.25" y="1.75" width="9" height="9" rx="1" stroke-width="1.33" fill="none" mask="url(#cutout)"/&gt;&lt;rect x="1.75" y="5.25" width="9" height="9" rx="1" stroke-width="1.33" fill="none"/&gt;&lt;/svg&gt;
&lt;/span&gt;Copy&lt;/button&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class="hljs language-shell"&gt;sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;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.&lt;/p&gt;
</description>
</item>


</channel>
</rss>