<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Janak Shrestha</title>
    <description>The latest articles on DEV Community by Janak Shrestha (@janak0ff).</description>
    <link>https://dev.to/janak0ff</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F669804%2F8baf407d-13b3-4a51-888b-808a72d4ef8f.jpg</url>
      <title>DEV Community: Janak Shrestha</title>
      <link>https://dev.to/janak0ff</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/janak0ff"/>
    <language>en</language>
    <item>
      <title>Clone Git Repository on Storage Server</title>
      <dc:creator>Janak Shrestha</dc:creator>
      <pubDate>Tue, 06 Oct 2026 05:25:01 +0000</pubDate>
      <link>https://dev.to/janak0ff/clone-git-repository-on-storage-server-55hn</link>
      <guid>https://dev.to/janak0ff/clone-git-repository-on-storage-server-55hn</guid>
      <description>&lt;p&gt;The DevOps team established a new Git repository last week, which remains unused at present. However, the Nautilus application development team now requires a copy of this repository on the Storage Server in the Stratos DC. Follow the provided details to clone the repository:&lt;/p&gt;

&lt;p&gt;The repository to be cloned is located at /opt/cluster.git&lt;/p&gt;

&lt;p&gt;Clone this Git repository to the /usr/src/kodekloudrepos directory. Perform this task using the natasha user, and ensure that no modifications are made to the repository or existing directories, such as changing permissions or making unauthorized alterations.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: SSH Into the Storage Server
&lt;/h2&gt;

&lt;p&gt;From the jump host, connect to the Storage Server as &lt;code&gt;natasha&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh natasha@ststor01        &lt;span class="c"&gt;# password: Bl@kW&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the hostname doesn't resolve, use the server's IP address instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh natasha@10.244.49.64    &lt;span class="c"&gt;# password: Bl@kW&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once connected, you'll see a prompt like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[natasha@ststor01 ~]$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Navigate to the Target Directory
&lt;/h2&gt;

&lt;p&gt;Move into the directory where the repository should be cloned:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/src/kodekloudrepos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify you're in the right place:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/usr/src/kodekloudrepos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Clone the Repository
&lt;/h2&gt;

&lt;p&gt;Clone the bare repository from &lt;code&gt;/opt/cluster.git&lt;/code&gt; into the current directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone /opt/cluster.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cloning into 'cluster'...
warning: You appear to have cloned an empty repository.
done.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;ℹ️ &lt;strong&gt;Note:&lt;/strong&gt; The "empty repository" warning is completely normal. It simply means the repository has no commits yet — the clone itself was successful.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This creates a new folder named &lt;code&gt;cluster&lt;/code&gt; inside &lt;code&gt;/usr/src/kodekloudrepos&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Verify the Clone
&lt;/h2&gt;

&lt;p&gt;Move into the cloned directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the remote configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;origin  /opt/cluster.git (fetch)
origin  /opt/cluster.git (push)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm the directory contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see the &lt;code&gt;.git/&lt;/code&gt; directory — this is the working copy of the repository.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Confirm Ownership
&lt;/h2&gt;

&lt;p&gt;Ensure everything is owned by &lt;code&gt;natasha&lt;/code&gt;, since the clone was performed under that user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /usr/src/kodekloudrepos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;drwxr-xr-x 3 natasha natasha 4096 Oct  6 05:18 cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And inside the cloned folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /usr/src/kodekloudrepos/cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;drwxr-xr-x 3 natasha natasha 4096 Oct  6 05:18 .
drwxr-xr-x 3 natasha natasha 4096 Oct  6 05:18 ..
drwxr-xr-x 6 natasha natasha 4096 Oct  6 05:18 .git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every entry should show &lt;code&gt;natasha natasha&lt;/code&gt; — confirming the clone is correctly owned. ✅&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6 (Optional): Document the Clone with a Heredoc
&lt;/h2&gt;

&lt;p&gt;If you want to leave a log or note file describing the clone, use a &lt;strong&gt;heredoc&lt;/strong&gt; to write it without opening an editor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;' &amp;gt; clone-info.txt
Repository cloned: /opt/cluster.git
Destination:      /usr/src/kodekloudrepos/cluster
Cloned by user:   natasha
Date:             &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;
Notes:
  - Bare source repo, non-bare working copy.
  - No permissions or ownership were modified.
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;clone-info.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ Only create this file if your task allows adding new files. If the instructions say "no modifications," skip this step.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Recap: What We Did
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;SSH'd into the Storage Server as &lt;code&gt;natasha&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Navigated to &lt;code&gt;/usr/src/kodekloudrepos&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Cloned &lt;code&gt;/opt/cluster.git&lt;/code&gt; with &lt;code&gt;git clone&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Verified the remote with &lt;code&gt;git remote -v&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Confirmed ownership with &lt;code&gt;ls -la&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;(Optional) Documented the clone using a heredoc&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Common Pitfalls to Avoid
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pitfall&lt;/th&gt;
&lt;th&gt;Why It's a Problem&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Using &lt;code&gt;git init&lt;/code&gt; instead of &lt;code&gt;git clone&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Creates a brand-new empty repo, not a copy of the source&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloning as the wrong user&lt;/td&gt;
&lt;td&gt;Files will be owned by that user, breaking team access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adding &lt;code&gt;sudo&lt;/code&gt; unnecessarily&lt;/td&gt;
&lt;td&gt;Files become root-owned, causing permission issues&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Worrying about "empty repository" warning&lt;/td&gt;
&lt;td&gt;This is expected for repos without commits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modifying permissions with &lt;code&gt;chmod&lt;/code&gt;/&lt;code&gt;chown&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Often prohibited; not needed when cloning as the right user&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Clone as the correct user&lt;/strong&gt; — ownership follows whoever runs the command.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;git clone &amp;lt;path&amp;gt;&lt;/code&gt; works with local paths&lt;/strong&gt;, not just URLs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The "empty repository" warning is not an error.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Always verify with &lt;code&gt;git remote -v&lt;/code&gt; and &lt;code&gt;ls -la&lt;/code&gt;.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use heredocs (&lt;code&gt;&amp;lt;&amp;lt;'EOF'&lt;/code&gt;) to write files cleanly&lt;/strong&gt; without opening an editor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid unnecessary &lt;code&gt;sudo&lt;/code&gt;&lt;/strong&gt; — it changes file ownership.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>git</category>
    </item>
    <item>
      <title>Set Up Git Repository on Storage Server</title>
      <dc:creator>Janak Shrestha</dc:creator>
      <pubDate>Mon, 05 Oct 2026 09:25:00 +0000</pubDate>
      <link>https://dev.to/janak0ff/set-up-git-repository-on-storage-server-347g</link>
      <guid>https://dev.to/janak0ff/set-up-git-repository-on-storage-server-347g</guid>
      <description>&lt;p&gt;The Nautilus development team has provided requirements to the DevOps team for a new application development project, specifically requesting the establishment of a Git repository. Follow the instructions below to create the Git repository on the Storage server in the Stratos DC:&lt;/p&gt;

&lt;p&gt;Utilize yum to install the git package on the Storage Server.&lt;br&gt;
Create a bare repository named /opt/games.git (ensure exact name usage).&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 1: SSH Into the Remote Server
&lt;/h2&gt;

&lt;p&gt;First, connect to your server from your local machine (or jump host):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh natasha@ststor01
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When prompted, enter the user's password. Once connected, you'll see something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[natasha@ststor01 ~]$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Tip:&lt;/strong&gt; If your server has a hostname that doesn't resolve, use the IP address instead:&lt;/p&gt;


&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh natasha@10.244.164.10
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 2: Elevate to Root (or Use sudo)
&lt;/h2&gt;

&lt;p&gt;Installing system packages and writing to &lt;code&gt;/opt&lt;/code&gt; requires elevated privileges. Switch to the root user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your prompt will change to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[root@ststor01 ~]#
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Security Note:&lt;/strong&gt; In production environments, prefer using &lt;code&gt;sudo&lt;/code&gt; for individual commands rather than staying logged in as root. We use &lt;code&gt;sudo -i&lt;/code&gt; here for simplicity.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 3: Install Git Using yum
&lt;/h2&gt;

&lt;p&gt;Now install the &lt;code&gt;git&lt;/code&gt; package with &lt;code&gt;yum&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see yum resolve dependencies and install Git along with required packages. Here's what a successful install looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dependencies resolved.
================================================================================
 Package              Architecture   Version             Repository      Size
================================================================================
Installing:
 git                  x86_64         2.52.0-1.el9        appstream       39 k
Installing dependencies:
 git-core             x86_64         2.52.0-1.el9        appstream      5.0 M
 git-core-doc         noarch         2.52.0-1.el9        appstream      3.1 M
 less                 x86_64         590-6.el9           baseos         162 k
 perl-Error           noarch         1:0.17029-7.el9     appstream       42 k
 perl-Git             noarch         2.52.0-1.el9        appstream       37 k
 perl-TermReadKey     x86_64         2.38-11.el9         appstream       37 k
 perl-lib             noarch         0.65-484.el9        baseos          13 k
================================================================================
...
Complete!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify the Installation
&lt;/h3&gt;

&lt;p&gt;Confirm Git is installed and check the version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git version 2.52.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Git is now installed.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Create the Bare Repository
&lt;/h2&gt;

&lt;p&gt;This is the core step. We'll use &lt;code&gt;git init --bare&lt;/code&gt; to create a repository &lt;strong&gt;without a working directory&lt;/strong&gt; — the correct approach for a central server repo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git init &lt;span class="nt"&gt;--bare&lt;/span&gt; /opt/games.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see output similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hint: Using 'master' as the name for the initial branch. This default branch name
hint: will change to "main" in Git 3.0. To configure the initial branch name
hint: to use in all of your new repositories, which will suppress this warning,
hint: call:
hint:
hint:   git config --global init.defaultBranch &amp;lt;name&amp;gt;
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint:   git branch -m &amp;lt;name&amp;gt;
hint:
hint: Disable this message with "git config set advice.defaultBranchName false"
Initialized empty Git repository in /opt/games.git/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🤔 What Is a "Bare" Repository?
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Normal Repo&lt;/th&gt;
&lt;th&gt;Bare Repo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Working directory&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;.git&lt;/code&gt; folder&lt;/td&gt;
&lt;td&gt;Nested inside project&lt;/td&gt;
&lt;td&gt;Repo &lt;strong&gt;is&lt;/strong&gt; the folder&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Purpose&lt;/td&gt;
&lt;td&gt;Local development&lt;/td&gt;
&lt;td&gt;Central server / remote&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Created with&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git init --bare&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A bare repo is what you'd typically use as the &lt;strong&gt;remote&lt;/strong&gt; on GitHub, GitLab, or a self-hosted Git server. It has no files to edit — only the version history.&lt;/p&gt;

&lt;h3&gt;
  
  
  ℹ️ About the "master" Hint Message
&lt;/h3&gt;

&lt;p&gt;Don't panic — that's &lt;strong&gt;just a hint, not an error&lt;/strong&gt;. Git is letting you know its default branch name is &lt;code&gt;master&lt;/code&gt; and will become &lt;code&gt;main&lt;/code&gt; in Git 3.0. Your repository is fully functional.&lt;/p&gt;

&lt;p&gt;To suppress the hint globally in the future:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; init.defaultBranch main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 5: Verify the Repository
&lt;/h2&gt;

&lt;p&gt;Confirm the repo was created with the correct structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /opt/games.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;total 36
drwxr-xr-x 6 root root 4096 Oct  5 09:20 .
drwxr-xr-x 1 root root 4096 Oct  5 09:20 ..
-rw-r--r-- 1 root root   23 Oct  5 09:20 HEAD
-rw-r--r-- 1 root root   66 Oct  5 09:20 config
-rw-r--r-- 1 root root   73 Oct  5 09:20 description
drwxr-xr-x 2 root root 4096 Oct  5 09:20 hooks
drwxr-xr-x 2 root root 4096 Oct  5 09:20 info
drwxr-xr-x 4 root root 4096 Oct  5 09:20 objects
drwxr-xr-x 4 root root 4096 Oct  5 09:20 refs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What Each Entry Means
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Entry&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;HEAD&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Points to the default branch (&lt;code&gt;master&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;config&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Repository configuration settings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;description&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Human-readable description (used by GitWeb)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hooks/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Server-side hook scripts (pre-receive, post-receive, etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;info/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contains &lt;code&gt;exclude&lt;/code&gt; patterns and refs info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;objects/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stores all commits, trees, and blobs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;refs/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Branch and tag references&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Notice there are &lt;strong&gt;no source files&lt;/strong&gt; — that's exactly what makes this a bare repo. ✅&lt;/p&gt;

&lt;h3&gt;
  
  
  Confirm "Bare" Mode Is Enabled
&lt;/h3&gt;

&lt;p&gt;Check the config file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /opt/games.git/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[core]&lt;/span&gt;
        &lt;span class="py"&gt;repositoryformatversion&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;0&lt;/span&gt;
        &lt;span class="py"&gt;filemode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;
        &lt;span class="py"&gt;bare&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key line is &lt;code&gt;bare = true&lt;/code&gt; — this confirms Git treats it as a server-side repository. ✅&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6 (Optional): Set Ownership for Team Access
&lt;/h2&gt;

&lt;p&gt;If multiple team members need to push/pull, adjust ownership and permissions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; natasha:natasha /opt/games.git
&lt;span class="nb"&gt;chmod&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; 755 /opt/games.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a shared team, consider creating a dedicated &lt;code&gt;git&lt;/code&gt; group:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;groupadd git
usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; git natasha
&lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; :git /opt/games.git
&lt;span class="nb"&gt;chmod&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; 775 /opt/games.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 7 (Optional): Test the Repository From Another Machine
&lt;/h2&gt;

&lt;p&gt;From any other server with SSH access and Git installed, try cloning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone natasha@ststor01:/opt/games.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cloning into 'games'...
warning: You appear to have cloned an empty repository.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This warning is &lt;strong&gt;expected&lt;/strong&gt; — you've cloned a fresh, empty bare repo. Everything is working. 🎉&lt;/p&gt;




&lt;h2&gt;
  
  
  Recap: What We Did
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;SSH'd into the remote server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Elevated privileges with &lt;code&gt;sudo -i&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Installed Git via &lt;code&gt;yum install -y git&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Created the bare repo with &lt;code&gt;git init --bare /opt/games.git&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Verified the repo structure and &lt;code&gt;bare = true&lt;/code&gt; config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;(Optional) Set ownership for team access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;(Optional) Tested cloning from another machine&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Common Pitfalls to Avoid
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;❌ &lt;strong&gt;Forgetting &lt;code&gt;--bare&lt;/code&gt;&lt;/strong&gt; → creates a normal repo, which breaks push workflows (you'll see "refusing to update checked out branch" errors).&lt;/li&gt;
&lt;li&gt;❌ &lt;strong&gt;Using the wrong path&lt;/strong&gt; → task requirements often specify exact paths like &lt;code&gt;/opt/games.git&lt;/code&gt;; a typo means failure.&lt;/li&gt;
&lt;li&gt;❌ &lt;strong&gt;Not using &lt;code&gt;sudo&lt;/code&gt;&lt;/strong&gt; → permission denied when writing to &lt;code&gt;/opt&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;❌ &lt;strong&gt;Confusing the hint message with an error&lt;/strong&gt; → the &lt;code&gt;master&lt;/code&gt; hint is harmless.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You now have a fully functional &lt;strong&gt;bare Git repository&lt;/strong&gt; hosted on a remote Linux server, ready to be used as a central code hub for your team. This setup forms the backbone of self-hosted Git workflows and is a fundamental skill for any DevOps engineer.&lt;/p&gt;

&lt;p&gt;From here, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add &lt;strong&gt;Git hooks&lt;/strong&gt; for CI/CD automation&lt;/li&gt;
&lt;li&gt;Configure &lt;strong&gt;SSH key authentication&lt;/strong&gt; for passwordless access&lt;/li&gt;
&lt;li&gt;Front it with &lt;strong&gt;Gitolite&lt;/strong&gt; or &lt;strong&gt;Gitea&lt;/strong&gt; for a full-featured experience&lt;/li&gt;
&lt;li&gt;Wire it into a &lt;strong&gt;Jenkins pipeline&lt;/strong&gt; for automated builds&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
    </item>
    <item>
      <title>Application Security</title>
      <dc:creator>Janak Shrestha</dc:creator>
      <pubDate>Tue, 29 Sep 2026 06:24:53 +0000</pubDate>
      <link>https://dev.to/janak0ff/application-security-1o4i</link>
      <guid>https://dev.to/janak0ff/application-security-1o4i</guid>
      <description>&lt;p&gt;We have a backup management application UI hosted on Nautilus's backup server in Stratos DC. That backup management application code is deployed under Apache on the backup server itself, and Nginx is running as a reverse proxy on the same server. Apache and Nginx ports are 8088 and 8099, respectively. We have to install the iptables firewall on the server. Make the appropriate changes to fulfill the requirements mentioned below:&lt;/p&gt;

&lt;p&gt;We want to open all incoming connections to Nginx's port and block all incoming connections to Apache's port. Also make sure rules are per&lt;br&gt;
&lt;strong&gt;Tags&lt;/strong&gt;: Linux, iptables, Firewall, Security, Nginx, Apache, System Administration, Networkingmanent.&lt;/p&gt;


&lt;h1&gt;
  
  
  Configuring iptables Firewall on Linux: Allow Nginx and Block Apache
&lt;/h1&gt;
&lt;h2&gt;
  
  
  A Complete Step-by-Step Guide for System Administrators
&lt;/h2&gt;


&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Firewall configuration is a critical aspect of server security. In Linux environments, iptables is a powerful tool for controlling incoming and outgoing network traffic. It allows administrators to define rules that determine which connections are allowed and which are blocked.&lt;/p&gt;

&lt;p&gt;This guide walks through a real-world scenario where the backup management application on the Nautilus backup server needed specific firewall rules. The goal was to allow all incoming connections to Nginx (port 8099) while blocking all incoming connections to Apache (port 8088), with rules made permanent.&lt;/p&gt;


&lt;h2&gt;
  
  
  Environment Details
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Server&lt;/td&gt;
&lt;td&gt;stbkp01&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User&lt;/td&gt;
&lt;td&gt;clint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password&lt;/td&gt;
&lt;td&gt;H@wk3y3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nginx Port&lt;/td&gt;
&lt;td&gt;8099&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apache Port&lt;/td&gt;
&lt;td&gt;8088&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Purpose&lt;/td&gt;
&lt;td&gt;Backup management application UI&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  Understanding iptables
&lt;/h2&gt;
&lt;h3&gt;
  
  
  What is iptables
&lt;/h3&gt;

&lt;p&gt;iptables is a command-line firewall utility that uses policy chains to allow or block network traffic. It is part of the Netfilter framework in the Linux kernel and provides a flexible way to define firewall rules.&lt;/p&gt;
&lt;h3&gt;
  
  
  Key Concepts
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Table&lt;/td&gt;
&lt;td&gt;Collection of chains (filter, nat, mangle)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chain&lt;/td&gt;
&lt;td&gt;List of rules (INPUT, OUTPUT, FORWARD)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rule&lt;/td&gt;
&lt;td&gt;Condition and action for matching packets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Target&lt;/td&gt;
&lt;td&gt;Action taken when a rule matches (ACCEPT, DROP, REJECT)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Policy&lt;/td&gt;
&lt;td&gt;Default action if no rule matches&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  iptables Chains
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Chain&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;INPUT&lt;/td&gt;
&lt;td&gt;Incoming packets to the local system&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OUTPUT&lt;/td&gt;
&lt;td&gt;Outgoing packets from the local system&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FORWARD&lt;/td&gt;
&lt;td&gt;Packets routed through the system&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Common Targets
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Target&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ACCEPT&lt;/td&gt;
&lt;td&gt;Allow the packet to pass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DROP&lt;/td&gt;
&lt;td&gt;Silently discard the packet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;REJECT&lt;/td&gt;
&lt;td&gt;Discard and send an error response&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LOG&lt;/td&gt;
&lt;td&gt;Log the packet and continue&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before beginning, ensure the following are available:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSH access to the backup server with sudo or root privileges&lt;/li&gt;
&lt;li&gt;Knowledge of the ports used by Nginx and Apache&lt;/li&gt;
&lt;li&gt;Basic understanding of Linux networking&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Step 1: Connect to the Backup Server
&lt;/h2&gt;

&lt;p&gt;Access the server using SSH.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh clint@stbkp01
Password: H@wk3y3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Switch to root to perform administrative tasks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo su -
Password: H@wk3y3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Install iptables
&lt;/h2&gt;

&lt;p&gt;Install the iptables packages using the package manager.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; iptables iptables-services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The installation may include additional packages depending on the system.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;iptables&lt;/td&gt;
&lt;td&gt;Core firewall utility&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;iptables-services&lt;/td&gt;
&lt;td&gt;Service files for systemd&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;iptables-legacy&lt;/td&gt;
&lt;td&gt;Legacy compatibility layer&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Verify the installation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rpm &lt;span class="nt"&gt;-q&lt;/span&gt; iptables-services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Check Current iptables Rules
&lt;/h2&gt;

&lt;p&gt;View the current rules before making changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iptables &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the output shows empty chains, no rules are currently defined.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Flush Existing Rules
&lt;/h2&gt;

&lt;p&gt;Clear any existing rules to start with a clean configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iptables &lt;span class="nt"&gt;-F&lt;/span&gt;
iptables &lt;span class="nt"&gt;-X&lt;/span&gt;
iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-F&lt;/span&gt;
iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-X&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Command Breakdown
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;iptables -F&lt;/td&gt;
&lt;td&gt;Flush all rules in the filter table&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;iptables -X&lt;/td&gt;
&lt;td&gt;Delete all user-defined chains&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;iptables -t nat -F&lt;/td&gt;
&lt;td&gt;Flush rules in the nat table&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;iptables -t nat -X&lt;/td&gt;
&lt;td&gt;Delete user-defined chains in nat table&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Step 5: Set Default Policies
&lt;/h2&gt;

&lt;p&gt;Set the default policy for each chain. For this task, the default policy is ACCEPT, and specific rules will handle blocking.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iptables &lt;span class="nt"&gt;-P&lt;/span&gt; INPUT ACCEPT
iptables &lt;span class="nt"&gt;-P&lt;/span&gt; FORWARD ACCEPT
iptables &lt;span class="nt"&gt;-P&lt;/span&gt; OUTPUT ACCEPT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why Start with ACCEPT
&lt;/h3&gt;

&lt;p&gt;Starting with ACCEPT ensures you do not lock yourself out of the server. Specific DROP rules are then added for the ports that need blocking.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: Allow Established and Related Connections
&lt;/h2&gt;

&lt;p&gt;Allow responses to outgoing connections. Without this rule, the server cannot receive return traffic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-m&lt;/span&gt; state &lt;span class="nt"&gt;--state&lt;/span&gt; ESTABLISHED,RELATED &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This rule is essential for normal network operations, including SSH sessions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 7: Allow Loopback Interface
&lt;/h2&gt;

&lt;p&gt;Allow traffic on the loopback interface for local communication.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-i&lt;/span&gt; lo &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Many services communicate internally via &lt;code&gt;127.0.0.1&lt;/code&gt;. Blocking loopback can cause unexpected failures.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 8: Allow SSH
&lt;/h2&gt;

&lt;p&gt;Allow SSH connections to prevent being locked out of the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 22 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Always allow SSH before adding any DROP rules.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 9: Allow Nginx Port
&lt;/h2&gt;

&lt;p&gt;Allow all incoming connections to Nginx on port 8099.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 8099 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Command Breakdown
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;-A INPUT&lt;/td&gt;
&lt;td&gt;Append rule to INPUT chain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-p tcp&lt;/td&gt;
&lt;td&gt;Match TCP protocol&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--dport 8099&lt;/td&gt;
&lt;td&gt;Match destination port 8099&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-j ACCEPT&lt;/td&gt;
&lt;td&gt;Accept matching packets&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Step 10: Block Apache Port
&lt;/h2&gt;

&lt;p&gt;Block all incoming connections to Apache on port 8088.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 8088 &lt;span class="nt"&gt;-j&lt;/span&gt; DROP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why DROP Instead of REJECT
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Target&lt;/th&gt;
&lt;th&gt;Behavior&lt;/th&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DROP&lt;/td&gt;
&lt;td&gt;Silently discards packets&lt;/td&gt;
&lt;td&gt;Security (hides service existence)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;REJECT&lt;/td&gt;
&lt;td&gt;Sends error response&lt;/td&gt;
&lt;td&gt;User-friendly (tells client port is closed)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;DROP is preferred for security because it does not reveal that a service is running on the port.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 11: Save the Rules Permanently
&lt;/h2&gt;

&lt;p&gt;Save the rules so they persist across reboots.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;service iptables save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On some systems, the &lt;code&gt;service&lt;/code&gt; command may not be available. Use &lt;code&gt;iptables-save&lt;/code&gt; instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iptables-save &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/sysconfig/iptables
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the saved rules.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/sysconfig/iptables
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*filter
:INPUT ACCEPT [34:2440]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [32:4704]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m tcp --dport 8099 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 8088 -j DROP
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
COMMIT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 12: Enable the iptables Service
&lt;/h2&gt;

&lt;p&gt;Enable the iptables service to load rules on boot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;iptables
systemctl start iptables
systemctl status iptables
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;● iptables.service - IPv4 firewall with iptables
     Loaded: loaded (/usr/lib/systemd/system/iptables.service; enabled)
     Active: active (exited) since Tue 2026-09-29 06:17:03 UTC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 13: Verify the Rules
&lt;/h2&gt;

&lt;p&gt;List all rules with line numbers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iptables &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;--line-numbers&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination         
1    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
2    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
3    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8099
4    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8088
5    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 14: Test the Configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Test Nginx (Should Work)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://localhost:8099/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx/1.20.1&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;text/html&lt;/span&gt;
&lt;span class="na"&gt;Content-Length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2713881&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Test Apache (Should Be Blocked)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://localhost:8088/ &lt;span class="nt"&gt;--connect-timeout&lt;/span&gt; 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output (external connection).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl: (7) Failed to connect to localhost port 8088: Connection timed out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Important Note on Local Testing
&lt;/h3&gt;

&lt;p&gt;Testing from &lt;code&gt;localhost&lt;/code&gt; may not accurately reflect the DROP rule due to how the loopback interface is handled. To properly test the block, run the curl command from an external host such as the jump host.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# From jump host&lt;/span&gt;
curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://stbkp01:8088/ &lt;span class="nt"&gt;--connect-timeout&lt;/span&gt; 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Complete Workflow Summary
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Connect to server&lt;/span&gt;
ssh clint@stbkp01
&lt;span class="nb"&gt;sudo &lt;/span&gt;su -

&lt;span class="c"&gt;# 2. Install iptables&lt;/span&gt;
yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; iptables iptables-services

&lt;span class="c"&gt;# 3. Flush existing rules&lt;/span&gt;
iptables &lt;span class="nt"&gt;-F&lt;/span&gt;
iptables &lt;span class="nt"&gt;-X&lt;/span&gt;
iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-F&lt;/span&gt;
iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-X&lt;/span&gt;

&lt;span class="c"&gt;# 4. Set default policies&lt;/span&gt;
iptables &lt;span class="nt"&gt;-P&lt;/span&gt; INPUT ACCEPT
iptables &lt;span class="nt"&gt;-P&lt;/span&gt; FORWARD ACCEPT
iptables &lt;span class="nt"&gt;-P&lt;/span&gt; OUTPUT ACCEPT

&lt;span class="c"&gt;# 5. Allow established connections&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-m&lt;/span&gt; state &lt;span class="nt"&gt;--state&lt;/span&gt; ESTABLISHED,RELATED &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# 6. Allow loopback&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-i&lt;/span&gt; lo &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# 7. Allow SSH&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 22 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# 8. Allow Nginx&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 8099 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# 9. Block Apache&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 8088 &lt;span class="nt"&gt;-j&lt;/span&gt; DROP

&lt;span class="c"&gt;# 10. Save rules&lt;/span&gt;
iptables-save &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/sysconfig/iptables

&lt;span class="c"&gt;# 11. Enable service&lt;/span&gt;
systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;iptables
systemctl start iptables

&lt;span class="c"&gt;# 12. Verify&lt;/span&gt;
iptables &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;--line-numbers&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Verification Checklist
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Expected&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;iptables installed&lt;/td&gt;
&lt;td&gt;rpm -q iptables-services&lt;/td&gt;
&lt;td&gt;Installed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nginx port allowed&lt;/td&gt;
&lt;td&gt;iptables -L -n | grep 8099&lt;/td&gt;
&lt;td&gt;ACCEPT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apache port blocked&lt;/td&gt;
&lt;td&gt;iptables -L -n | grep 8088&lt;/td&gt;
&lt;td&gt;DROP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rules saved&lt;/td&gt;
&lt;td&gt;cat /etc/sysconfig/iptables&lt;/td&gt;
&lt;td&gt;Rules present&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service enabled&lt;/td&gt;
&lt;td&gt;systemctl is-enabled iptables&lt;/td&gt;
&lt;td&gt;enabled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nginx accessible&lt;/td&gt;
&lt;td&gt;curl -I &lt;a href="http://localhost:8099/" rel="noopener noreferrer"&gt;http://localhost:8099/&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;HTTP 200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apache blocked&lt;/td&gt;
&lt;td&gt;curl -I &lt;a href="http://stbkp01:8088/" rel="noopener noreferrer"&gt;http://stbkp01:8088/&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;Timeout&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Troubleshooting Common Issues
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Issue 1: service Command Not Found
&lt;/h3&gt;

&lt;p&gt;On newer systems, the &lt;code&gt;service&lt;/code&gt; command may be deprecated. Use &lt;code&gt;iptables-save&lt;/code&gt; instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iptables-save &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/sysconfig/iptables
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue 2: Rules Not Persisting After Reboot
&lt;/h3&gt;

&lt;p&gt;Ensure the iptables service is enabled and the rules are saved.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;iptables
iptables-save &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/sysconfig/iptables
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue 3: Locked Out of Server
&lt;/h3&gt;

&lt;p&gt;If you lose SSH access, access the server through the console and flush the rules.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iptables &lt;span class="nt"&gt;-F&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue 4: Nginx Not Accessible
&lt;/h3&gt;

&lt;p&gt;Check rule order. Ensure the Nginx ACCEPT rule comes before any DROP rule.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iptables &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;--line-numbers&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue 5: Apache Still Accessible Externally
&lt;/h3&gt;

&lt;p&gt;Verify the DROP rule is present and positioned correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iptables &lt;span class="nt"&gt;-L&lt;/span&gt; INPUT &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;--line-numbers&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Always allow SSH before adding any DROP rules.&lt;/li&gt;
&lt;li&gt;Test rules from an external host to confirm blocking works.&lt;/li&gt;
&lt;li&gt;Save rules immediately after making changes.&lt;/li&gt;
&lt;li&gt;Enable the iptables service for persistence.&lt;/li&gt;
&lt;li&gt;Use DROP instead of REJECT for security-sensitive ports.&lt;/li&gt;
&lt;li&gt;Document firewall rules for audit purposes.&lt;/li&gt;
&lt;li&gt;Monitor firewall logs for blocked connection attempts.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This guide covered the complete process of configuring iptables on the backup server to allow Nginx traffic and block Apache traffic permanently. The key steps were installing iptables, flushing existing rules, setting default policies, adding specific allow and block rules, and saving the configuration.&lt;/p&gt;

&lt;p&gt;The rules were verified with &lt;code&gt;iptables -L -n --line-numbers&lt;/code&gt; and tested with curl. The iptables service was enabled to ensure the rules persist across reboots.&lt;/p&gt;

&lt;p&gt;By following these steps, system administrators can implement precise firewall policies that enhance server security while maintaining required service accessibility.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Install iptables&lt;/td&gt;
&lt;td&gt;yum install -y iptables iptables-services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flush rules&lt;/td&gt;
&lt;td&gt;iptables -F&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Allow port&lt;/td&gt;
&lt;td&gt;iptables -A INPUT -p tcp --dport PORT -j ACCEPT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Block port&lt;/td&gt;
&lt;td&gt;iptables -A INPUT -p tcp --dport PORT -j DROP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Save rules&lt;/td&gt;
&lt;td&gt;iptables-save &amp;gt; /etc/sysconfig/iptables&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enable service&lt;/td&gt;
&lt;td&gt;systemctl enable iptables&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Start service&lt;/td&gt;
&lt;td&gt;systemctl start iptables&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List rules&lt;/td&gt;
&lt;td&gt;iptables -L -n --line-numbers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test Nginx&lt;/td&gt;
&lt;td&gt;curl -I &lt;a href="http://localhost:8099/" rel="noopener noreferrer"&gt;http://localhost:8099/&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test Apache&lt;/td&gt;
&lt;td&gt;curl -I &lt;a href="http://stbkp01:8088/" rel="noopener noreferrer"&gt;http://stbkp01:8088/&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;This guide was created based on a real-world iptables configuration task on the Nautilus Backup Server in the Stratos Datacenter.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>iptable</category>
      <category>firewall</category>
      <category>security</category>
    </item>
    <item>
      <title>Linux LogRotate</title>
      <dc:creator>Janak Shrestha</dc:creator>
      <pubDate>Mon, 28 Sep 2026 11:57:15 +0000</pubDate>
      <link>https://dev.to/janak0ff/linux-logrotate-961</link>
      <guid>https://dev.to/janak0ff/linux-logrotate-961</guid>
      <description>&lt;p&gt;The &lt;code&gt;Nautilus&lt;/code&gt; DevOps team is ready to launch a new application, which they will deploy on app servers in &lt;code&gt;Stratos Datacenter&lt;/code&gt;. They are expecting significant traffic/usage of &lt;code&gt;tomcat&lt;/code&gt; on app servers after that. This will generate massive logs, creating huge log files. To utilise the storage efficiently, they need to compress the log files and need to rotate old logs. Check the requirements shared below:  &lt;/p&gt;

&lt;p&gt;a. In all app servers install &lt;code&gt;tomcat&lt;/code&gt; package.&lt;br&gt;&lt;br&gt;
b. Using &lt;code&gt;logrotate&lt;/code&gt; configure &lt;code&gt;tomcat&lt;/code&gt; logs rotation to monthly and keep only 3 rotated logs.&lt;br&gt;&lt;br&gt;
(If by default log rotation is set, then please update configuration as needed)&lt;/p&gt;


&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Log files are essential for troubleshooting, auditing, and monitoring applications. However, without proper management, log files can grow uncontrollably, consuming disk space and potentially causing service outages. LogRotate is a Linux utility that automates the rotation, compression, and removal of log files, ensuring efficient use of storage.&lt;/p&gt;

&lt;p&gt;This guide walks through a real-world scenario where the Nautilus DevOps team needed to install Tomcat on three application servers and configure logrotate to rotate Tomcat logs monthly while keeping only three rotated logs.&lt;/p&gt;


&lt;h2&gt;
  
  
  Environment Details
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Server&lt;/th&gt;
&lt;th&gt;Hostname&lt;/th&gt;
&lt;th&gt;User&lt;/th&gt;
&lt;th&gt;Password&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;App Server 1&lt;/td&gt;
&lt;td&gt;stapp01&lt;/td&gt;
&lt;td&gt;tony&lt;/td&gt;
&lt;td&gt;Ir0nM@n&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App Server 2&lt;/td&gt;
&lt;td&gt;stapp02&lt;/td&gt;
&lt;td&gt;steve&lt;/td&gt;
&lt;td&gt;Am3ric@&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App Server 3&lt;/td&gt;
&lt;td&gt;stapp03&lt;/td&gt;
&lt;td&gt;banner&lt;/td&gt;
&lt;td&gt;BigGr33n&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jump Host&lt;/td&gt;
&lt;td&gt;jump-host&lt;/td&gt;
&lt;td&gt;thor&lt;/td&gt;
&lt;td&gt;mjolnir123&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  Understanding LogRotate
&lt;/h2&gt;
&lt;h3&gt;
  
  
  What is LogRotate
&lt;/h3&gt;

&lt;p&gt;LogRotate is a Linux utility that manages log files by rotating them based on size or time. It prevents log files from growing indefinitely, compresses old logs to save space, and removes the oldest logs based on a retention policy.&lt;/p&gt;
&lt;h3&gt;
  
  
  Key Concepts
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rotation&lt;/td&gt;
&lt;td&gt;Moving the current log to a new file and starting fresh&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compression&lt;/td&gt;
&lt;td&gt;Reducing the size of rotated logs using gzip&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retention&lt;/td&gt;
&lt;td&gt;Number of rotated logs to keep before deletion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frequency&lt;/td&gt;
&lt;td&gt;How often rotation occurs (daily, weekly, monthly)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Why Use LogRotate
&lt;/h3&gt;

&lt;p&gt;LogRotate provides several benefits. It prevents disk space exhaustion by keeping log files at manageable sizes. It preserves historical data for troubleshooting and auditing. It automates routine maintenance, reducing manual intervention. It compresses old logs to save storage space. It integrates with systemd timers for reliable scheduling.&lt;/p&gt;


&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before beginning, ensure the following are available. You need SSH access to all three app servers with sudo or root privileges. You should have basic knowledge of Linux commands. The servers should have network access to package repositories.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 1: Connect to App Server 1
&lt;/h2&gt;

&lt;p&gt;Access the server using SSH.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="k"&gt;ssh&lt;/span&gt; tony@stapp01
&lt;span class="k"&gt;Password&lt;/span&gt;: Ir0nM@n
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Switch to root to perform administrative tasks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;sudo su -
Password: Ir0nM@n
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Install Tomcat
&lt;/h2&gt;

&lt;p&gt;Install Tomcat using the package manager. On CentOS Stream 9, Tomcat is available in the AppStream repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; tomcat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The installation pulls in several dependencies.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;tomcat&lt;/td&gt;
&lt;td&gt;Main Tomcat server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tomcat-lib&lt;/td&gt;
&lt;td&gt;Core libraries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tomcat-servlet-4.0-api&lt;/td&gt;
&lt;td&gt;Servlet API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tomcat-jsp-2.3-api&lt;/td&gt;
&lt;td&gt;JSP API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tomcat-el-3.0-api&lt;/td&gt;
&lt;td&gt;Expression Language API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ecj&lt;/td&gt;
&lt;td&gt;Eclipse Compiler for Java&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;apr&lt;/td&gt;
&lt;td&gt;Apache Portable Runtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tomcat-native&lt;/td&gt;
&lt;td&gt;Native library for performance&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Verify the installation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rpm &lt;span class="nt"&gt;-q&lt;/span&gt; tomcat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tomcat-9.0.120-1.el9.noarch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Start and Enable Tomcat
&lt;/h2&gt;

&lt;p&gt;Start the Tomcat service and enable it to start on boot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl start tomcat
systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;tomcat
systemctl status tomcat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The status output should show the service is active and running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight systemd"&gt;&lt;code&gt;&lt;span class="err"&gt;●&lt;/span&gt; &lt;span class="err"&gt;tomcat.service&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;Apache&lt;/span&gt; &lt;span class="err"&gt;Tomcat&lt;/span&gt; &lt;span class="err"&gt;Web&lt;/span&gt; &lt;span class="err"&gt;Application&lt;/span&gt; &lt;span class="err"&gt;Container&lt;/span&gt;
     &lt;span class="err"&gt;Loaded:&lt;/span&gt; &lt;span class="err"&gt;loaded&lt;/span&gt; &lt;span class="err"&gt;(/usr/lib/systemd/system/tomcat.service&lt;/span&gt;&lt;span class="c"&gt;; enabled; preset: disabled)&lt;/span&gt;
     &lt;span class="err"&gt;Active:&lt;/span&gt; &lt;span class="err"&gt;active&lt;/span&gt; &lt;span class="err"&gt;(running)&lt;/span&gt; &lt;span class="err"&gt;since&lt;/span&gt; &lt;span class="err"&gt;Mon&lt;/span&gt; &lt;span class="err"&gt;2026-09-28&lt;/span&gt; &lt;span class="err"&gt;11:49:38&lt;/span&gt; &lt;span class="err"&gt;UTC&lt;/span&gt;&lt;span class="c"&gt;; 359ms ago&lt;/span&gt;
   &lt;span class="err"&gt;Main&lt;/span&gt; &lt;span class="err"&gt;PID:&lt;/span&gt; &lt;span class="err"&gt;6545&lt;/span&gt; &lt;span class="err"&gt;(java)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why Start the Service
&lt;/h3&gt;

&lt;p&gt;Starting Tomcat generates the log files that logrotate will manage. Without running the service, the log directory remains empty.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Verify Log Files are Generated
&lt;/h2&gt;

&lt;p&gt;Check the Tomcat log directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /var/log/tomcat/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;-rw-r--r-- 1 tomcat tomcat 7321 Sep 28 11:49 catalina.2026-09-28.log
-rw-r--r-- 1 tomcat tomcat    0 Sep 28 11:49 host-manager.2026-09-28.log
-rw-r--r-- 1 tomcat tomcat    0 Sep 28 11:49 localhost.2026-09-28.log
-rw-r--r-- 1 tomcat tomcat    0 Sep 28 11:49 localhost_access_log.2026-09-28.txt
-rw-r--r-- 1 tomcat tomcat    0 Sep 28 11:49 manager.2026-09-28.log
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Log File&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;catalina.log&lt;/td&gt;
&lt;td&gt;Main Tomcat log&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;host-manager.log&lt;/td&gt;
&lt;td&gt;Host Manager application log&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;localhost.log&lt;/td&gt;
&lt;td&gt;Localhost application log&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;localhost_access_log.txt&lt;/td&gt;
&lt;td&gt;HTTP access log&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;manager.log&lt;/td&gt;
&lt;td&gt;Manager application log&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Step 5: Install LogRotate
&lt;/h2&gt;

&lt;p&gt;Check if logrotate is installed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rpm &lt;span class="nt"&gt;-q&lt;/span&gt; logrotate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If not installed, install it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; logrotate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The installation creates a systemd timer for logrotate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Created symlink /etc/systemd/system/timers.target.wants/logrotate.timer → /usr/lib/systemd/system/logrotate.timer.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 6: Create the LogRotate Configuration
&lt;/h2&gt;

&lt;p&gt;Create a configuration file for Tomcat at &lt;code&gt;/etc/logrotate.d/tomcat&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vi /etc/logrotate.d/tomcat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;/&lt;span class="n"&gt;var&lt;/span&gt;/&lt;span class="n"&gt;log&lt;/span&gt;/&lt;span class="n"&gt;tomcat&lt;/span&gt;/*.&lt;span class="n"&gt;log&lt;/span&gt; {
    &lt;span class="n"&gt;monthly&lt;/span&gt;
    &lt;span class="n"&gt;rotate&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
    &lt;span class="n"&gt;compress&lt;/span&gt;
    &lt;span class="n"&gt;missingok&lt;/span&gt;
    &lt;span class="n"&gt;notifempty&lt;/span&gt;
    &lt;span class="n"&gt;copytruncate&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuration Directive Breakdown
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Directive&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;monthly&lt;/td&gt;
&lt;td&gt;Rotate logs once per month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rotate 3&lt;/td&gt;
&lt;td&gt;Keep only 3 rotated log files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;compress&lt;/td&gt;
&lt;td&gt;Compress rotated logs with gzip&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;missingok&lt;/td&gt;
&lt;td&gt;Do not error if log file is missing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;notifempty&lt;/td&gt;
&lt;td&gt;Do not rotate empty log files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;copytruncate&lt;/td&gt;
&lt;td&gt;Copy then truncate original log&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Why copytruncate is Essential
&lt;/h3&gt;

&lt;p&gt;Tomcat keeps log files open while running. Without &lt;code&gt;copytruncate&lt;/code&gt;, logrotate would rename the log file, but Tomcat would continue writing to the renamed file. The new log file would remain empty. The &lt;code&gt;copytruncate&lt;/code&gt; directive copies the log file and then truncates the original, allowing Tomcat to continue writing to the same file without interruption.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 7: Verify the Configuration
&lt;/h2&gt;

&lt;p&gt;Test the configuration with a dry run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;logrotate &lt;span class="nt"&gt;-d&lt;/span&gt; /etc/logrotate.d/tomcat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;reading config file /etc/logrotate.d/tomcat
Reading state from file: /var/lib/logrotate/logrotate.status
Allocating hash table for state file, size 64 entries

Handling 1 logs

rotating pattern: /var/log/tomcat/*.log  monthly (3 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/tomcat/catalina.2026-09-28.log
  Now: 2026-09-28 11:52
  Last rotated at 2026-09-28 11:00
  log does not need rotating (log has already been rotated)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dry run shows what logrotate would do without making changes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 8: Apply to App Server 2
&lt;/h2&gt;

&lt;p&gt;Connect to stapp02 and repeat the process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh steve@stapp02
&lt;span class="nb"&gt;sudo &lt;/span&gt;su -
Password: Am3ric@
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; tomcat
yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; logrotate

systemctl start tomcat
systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;tomcat

&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/logrotate.d/tomcat &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
/var/log/tomcat/*.log {
    monthly
    rotate 3
    compress
    missingok
    notifempty
    copytruncate
}
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;logrotate &lt;span class="nt"&gt;-d&lt;/span&gt; /etc/logrotate.d/tomcat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 9: Apply to App Server 3
&lt;/h2&gt;

&lt;p&gt;Connect to stapp03 and repeat the process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh banner@stapp03
&lt;span class="nb"&gt;sudo &lt;/span&gt;su -
Password: BigGr33n
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; tomcat
yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; logrotate

systemctl start tomcat
systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;tomcat

&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/logrotate.d/tomcat &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
/var/log/tomcat/*.log {
    monthly
    rotate 3
    compress
    missingok
    notifempty
    copytruncate
}
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;logrotate &lt;span class="nt"&gt;-d&lt;/span&gt; /etc/logrotate.d/tomcat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 10: Verify All Servers
&lt;/h2&gt;

&lt;p&gt;Run verification commands on all servers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check Tomcat service&lt;/span&gt;
ssh tony@stapp01 &lt;span class="s2"&gt;"systemctl is-active tomcat"&lt;/span&gt;
ssh steve@stapp02 &lt;span class="s2"&gt;"systemctl is-active tomcat"&lt;/span&gt;
ssh banner@stapp03 &lt;span class="s2"&gt;"systemctl is-active tomcat"&lt;/span&gt;

&lt;span class="c"&gt;# Check logrotate configuration&lt;/span&gt;
ssh tony@stapp01 &lt;span class="s2"&gt;"cat /etc/logrotate.d/tomcat"&lt;/span&gt;
ssh steve@stapp02 &lt;span class="s2"&gt;"cat /etc/logrotate.d/tomcat"&lt;/span&gt;
ssh banner@stapp03 &lt;span class="s2"&gt;"cat /etc/logrotate.d/tomcat"&lt;/span&gt;

&lt;span class="c"&gt;# Check log files&lt;/span&gt;
ssh tony@stapp01 &lt;span class="s2"&gt;"sudo ls -la /var/log/tomcat/"&lt;/span&gt;
ssh steve@stapp02 &lt;span class="s2"&gt;"sudo ls -la /var/log/tomcat/"&lt;/span&gt;
ssh banner@stapp03 &lt;span class="s2"&gt;"sudo ls -la /var/log/tomcat/"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Understanding the Rotation Process
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Before Rotation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/var/log/tomcat/catalina.2026-09-28.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  After Rotation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/var/log/tomcat/catalina.2026-09-28.log.1.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  After Multiple Rotations
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/var/log/tomcat/catalina.2026-09-28.log.1.gz
/var/log/tomcat/catalina.2026-09-28.log.2.gz
/var/log/tomcat/catalina.2026-09-28.log.3.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the fourth rotation occurs, the oldest file (&lt;code&gt;.3.gz&lt;/code&gt;) is deleted, and the others are renamed to make room for the new rotation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Verification Checklist
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Expected&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tomcat installed&lt;/td&gt;
&lt;td&gt;rpm -q tomcat&lt;/td&gt;
&lt;td&gt;tomcat-9.0.120&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tomcat running&lt;/td&gt;
&lt;td&gt;systemctl is-active tomcat&lt;/td&gt;
&lt;td&gt;active&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;logrotate installed&lt;/td&gt;
&lt;td&gt;rpm -q logrotate&lt;/td&gt;
&lt;td&gt;logrotate-3.18.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Config file exists&lt;/td&gt;
&lt;td&gt;cat /etc/logrotate.d/tomcat&lt;/td&gt;
&lt;td&gt;Configuration content&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dry run passes&lt;/td&gt;
&lt;td&gt;logrotate -d /etc/logrotate.d/tomcat&lt;/td&gt;
&lt;td&gt;No errors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Log files exist&lt;/td&gt;
&lt;td&gt;ls -la /var/log/tomcat/&lt;/td&gt;
&lt;td&gt;Log files listed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Troubleshooting Common Issues
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Issue 1: logrotate Command Not Found
&lt;/h3&gt;

&lt;p&gt;Install the logrotate package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; logrotate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue 2: State File Warning
&lt;/h3&gt;

&lt;p&gt;When running logrotate for the first time, you may see a warning about the state file. This is normal. LogRotate creates the state file automatically when it runs for the first time during a real rotation cycle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Issue 3: Logs Not Rotating
&lt;/h3&gt;

&lt;p&gt;Check that the logrotate timer is active.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl status logrotate.timer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the logrotate status.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /var/lib/logrotate/logrotate.status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue 4: Tomcat Not Writing to New Logs
&lt;/h3&gt;

&lt;p&gt;Ensure &lt;code&gt;copytruncate&lt;/code&gt; is in the configuration. Without it, Tomcat may continue writing to the old log file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Issue 5: Configuration Syntax Errors
&lt;/h3&gt;

&lt;p&gt;Verify the configuration syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;logrotate &lt;span class="nt"&gt;-d&lt;/span&gt; /etc/logrotate.d/tomcat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fix any syntax errors before the next rotation cycle.&lt;/p&gt;




&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Use &lt;code&gt;copytruncate&lt;/code&gt; for applications that keep log files open.&lt;/li&gt;
&lt;li&gt;Set appropriate rotation frequency based on log volume.&lt;/li&gt;
&lt;li&gt;Configure compression to save disk space.&lt;/li&gt;
&lt;li&gt;Set retention based on compliance and storage requirements.&lt;/li&gt;
&lt;li&gt;Test configuration with dry run before applying.&lt;/li&gt;
&lt;li&gt;Monitor logrotate status regularly.&lt;/li&gt;
&lt;li&gt;Document log rotation policies for audit purposes.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This guide covered the complete process of installing Tomcat on three application servers and configuring logrotate for monthly rotation with three retained logs. The key steps were installing the packages, starting the service to generate logs, creating the logrotate configuration, and verifying the setup.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;copytruncate&lt;/code&gt; directive is essential for Tomcat because it keeps log files open while running. Without it, Tomcat would continue writing to the renamed log file, and the new log file would remain empty.&lt;/p&gt;

&lt;p&gt;LogRotate is a powerful tool for managing log files efficiently. By configuring it properly, system administrators can ensure that log files do not consume excessive disk space while preserving historical data for troubleshooting and auditing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Install Tomcat&lt;/td&gt;
&lt;td&gt;yum install -y tomcat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Start Tomcat&lt;/td&gt;
&lt;td&gt;systemctl start tomcat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enable Tomcat&lt;/td&gt;
&lt;td&gt;systemctl enable tomcat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Install logrotate&lt;/td&gt;
&lt;td&gt;yum install -y logrotate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Create config&lt;/td&gt;
&lt;td&gt;vi /etc/logrotate.d/tomcat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test config&lt;/td&gt;
&lt;td&gt;logrotate -d /etc/logrotate.d/tomcat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check logs&lt;/td&gt;
&lt;td&gt;ls -la /var/log/tomcat/&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check status&lt;/td&gt;
&lt;td&gt;cat /var/lib/logrotate/logrotate.status&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Configuration File Summary
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;/&lt;span class="n"&gt;var&lt;/span&gt;/&lt;span class="n"&gt;log&lt;/span&gt;/&lt;span class="n"&gt;tomcat&lt;/span&gt;/*.&lt;span class="n"&gt;log&lt;/span&gt; {
    &lt;span class="n"&gt;monthly&lt;/span&gt;
    &lt;span class="n"&gt;rotate&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
    &lt;span class="n"&gt;compress&lt;/span&gt;
    &lt;span class="n"&gt;missingok&lt;/span&gt;
    &lt;span class="n"&gt;notifempty&lt;/span&gt;
    &lt;span class="n"&gt;copytruncate&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;This guide was created based on a real-world logrotate implementation on the Nautilus Application Servers in the Stratos Datacenter.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>logrotate</category>
    </item>
    <item>
      <title>Linux GPG Encryption</title>
      <dc:creator>Janak Shrestha</dc:creator>
      <pubDate>Sun, 27 Sep 2026 14:17:06 +0000</pubDate>
      <link>https://dev.to/janak0ff/linux-gpg-encryption-3c3</link>
      <guid>https://dev.to/janak0ff/linux-gpg-encryption-3c3</guid>
      <description>&lt;p&gt;We have confidential data that needs to be transferred to a remote location, so we need to encrypt that data.We also need to decrypt data we received from a remote location in order to understand its content.  &lt;/p&gt;

&lt;p&gt;On &lt;code&gt;storage server&lt;/code&gt; in &lt;code&gt;Stratos Datacenter&lt;/code&gt; we have private and public keys stored at &lt;code&gt;/home/*_key.asc&lt;/code&gt;. Use these keys to perform the following actions.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encrypt &lt;code&gt;/home/encrypt_me.txt&lt;/code&gt; to &lt;code&gt;/home/encrypted_me.asc&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;Decrypt &lt;code&gt;/home/decrypt_me.asc&lt;/code&gt; to &lt;code&gt;/home/decrypted_me.txt&lt;/code&gt;. (Passphrase for decryption and encryption is &lt;code&gt;kodekloud&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;The user ID you can use is &lt;code&gt;kodekloud@kodekloud.com&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;GPG (GNU Privacy Guard) is a powerful encryption tool used to secure data during transfer and storage. It supports both symmetric encryption (using a passphrase) and asymmetric encryption (using public and private key pairs). In enterprise environments, GPG is commonly used to protect confidential data before transferring it to remote locations.&lt;/p&gt;

&lt;p&gt;This guide walks through a real-world GPG encryption and decryption task on the Nautilus Storage Server in the Stratos Datacenter. The task involved importing keys, encrypting a file with a recipient's public key, and decrypting a file using a passphrase.&lt;/p&gt;




&lt;h2&gt;
  
  
  Environment Details
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Server&lt;/th&gt;
&lt;th&gt;Hostname&lt;/th&gt;
&lt;th&gt;User&lt;/th&gt;
&lt;th&gt;Password&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Storage Server&lt;/td&gt;
&lt;td&gt;ststor01&lt;/td&gt;
&lt;td&gt;natasha&lt;/td&gt;
&lt;td&gt;Bl@kW&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jump Host&lt;/td&gt;
&lt;td&gt;jump-host&lt;/td&gt;
&lt;td&gt;thor&lt;/td&gt;
&lt;td&gt;mjolnir123&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;/home/public_key.asc&lt;/td&gt;
&lt;td&gt;Public key for encryption&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/home/private_key.asc&lt;/td&gt;
&lt;td&gt;Private key for decryption&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/home/encrypt_me.txt&lt;/td&gt;
&lt;td&gt;File to encrypt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/home/decrypt_me.asc&lt;/td&gt;
&lt;td&gt;File to decrypt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="mailto:kodekloud@kodekloud.com"&gt;kodekloud@kodekloud.com&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;User ID for encryption&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;kodekloud&lt;/td&gt;
&lt;td&gt;Passphrase for decryption&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Step 1: Connect to the Storage Server
&lt;/h2&gt;

&lt;p&gt;Access the storage server using SSH.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="k"&gt;ssh&lt;/span&gt; natasha@ststor01
&lt;span class="k"&gt;Password&lt;/span&gt;: Bl@kW
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Switch to root to perform administrative tasks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;sudo su -
Password: Bl@kW
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Verify the Available Keys
&lt;/h2&gt;

&lt;p&gt;Check the key files available in the home directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /home/&lt;span class="k"&gt;*&lt;/span&gt;_key.asc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-rw-r--r-- 1 root root 3590 Sep 27 13:43 /home/private_key.asc
-rw-r--r-- 1 root root 1723 Sep 27 13:43 /home/public_key.asc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The public key is used for encryption, and the private key is used for decryption.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Import the Public Key
&lt;/h2&gt;

&lt;p&gt;Import the public key so GPG can use it for encryption.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--import&lt;/span&gt; /home/public_key.asc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpg: key 8F17F26ECCE3AF51: public key "kodekloud &amp;lt;kodekloud@kodekloud.com&amp;gt;" imported
gpg: Total number processed: 1
gpg:               imported: 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the public key is imported.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--list-keys&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/root/.gnupg/pubring.kbx
------------------------
pub   rsa2048 2020-01-19 [SC]
      FEA85011C456B5E9AE5A516F8F17F26ECCE3AF51
uid           [ unknown] kodekloud &amp;lt;kodekloud@kodekloud.com&amp;gt;
sub   rsa2048 2020-01-19 [E]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Import the Private Key
&lt;/h2&gt;

&lt;p&gt;Import the private key. This key is protected with a passphrase.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--import&lt;/span&gt; /home/private_key.asc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When prompted, enter the passphrase.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Passphrase: kodekloud
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpg: key 8F17F26ECCE3AF51: "kodekloud &amp;lt;kodekloud@kodekloud.com&amp;gt;" not changed
gpg: key 8F17F26ECCE3AF51: secret key imported
gpg: Total number processed: 1
gpg:              unchanged: 1
gpg:       secret keys read: 1
gpg:   secret keys imported: 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the secret key is imported.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--list-secret-keys&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/root/.gnupg/pubring.kbx
------------------------
sec   rsa2048 2020-01-19 [SC]
      FEA85011C456B5E9AE5A516F8F17F26ECCE3AF51
uid           [ unknown] kodekloud &amp;lt;kodekloud@kodekloud.com&amp;gt;
ssb   rsa2048 2020-01-19 [E]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 5: Encrypt the File
&lt;/h2&gt;

&lt;p&gt;Encrypt &lt;code&gt;/home/encrypt_me.txt&lt;/code&gt; using the recipient's public key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--encrypt&lt;/span&gt; &lt;span class="nt"&gt;--armor&lt;/span&gt; &lt;span class="nt"&gt;--recipient&lt;/span&gt; kodekloud@kodekloud.com &lt;span class="nt"&gt;--output&lt;/span&gt; /home/encrypted_me.asc /home/encrypt_me.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When prompted about the key trust, answer yes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;It is NOT certain that the key belongs to the person named
in the user ID.  If you *really* know what you are doing,
you may answer the next question with yes.

Use this key anyway? (y/N) y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Command Breakdown
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;--encrypt&lt;/td&gt;
&lt;td&gt;Encrypt the file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--armor&lt;/td&gt;
&lt;td&gt;Create ASCII armored output (.asc format)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--recipient&lt;/td&gt;
&lt;td&gt;Specify the recipient's user ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;--output&lt;/td&gt;
&lt;td&gt;Output file path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/home/encrypt_me.txt&lt;/td&gt;
&lt;td&gt;Input file to encrypt&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Verify the encrypted file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /home/encrypted_me.asc
&lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-5&lt;/span&gt; /home/encrypted_me.asc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-rw-r--r-- 1 root root 651 Sep 27 14:10 /home/encrypted_me.asc

-----BEGIN PGP MESSAGE-----

hQEMA91rhQaGXAcNAQf9FKNgOTXnf1l19NE12N8iKxweVSkBHULQNQbl6VHAB6xV
7dsOkT79xGIjMD45ktzI56eczklbZg6l6sFfwcdjFDheO8YkSiPPN526HIl4hFoW
tvP1l+H6kvi1qqFnQxb6H96zZLgaUSkxyGK/kBBV1KuPxJiNH4xGOrr6J0DhfN6g
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 6: Decrypt the File
&lt;/h2&gt;

&lt;p&gt;Decrypt &lt;code&gt;/home/decrypt_me.asc&lt;/code&gt; to &lt;code&gt;/home/decrypted_me.txt&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--output&lt;/span&gt; /home/decrypted_me.txt &lt;span class="nt"&gt;--decrypt&lt;/span&gt; /home/decrypt_me.asc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When prompted, enter the passphrase.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Passphrase: kodekloud
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If successful, the decrypted file will be created.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpg: AES.CFB encrypted data
gpg: encrypted with 1 passphrase
gpg: Signature made ...
gpg: Good signature from "kodekloud &amp;lt;kodekloud@kodekloud.com&amp;gt;"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the decrypted file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /home/decrypted_me.txt
&lt;span class="nb"&gt;cat&lt;/span&gt; /home/decrypted_me.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-rw-r--r-- 1 root root 80 Sep 27 14:01 /home/decrypted_me.txt
Welcome to xFusionCorp Industries. This is KodeKloud System Administration Lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Understanding the Process
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Public Key Cryptography
&lt;/h3&gt;

&lt;p&gt;GPG uses asymmetric cryptography, which involves two keys:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Key&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Shared With&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Public key&lt;/td&gt;
&lt;td&gt;Encrypt data&lt;/td&gt;
&lt;td&gt;Anyone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Private key&lt;/td&gt;
&lt;td&gt;Decrypt data&lt;/td&gt;
&lt;td&gt;Only the owner&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When you encrypt a file with someone's public key, only their private key can decrypt it. This ensures confidentiality during transfer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Symmetric Encryption
&lt;/h3&gt;

&lt;p&gt;GPG also supports symmetric encryption, which uses a single passphrase for both encryption and decryption. This is simpler but requires securely sharing the passphrase.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Trust
&lt;/h3&gt;

&lt;p&gt;When importing a key, GPG marks it as untrusted because it cannot verify the key belongs to the stated owner. You must manually confirm trust by answering "yes" when prompted.&lt;/p&gt;




&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bad Session Key
&lt;/h3&gt;

&lt;p&gt;If decryption fails with &lt;code&gt;Bad session key&lt;/code&gt;, the passphrase does not match. Possible causes include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The passphrase is incorrect&lt;/li&gt;
&lt;li&gt;The file was encrypted with a different passphrase&lt;/li&gt;
&lt;li&gt;The file is corrupted&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Verify the passphrase from the task description. If the file was encrypted with a known passphrase, use the exact value.&lt;/p&gt;

&lt;h3&gt;
  
  
  Public Key Not Found
&lt;/h3&gt;

&lt;p&gt;If encryption fails with &lt;code&gt;public key not found&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--import&lt;/span&gt; /home/public_key.asc
gpg &lt;span class="nt"&gt;--list-keys&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure the key is imported before encrypting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Secret Key Not Found
&lt;/h3&gt;

&lt;p&gt;If decryption fails with &lt;code&gt;No secret key&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--import&lt;/span&gt; /home/private_key.asc
gpg &lt;span class="nt"&gt;--list-secret-keys&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure the private key is imported before decrypting.&lt;/p&gt;

&lt;h3&gt;
  
  
  File Format Issues
&lt;/h3&gt;

&lt;p&gt;If the file does not have the expected format, check it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpg &lt;span class="nt"&gt;--list-packets&lt;/span&gt; /home/decrypt_me.asc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This shows the packet structure and helps identify whether the file is symmetrically or asymmetrically encrypted.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Import public key&lt;/td&gt;
&lt;td&gt;Complete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Import private key&lt;/td&gt;
&lt;td&gt;Complete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Encrypt &lt;code&gt;/home/encrypt_me.txt&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Complete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decrypt &lt;code&gt;/home/decrypt_me.asc&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Complete&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Final File Status
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;-rw-r--r--&lt;/span&gt; 1 root root 651 Sep 27 14:10 /home/encrypted_me.asc
&lt;span class="nt"&gt;-rw-r--r--&lt;/span&gt; 1 root root  80 Sep 27 14:01 /home/decrypted_me.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Decrypted Content
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Welcome to xFusionCorp Industries. This is KodeKloud System Administration Lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Key GPG Commands
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpg --import key.asc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Import a key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpg --list-keys&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List public keys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpg --list-secret-keys&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List private keys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpg --encrypt --armor --recipient user@domain --output file.asc file.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Encrypt a file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpg --decrypt --output file.txt file.asc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Decrypt a file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpg --symmetric --passphrase pass --output file.asc file.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Symmetric encryption&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpg --list-packets file.asc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;View file structure&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Always verify keys after import with &lt;code&gt;gpg --list-keys&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;--armor&lt;/code&gt; to create ASCII-armored output that is safe for email and text transfer.&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;--recipient&lt;/code&gt; flag with the exact user ID to encrypt for a specific person.&lt;/li&gt;
&lt;li&gt;Store private keys securely and protect them with a strong passphrase.&lt;/li&gt;
&lt;li&gt;Test GPG functionality with a small file before working with critical data.&lt;/li&gt;
&lt;li&gt;When decryption fails, check the file format with &lt;code&gt;gpg --list-packets&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If the passphrase is wrong, verify it from a trusted source.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This guide covered the complete process of importing GPG keys, encrypting a file with a recipient's public key, and decrypting a file with a passphrase. The tasks were completed successfully on the Nautilus Storage Server.&lt;/p&gt;

&lt;p&gt;The key takeaways are understanding the difference between public and private keys, knowing how to import keys, and using the correct GPG commands for encryption and decryption. When issues arise, the &lt;code&gt;gpg --list-packets&lt;/code&gt; command is invaluable for understanding the file structure.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Import key&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gpg --import key.asc&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List keys&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gpg --list-keys&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List secret keys&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gpg --list-secret-keys&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Encrypt&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gpg --encrypt --armor --recipient user@domain --output out.asc in.txt&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decrypt&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gpg --output out.txt --decrypt in.asc&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Symmetric encrypt&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gpg --symmetric --passphrase pass --output out.asc in.txt&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;View packets&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gpg --list-packets file.asc&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>linux</category>
      <category>encryption</category>
      <category>security</category>
    </item>
    <item>
      <title>Apache Troubleshooting</title>
      <dc:creator>Janak Shrestha</dc:creator>
      <pubDate>Sat, 26 Sep 2026 12:17:26 +0000</pubDate>
      <link>https://dev.to/janak0ff/apache-troubleshooting-4o6k</link>
      <guid>https://dev.to/janak0ff/apache-troubleshooting-4o6k</guid>
      <description>&lt;p&gt;&lt;code&gt;xFusionCorp Industries&lt;/code&gt; uses some monitoring tools to check the status of every service, application, etc running on the systems. Recently, the monitoring system identified that Apache service is not running on some of the &lt;code&gt;Nautilus Application Servers&lt;/code&gt; in &lt;code&gt;Stratos Datacenter&lt;/code&gt;.  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Identify the faulty &lt;code&gt;Nautilus Application Server&lt;/code&gt; and fix the issue. Also, make sure Apache service is up and running on all &lt;code&gt;Nautilus Application Servers&lt;/code&gt;. Do not try to stop any kind of firewall that is already running.
&lt;/li&gt;
&lt;li&gt;Apache is running on &lt;code&gt;8089&lt;/code&gt; port on all &lt;code&gt;Nautilus Application Servers&lt;/code&gt; and its document root must be &lt;code&gt;/var/www/html&lt;/code&gt; on all app servers.  o&lt;/li&gt;
&lt;li&gt;Finally you can test from &lt;code&gt;jump host&lt;/code&gt; using curl command to access Apache on all app servers and it should be reachable and you should get some static page. E.g. &lt;code&gt;curl http://stapp01:8089/&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Environment Details
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Server&lt;/th&gt;
&lt;th&gt;Hostname&lt;/th&gt;
&lt;th&gt;User&lt;/th&gt;
&lt;th&gt;Password&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;App Server 1&lt;/td&gt;
&lt;td&gt;stapp01&lt;/td&gt;
&lt;td&gt;tony&lt;/td&gt;
&lt;td&gt;Ir0nM@n&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App Server 2&lt;/td&gt;
&lt;td&gt;stapp02&lt;/td&gt;
&lt;td&gt;steve&lt;/td&gt;
&lt;td&gt;Am3ric@&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App Server 3&lt;/td&gt;
&lt;td&gt;stapp03&lt;/td&gt;
&lt;td&gt;banner&lt;/td&gt;
&lt;td&gt;BigGr33n&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jump Host&lt;/td&gt;
&lt;td&gt;jump-host&lt;/td&gt;
&lt;td&gt;thor&lt;/td&gt;
&lt;td&gt;mjolnir123&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Step 1: Identify the Faulty Server
&lt;/h2&gt;

&lt;p&gt;Connect to the jump host and test each app server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="k"&gt;ssh&lt;/span&gt; thor@jump-host
&lt;span class="k"&gt;Password&lt;/span&gt;: mjolnir123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test Apache on each server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://stapp01:8089/
curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://stapp02:8089/
curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://stapp03:8089/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this scenario, all three servers returned connection refused, indicating Apache was not running on any of them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl: (7) Failed to connect to stapp01 port 8089: Connection refused
curl: (7) Failed to connect to stapp02 port 8089: Connection refused
curl: (7) Failed to connect to stapp03 port 8089: Connection refused
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Troubleshoot App Server 1 (stapp01)
&lt;/h2&gt;

&lt;p&gt;Connect to stapp01 and switch to root.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh tony@stapp01
&lt;span class="nb"&gt;sudo &lt;/span&gt;su -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Check the Service Status
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl status httpd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output showed the service was inactive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;○ httpd.service - The Apache HTTP Server
     Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled)
     Active: inactive (dead)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Check the Configuration for Syntax Errors
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;httpd &lt;span class="nt"&gt;-t&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output revealed the root cause.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AH00526: Syntax error on line 47 of /etc/httpd/conf/httpd.conf:
Invalid command 'Listen 808989', perhaps misspelled or defined by a module not included in the server configuration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Listen&lt;/code&gt; directive had a typo: &lt;code&gt;Listen 808989&lt;/code&gt; instead of &lt;code&gt;Listen 8089&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Examine the Problematic Line
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'40,55p'&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The line was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Listen 808989"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The line had &lt;strong&gt;quotes around it&lt;/strong&gt;, which prevented standard &lt;code&gt;sed&lt;/code&gt; commands from matching it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check DocumentRoot
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"DocumentRoot"&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output showed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DocumentRoot /var/www/html;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The semicolon at the end made the path invalid.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix the Configuration
&lt;/h3&gt;

&lt;p&gt;Remove the problematic line and ensure correct directives.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Remove the line containing "Listen 808989"&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'/Listen 808989/d'&lt;/span&gt; /etc/httpd/conf/httpd.conf

&lt;span class="c"&gt;# Remove any other Listen lines with quotes&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'/"Listen/d'&lt;/span&gt; /etc/httpd/conf/httpd.conf

&lt;span class="c"&gt;# Ensure correct Listen directive&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"^Listen 8089"&lt;/span&gt; /etc/httpd/conf/httpd.conf &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Listen 8089"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/httpd/conf/httpd.conf

&lt;span class="c"&gt;# Fix DocumentRoot&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s|^DocumentRoot.*|DocumentRoot "/var/www/html"|'&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify the Fix
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"^Listen"&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"^DocumentRoot"&lt;/span&gt; /etc/httpd/conf/httpd.conf
httpd &lt;span class="nt"&gt;-t&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;358:Listen 8089
124:DocumentRoot "/var/www/html"
Syntax OK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Start and Enable Apache
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl start httpd
systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;httpd
systemctl status httpd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The service started successfully.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;● httpd.service - The Apache HTTP Server
     Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled)
     Active: active (running)
   Main PID: 11989 (httpd)
     Status: "Started, listening on: port 8089"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Troubleshoot App Server 2 (stapp02)
&lt;/h2&gt;

&lt;p&gt;Connect to stapp02 and switch to root.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh steve@stapp02
&lt;span class="nb"&gt;sudo &lt;/span&gt;su -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Check the Configuration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"^Listen"&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"^DocumentRoot"&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"^ServerRoot"&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output showed two issues:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;47:Listen 808989
124:DocumentRoot "/var/www/html"
34:ServerRoot "/etc/httpd;"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Listen&lt;/code&gt; directive had a typo, and the &lt;code&gt;ServerRoot&lt;/code&gt; had a semicolon making it invalid.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check the Syntax
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;httpd &lt;span class="nt"&gt;-t&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output revealed the ServerRoot issue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;httpd: Syntax error on line 34 of /etc/httpd/conf/httpd.conf: ServerRoot must be a valid directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Fix the Configuration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Remove the problematic Listen line&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'/Listen 808989/d'&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'/"Listen/d'&lt;/span&gt; /etc/httpd/conf/httpd.conf

&lt;span class="c"&gt;# Ensure correct Listen directive&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"^Listen 8089"&lt;/span&gt; /etc/httpd/conf/httpd.conf &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Listen 8089"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/httpd/conf/httpd.conf

&lt;span class="c"&gt;# Fix ServerRoot&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s|^ServerRoot.*|ServerRoot "/etc/httpd"|'&lt;/span&gt; /etc/httpd/conf/httpd.conf

&lt;span class="c"&gt;# Fix DocumentRoot&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s|^DocumentRoot.*|DocumentRoot "/var/www/html"|'&lt;/span&gt; /etc/httpd/conf/httpd.conf

&lt;span class="c"&gt;# Ensure index.html&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Welcome to xFusionCorp Industries"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /var/www/html/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify and Start Apache
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"^ServerRoot"&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"^Listen"&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"^DocumentRoot"&lt;/span&gt; /etc/httpd/conf/httpd.conf
httpd &lt;span class="nt"&gt;-t&lt;/span&gt;
systemctl start httpd
systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;httpd
systemctl status httpd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The service started successfully.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;● httpd.service - The Apache HTTP Server
     Active: active (running)
     Status: "Started, listening on: port 8089"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Troubleshoot App Server 3 (stapp03)
&lt;/h2&gt;

&lt;p&gt;Connect to stapp03 and switch to root.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh banner@stapp03
&lt;span class="nb"&gt;sudo &lt;/span&gt;su -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Check the Configuration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"^ServerRoot"&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"^Listen"&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"^DocumentRoot"&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Apply the Same Fixes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Fix ServerRoot&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s|^ServerRoot.*|ServerRoot "/etc/httpd"|'&lt;/span&gt; /etc/httpd/conf/httpd.conf

&lt;span class="c"&gt;# Fix Listen&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'/Listen 808989/d'&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'/"Listen/d'&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"^Listen 8089"&lt;/span&gt; /etc/httpd/conf/httpd.conf &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Listen 8089"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/httpd/conf/httpd.conf

&lt;span class="c"&gt;# Fix DocumentRoot&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s|^DocumentRoot.*|DocumentRoot "/var/www/html"|'&lt;/span&gt; /etc/httpd/conf/httpd.conf

&lt;span class="c"&gt;# Ensure index.html&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Welcome to xFusionCorp Industries"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /var/www/html/index.html

&lt;span class="c"&gt;# Verify&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"^ServerRoot"&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"^Listen"&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"^DocumentRoot"&lt;/span&gt; /etc/httpd/conf/httpd.conf

&lt;span class="c"&gt;# Check syntax&lt;/span&gt;
httpd &lt;span class="nt"&gt;-t&lt;/span&gt;

&lt;span class="c"&gt;# Start and enable&lt;/span&gt;
systemctl start httpd
systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;httpd
systemctl status httpd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The service started successfully.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Verify from Jump Host
&lt;/h2&gt;

&lt;p&gt;Return to the jump host and test all servers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://stapp01:8089/
curl http://stapp02:8089/
curl http://stapp03:8089/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Welcome to xFusionCorp Industries!
Welcome to xFusionCorp Industries
Welcome to xFusionCorp Industries
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All three servers returned the static page content successfully.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary of Issues and Fixes
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Server&lt;/th&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;stapp01&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;"Listen 808989"&lt;/code&gt; typo with quotes&lt;/td&gt;
&lt;td&gt;Removed line, added &lt;code&gt;Listen 8089&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;stapp01&lt;/td&gt;
&lt;td&gt;&lt;code&gt;DocumentRoot /var/www/html;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fixed to &lt;code&gt;DocumentRoot "/var/www/html"&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;stapp02&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Listen 808989&lt;/code&gt; typo&lt;/td&gt;
&lt;td&gt;Removed line, added &lt;code&gt;Listen 8089&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;stapp02&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ServerRoot "/etc/httpd;"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fixed to &lt;code&gt;ServerRoot "/etc/httpd"&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;stapp03&lt;/td&gt;
&lt;td&gt;Same issues as stapp02&lt;/td&gt;
&lt;td&gt;Applied same fixes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Verification Checklist
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;stapp01&lt;/th&gt;
&lt;th&gt;stapp02&lt;/th&gt;
&lt;th&gt;stapp03&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Apache running&lt;/td&gt;
&lt;td&gt;Active&lt;/td&gt;
&lt;td&gt;Active&lt;/td&gt;
&lt;td&gt;Active&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Port 8089&lt;/td&gt;
&lt;td&gt;Listening&lt;/td&gt;
&lt;td&gt;Listening&lt;/td&gt;
&lt;td&gt;Listening&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DocumentRoot&lt;/td&gt;
&lt;td&gt;/var/www/html&lt;/td&gt;
&lt;td&gt;/var/www/html&lt;/td&gt;
&lt;td&gt;/var/www/html&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Index page&lt;/td&gt;
&lt;td&gt;Present&lt;/td&gt;
&lt;td&gt;Present&lt;/td&gt;
&lt;td&gt;Present&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;curl test&lt;/td&gt;
&lt;td&gt;200 OK&lt;/td&gt;
&lt;td&gt;200 OK&lt;/td&gt;
&lt;td&gt;200 OK&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Common Apache Configuration Errors
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Error&lt;/th&gt;
&lt;th&gt;Cause&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Invalid command 'Listen ...'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Typo in port number&lt;/td&gt;
&lt;td&gt;Correct the Listen directive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ServerRoot must be a valid directory&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Semicolon or wrong path&lt;/td&gt;
&lt;td&gt;Set &lt;code&gt;ServerRoot "/etc/httpd"&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;DocumentRoot&lt;/code&gt; not working&lt;/td&gt;
&lt;td&gt;Semicolon in path&lt;/td&gt;
&lt;td&gt;Set &lt;code&gt;DocumentRoot "/var/www/html"&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service fails to start&lt;/td&gt;
&lt;td&gt;Syntax error&lt;/td&gt;
&lt;td&gt;Run &lt;code&gt;httpd -t&lt;/code&gt; to identify&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Port already in use&lt;/td&gt;
&lt;td&gt;Another service on port&lt;/td&gt;
&lt;td&gt;Change port or stop conflicting service&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Always run &lt;code&gt;httpd -t&lt;/code&gt; before restarting Apache to catch syntax errors.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;grep -n&lt;/code&gt; to view configuration lines with line numbers.&lt;/li&gt;
&lt;li&gt;Remove problematic lines entirely rather than trying to edit them in place.&lt;/li&gt;
&lt;li&gt;Verify the ServerRoot, Listen, and DocumentRoot directives are correct.&lt;/li&gt;
&lt;li&gt;Ensure the index.html file exists in the document root.&lt;/li&gt;
&lt;li&gt;Check the service status after starting Apache.&lt;/li&gt;
&lt;li&gt;Test from a remote host to confirm the service is reachable.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Useful Commands
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Check syntax&lt;/td&gt;
&lt;td&gt;&lt;code&gt;httpd -t&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check service&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl status httpd&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Start service&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl start httpd&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enable service&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl enable httpd&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check listening ports&lt;/td&gt;
&lt;td&gt;`ss -tlnp \&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;View configuration&lt;/td&gt;
&lt;td&gt;{% raw %}&lt;code&gt;grep -n "^Listen" /etc/httpd/conf/httpd.conf&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remove a line&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sed -i '/pattern/d' /etc/httpd/conf/httpd.conf&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Replace a line&lt;/td&gt;
&lt;td&gt;`sed -i 's\&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This guide covered a complete Apache troubleshooting workflow on three application servers. The root causes were configuration errors: typos in the Listen directive, semicolons in ServerRoot and DocumentRoot paths, and quotes around directive values.&lt;/p&gt;

&lt;p&gt;By systematically checking the service status, configuration syntax, and specific directives, the issues were identified and fixed. After correcting the configuration and restarting Apache, all three servers responded correctly on port 8089.&lt;/p&gt;

&lt;p&gt;The key takeaway is that Apache configuration errors are often caused by small typos or stray characters. Using {% raw %}&lt;code&gt;httpd -t&lt;/code&gt; to check syntax and &lt;code&gt;grep&lt;/code&gt; to inspect specific directives makes troubleshooting efficient and reliable.&lt;/p&gt;

</description>
      <category>linux</category>
    </item>
    <item>
      <title>Jenkins Parameterized Builds</title>
      <dc:creator>Janak Shrestha</dc:creator>
      <pubDate>Sat, 26 Sep 2026 11:44:08 +0000</pubDate>
      <link>https://dev.to/janak0ff/jenkins-parameterized-builds-1kio</link>
      <guid>https://dev.to/janak0ff/jenkins-parameterized-builds-1kio</guid>
      <description>&lt;p&gt;A new DevOps Engineer has joined the team and he will be assigned some Jenkins related tasks. Before that, the team wanted to test a simple parameterized job to understand basic functionality of parameterized builds. He is given a simple parameterized job to build in Jenkins. Please find more details below:  &lt;/p&gt;

&lt;p&gt;Click on the &lt;code&gt;Jenkins&lt;/code&gt; button on the top bar to access the Jenkins UI. Login using username &lt;code&gt;admin&lt;/code&gt; and password &lt;code&gt;Adm!n321&lt;/code&gt;.  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a &lt;code&gt;parameterized&lt;/code&gt; job which should be named as &lt;code&gt;parameterized-job&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add a &lt;code&gt;string&lt;/code&gt; parameter named &lt;code&gt;Stage&lt;/code&gt;; its default value should be &lt;code&gt;Build&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;Add a &lt;code&gt;choice&lt;/code&gt; parameter named &lt;code&gt;env&lt;/code&gt;; its choices should be &lt;code&gt;Development&lt;/code&gt;, &lt;code&gt;Staging&lt;/code&gt; and &lt;code&gt;Production&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;Configure job to execute a shell command, which should echo both parameter values (you are passing in the job).
&lt;/li&gt;
&lt;li&gt;Build the Jenkins job at least once with choice parameter value &lt;code&gt;Development&lt;/code&gt; to make sure it passes.
&lt;code&gt;Note:&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;You might need to install some plugins and restart Jenkins service. So, we recommend clicking on &lt;code&gt;Restart Jenkins when installation is complete and no jobs are running&lt;/code&gt; on plugin installation/update page i.e &lt;code&gt;update centre&lt;/code&gt;. Also, Jenkins UI sometimes gets stuck when Jenkins service restarts in the back end. In this case, please make sure to refresh the UI page.
&lt;/li&gt;
&lt;li&gt;For these kind of scenarios requiring changes to be done in a web UI, please take screenshots so that you can share it with us for review in case your task is marked incomplete. You may also consider using a screen recording software such as loom.com to record and share your work.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 1: Access the Jenkins UI
&lt;/h2&gt;

&lt;p&gt;Click the &lt;strong&gt;Jenkins&lt;/strong&gt; button on the top bar of your KodeKloud lab environment. This opens the Jenkins UI in a new tab.&lt;/p&gt;

&lt;p&gt;Log in with:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Username&lt;/td&gt;
&lt;td&gt;&lt;code&gt;admin&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Adm!n321&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You'll land on the Jenkins dashboard.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Create the Job
&lt;/h2&gt;

&lt;p&gt;From the dashboard:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;New Item&lt;/strong&gt; in the left sidebar&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Enter an item name&lt;/strong&gt; field, type: &lt;code&gt;parameterized-job&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Freestyle project&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;OK&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You'll be taken to the job configuration page.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Enable Parameterized Build
&lt;/h2&gt;

&lt;p&gt;At the top of the configuration page, in the &lt;strong&gt;General&lt;/strong&gt; section:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check the box: ☑️ &lt;strong&gt;This project is parameterized&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once checked, an &lt;strong&gt;Add Parameter&lt;/strong&gt; dropdown button will appear. This is where we'll define our parameters.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Add the String Parameter (&lt;code&gt;Stage&lt;/code&gt;)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Add Parameter&lt;/strong&gt; → select &lt;strong&gt;String Parameter&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Fill in the fields:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Name&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Stage&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default Value&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Build&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Description&lt;/td&gt;
&lt;td&gt;(optional) &lt;code&gt;Enter the stage name&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;What is a String Parameter?&lt;/strong&gt;&lt;br&gt;
It accepts free-form text input. You can set a default value that pre-fills the input box when a user runs the job.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 5: Add the Choice Parameter (&lt;code&gt;env&lt;/code&gt;)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Add Parameter&lt;/strong&gt; again → select &lt;strong&gt;Choice Parameter&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Fill in the fields:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Name&lt;/td&gt;
&lt;td&gt;&lt;code&gt;env&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Choices&lt;/td&gt;
&lt;td&gt;See below&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Description&lt;/td&gt;
&lt;td&gt;(optional) &lt;code&gt;Select the environment&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For the &lt;strong&gt;Choices&lt;/strong&gt; field, enter each option on its own line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Development
Staging
Production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Important:&lt;/strong&gt; Do NOT use commas. Each choice must be on a &lt;strong&gt;separate line&lt;/strong&gt;. Jenkins will parse them into a dropdown list. The order matters — &lt;code&gt;Development&lt;/code&gt; should be first so it appears at the top.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;What is a Choice Parameter?&lt;/strong&gt;&lt;br&gt;
It presents a dropdown of predefined options. Users pick one; no free-text input is allowed.&lt;/p&gt;
&lt;h3&gt;
  
  
  Final Parameter Order
&lt;/h3&gt;

&lt;p&gt;Your configuration should show:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Parameters:
├── Stage (String)  → default: "Build"
└── env   (Choice)  → Development | Staging | Production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 6: Configure the Shell Command
&lt;/h2&gt;

&lt;p&gt;Scroll down to the &lt;strong&gt;Build&lt;/strong&gt; section:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Add build step&lt;/strong&gt; → select &lt;strong&gt;Execute shell&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Command&lt;/strong&gt; text area, enter:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Stage: &lt;/span&gt;&lt;span class="nv"&gt;$Stage&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Environment: &lt;/span&gt;&lt;span class="nv"&gt;$env&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How Parameter Injection Works
&lt;/h3&gt;

&lt;p&gt;Jenkins exposes parameters as &lt;strong&gt;environment variables&lt;/strong&gt; during the build. So &lt;code&gt;$Stage&lt;/code&gt; and &lt;code&gt;$env&lt;/code&gt; are available just like any shell variable. The syntax is case-sensitive — &lt;code&gt;$env&lt;/code&gt; won't match &lt;code&gt;$ENV&lt;/code&gt; or &lt;code&gt;$Env&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 7: Save the Job
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Save&lt;/strong&gt; at the bottom of the page&lt;/li&gt;
&lt;li&gt;You'll be redirected to the job page&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The job page will now show a &lt;strong&gt;Build with Parameters&lt;/strong&gt; option in the left sidebar (instead of just "Build Now").&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 8: Build with Parameters
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Build with Parameters&lt;/strong&gt; in the left sidebar&lt;/li&gt;
&lt;li&gt;You'll see a form:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stage:&lt;/strong&gt; text field pre-filled with &lt;code&gt;Build&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;env:&lt;/strong&gt; dropdown with Development, Staging, Production&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Development&lt;/strong&gt; from the &lt;code&gt;env&lt;/code&gt; dropdown&lt;/li&gt;
&lt;li&gt;Leave &lt;code&gt;Stage&lt;/code&gt; as &lt;code&gt;Build&lt;/code&gt; (the default)&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Build&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 9: Verify the Build Output
&lt;/h2&gt;

&lt;p&gt;In the left sidebar, &lt;strong&gt;Build History&lt;/strong&gt; will show &lt;strong&gt;#1&lt;/strong&gt; appear. Click on &lt;strong&gt;#1&lt;/strong&gt; → &lt;strong&gt;Console Output&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Started by user admin
Running as SYSTEM
Building in workspace /var/lib/jenkins/workspace/parameterized-job
&lt;/span&gt;&lt;span class="gp"&gt;[parameterized-job] $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/bin/sh &lt;span class="nt"&gt;-xe&lt;/span&gt; /tmp/jenkins4687125526416196371.sh
&lt;span class="go"&gt;+ echo Stage: Build
Stage: Build
+ echo Environment: Development
Environment: Development
Finished: SUCCESS
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Reading the Output
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Line&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;+ echo Stage: Build&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Shell command Jenkins executed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Stage: Build&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The string parameter value printed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;+ echo Environment: Development&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Second shell command&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Environment: Development&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The choice parameter value printed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Finished: SUCCESS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Build completed without errors&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;+&lt;/code&gt; prefix is the shell's trace mode (&lt;code&gt;sh -x&lt;/code&gt;), which Jenkins enables by default to show every command it runs. It's incredibly useful for debugging.&lt;/p&gt;




&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;th&gt;Solution&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Add Parameter" button missing&lt;/td&gt;
&lt;td&gt;Make sure &lt;strong&gt;This project is parameterized&lt;/strong&gt; is checked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Choice parameter only shows one option&lt;/td&gt;
&lt;td&gt;Each choice must be on a &lt;strong&gt;separate line&lt;/strong&gt;, not comma-separated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;$Stage&lt;/code&gt; prints empty&lt;/td&gt;
&lt;td&gt;Variable name must match exactly — Jenkins is case-sensitive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Build with Parameters" not visible&lt;/td&gt;
&lt;td&gt;Refresh the job page; ensure parameters were saved correctly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build fails&lt;/td&gt;
&lt;td&gt;Read the Console Output — the &lt;code&gt;+&lt;/code&gt; lines show exactly what ran&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Created &lt;code&gt;parameterized-job&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Freestyle project ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Added String Parameter &lt;code&gt;Stage&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Default: &lt;code&gt;Build&lt;/code&gt; ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Added Choice Parameter &lt;code&gt;env&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Development / Staging / Production ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Configured shell command&lt;/td&gt;
&lt;td&gt;Echoed both values ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Built with &lt;code&gt;env = Development&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Build #1 SUCCESS ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Parameterized builds eliminate job duplication.&lt;/strong&gt; One job, many configurations — perfect for multi-environment deployments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;String vs. Choice has a clear purpose.&lt;/strong&gt; Use String for free-text input with a sensible default; use Choice to constrain input to valid options.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parameters become environment variables.&lt;/strong&gt; Any script step can reference them via &lt;code&gt;$NAME&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Order matters in the UI.&lt;/strong&gt; The order you add parameters is the order users see them in the "Build with Parameters" form.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Console Output is your best friend.&lt;/strong&gt; The &lt;code&gt;+&lt;/code&gt; lines reveal exactly what Jenkins executed — invaluable when debugging.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Real-World Applications
&lt;/h2&gt;

&lt;p&gt;This simple pattern scales into serious CI/CD workflows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deploy to a specific environment:&lt;/strong&gt; Choice parameter for &lt;code&gt;env&lt;/code&gt;, then use it in a deployment script&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build a specific branch:&lt;/strong&gt; String parameter for &lt;code&gt;BRANCH&lt;/code&gt;, then &lt;code&gt;git checkout $BRANCH&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run with configurable versions:&lt;/strong&gt; String parameter for &lt;code&gt;VERSION&lt;/code&gt;, then &lt;code&gt;docker build -t app:$VERSION&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Release channels:&lt;/strong&gt; Choice parameter for &lt;code&gt;CHANNEL&lt;/code&gt; (stable/beta/nightly)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you're comfortable with parameters, the next step is chaining jobs together with the &lt;strong&gt;Parameterized Trigger&lt;/strong&gt; plugin — but that's a topic for another blog.&lt;/p&gt;

</description>
      <category>jenkins</category>
    </item>
    <item>
      <title>Jenkins Views</title>
      <dc:creator>Janak Shrestha</dc:creator>
      <pubDate>Fri, 25 Sep 2026 11:09:21 +0000</pubDate>
      <link>https://dev.to/janak0ff/jenkins-views-23gp</link>
      <guid>https://dev.to/janak0ff/jenkins-views-23gp</guid>
      <description>&lt;p&gt;The DevOps team of xFusionCorp Industries is planning to create a number of Jenkins jobs for different tasks. So to easily manage the jobs within Jenkins UI they decided to create different views for all Jenkins jobs based on usage/nature of these jobs, - for example nautilus-crons view for all cron jobs. Based on the requirements shared below please perform the below mentioned task:&lt;/p&gt;

&lt;p&gt;Click on the Jenkins button on the top bar to access the Jenkins UI. Login using username admin and password Adm!n321.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a Jenkins job named nautilus-test-job.&lt;/li&gt;
&lt;li&gt;Configure this job to run a simple bash command i.e echo "hello world!!".&lt;/li&gt;
&lt;li&gt;Create a view named nautilus-crons (it must be a global view of type List View) and make sure nautilus-test-job and nautilus-cron-job (which is already present on Jenkins) jobs are listed under this new view.&lt;/li&gt;
&lt;li&gt;Schedule this newly created job to build periodically at every minute i.e * * * * * (please make sure to use the cron expression exactly same how it is mentioned here).&lt;/li&gt;
&lt;li&gt;Make sure the job builds successfully.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You might need to install some plugins and restart Jenkins service. So, we recommend clicking on Restart Jenkins when installation is complete and no jobs are running on plugin installation/update page i.e update centre. Also, Jenkins UI sometimes gets stuck when Jenkins service restarts in the back end. In this case please make sure to refresh the UI page.&lt;/li&gt;
&lt;li&gt;For these kind of scenarios requiring changes to be done in a web UI, please take screenshots so that you can share it with us for review in case your task is marked incomplete. You may also consider using a screen recording software such as loom.com to record and share your work.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 1: Access the Jenkins UI
&lt;/h2&gt;

&lt;p&gt;Click the &lt;strong&gt;Jenkins&lt;/strong&gt; button on the top bar of your KodeKloud lab environment. This opens the Jenkins UI in a new tab.&lt;/p&gt;

&lt;p&gt;Log in with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Username:&lt;/strong&gt; &lt;code&gt;admin&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Password:&lt;/strong&gt; &lt;code&gt;Adm!n321&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once logged in, you'll land on the Jenkins dashboard. Take a moment to note the existing jobs and the &lt;strong&gt;"All"&lt;/strong&gt; view tab at the top.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Create the &lt;code&gt;nautilus-test-job&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;From the dashboard:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;New Item&lt;/strong&gt; in the left sidebar&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Enter an item name&lt;/strong&gt; field, type: &lt;code&gt;nautilus-test-job&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Freestyle project&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;OK&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You'll be taken to the job configuration page.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Configure the Build Command
&lt;/h2&gt;

&lt;p&gt;Scroll down to the &lt;strong&gt;Build&lt;/strong&gt; section:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Add build step&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Execute shell&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Command&lt;/strong&gt; text area, type exactly:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"hello world!!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Use double quotes exactly as shown. Using single quotes may cause inconsistent behavior during evaluation.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 4: Schedule the Job (Every Minute)
&lt;/h2&gt;

&lt;p&gt;Still on the job configuration page, scroll up to the &lt;strong&gt;Build Triggers&lt;/strong&gt; section:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check the box: &lt;strong&gt;Build periodically&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Schedule&lt;/strong&gt; text field, enter exactly:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* * * * *
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Understanding the Cron Expression
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Minute&lt;/td&gt;
&lt;td&gt;&lt;code&gt;*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Every minute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hour&lt;/td&gt;
&lt;td&gt;&lt;code&gt;*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Every hour&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day of Month&lt;/td&gt;
&lt;td&gt;&lt;code&gt;*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Every day of the month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Month&lt;/td&gt;
&lt;td&gt;&lt;code&gt;*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Every month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day of Week&lt;/td&gt;
&lt;td&gt;&lt;code&gt;*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Every day of the week&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This means Jenkins will trigger the job &lt;strong&gt;once per minute&lt;/strong&gt;, continuously.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Important:&lt;/strong&gt; The expression must be exactly &lt;code&gt;* * * * *&lt;/code&gt; with single spaces between each asterisk. Any extra spaces or characters will cause the schedule to fail validation or behave incorrectly.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 5: Save and Trigger a Manual Build
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Save&lt;/strong&gt; at the bottom of the page&lt;/li&gt;
&lt;li&gt;You'll be redirected to the job page&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Build Now&lt;/strong&gt; in the left sidebar&lt;/li&gt;
&lt;li&gt;Watch the &lt;strong&gt;Build History&lt;/strong&gt; box on the left — a blue ball will appear&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Verify the Build Output
&lt;/h3&gt;

&lt;p&gt;Click on the build number (e.g., &lt;code&gt;#1&lt;/code&gt;) → &lt;strong&gt;Console Output&lt;/strong&gt;. You should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Started by user admin
Running as SYSTEM
Building in workspace /var/lib/jenkins/workspace/nautilus-test-job
[nautilus-test-job] $ /bin/sh -xe /tmp/jenkins...sh
+ echo 'hello world!!'
hello world!!
Finished: SUCCESS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see &lt;code&gt;hello world!!&lt;/code&gt; and &lt;code&gt;Finished: SUCCESS&lt;/code&gt;, the job is working.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: Create the &lt;code&gt;nautilus-crons&lt;/code&gt; List View
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F84chxh2hf2obmxo3bd5t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F84chxh2hf2obmxo3bd5t.png" alt="Image" width="799" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's organize our jobs. From the Jenkins dashboard:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Look at the top-left area, next to the &lt;strong&gt;All&lt;/strong&gt; tab&lt;/li&gt;
&lt;li&gt;Click the small &lt;strong&gt;&lt;code&gt;+&lt;/code&gt;&lt;/strong&gt; button — this is the &lt;strong&gt;New View&lt;/strong&gt; button&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The "+" button is easy to miss because it's small and unlabeled. It's located right next to the "All" tab. If you can't find it, you can also navigate directly to &lt;code&gt;&amp;lt;jenkins-url&amp;gt;/newView&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On the &lt;strong&gt;New View&lt;/strong&gt; page:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;nautilus-crons&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type:&lt;/strong&gt; Select &lt;strong&gt;List View&lt;/strong&gt; (radio button)

&lt;ul&gt;
&lt;li&gt;❌ Do NOT select "My View" — this creates a personal view, not a global one&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 7: Add Jobs to the View
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flazv8v6s1vhjje6omzoy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flazv8v6s1vhjje6omzoy.png" alt="Image" width="799" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the view configuration page:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Under &lt;strong&gt;Job Filters&lt;/strong&gt;, make sure &lt;strong&gt;All&lt;/strong&gt; is selected&lt;/li&gt;
&lt;li&gt;Scroll down to the &lt;strong&gt;Jobs&lt;/strong&gt; section&lt;/li&gt;
&lt;li&gt;Check the boxes next to:

&lt;ul&gt;
&lt;li&gt;☑️ &lt;code&gt;nautilus-cron-job&lt;/code&gt; (existing job)&lt;/li&gt;
&lt;li&gt;☑️ &lt;code&gt;nautilus-test-job&lt;/code&gt; (newly created)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Optionally customize columns (Last Success, Last Failure, Last Duration are useful)&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Save&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 8: Verify the View
&lt;/h2&gt;

&lt;p&gt;After saving, you'll be redirected to the &lt;code&gt;nautilus-crons&lt;/code&gt; view. Confirm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ A new tab named &lt;strong&gt;&lt;code&gt;nautilus-crons&lt;/code&gt;&lt;/strong&gt; appears next to &lt;strong&gt;&lt;code&gt;All&lt;/code&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;✅ Both jobs are listed:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nautilus-cron-job&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nautilus-test-job&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 9: Confirm Automated Builds Are Working
&lt;/h2&gt;

&lt;p&gt;Wait 1–2 minutes, then check &lt;code&gt;nautilus-test-job&lt;/code&gt; again.&lt;/p&gt;

&lt;p&gt;You should see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Build History&lt;/strong&gt; growing (#1, #2, #3, ...)&lt;/li&gt;
&lt;li&gt;✅ Each new build shows "Started by timer" in the console output&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Last Success&lt;/strong&gt; column shows a recent timestamp&lt;/li&gt;
&lt;li&gt;✅ A &lt;strong&gt;green checkmark&lt;/strong&gt; next to the job name&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This confirms the cron schedule is working correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sample Console Output from an Automated Build
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Started by timer
Running as SYSTEM
Building in workspace /var/lib/jenkins/workspace/nautilus-test-job
[nautilus-test-job] $ /bin/sh -xe /tmp/jenkins...sh
+ echo 'hello world!!'
hello world!!
Finished: SUCCESS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key indicator here is &lt;strong&gt;"Started by timer"&lt;/strong&gt; — that's proof Jenkins is triggering the job based on the cron schedule, not manual clicks.&lt;/p&gt;




</description>
      <category>jenkins</category>
    </item>
    <item>
      <title>Add Response Headers in Apache</title>
      <dc:creator>Janak Shrestha</dc:creator>
      <pubDate>Thu, 24 Sep 2026 12:04:41 +0000</pubDate>
      <link>https://dev.to/janak0ff/add-response-headers-in-apache-398p</link>
      <guid>https://dev.to/janak0ff/add-response-headers-in-apache-398p</guid>
      <description>&lt;p&gt;We are working on hardening Apache web server on all app servers. As a part of this process we want to add some of the Apache response headers for security purpose. We are testing the settings one by one on all app servers. As per details mentioned below enable these headers for Apache:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install &lt;code&gt;httpd&lt;/code&gt; package on &lt;code&gt;App Server 2&lt;/code&gt; using yum and configure it to run on &lt;code&gt;3000&lt;/code&gt; port, make sure to start its service.
&lt;/li&gt;
&lt;li&gt;Create an &lt;code&gt;index.html&lt;/code&gt; file under Apache's default document root i.e &lt;code&gt;/var/www/html&lt;/code&gt; and add below given content in it.
&lt;code&gt;Welcome to the xFusionCorp Industries!&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Configure Apache to enable below mentioned headers:
&lt;code&gt;X-XSS-Protection&lt;/code&gt; header with value &lt;code&gt;1; mode=block&lt;/code&gt;
&lt;code&gt;X-Frame-Options&lt;/code&gt; header with value &lt;code&gt;SAMEORIGIN&lt;/code&gt;
&lt;code&gt;X-Content-Type-Options&lt;/code&gt; header with value &lt;code&gt;nosniff&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;Note:&lt;/code&gt; You can test using curl on the given app server as LBR URL will not work for this task.&lt;/p&gt;




&lt;h1&gt;
  
  
  Configuring Apache with Security Headers on a Custom Port
&lt;/h1&gt;

&lt;h2&gt;
  
  
  A Deep Dive for System Administrators
&lt;/h2&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Web server hardening is a critical part of securing modern infrastructure. One of the most effective ways to harden Apache is by adding HTTP response headers that instruct browsers to enforce security policies. These headers protect against common web vulnerabilities such as cross-site scripting (XSS), clickjacking, and MIME-type sniffing attacks.&lt;/p&gt;

&lt;p&gt;This guide walks through a complete implementation on a CentOS Stream 9 server. The task involves installing Apache, running it on a custom port, creating a test page, and enabling three specific security headers. Each step is explained in depth to build a strong understanding of the underlying concepts.&lt;/p&gt;




&lt;h2&gt;
  
  
  Environment Details
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Server&lt;/td&gt;
&lt;td&gt;stapp02&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User&lt;/td&gt;
&lt;td&gt;steve&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password&lt;/td&gt;
&lt;td&gt;Am3ric@&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OS&lt;/td&gt;
&lt;td&gt;CentOS Stream 9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apache Version&lt;/td&gt;
&lt;td&gt;2.4.62&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom Port&lt;/td&gt;
&lt;td&gt;3000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Document Root&lt;/td&gt;
&lt;td&gt;/var/www/html&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Understanding the Security Headers
&lt;/h2&gt;

&lt;p&gt;Before diving into the configuration, it is essential to understand what each header does and why it matters.&lt;/p&gt;

&lt;h3&gt;
  
  
  X-XSS-Protection
&lt;/h3&gt;

&lt;p&gt;This header enables the browser's built-in Cross-Site Scripting (XSS) filter. When set to &lt;code&gt;1; mode=block&lt;/code&gt;, the browser detects reflected XSS attacks and blocks the page from rendering rather than attempting to sanitize it. While modern browsers rely more on Content Security Policy, this header still provides protection for older browsers.&lt;/p&gt;

&lt;h3&gt;
  
  
  X-Frame-Options
&lt;/h3&gt;

&lt;p&gt;This header prevents clickjacking attacks by controlling whether a page can be embedded in a frame or iframe. Setting it to &lt;code&gt;SAMEORIGIN&lt;/code&gt; allows only pages from the same origin to embed the content. Attackers cannot trick users into clicking hidden elements on a different site.&lt;/p&gt;

&lt;h3&gt;
  
  
  X-Content-Type-Options
&lt;/h3&gt;

&lt;p&gt;This header set to &lt;code&gt;nosniff&lt;/code&gt; prevents browsers from guessing the MIME type of a file. Without this header, a browser might interpret a text file as JavaScript or HTML, leading to security vulnerabilities. Setting it to &lt;code&gt;nosniff&lt;/code&gt; forces the browser to trust the server's declared Content-Type.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary Table
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Header&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Protection&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;X-XSS-Protection&lt;/td&gt;
&lt;td&gt;1; mode=block&lt;/td&gt;
&lt;td&gt;Cross-site scripting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;X-Frame-Options&lt;/td&gt;
&lt;td&gt;SAMEORIGIN&lt;/td&gt;
&lt;td&gt;Clickjacking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;X-Content-Type-Options&lt;/td&gt;
&lt;td&gt;nosniff&lt;/td&gt;
&lt;td&gt;MIME sniffing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Step 1: Connect to the Server
&lt;/h2&gt;

&lt;p&gt;Access the server using SSH.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="k"&gt;ssh&lt;/span&gt; steve@stapp02
&lt;span class="k"&gt;Password&lt;/span&gt;: Am3ric@
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Switch to root to perform administrative tasks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;sudo su -
Password: Am3ric@
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The sudo command provides elevated privileges required for installing packages and editing system configuration files.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Install the httpd Package
&lt;/h2&gt;

&lt;p&gt;Install Apache using the yum package manager.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; httpd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The installation pulls in several dependencies.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;httpd&lt;/td&gt;
&lt;td&gt;Main Apache server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;httpd-core&lt;/td&gt;
&lt;td&gt;Core server binary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;httpd-tools&lt;/td&gt;
&lt;td&gt;Utilities like apachectl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;apr&lt;/td&gt;
&lt;td&gt;Apache Portable Runtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;apr-util&lt;/td&gt;
&lt;td&gt;Utility library for APR&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mod_http2&lt;/td&gt;
&lt;td&gt;HTTP/2 protocol support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mod_lua&lt;/td&gt;
&lt;td&gt;Lua scripting support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mailcap&lt;/td&gt;
&lt;td&gt;MIME type handling&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;After installation, the &lt;code&gt;httpd.service&lt;/code&gt; is registered with systemd.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Configure Apache to Listen on Port 3000
&lt;/h2&gt;

&lt;p&gt;By default, Apache listens on port 80. The task requires port 3000. The Listen directive in the main configuration file controls this.&lt;/p&gt;

&lt;p&gt;Edit the file at &lt;code&gt;/etc/httpd/conf/httpd.conf&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s/^Listen 80/Listen 3000/'&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the change.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"^Listen"&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;&lt;span class="nc"&gt;Listen&lt;/span&gt; 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why Use sed
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;sed&lt;/code&gt; command performs a search and replace in place. The &lt;code&gt;^&lt;/code&gt; anchors the match to the start of the line, ensuring only the Listen directive is changed and not other occurrences of &lt;code&gt;80&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Create the Index Page
&lt;/h2&gt;

&lt;p&gt;Create a simple index.html file in the document root.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Welcome to the xFusionCorp Industries!"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /var/www/html/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /var/www/html/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The document root &lt;code&gt;/var/www/html&lt;/code&gt; is the default location from which Apache serves files. The DirectoryIndex directive in the configuration tells Apache to look for index.html when a directory is requested.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Configure Security Headers
&lt;/h2&gt;

&lt;p&gt;Apache uses the &lt;code&gt;mod_headers&lt;/code&gt; module to manipulate HTTP headers. This module is enabled by default on CentOS Stream 9.&lt;/p&gt;

&lt;p&gt;Create a dedicated configuration file in the &lt;code&gt;conf.d&lt;/code&gt; directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;cat &amp;gt; /etc/httpd/conf.d/security-headers.conf &amp;lt;&amp;lt; 'EOF'
&lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="ss"&gt;always&lt;/span&gt; &lt;span class="ss"&gt;set&lt;/span&gt; X-XSS-Protection "1; mode=block"
&lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="ss"&gt;always&lt;/span&gt; &lt;span class="ss"&gt;set&lt;/span&gt; X-Frame-Options "SAMEORIGIN"
&lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="ss"&gt;always&lt;/span&gt; &lt;span class="ss"&gt;set&lt;/span&gt; X-Content-Type-Options "nosniff"
EOF
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why Use a Separate Configuration File
&lt;/h3&gt;

&lt;p&gt;Keeping custom configurations in &lt;code&gt;/etc/httpd/conf.d/&lt;/code&gt; is a best practice. Files in this directory are automatically included by the main configuration. This approach avoids modifying the main file and makes it easier to manage changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding the Directives
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Directive&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Header always set&lt;/td&gt;
&lt;td&gt;Adds the header to all responses&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;X-XSS-Protection&lt;/td&gt;
&lt;td&gt;Header name&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"1; mode=block"&lt;/td&gt;
&lt;td&gt;Header value (quoted)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;always&lt;/code&gt; keyword ensures the header is added even to error responses and redirects.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: Start and Enable the Apache Service
&lt;/h2&gt;

&lt;p&gt;Start the service and configure it to start on boot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl start httpd
systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;httpd
systemctl status httpd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The status output confirms the service is running and listening on port 3000.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight systemd"&gt;&lt;code&gt;&lt;span class="err"&gt;●&lt;/span&gt; &lt;span class="err"&gt;httpd.service&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;The&lt;/span&gt; &lt;span class="err"&gt;Apache&lt;/span&gt; &lt;span class="err"&gt;HTTP&lt;/span&gt; &lt;span class="err"&gt;Server&lt;/span&gt;
     &lt;span class="err"&gt;Loaded:&lt;/span&gt; &lt;span class="err"&gt;loaded&lt;/span&gt; &lt;span class="err"&gt;(/usr/lib/systemd/system/httpd.service&lt;/span&gt;&lt;span class="c"&gt;; enabled; preset: disabled)&lt;/span&gt;
     &lt;span class="err"&gt;Active:&lt;/span&gt; &lt;span class="err"&gt;active&lt;/span&gt; &lt;span class="err"&gt;(running)&lt;/span&gt;
   &lt;span class="err"&gt;Main&lt;/span&gt; &lt;span class="err"&gt;PID:&lt;/span&gt; &lt;span class="err"&gt;29475&lt;/span&gt; &lt;span class="err"&gt;(httpd)&lt;/span&gt;
     &lt;span class="err"&gt;Status:&lt;/span&gt; &lt;span class="err"&gt;"Started,&lt;/span&gt; &lt;span class="err"&gt;listening&lt;/span&gt; &lt;span class="err"&gt;on:&lt;/span&gt; &lt;span class="err"&gt;port&lt;/span&gt; &lt;span class="err"&gt;3000"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Understanding systemctl
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;systemctl start&lt;/td&gt;
&lt;td&gt;Starts the service immediately&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;systemctl enable&lt;/td&gt;
&lt;td&gt;Configures the service to start on boot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;systemctl status&lt;/td&gt;
&lt;td&gt;Shows the current state&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Step 7: Verify Firewall Status
&lt;/h2&gt;

&lt;p&gt;Check if firewalld is active.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl status firewalld
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this environment, firewalld was not installed. If it were active, port 3000 would need to be allowed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;firewall-cmd &lt;span class="nt"&gt;--zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;public &lt;span class="nt"&gt;--add-port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3000/tcp &lt;span class="nt"&gt;--permanent&lt;/span&gt;
firewall-cmd &lt;span class="nt"&gt;--reload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 8: Verify the Headers
&lt;/h2&gt;

&lt;p&gt;Test the configuration using curl.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://localhost:3000/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output shows the HTTP response headers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Thu, 24 Sep 2026 12:01:11 GMT&lt;/span&gt;
&lt;span class="na"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Apache/2.4.62 (CentOS Stream)&lt;/span&gt;
&lt;span class="na"&gt;X-XSS-Protection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1; mode=block&lt;/span&gt;
&lt;span class="na"&gt;X-Frame-Options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SAMEORIGIN&lt;/span&gt;
&lt;span class="na"&gt;X-Content-Type-Options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nosniff&lt;/span&gt;
&lt;span class="na"&gt;Last-Modified&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Thu, 24 Sep 2026 11:59:33 GMT&lt;/span&gt;
&lt;span class="na"&gt;ETag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"27-65c39553de0df"&lt;/span&gt;
&lt;span class="na"&gt;Accept-Ranges&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bytes&lt;/span&gt;
&lt;span class="na"&gt;Content-Length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;39&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;text/html; charset=UTF-8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All three headers are present with the correct values.&lt;/p&gt;

&lt;p&gt;Filter the output for specific headers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://localhost:3000/ | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"X-XSS|X-Frame|X-Content"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Complete Workflow Summary
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Connect to the server&lt;/span&gt;
ssh steve@stapp02
&lt;span class="nb"&gt;sudo &lt;/span&gt;su -

&lt;span class="c"&gt;# 2. Install httpd&lt;/span&gt;
yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; httpd

&lt;span class="c"&gt;# 3. Configure port 3000&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s/^Listen 80/Listen 3000/'&lt;/span&gt; /etc/httpd/conf/httpd.conf
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"^Listen"&lt;/span&gt; /etc/httpd/conf/httpd.conf

&lt;span class="c"&gt;# 4. Create index.html&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Welcome to the xFusionCorp Industries!"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /var/www/html/index.html

&lt;span class="c"&gt;# 5. Configure security headers&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/httpd/conf.d/security-headers.conf &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
Header always set X-XSS-Protection "1; mode=block"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# 6. Start and enable Apache&lt;/span&gt;
systemctl start httpd
systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;httpd
systemctl status httpd

&lt;span class="c"&gt;# 7. Configure firewall (if applicable)&lt;/span&gt;
systemctl status firewalld
&lt;span class="c"&gt;# If active:&lt;/span&gt;
&lt;span class="c"&gt;# firewall-cmd --zone=public --add-port=3000/tcp --permanent&lt;/span&gt;
&lt;span class="c"&gt;# firewall-cmd --reload&lt;/span&gt;

&lt;span class="c"&gt;# 8. Verify&lt;/span&gt;
curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://localhost:3000/
curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://localhost:3000/ | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"X-XSS|X-Frame|X-Content"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Verification Checklist
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Expected&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Apache installed&lt;/td&gt;
&lt;td&gt;`rpm -qa \&lt;/td&gt;
&lt;td&gt;grep httpd`&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Listening on 3000&lt;/td&gt;
&lt;td&gt;`ss -tlnp \&lt;/td&gt;
&lt;td&gt;grep :3000`&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Index page&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cat /var/www/html/index.html&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Welcome message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Headers file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cat /etc/httpd/conf.d/security-headers.conf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Three headers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service running&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl is-active httpd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;active&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service enabled&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl is-enabled httpd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;enabled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Headers present&lt;/td&gt;
&lt;td&gt;&lt;code&gt;curl -I http://localhost:3000/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;All three headers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Apache Fails to Start
&lt;/h3&gt;

&lt;p&gt;Check the configuration syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;httpd &lt;span class="nt"&gt;-t&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the error log.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt; /var/log/httpd/error_log
journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; httpd &lt;span class="nt"&gt;-n&lt;/span&gt; 50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Headers Not Appearing
&lt;/h3&gt;

&lt;p&gt;Verify that mod_headers is enabled.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;httpd &lt;span class="nt"&gt;-M&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;headers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If not enabled, uncomment the LoadModule line in &lt;code&gt;/etc/httpd/conf.modules.d/00-base.conf&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Port Already in Use
&lt;/h3&gt;

&lt;p&gt;Check what is listening on port 3000.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ss &lt;span class="nt"&gt;-tlnp&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; :3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Stop the conflicting service or choose a different port.&lt;/p&gt;

&lt;h3&gt;
  
  
  Firewall Blocking Access
&lt;/h3&gt;

&lt;p&gt;Check firewalld status and allow the port if needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl status firewalld
firewall-cmd &lt;span class="nt"&gt;--zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;public &lt;span class="nt"&gt;--add-port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3000/tcp &lt;span class="nt"&gt;--permanent&lt;/span&gt;
firewall-cmd &lt;span class="nt"&gt;--reload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  SELinux Blocking Port
&lt;/h3&gt;

&lt;p&gt;If SELinux is enforcing, Apache may not be able to bind to port 3000.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;semanage port &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; http_port_t &lt;span class="nt"&gt;-p&lt;/span&gt; tcp 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Use a separate configuration file in &lt;code&gt;/etc/httpd/conf.d/&lt;/code&gt; for custom headers.&lt;/li&gt;
&lt;li&gt;Always test configuration with &lt;code&gt;httpd -t&lt;/code&gt; before restarting.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;Header always set&lt;/code&gt; to ensure headers appear on all responses.&lt;/li&gt;
&lt;li&gt;Document the purpose of each header for future reference.&lt;/li&gt;
&lt;li&gt;Check both the service status and the actual HTTP response after changes.&lt;/li&gt;
&lt;li&gt;Consider Content Security Policy (CSP) for modern XSS protection.&lt;/li&gt;
&lt;li&gt;Regularly review and update security headers as standards evolve.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This guide demonstrated the complete process of installing Apache, configuring it to run on a custom port, creating a test page, and enabling three important security headers. Each step was explained with the underlying concepts to build a deep understanding.&lt;/p&gt;

&lt;p&gt;The key takeaways are that HTTP response headers provide browser-enforced security controls, Apache configuration is modular and can be extended via files in &lt;code&gt;/etc/httpd/conf.d/&lt;/code&gt;, and verification with tools like curl confirms that the configuration is working as intended.&lt;/p&gt;

&lt;p&gt;By applying these headers, the web server gains protection against cross-site scripting, clickjacking, and MIME-type sniffing attacks, contributing to a more secure application environment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Install httpd&lt;/td&gt;
&lt;td&gt;&lt;code&gt;yum install -y httpd&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Change port&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sed -i 's/^Listen 80/Listen 3000/' /etc/httpd/conf/httpd.conf&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Create index&lt;/td&gt;
&lt;td&gt;&lt;code&gt;echo "Welcome..." &amp;gt; /var/www/html/index.html&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add headers&lt;/td&gt;
&lt;td&gt;Create &lt;code&gt;/etc/httpd/conf.d/security-headers.conf&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Start service&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl start httpd&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enable service&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl enable httpd&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test headers&lt;/td&gt;
&lt;td&gt;&lt;code&gt;curl -I http://localhost:3000/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check syntax&lt;/td&gt;
&lt;td&gt;&lt;code&gt;httpd -t&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>linux</category>
    </item>
    <item>
      <title>Linux Bash Scripts</title>
      <dc:creator>Janak Shrestha</dc:creator>
      <pubDate>Wed, 23 Sep 2026 10:49:58 +0000</pubDate>
      <link>https://dev.to/janak0ff/linux-bash-scripts-76d</link>
      <guid>https://dev.to/janak0ff/linux-bash-scripts-76d</guid>
      <description>&lt;p&gt;The production support team of &lt;code&gt;xFusionCorp Industries&lt;/code&gt; is working on developing some bash scripts to automate different day to day tasks. One is to create a bash script for archiving website content files. They have a static website running on &lt;code&gt;App Server 3&lt;/code&gt; in &lt;code&gt;Stratos Datacenter&lt;/code&gt;, and they need to create a bash script named &lt;code&gt;blog_archive.sh&lt;/code&gt; which should accomplish the following tasks. (Also remember to place the script under the &lt;code&gt;/scripts&lt;/code&gt; directory on &lt;code&gt;App Server 3&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;a. Create a zip archive named &lt;code&gt;xfusioncorp_blog.zip&lt;/code&gt; of &lt;code&gt;/var/www/html/blog&lt;/code&gt; directory.&lt;br&gt;&lt;br&gt;
b. Save the archive in the &lt;code&gt;/archives/&lt;/code&gt; directory on the &lt;code&gt;App Server 3&lt;/code&gt;. This is a temporary storage, as archives from this location will be cleaned on a weekly basis. Therefore, the archive should also be copied to the &lt;code&gt;Nautilus Storage Server&lt;/code&gt; so it can be retrieved later for validation purposes.&lt;br&gt;&lt;br&gt;
c. Copy the created archive to the &lt;code&gt;Nautilus Storage Server&lt;/code&gt; server in the &lt;code&gt;/archives/&lt;/code&gt; location.&lt;br&gt;&lt;br&gt;
d. Please make sure script won't ask for password while copying the archive file. Additionally, the respective server user (for example, &lt;code&gt;tony&lt;/code&gt; in case of &lt;code&gt;App Server 1&lt;/code&gt;) must be able to run it.&lt;br&gt;&lt;br&gt;
e. Do not use sudo inside the script.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The zip package must be installed on given App Server before executing the script. This package is essential for creating the zip archive of the website files. Install it manually outside the script.&lt;/p&gt;


&lt;h2&gt;
  
  
  Environment Details
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;App Server&lt;/td&gt;
&lt;td&gt;stapp03&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App Server User&lt;/td&gt;
&lt;td&gt;banner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App Server Password&lt;/td&gt;
&lt;td&gt;BigGr33n&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage Server&lt;/td&gt;
&lt;td&gt;ststor01&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage Server User&lt;/td&gt;
&lt;td&gt;natasha&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage Server Password&lt;/td&gt;
&lt;td&gt;Bl@kW&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Website Directory&lt;/td&gt;
&lt;td&gt;/var/www/html/blog&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Script Location&lt;/td&gt;
&lt;td&gt;/scripts/blog_archive.sh&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Archive Location&lt;/td&gt;
&lt;td&gt;/archives/xfusioncorp_blog.zip&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  Step 1: Connect to App Server 3
&lt;/h2&gt;

&lt;p&gt;Access the server using SSH.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;ssh banner@stapp03
Password: BigGr33n
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Switch to root to perform administrative tasks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;sudo su -
Password: BigGr33n
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Install the zip Package
&lt;/h2&gt;

&lt;p&gt;The zip package is required to create the archive. Install it manually outside the script as specified in the task requirements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the installation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rpm &lt;span class="nt"&gt;-qa&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the package is already installed, the output will show the version.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Create Required Directories
&lt;/h2&gt;

&lt;p&gt;Create the &lt;code&gt;/scripts&lt;/code&gt; directory for the script and the &lt;code&gt;/archives&lt;/code&gt; directory for the archive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /scripts
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /archives
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set ownership so the banner user can write to these directories.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; banner:banner /scripts
&lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; banner:banner /archives
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Generate SSH Keys for Passwordless Copy
&lt;/h2&gt;

&lt;p&gt;The script must copy the archive to the storage server without prompting for a password. This requires SSH key-based authentication.&lt;/p&gt;

&lt;p&gt;Switch to the banner user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;su - banner
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generate an SSH key pair.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-b&lt;/span&gt; 4096 &lt;span class="nt"&gt;-N&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; ~/.ssh/id_rsa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the public key to the storage server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;ssh-copy-id natasha@ststor01
Password: Bl@kW
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test the passwordless login.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh natasha@ststor01 &lt;span class="s2"&gt;"hostname"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the command returns the storage server hostname without prompting for a password, the key authentication is working.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Create the Bash Script
&lt;/h2&gt;

&lt;p&gt;Create the script file at &lt;code&gt;/scripts/blog_archive.sh&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vi /scripts/blog_archive.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# Create a zip archive of the blog directory&lt;/span&gt;
zip &lt;span class="nt"&gt;-r&lt;/span&gt; /archives/xfusioncorp_blog.zip /var/www/html/blog

&lt;span class="c"&gt;# Copy the archive to the Nautilus Storage Server&lt;/span&gt;
scp /archives/xfusioncorp_blog.zip natasha@ststor01:/archives/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the file and exit the editor.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: Make the Script Executable
&lt;/h2&gt;

&lt;p&gt;Set execute permissions on the script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /scripts/blog_archive.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the permissions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /scripts/blog_archive.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 7: Run the Script as the banner User
&lt;/h2&gt;

&lt;p&gt;The task requires that the banner user can run the script. Execute it as banner.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;su - banner &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"/scripts/blog_archive.sh"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output shows the files being added to the archive and the copy progress.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  adding: var/www/html/blog/ (stored 0%)
  adding: var/www/html/blog/index.html (stored 0%)
  adding: var/www/html/blog/.gitkeep (stored 0%)
xfusioncorp_blog.zip                                   100%  588     1.0MB/s   00:00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 8: Verify the Archive
&lt;/h2&gt;

&lt;p&gt;Check that the archive was created locally.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /archives/xfusioncorp_blog.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-rw-r--r-- 1 banner banner 588 Sep 23 10:38 /archives/xfusioncorp_blog.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check that the archive was copied to the storage server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh natasha@ststor01 &lt;span class="s2"&gt;"ls -la /archives/xfusioncorp_blog.zip"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-rw-r--r-- 1 natasha natasha 588 Sep 23 10:38 /archives/xfusioncorp_blog.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the contents of the archive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;unzip &lt;span class="nt"&gt;-l&lt;/span&gt; /archives/xfusioncorp_blog.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Complete Workflow Summary
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Connect to App Server 3&lt;/span&gt;
ssh banner@stapp03
&lt;span class="nb"&gt;sudo &lt;/span&gt;su -

&lt;span class="c"&gt;# 2. Install zip&lt;/span&gt;
yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; zip

&lt;span class="c"&gt;# 3. Create directories&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /scripts /archives
&lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; banner:banner /scripts /archives

&lt;span class="c"&gt;# 4. Generate SSH keys as banner&lt;/span&gt;
su - banner
ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-b&lt;/span&gt; 4096 &lt;span class="nt"&gt;-N&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; ~/.ssh/id_rsa
ssh-copy-id natasha@ststor01

&lt;span class="c"&gt;# 5. Create the script&lt;/span&gt;
vi /scripts/blog_archive.sh
&lt;span class="c"&gt;# Add: zip -r /archives/xfusioncorp_blog.zip /var/www/html/blog&lt;/span&gt;
&lt;span class="c"&gt;# Add: scp /archives/xfusioncorp_blog.zip natasha@ststor01:/archives/&lt;/span&gt;

&lt;span class="c"&gt;# 6. Make executable&lt;/span&gt;
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /scripts/blog_archive.sh

&lt;span class="c"&gt;# 7. Run the script as banner&lt;/span&gt;
su - banner &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"/scripts/blog_archive.sh"&lt;/span&gt;

&lt;span class="c"&gt;# 8. Verify&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /archives/xfusioncorp_blog.zip
ssh natasha@ststor01 &lt;span class="s2"&gt;"ls -la /archives/xfusioncorp_blog.zip"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Script Content
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# Create a zip archive of the blog directory&lt;/span&gt;
zip &lt;span class="nt"&gt;-r&lt;/span&gt; /archives/xfusioncorp_blog.zip /var/www/html/blog

&lt;span class="c"&gt;# Copy the archive to the Nautilus Storage Server&lt;/span&gt;
scp /archives/xfusioncorp_blog.zip natasha@ststor01:/archives/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Key Requirements Explained
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;How It Is Met&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Script named &lt;code&gt;blog_archive.sh&lt;/code&gt; under &lt;code&gt;/scripts&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Created at &lt;code&gt;/scripts/blog_archive.sh&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zip archive of &lt;code&gt;/var/www/html/blog&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;zip -r /archives/xfusioncorp_blog.zip /var/www/html/blog&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Save archive to &lt;code&gt;/archives/&lt;/code&gt; on App Server 3&lt;/td&gt;
&lt;td&gt;Archive saved locally&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copy to Nautilus Storage Server&lt;/td&gt;
&lt;td&gt;&lt;code&gt;scp /archives/xfusioncorp_blog.zip natasha@ststor01:/archives/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No password prompt during copy&lt;/td&gt;
&lt;td&gt;SSH key-based authentication configured&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Run as the banner user&lt;/td&gt;
&lt;td&gt;Script owned by banner, keys generated for banner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No sudo inside the script&lt;/td&gt;
&lt;td&gt;Script uses only zip and scp&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;th&gt;Cause&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;zip: command not found&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;zip package not installed&lt;/td&gt;
&lt;td&gt;&lt;code&gt;yum install -y zip&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;Permission denied&lt;/code&gt; when running script&lt;/td&gt;
&lt;td&gt;Script not executable&lt;/td&gt;
&lt;td&gt;&lt;code&gt;chmod +x /scripts/blog_archive.sh&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password prompt during scp&lt;/td&gt;
&lt;td&gt;SSH keys not configured for banner&lt;/td&gt;
&lt;td&gt;Regenerate keys as banner user&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Host key verification failed&lt;/td&gt;
&lt;td&gt;Host key not accepted&lt;/td&gt;
&lt;td&gt;Run &lt;code&gt;ssh natasha@ststor01&lt;/code&gt; first to accept the key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Archive not copied&lt;/td&gt;
&lt;td&gt;SSH connectivity issue&lt;/td&gt;
&lt;td&gt;Test with &lt;code&gt;ssh natasha@ststor01 "echo test"&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;chown: Operation not permitted&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Not running as root&lt;/td&gt;
&lt;td&gt;Run &lt;code&gt;chown&lt;/code&gt; commands as root&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Always install required packages outside the script, not inside.&lt;/li&gt;
&lt;li&gt;Generate SSH keys as the user who will run the script.&lt;/li&gt;
&lt;li&gt;Test passwordless SSH before relying on it in a script.&lt;/li&gt;
&lt;li&gt;Set appropriate ownership on script and archive directories.&lt;/li&gt;
&lt;li&gt;Keep the script simple and focused on a single task.&lt;/li&gt;
&lt;li&gt;Avoid using sudo inside scripts when not necessary.&lt;/li&gt;
&lt;li&gt;Verify both the local and remote copies of the archive.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This guide covered the creation of a bash script that archives website content and copies it to a remote server. The script uses zip to create the archive and scp to transfer it, with SSH key-based authentication enabling passwordless operation.&lt;/p&gt;

&lt;p&gt;The key steps were installing the zip package, creating the required directories, generating SSH keys for the banner user, writing the script, and verifying that the archive was created and copied successfully.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Install zip&lt;/td&gt;
&lt;td&gt;&lt;code&gt;yum install -y zip&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Create directories&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mkdir -p /scripts /archives&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generate SSH key&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copy SSH key&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh-copy-id natasha@ststor01&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Create archive&lt;/td&gt;
&lt;td&gt;&lt;code&gt;zip -r /archives/xfusioncorp_blog.zip /var/www/html/blog&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copy to remote&lt;/td&gt;
&lt;td&gt;&lt;code&gt;scp /archives/xfusioncorp_blog.zip natasha@ststor01:/archives/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Run script&lt;/td&gt;
&lt;td&gt;&lt;code&gt;su - banner -c "/scripts/blog_archive.sh"&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verify local&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ls -la /archives/xfusioncorp_blog.zip&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verify remote&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh natasha@ststor01 "ls -la /archives/xfusioncorp_blog.zip"&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>linux</category>
      <category>devops</category>
      <category>automation</category>
    </item>
    <item>
      <title>MariaDB Troubleshooting</title>
      <dc:creator>Janak Shrestha</dc:creator>
      <pubDate>Tue, 22 Sep 2026 11:48:08 +0000</pubDate>
      <link>https://dev.to/janak0ff/mariadb-troubleshooting-3m</link>
      <guid>https://dev.to/janak0ff/mariadb-troubleshooting-3m</guid>
      <description>&lt;p&gt;There is a critical issue going on with the &lt;code&gt;Nautilus&lt;/code&gt; application in &lt;code&gt;Stratos DC&lt;/code&gt;. The production support team identified that the application is unable to connect to the database. After digging into the issue, the team found that mariadb service is down on the database server.&lt;br&gt;&lt;br&gt;
Look into the issue and fix the same.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 1: Connect to the Database Server
&lt;/h2&gt;

&lt;p&gt;Access the database server using SSH.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="k"&gt;ssh&lt;/span&gt; peter@stdb01
&lt;span class="k"&gt;Password&lt;/span&gt;: Sp!dy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Switch to root to perform administrative tasks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;su -
Password: Sp!dy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Check the MariaDB Service Status
&lt;/h2&gt;

&lt;p&gt;The first step is to check whether the service is running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl status mariadb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output showed the service was inactive and dead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight systemd"&gt;&lt;code&gt;&lt;span class="err"&gt;○&lt;/span&gt; &lt;span class="err"&gt;mariadb.service&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;MariaDB&lt;/span&gt; &lt;span class="err"&gt;10.5&lt;/span&gt; &lt;span class="err"&gt;database&lt;/span&gt; &lt;span class="err"&gt;server&lt;/span&gt;
     &lt;span class="err"&gt;Loaded:&lt;/span&gt; &lt;span class="err"&gt;loaded&lt;/span&gt; &lt;span class="err"&gt;(/usr/lib/systemd/system/mariadb.service&lt;/span&gt;&lt;span class="c"&gt;; disabled; preset: disabled)&lt;/span&gt;
     &lt;span class="err"&gt;Active:&lt;/span&gt; &lt;span class="err"&gt;inactive&lt;/span&gt; &lt;span class="err"&gt;(dead)&lt;/span&gt;
       &lt;span class="err"&gt;Docs:&lt;/span&gt; &lt;span class="err"&gt;man:mariadbd(8)&lt;/span&gt;
             &lt;span class="err"&gt;https://mariadb.com/kb/en/library/systemd/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The service was not running and was also disabled, meaning it would not start on boot.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Attempt to Start and Enable the Service
&lt;/h2&gt;

&lt;p&gt;Try to start and enable the service to see what error occurs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; &lt;span class="nt"&gt;--now&lt;/span&gt; mariadb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output showed the service failed to start.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Job for mariadb.service failed because the control process exited with error code.
See "systemctl status mariadb.service" and "journalctl -xeu mariadb.service" for details.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Check the Logs
&lt;/h2&gt;

&lt;p&gt;Check the system logs for MariaDB.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; mariadb &lt;span class="nt"&gt;-n&lt;/span&gt; 50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The logs showed the initialization process but did not immediately reveal the root cause.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sep 22 11:41:00 stdb01 systemd[1]: Starting MariaDB 10.5 database server...
Sep 22 11:41:00 stdb01 mariadb-prepare-db-dir[22278]: Initializing MariaDB database
...
Sep 22 11:41:01 stdb01 systemd[1]: mariadb.service: Main process exited, code=exited, st...
Sep 22 11:41:01 stdb01 systemd[1]: mariadb.service: Failed with result 'exit-code'.
Sep 22 11:41:01 stdb01 systemd[1]: Failed to start MariaDB 10.5 database server.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 5: Check the MariaDB Error Log
&lt;/h2&gt;

&lt;p&gt;The MariaDB error log contains more detailed information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /var/log/mariadb/mariadb.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The error log clearly identified the root cause.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2026-09-22 11:41:01 0 [Note] Server socket created on IP: '::'.
2026-09-22 11:41:01 0 [ERROR] mariadbd: Can't create/write to file '/run/mariadb/mariadb.pid' (Errcode: 13 "Permission denied")
2026-09-22 11:41:01 0 [ERROR] Can't start server: can't create PID file: Permission denied
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Root Cause Identified
&lt;/h3&gt;

&lt;p&gt;MariaDB cannot create its PID file at &lt;code&gt;/run/mariadb/mariadb.pid&lt;/code&gt; because of a permission issue. The directory &lt;code&gt;/run/mariadb/&lt;/code&gt; has incorrect ownership or permissions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: Check the Directory Permissions
&lt;/h2&gt;

&lt;p&gt;Inspect the &lt;code&gt;/run/mariadb/&lt;/code&gt; directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /run/mariadb/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output showed the directory was owned by &lt;code&gt;root:mysql&lt;/code&gt; with permissions &lt;code&gt;755&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;drwxr-xr-x 2 root mysql 40 Sep 22 10:23 .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MariaDB runs as the &lt;code&gt;mysql&lt;/code&gt; user. While the group is correct, the directory is owned by &lt;code&gt;root&lt;/code&gt;, and the &lt;code&gt;mysql&lt;/code&gt; user cannot create files in it because the owner permissions do not include write for the &lt;code&gt;mysql&lt;/code&gt; user (the owner is root, and root has write, but mysql is not root).&lt;/p&gt;

&lt;p&gt;Wait, &lt;code&gt;755&lt;/code&gt; means the owner has &lt;code&gt;rwx&lt;/code&gt;, group has &lt;code&gt;r-x&lt;/code&gt;, and others have &lt;code&gt;r-x&lt;/code&gt;. Since the owner is &lt;code&gt;root&lt;/code&gt;, the &lt;code&gt;mysql&lt;/code&gt; user only has group permissions (&lt;code&gt;r-x&lt;/code&gt;), which do not include write. Therefore, &lt;code&gt;mysql&lt;/code&gt; cannot create the PID file.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 7: Fix the Directory Ownership
&lt;/h2&gt;

&lt;p&gt;Change the ownership of the directory to &lt;code&gt;mysql:mysql&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; mysql:mysql /run/mariadb
&lt;span class="nb"&gt;chmod &lt;/span&gt;755 /run/mariadb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the change.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /run/mariadb/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;drwxr-xr-x 2 mysql mysql 40 Sep 22 10:23 .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the &lt;code&gt;mysql&lt;/code&gt; user owns the directory and has write permission.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 8: Start the MariaDB Service
&lt;/h2&gt;

&lt;p&gt;Start the service again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl start mariadb
systemctl status mariadb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The service started successfully.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight systemd"&gt;&lt;code&gt;&lt;span class="err"&gt;●&lt;/span&gt; &lt;span class="err"&gt;mariadb.service&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;MariaDB&lt;/span&gt; &lt;span class="err"&gt;10.5&lt;/span&gt; &lt;span class="err"&gt;database&lt;/span&gt; &lt;span class="err"&gt;server&lt;/span&gt;
     &lt;span class="err"&gt;Loaded:&lt;/span&gt; &lt;span class="err"&gt;loaded&lt;/span&gt; &lt;span class="err"&gt;(/usr/lib/systemd/system/mariadb.service&lt;/span&gt;&lt;span class="c"&gt;; enabled; preset: disabled)&lt;/span&gt;
     &lt;span class="err"&gt;Active:&lt;/span&gt; &lt;span class="err"&gt;active&lt;/span&gt; &lt;span class="err"&gt;(running)&lt;/span&gt; &lt;span class="err"&gt;since&lt;/span&gt; &lt;span class="err"&gt;Tue&lt;/span&gt; &lt;span class="err"&gt;2026-09-22&lt;/span&gt; &lt;span class="err"&gt;11:43:18&lt;/span&gt; &lt;span class="err"&gt;UTC&lt;/span&gt;&lt;span class="c"&gt;; 18ms ago&lt;/span&gt;
   &lt;span class="err"&gt;Main&lt;/span&gt; &lt;span class="err"&gt;PID:&lt;/span&gt; &lt;span class="err"&gt;23135&lt;/span&gt; &lt;span class="err"&gt;(mariadbd)&lt;/span&gt;
     &lt;span class="err"&gt;Status:&lt;/span&gt; &lt;span class="err"&gt;"Taking&lt;/span&gt; &lt;span class="err"&gt;your&lt;/span&gt; &lt;span class="err"&gt;SQL&lt;/span&gt; &lt;span class="err"&gt;requests&lt;/span&gt; &lt;span class="err"&gt;now..."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 9: Verify the Service
&lt;/h2&gt;

&lt;p&gt;Check that the service is listening on port 3306.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ss &lt;span class="nt"&gt;-tlnp&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;3306
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LISTEN 0 80 *:3306 *:* users:(("mariadbd",pid=23135,fd=19))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test the database connection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;mysql&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="nv"&gt;"SELECT 1;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+---+
| 1 |
+---+
| 1 |
+---+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 10: Ensure the Service is Enabled
&lt;/h2&gt;

&lt;p&gt;Confirm the service is enabled to start on boot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl is-enabled mariadb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Complete Troubleshooting Workflow
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Connect to the database server&lt;/span&gt;
ssh peter@stdb01
&lt;span class="nb"&gt;sudo &lt;/span&gt;su -

&lt;span class="c"&gt;# 2. Check service status&lt;/span&gt;
systemctl status mariadb

&lt;span class="c"&gt;# 3. Attempt to start and enable&lt;/span&gt;
systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; &lt;span class="nt"&gt;--now&lt;/span&gt; mariadb

&lt;span class="c"&gt;# 4. Check logs&lt;/span&gt;
journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; mariadb &lt;span class="nt"&gt;-n&lt;/span&gt; 50

&lt;span class="c"&gt;# 5. Check MariaDB error log&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /var/log/mariadb/mariadb.log

&lt;span class="c"&gt;# 6. Check directory permissions&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /run/mariadb/

&lt;span class="c"&gt;# 7. Fix ownership&lt;/span&gt;
&lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; mysql:mysql /run/mariadb
&lt;span class="nb"&gt;chmod &lt;/span&gt;755 /run/mariadb

&lt;span class="c"&gt;# 8. Start service&lt;/span&gt;
systemctl start mariadb
systemctl status mariadb

&lt;span class="c"&gt;# 9. Verify port&lt;/span&gt;
ss &lt;span class="nt"&gt;-tlnp&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;3306

&lt;span class="c"&gt;# 10. Test connection&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SELECT 1;"&lt;/span&gt;

&lt;span class="c"&gt;# 11. Check enabled&lt;/span&gt;
systemctl is-enabled mariadb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Summary of the Fix
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;th&gt;Cause&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MariaDB fails to start&lt;/td&gt;
&lt;td&gt;Permission denied on &lt;code&gt;/run/mariadb/mariadb.pid&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;chown -R mysql:mysql /run/mariadb&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Directory owned by root&lt;/td&gt;
&lt;td&gt;MariaDB runs as mysql user&lt;/td&gt;
&lt;td&gt;Change ownership to mysql:mysql&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service disabled&lt;/td&gt;
&lt;td&gt;Not enabled on boot&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl enable mariadb&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Common MariaDB Issues and Fixes
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Permission denied on PID file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Can't create/write to file '/run/mariadb/mariadb.pid'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;chown -R mysql:mysql /run/mariadb&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;InnoDB corruption&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ib_logfile0 not found&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remove &lt;code&gt;ib_logfile*&lt;/code&gt; and restart&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Port already in use&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Address already in use&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Find and stop conflicting process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data directory permissions&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Can't open file&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;chown -R mysql:mysql /var/lib/mysql&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Configuration errors&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Unknown variable&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Check &lt;code&gt;my.cnf&lt;/code&gt; files&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Verification Checklist
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Expected&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Service Status&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl status mariadb&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;active (running)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Port Listening&lt;/td&gt;
&lt;td&gt;`ss -tlnp \&lt;/td&gt;
&lt;td&gt;grep 3306`&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Connection Test&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mysql -u root -e "SELECT 1;"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enabled on Boot&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl is-enabled mariadb&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;enabled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error Log&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tail /var/log/mariadb/mariadb.log&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No errors&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Always check the service status first.&lt;/li&gt;
&lt;li&gt;Review both system logs and application-specific logs.&lt;/li&gt;
&lt;li&gt;Identify the exact error message before making changes.&lt;/li&gt;
&lt;li&gt;Fix permissions based on the user the service runs as.&lt;/li&gt;
&lt;li&gt;Verify the service after starting it.&lt;/li&gt;
&lt;li&gt;Ensure the service is enabled for boot persistence.&lt;/li&gt;
&lt;li&gt;Document the fix for future reference.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This guide covered a complete MariaDB troubleshooting workflow. The root cause was a permission issue on the &lt;code&gt;/run/mariadb/&lt;/code&gt; directory, which prevented MariaDB from creating its PID file. By changing the ownership to &lt;code&gt;mysql:mysql&lt;/code&gt;, the service started successfully.&lt;/p&gt;

&lt;p&gt;The key steps were checking the service status, reviewing logs, identifying the permission error, fixing the directory ownership, and verifying the service is running and listening on port 3306.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>mariadb</category>
      <category>debugging</category>
    </item>
    <item>
      <title>Haproxy LBR Troubleshooting</title>
      <dc:creator>Janak Shrestha</dc:creator>
      <pubDate>Mon, 21 Sep 2026 11:20:33 +0000</pubDate>
      <link>https://dev.to/janak0ff/haproxy-lbr-troubleshooting-474i</link>
      <guid>https://dev.to/janak0ff/haproxy-lbr-troubleshooting-474i</guid>
      <description>&lt;p&gt;&lt;code&gt;xFusionCorp Industries&lt;/code&gt; has an application running on &lt;code&gt;Nautlitus&lt;/code&gt; infrastructure in &lt;code&gt;Stratos Datacenter&lt;/code&gt;. The monitoring tool recognised that there is an issue with the &lt;code&gt;haproxy&lt;/code&gt; service on the &lt;code&gt;LBR&lt;/code&gt; server. That needs to fixed to make the application work properly.  &lt;/p&gt;

&lt;p&gt;Troubleshoot and fix the issue, and make sure &lt;code&gt;haproxy&lt;/code&gt; service is running on the &lt;code&gt;Nautilus LBR&lt;/code&gt; server. Once fixed, make sure you are able to access the website by running the command &lt;code&gt;curl http://stlb01:80/&lt;/code&gt; in the terminal.&lt;/p&gt;




&lt;h2&gt;
  
  
  Understanding the Environment
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Details&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LBR Server&lt;/td&gt;
&lt;td&gt;stlb01&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LBR User&lt;/td&gt;
&lt;td&gt;loki&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LBR Password&lt;/td&gt;
&lt;td&gt;Mischi3f&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App Server 1&lt;/td&gt;
&lt;td&gt;stapp01 (Apache on port 8080)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App Server 2&lt;/td&gt;
&lt;td&gt;stapp02 (Apache on port 8080)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App Server 3&lt;/td&gt;
&lt;td&gt;stapp03 (Apache on port 8080)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HAProxy Port&lt;/td&gt;
&lt;td&gt;80&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Step 1: Connect to the LBR Server
&lt;/h2&gt;

&lt;p&gt;Access the load balancer server using SSH.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="k"&gt;ssh&lt;/span&gt; loki@stlb01
&lt;span class="k"&gt;Password&lt;/span&gt;: Mischi3f
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Switch to root to perform administrative tasks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;sudo su -
Password: Mischi3f
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Check the HAProxy Service Status
&lt;/h2&gt;

&lt;p&gt;The first step is to check whether the HAProxy service is running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;systemctl status haproxy
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this scenario, the output showed the service had failed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight systemd"&gt;&lt;code&gt;&lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="err"&gt;haproxy.service&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;HAProxy&lt;/span&gt; &lt;span class="err"&gt;Load&lt;/span&gt; &lt;span class="err"&gt;Balancer&lt;/span&gt;
     &lt;span class="err"&gt;Loaded:&lt;/span&gt; &lt;span class="err"&gt;loaded&lt;/span&gt; &lt;span class="err"&gt;(/usr/lib/systemd/system/haproxy.service&lt;/span&gt;&lt;span class="c"&gt;; enabled; preset: disabled)&lt;/span&gt;
    &lt;span class="err"&gt;Drop-In:&lt;/span&gt; &lt;span class="err"&gt;/etc/systemd/system/haproxy.service.d&lt;/span&gt;
             &lt;span class="err"&gt;└─override.conf&lt;/span&gt;
     &lt;span class="err"&gt;Active:&lt;/span&gt; &lt;span class="err"&gt;failed&lt;/span&gt; &lt;span class="err"&gt;(Result:&lt;/span&gt; &lt;span class="err"&gt;exit-code)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The service was in a failed state, indicating a configuration or runtime issue.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Check HAProxy Logs
&lt;/h2&gt;

&lt;p&gt;Check the system logs for HAProxy to identify the root cause.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;journalctl -u haproxy -n 50
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The logs showed the service was trying to execute the haproxy binary with a configuration file but failing with an exit code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;haproxy.service: Executing: /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg ...
haproxy.service: Control process exited, code=exited, status=...
haproxy.service: Failed with result 'exit-code'.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Verify the Configuration Syntax
&lt;/h2&gt;

&lt;p&gt;Run the HAProxy configuration check to identify syntax errors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;haproxy -c -f /etc/haproxy/haproxy.cfg
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output revealed multiple errors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ALERT] (3689) : config : parsing [/etc/haproxy/haproxy.cfg:39] : please use the 'bind' keyword for listening addresses.
[ALERT] (3689) : config : parsing [/etc/haproxy/haproxy.cfg:40] : 'listen' or 'defaults' expected.
[ALERT] (3689) : config : parsing [/etc/haproxy/haproxy.cfg:41] : 'listen' or 'defaults' expected.
[ALERT] (3689) : config : parsing [/etc/haproxy/haproxy.cfg:43] : 'listen' or 'defaults' expected.
[ALERT] (3689) : config : parsing [/etc/haproxy/haproxy.cfg:44] : 'listen' or 'defaults' expected.
[ALERT] (3689) : config : parsing [/etc/haproxy/haproxy.cfg:60]: Missing LF on last line, file might have been truncated at position 36.
[ALERT] (3689) : config : Error(s) found in configuration file : /etc/haproxy/haproxy.cfg
[ALERT] (3689) : config : Fatal errors found in configuration.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Root Cause Identified
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Deprecated Syntax&lt;/strong&gt;: The &lt;code&gt;frontend main *:80&lt;/code&gt; line used old syntax. Modern HAProxy requires &lt;code&gt;frontend main&lt;/code&gt; followed by &lt;code&gt;bind *:80&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Commented-Out Backend&lt;/strong&gt;: The &lt;code&gt;backend app&lt;/code&gt; section was commented out, leaving orphaned &lt;code&gt;balance&lt;/code&gt; and &lt;code&gt;server&lt;/code&gt; lines that caused parsing errors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Missing Newline&lt;/strong&gt;: The file was truncated without a newline at the end.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 5: Examine the Configuration File
&lt;/h2&gt;

&lt;p&gt;View the current configuration to understand the issues.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;cat /etc/haproxy/haproxy.cfg
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problematic sections were identified.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;frontend  main *:80
    acl url_static       path_beg       -i /static /images /javascript /stylesheets
    ...

#backend app
    balance     roundrobin
    server  app1 stapp01:3000 check
    server  app2 stapp02:3000 check
    server  app3 stapp03:3000 check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;backend app&lt;/code&gt; was commented out, and the server definitions were on port 3000.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: Check the Drop-In Override
&lt;/h2&gt;

&lt;p&gt;A systemd drop-in override was present at &lt;code&gt;/etc/systemd/system/haproxy.service.d/override.conf&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;cat /etc/systemd/system/haproxy.service.d/override.conf
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[Service]&lt;/span&gt;
&lt;span class="py"&gt;ExecStartPre&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;
&lt;span class="py"&gt;ExecStartPre&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q&lt;/span&gt;
&lt;span class="py"&gt;ExecStart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;
&lt;span class="py"&gt;ExecStart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -S /run/haproxy-master.sock&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This override forces HAProxy to use only the main configuration file, which is fine. The issue was in the main configuration itself.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 7: Determine the Correct Backend Port
&lt;/h2&gt;

&lt;p&gt;Before fixing the configuration, verify which port the app servers are listening on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;curl -I http://stapp01:8087
curl -I http://stapp02:8087
curl -I http://stapp03:8087
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result: Connection refused on port 8087.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;curl -I http://stapp01:8080
curl -I http://stapp02:8080
curl -I http://stapp03:8080
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result: HTTP 200 OK on port 8080.&lt;/p&gt;

&lt;p&gt;The app servers are listening on &lt;strong&gt;port 8080&lt;/strong&gt;, not 3000 or 8087.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 8: Replace the Configuration with a Valid Version
&lt;/h2&gt;

&lt;p&gt;Replace the configuration file with a clean, valid version.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat &amp;gt; /etc/haproxy/haproxy.cfg &amp;lt;&amp;lt; 'EOF'
global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    stats socket /var/lib/haproxy/stats

defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

frontend main
    bind *:80
    default_backend app

backend app
    balance roundrobin
    server stapp01 stapp01:8080 check
    server stapp02 stapp02:8080 check
    server stapp03 stapp03:8080 check
EOF
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Changes
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Original&lt;/th&gt;
&lt;th&gt;Fixed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;frontend main *:80&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;frontend main&lt;/code&gt; + &lt;code&gt;bind *:80&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;#backend app&lt;/code&gt; (commented)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;backend app&lt;/code&gt; (uncommented)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Orphaned &lt;code&gt;balance&lt;/code&gt; and &lt;code&gt;server&lt;/code&gt; lines&lt;/td&gt;
&lt;td&gt;Properly nested under &lt;code&gt;backend app&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Port 3000&lt;/td&gt;
&lt;td&gt;Port 8080 (correct port)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Missing newline at end&lt;/td&gt;
&lt;td&gt;File ends with newline&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Step 9: Verify the Configuration
&lt;/h2&gt;

&lt;p&gt;Run the configuration check again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;haproxy -c -f /etc/haproxy/haproxy.cfg
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Configuration file is valid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 10: Restart HAProxy
&lt;/h2&gt;

&lt;p&gt;Restart the service to apply the changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;systemctl restart haproxy
systemctl status haproxy
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output should show the service is active and running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight systemd"&gt;&lt;code&gt;&lt;span class="err"&gt;●&lt;/span&gt; &lt;span class="err"&gt;haproxy.service&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;HAProxy&lt;/span&gt; &lt;span class="err"&gt;Load&lt;/span&gt; &lt;span class="err"&gt;Balancer&lt;/span&gt;
     &lt;span class="err"&gt;Loaded:&lt;/span&gt; &lt;span class="err"&gt;loaded&lt;/span&gt; &lt;span class="err"&gt;(/usr/lib/systemd/system/haproxy.service&lt;/span&gt;&lt;span class="c"&gt;; enabled; preset: disabled)&lt;/span&gt;
    &lt;span class="err"&gt;Drop-In:&lt;/span&gt; &lt;span class="err"&gt;/etc/systemd/system/haproxy.service.d&lt;/span&gt;
             &lt;span class="err"&gt;└─override.conf&lt;/span&gt;
     &lt;span class="err"&gt;Active:&lt;/span&gt; &lt;span class="err"&gt;active&lt;/span&gt; &lt;span class="err"&gt;(running)&lt;/span&gt; &lt;span class="err"&gt;since&lt;/span&gt; &lt;span class="err"&gt;Mon&lt;/span&gt; &lt;span class="err"&gt;2026-09-21&lt;/span&gt; &lt;span class="err"&gt;11:16:59&lt;/span&gt; &lt;span class="err"&gt;UTC&lt;/span&gt;&lt;span class="c"&gt;; 23ms ago&lt;/span&gt;
   &lt;span class="err"&gt;Main&lt;/span&gt; &lt;span class="err"&gt;PID:&lt;/span&gt; &lt;span class="err"&gt;3968&lt;/span&gt; &lt;span class="err"&gt;(haproxy)&lt;/span&gt;
     &lt;span class="err"&gt;Status:&lt;/span&gt; &lt;span class="err"&gt;"Ready."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 11: Verify Listening Ports
&lt;/h2&gt;

&lt;p&gt;Confirm HAProxy is listening on port 80.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;ss -tlnp | grep :80
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;LISTEN 0 3000 0.0.0.0:80 0.0.0.0:* users:(("haproxy",pid=3982,fd=9))
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 12: Test the Website
&lt;/h2&gt;

&lt;p&gt;Test the website using curl.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;curl http://stlb01:80/
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Welcome to xFusionCorp Industries!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Complete Troubleshooting Workflow
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Connect to the LBR server&lt;/span&gt;
ssh loki@stlb01
&lt;span class="nb"&gt;sudo &lt;/span&gt;su -

&lt;span class="c"&gt;# 2. Check service status&lt;/span&gt;
systemctl status haproxy

&lt;span class="c"&gt;# 3. Check logs&lt;/span&gt;
journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; haproxy &lt;span class="nt"&gt;-n&lt;/span&gt; 50

&lt;span class="c"&gt;# 4. Check configuration syntax&lt;/span&gt;
haproxy &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /etc/haproxy/haproxy.cfg

&lt;span class="c"&gt;# 5. Examine the configuration file&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/haproxy/haproxy.cfg

&lt;span class="c"&gt;# 6. Check the drop-in override&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/systemd/system/haproxy.service.d/override.conf

&lt;span class="c"&gt;# 7. Determine the correct backend port&lt;/span&gt;
curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://stapp01:8080
curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://stapp02:8080
curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://stapp03:8080

&lt;span class="c"&gt;# 8. Replace configuration with valid version&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/haproxy/haproxy.cfg &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
... (valid configuration) ...
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# 9. Verify configuration&lt;/span&gt;
haproxy &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /etc/haproxy/haproxy.cfg

&lt;span class="c"&gt;# 10. Restart HAProxy&lt;/span&gt;
systemctl restart haproxy
systemctl status haproxy

&lt;span class="c"&gt;# 11. Verify listening ports&lt;/span&gt;
ss &lt;span class="nt"&gt;-tlnp&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; :80

&lt;span class="c"&gt;# 12. Test the website&lt;/span&gt;
curl http://stlb01:80/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Common HAProxy Issues and Fixes
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Deprecated syntax&lt;/td&gt;
&lt;td&gt;&lt;code&gt;please use the 'bind' keyword&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;frontend main&lt;/code&gt; + &lt;code&gt;bind *:80&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commented backend&lt;/td&gt;
&lt;td&gt;&lt;code&gt;'listen' or 'defaults' expected&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Uncomment &lt;code&gt;backend app&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wrong backend port&lt;/td&gt;
&lt;td&gt;503 Service Unavailable&lt;/td&gt;
&lt;td&gt;Verify port with &lt;code&gt;curl&lt;/code&gt; and update config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Missing newline&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Missing LF on last line&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ensure file ends with a newline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Duplicate sections&lt;/td&gt;
&lt;td&gt;Fatal errors&lt;/td&gt;
&lt;td&gt;Ensure unique section names&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Port conflict&lt;/td&gt;
&lt;td&gt;Service fails to start&lt;/td&gt;
&lt;td&gt;Check `ss -tlnp \&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stats socket missing&lt;/td&gt;
&lt;td&gt;Service fails&lt;/td&gt;
&lt;td&gt;Ensure {% raw %}&lt;code&gt;stats socket /var/lib/haproxy/stats&lt;/code&gt; present&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Verification Checklist
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Expected&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Configuration valid&lt;/td&gt;
&lt;td&gt;&lt;code&gt;haproxy -c -f /etc/haproxy/haproxy.cfg&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Configuration file is valid&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service running&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl status haproxy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;active (running)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Listening on port 80&lt;/td&gt;
&lt;td&gt;`ss -tlnp \&lt;/td&gt;
&lt;td&gt;grep :80`&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Website accessible&lt;/td&gt;
&lt;td&gt;&lt;code&gt;curl http://stlb01:80/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Welcome message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backends reachable&lt;/td&gt;
&lt;td&gt;&lt;code&gt;curl -I http://stapp01:8080&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HTTP 200 OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logs clean&lt;/td&gt;
&lt;td&gt;&lt;code&gt;journalctl -u haproxy -n 30&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No errors&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Always verify configuration before restarting&lt;/strong&gt;: Use &lt;code&gt;haproxy -c -f&lt;/code&gt; to check syntax.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use modern syntax&lt;/strong&gt;: Use &lt;code&gt;bind&lt;/code&gt; instead of the deprecated &lt;code&gt;frontend name *:port&lt;/code&gt; syntax.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Verify backend ports&lt;/strong&gt;: Test each backend with &lt;code&gt;curl&lt;/code&gt; before configuring HAProxy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Keep the stats socket&lt;/strong&gt;: The &lt;code&gt;stats socket /var/lib/haproxy/stats&lt;/code&gt; line is required for monitoring.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Check logs regularly&lt;/strong&gt;: Use &lt;code&gt;journalctl -u haproxy&lt;/code&gt; to identify issues early.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Maintain backups&lt;/strong&gt;: Back up the configuration before making changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Document changes&lt;/strong&gt;: Keep a record of configuration changes for auditing.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This guide covered a complete HAProxy troubleshooting workflow. The main issues were:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Deprecated frontend syntax&lt;/strong&gt; that caused parsing errors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commented-out backend&lt;/strong&gt; that left orphaned directives.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Incorrect backend port&lt;/strong&gt; (3000 instead of 8080) that caused 503 errors.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By systematically checking the service status, logs, and configuration, the root cause was identified and fixed. After replacing the configuration with a valid version, HAProxy started successfully and the website became accessible.&lt;/p&gt;

&lt;p&gt;The key takeaways are to always verify configuration syntax before restarting, use modern HAProxy syntax, and confirm backend ports by testing them directly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Check config&lt;/td&gt;
&lt;td&gt;&lt;code&gt;haproxy -c -f /etc/haproxy/haproxy.cfg&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check status&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl status haproxy&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check logs&lt;/td&gt;
&lt;td&gt;&lt;code&gt;journalctl -u haproxy -n 50&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check ports&lt;/td&gt;
&lt;td&gt;`ss -tlnp \&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test website&lt;/td&gt;
&lt;td&gt;{% raw %}&lt;code&gt;curl http://stlb01:80/&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test backend&lt;/td&gt;
&lt;td&gt;&lt;code&gt;curl -I http://stapp01:8080&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Restart service&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl restart haproxy&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;This guide was created based on a real-world HAProxy troubleshooting scenario on the Nautilus LBR server in the Stratos Datacenter.&lt;/p&gt;

</description>
      <category>haproxy</category>
      <category>linux</category>
      <category>debugging</category>
    </item>
  </channel>
</rss>
