<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[The Logbook]]></title><description><![CDATA[A running log of everything I'm learning — Linux, 
cloud, networking, DevOps, and whatever else I'm 
figuring out. Notes written to actually understand 
things,]]></description><link>https://thelogbook.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/6a0b3c4c4e81b730487696bf/98d9b788-1295-470e-b93b-302b379ef342.png</url><title>The Logbook</title><link>https://thelogbook.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Fri, 11 Sep 2026 03:40:31 GMT</lastBuildDate><atom:link href="https://thelogbook.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[The Logbook #08 - Linux Behind the Scenes: Services, SSH, Firewalls, and Flatpak]]></title><description><![CDATA[When I first started using Linux, I learned commands one at a time. I knew that systemctl start httpd started a web server and that ssh connected me to another machine—but I did not fully understand w]]></description><link>https://thelogbook.hashnode.dev/the-logbook-08-linux-services-ssh-firewalls-and-flatpak</link><guid isPermaLink="true">https://thelogbook.hashnode.dev/the-logbook-08-linux-services-ssh-firewalls-and-flatpak</guid><category><![CDATA[AWS]]></category><category><![CDATA[Cloud Computing]]></category><category><![CDATA[rhcsa]]></category><category><![CDATA[Linux]]></category><dc:creator><![CDATA[Anousheh Hussain]]></dc:creator><pubDate>Mon, 07 Sep 2026 15:04:04 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a0b3c4c4e81b730487696bf/facd8d26-64d0-4f07-bc6d-3fa2ef823ada.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When I first started using Linux, I learned commands one at a time. I knew that <code>systemctl start httpd</code> started a web server and that <code>ssh</code> connected me to another machine—but I did not fully understand what was happening behind those commands.</p>
<p>This week, I focused on connecting those pieces.</p>
<p>In this post, I will cover a few foundational terms, explain how Linux services are managed with <code>systemd</code>, set up a simple Apache web server, and finally look at how Flatpak installs desktop applications differently from DNF.</p>
<blockquote>
<p><strong>Note:</strong> I practised these commands on Red Hat Enterprise Linux (RHEL) while logged in as the <code>root</code> user, as we do during system-administration practice. Therefore, the administrative commands below do not use <code>sudo</code>. On a regular user account, equivalent commands require appropriate privileges.</p>
</blockquote>
<hr />
<h2>1. A Few Terms That Made Everything Easier</h2>
<p>Before working with services and software, it helps to understand a few terms that appear everywhere in Linux.</p>
<h3>Configuration file</h3>
<p>A <strong>configuration file</strong> is a file that stores settings used by a program or service.</p>
<p>Instead of changing the program's source code, we edit its configuration to control how it behaves. For example, a web server's configuration can define which port it listens on, where website files are stored, and which modules are enabled.</p>
<p>Configuration files are commonly found inside <code>/etc</code>.</p>
<h3>Plug-in</h3>
<p>A <strong>plug-in</strong> is an additional component that adds a feature to an existing program without replacing the entire program.</p>
<p>For example, a plug-in may add authentication support, a new command, or integration with another tool.</p>
<h3>Bare metal</h3>
<p><strong>Bare metal</strong> means a physical computer running an operating system directly on its hardware, without a virtualization layer between them.</p>
<h3>Virtual machine and hypervisor</h3>
<p>A <strong>virtual machine (VM)</strong> is a software-created computer with its own virtual CPU, memory, storage, and operating system.</p>
<p>A <strong>hypervisor</strong> creates and manages virtual machines by allocating physical resources to them.</p>
<table>
<thead>
<tr>
<th>Hypervisor type</th>
<th>Where it runs</th>
<th>Examples</th>
</tr>
</thead>
<tbody><tr>
<td>Type 1 — bare-metal</td>
<td>Directly on the physical hardware</td>
<td>VMware ESXi, Microsoft Hyper-V, KVM-based platforms</td>
</tr>
<tr>
<td>Type 2 — hosted</td>
<td>As an application on a host operating system</td>
<td>Oracle VirtualBox, VMware Workstation</td>
</tr>
</tbody></table>
<p>I use VMware Workstation on my laptop to run a RHEL virtual machine, so that is a <strong>Type 2 hypervisor setup</strong>.</p>
<hr />
<h2>2. What Does SSH Actually Do?</h2>
<p><strong>SSH (Secure Shell)</strong> lets us securely access and control another machine over a network.</p>
<p>Suppose my laptop needs to manage a remote Linux server:</p>
<ul>
<li><p>My laptop is the <strong>SSH client</strong> because it initiates the connection.</p>
</li>
<li><p>The remote machine is the <strong>SSH server</strong> because it accepts the connection.</p>
</li>
<li><p>The <code>sshd</code> daemon on the server listens for SSH connections.</p>
</li>
<li><p>SSH normally uses <strong>TCP port 22</strong>.</p>
</li>
</ul>
<p>To connect, I can run:</p>
<pre><code class="language-bash">ssh username@server-ip
</code></pre>
<p>For example:</p>
<pre><code class="language-bash">ssh zia@192.168.1.50
</code></pre>
<p>Once the connection is established, commands typed in my terminal are executed on the <strong>remote machine</strong>, not on my laptop. SSH encrypts the communication between the client and server.</p>
<h3>SSH authentication</h3>
<p>Two common ways to authenticate are:</p>
<ol>
<li><p><strong>Password authentication</strong> — enter the remote user's password.</p>
</li>
<li><p><strong>SSH key authentication</strong> — the client keeps a private key, while the matching public key is placed on the server.</p>
</li>
</ol>
<p>The private key must remain secret. The public key can safely be copied to the server.</p>
<h3>Checking the SSH service</h3>
<p>The remote server needs its SSH service running:</p>
<pre><code class="language-bash">systemctl status sshd
systemctl enable --now sshd
</code></pre>
<p>The second command both starts <code>sshd</code> now and enables it to start automatically during future boots.</p>
<p>If <code>firewalld</code> is running on the server, SSH must also be allowed through the appropriate firewall zone:</p>
<pre><code class="language-bash">firewall-cmd --permanent --add-service=ssh
firewall-cmd --reload
</code></pre>
<p>Opening SSH on my laptop is not required merely to connect <em>out</em> to another machine. The firewall rule matters on the machine accepting incoming SSH connections.</p>
<hr />
<h2>3. Services and Daemons in Linux</h2>
<p>A <strong>service</strong> is a program or process that provides a function, usually in the background.</p>
<p>Examples include:</p>
<table>
<thead>
<tr>
<th>Service</th>
<th>Purpose</th>
</tr>
</thead>
<tbody><tr>
<td><code>httpd</code></td>
<td>Runs the Apache HTTP web server</td>
</tr>
<tr>
<td><code>sshd</code></td>
<td>Accepts remote SSH connections</td>
</tr>
<tr>
<td><code>firewalld</code></td>
<td>Manages firewall rules</td>
</tr>
<tr>
<td><code>chronyd</code></td>
<td>Keeps system time synchronized</td>
</tr>
<tr>
<td><code>tuned</code></td>
<td>Applies system performance-tuning profiles</td>
</tr>
</tbody></table>
<p>A <strong>daemon</strong> is a background process that waits for work or continuously provides a service. Many daemon names end in <code>d</code>, such as <code>sshd</code> and <code>httpd</code>, although this is a convention rather than a strict rule.</p>
<h3>What is systemd?</h3>
<p><code>systemd</code> is the system and service manager used by RHEL and many other Linux distributions.</p>
<p>During boot, the Linux kernel starts <code>systemd</code> as the first user-space process, normally with <strong>Process ID (PID) 1</strong>. <code>systemd</code> then starts the services and other units required by the system.</p>
<h3>What is systemctl?</h3>
<p><code>systemctl</code> is the command-line tool used to communicate with <code>systemd</code>.</p>
<p>The basic pattern is:</p>
<pre><code class="language-bash">systemctl action unit
</code></pre>
<p>For example:</p>
<pre><code class="language-bash">systemctl restart httpd
</code></pre>
<p>Here:</p>
<ul>
<li><p><code>systemctl</code> is the management command.</p>
</li>
<li><p><code>restart</code> is the requested action.</p>
</li>
<li><p><code>httpd</code> is the service being managed.</p>
</li>
</ul>
<h3>Common systemctl commands</h3>
<pre><code class="language-bash">systemctl start httpd
systemctl stop httpd
systemctl restart httpd
systemctl status httpd
systemctl enable httpd
systemctl disable httpd
</code></pre>
<p>These actions are not interchangeable:</p>
<table>
<thead>
<tr>
<th>Command</th>
<th>What it changes</th>
</tr>
</thead>
<tbody><tr>
<td><code>start</code></td>
<td>Starts the service in the current session</td>
</tr>
<tr>
<td><code>stop</code></td>
<td>Stops it now</td>
</tr>
<tr>
<td><code>restart</code></td>
<td>Stops and starts it again; useful after many configuration changes</td>
</tr>
<tr>
<td><code>status</code></td>
<td>Shows whether it is running and displays recent status information</td>
</tr>
<tr>
<td><code>enable</code></td>
<td>Configures it to start automatically at boot</td>
</tr>
<tr>
<td><code>disable</code></td>
<td>Prevents automatic startup at boot; it does not necessarily stop a running service</td>
</tr>
</tbody></table>
<p>To start a service now <strong>and</strong> enable it for future boots in one command:</p>
<pre><code class="language-bash">systemctl enable --now httpd
</code></pre>
<p>To verify both conditions separately:</p>
<pre><code class="language-bash">systemctl is-active httpd
systemctl is-enabled httpd
</code></pre>
<h3>What is a unit file?</h3>
<p><code>systemd</code> manages resources as <strong>units</strong>. A service unit file, such as <code>httpd.service</code>, contains instructions that tell <code>systemd</code> how the service should be started, stopped, and supervised, along with dependencies and boot-related settings.</p>
<p>Common unit-file locations include:</p>
<ul>
<li><p><code>/usr/lib/systemd/system/</code> for files supplied by installed packages</p>
</li>
<li><p><code>/etc/systemd/system/</code> for administrator-created units and overrides</p>
</li>
<li><p><code>/run/systemd/system/</code> for temporary runtime units</p>
</li>
</ul>
<p>To see the unit file used for a service:</p>
<pre><code class="language-bash">systemctl cat httpd
</code></pre>
<p>If a unit file is manually added or changed, tell <code>systemd</code> to reread its unit definitions:</p>
<pre><code class="language-bash">systemctl daemon-reload
</code></pre>
<p>This reloads <code>systemd</code>'s unit-file configuration. It does <strong>not</strong> automatically restart the service itself.</p>
<hr />
<h2>4. Practical Example: Running an Apache Web Server</h2>
<p>Apache HTTP Server provides web pages to clients. On RHEL, its package and service are called <code>httpd</code>.</p>
<h3>Step 1: Install Apache</h3>
<pre><code class="language-bash">dnf install -y httpd
</code></pre>
<p><code>dnf</code> installs the <code>httpd</code> package and its required dependencies from configured RPM repositories.</p>
<h3>Step 2: Start it now and at boot</h3>
<pre><code class="language-bash">systemctl enable --now httpd
</code></pre>
<h3>Step 3: Check its status</h3>
<pre><code class="language-bash">systemctl status httpd
</code></pre>
<h3>Step 4: Create a simple web page</h3>
<p>Apache's default document root on RHEL is <code>/var/www/html</code>.</p>
<pre><code class="language-bash">echo "Hello from The Logbook" &gt; /var/www/html/index.html
</code></pre>
<h3>Step 5: Test it locally</h3>
<pre><code class="language-bash">curl http://localhost
</code></pre>
<p>If Apache is working, the terminal should return:</p>
<pre><code class="language-text">Hello from The Logbook
</code></pre>
<h3>Step 6: Allow HTTP through the firewall</h3>
<p>If other machines need to open the page and <code>firewalld</code> is active, allow the predefined HTTP service:</p>
<pre><code class="language-bash">firewall-cmd --permanent --add-service=http
firewall-cmd --reload
</code></pre>
<p>HTTP normally uses <strong>TCP port 80</strong>, while HTTPS normally uses <strong>TCP port 443</strong>.</p>
<p>The <code>--permanent</code> option saves the rule so it remains after reboot. <code>--reload</code> applies the permanent configuration to the running firewall.</p>
<p>Check the active firewall configuration with:</p>
<pre><code class="language-bash">firewall-cmd --list-all
</code></pre>
<p>The complete request path now looks like this:</p>
<pre><code class="language-text">Browser -&gt; server firewall -&gt; httpd -&gt; /var/www/html/index.html
</code></pre>
<p>The service may be running correctly while the website is still unreachable from another machine if the firewall blocks HTTP. That is why checking only <code>systemctl status httpd</code> is not always enough.</p>
<h3>A simple troubleshooting order</h3>
<p>When a service does not work, I now check it layer by layer:</p>
<ol>
<li><p><strong>Is the package installed?</strong></p>
<pre><code class="language-bash">rpm -q httpd
</code></pre>
</li>
<li><p><strong>Is the service running?</strong></p>
<pre><code class="language-bash">systemctl status httpd
</code></pre>
</li>
<li><p><strong>What do its logs say?</strong></p>
<pre><code class="language-bash">journalctl -u httpd --since today
</code></pre>
</li>
<li><p><strong>Is it listening on the expected port?</strong></p>
<pre><code class="language-bash">ss -ltnp | grep ':80'
</code></pre>
</li>
<li><p><strong>Does it work locally?</strong></p>
<pre><code class="language-bash">curl http://localhost
</code></pre>
</li>
<li><p><strong>Does the firewall allow the traffic?</strong></p>
<pre><code class="language-bash">firewall-cmd --list-services
</code></pre>
</li>
</ol>
<p>This order helps separate a service problem from a network or firewall problem.</p>
<hr />
<h2>5. Flatpak: A Different Way to Install Applications</h2>
<p>Normally, RHEL installs software as <strong>RPM packages</strong> using DNF. These packages are built for the distribution and use libraries available on the operating system.</p>
<p>For example:</p>
<pre><code class="language-bash">dnf install package-name
</code></pre>
<p>This approach integrates applications closely with the operating system, but desktop application developers may need to package their software differently for multiple Linux distributions. A distribution's repositories may also intentionally provide an older, well-tested version instead of the newest release.</p>
<p><strong>Flatpak</strong> provides another way to distribute and run applications across Linux distributions.</p>
<p>A Flatpak application uses:</p>
<ul>
<li><p>The application itself</p>
</li>
<li><p>A <strong>runtime</strong> containing shared libraries needed by multiple applications</p>
</li>
<li><p>Any additional dependencies that are not already supplied by that runtime</p>
</li>
<li><p>A <strong>sandbox</strong> that limits the application's access to the rest of the system</p>
</li>
</ul>
<p>This reduces dependency and compatibility problems, although Flatpak applications can use more disk space because runtimes and additional components must also be installed.</p>
<h3>Repository vs remote</h3>
<p>Flatpak downloads applications and runtimes from repositories. A configured source pointing to one of these repositories is called a <strong>remote</strong>.</p>
<p>One well-known remote is <strong>Flathub</strong>, which hosts Flatpak applications from many publishers. A remote is the source; Flatpak is the tool that communicates with it.</p>
<blockquote>
<p>A sandbox improves isolation, but it does not automatically make every application trustworthy. The publisher and requested permissions still matter.</p>
</blockquote>
<h3>DNF and Flatpak are not replacements for each other</h3>
<table>
<thead>
<tr>
<th>DNF</th>
<th>Flatpak</th>
</tr>
</thead>
<tbody><tr>
<td>Manages RPM packages</td>
<td>Manages Flatpak applications and runtimes</td>
</tr>
<tr>
<td>Used for system packages, services, libraries, and command-line tools</td>
<td>Used mainly for graphical desktop applications</td>
</tr>
<tr>
<td>Integrates closely with RHEL</td>
<td>Runs applications with sandboxing and Flatpak runtimes</td>
</tr>
<tr>
<td>Uses configured RPM repositories</td>
<td>Uses configured Flatpak remotes</td>
</tr>
</tbody></table>
<p>Flatpak does <strong>not</strong> replace DNF. I would use DNF for components such as <code>httpd</code>, system utilities, libraries, and administrative tools. Flatpak is useful for desktop applications.</p>
<p>On RHEL 10, Flatpak is especially relevant because Flatpaks are the default delivery method for Firefox and Thunderbird.</p>
<hr />
<h2>6. Essential Flatpak Commands</h2>
<h3>Install Flatpak itself</h3>
<p>Flatpak is first installed as a normal RPM package:</p>
<pre><code class="language-bash">dnf install -y flatpak
</code></pre>
<h3>See configured remotes</h3>
<pre><code class="language-bash">flatpak remotes
</code></pre>
<h3>Add Flathub for the current user</h3>
<pre><code class="language-bash">flatpak remote-add --user --if-not-exists flathub \
https://dl.flathub.org/repo/flathub.flatpakrepo
</code></pre>
<p>Here:</p>
<ul>
<li><p><code>--user</code> configures the remote only for the current user.</p>
</li>
<li><p><code>--if-not-exists</code> avoids an error if it has already been added.</p>
</li>
<li><p><code>flathub</code> is the local name assigned to the remote.</p>
</li>
</ul>
<h3>Search for an application</h3>
<pre><code class="language-bash">flatpak search firefox
</code></pre>
<h3>Understand the application ID</h3>
<p>Flatpak applications have unique IDs, usually written in reverse-domain style:</p>
<pre><code class="language-text">org.mozilla.firefox
</code></pre>
<p>Using the application ID avoids confusion when applications have similar names.</p>
<h3>Install an application</h3>
<pre><code class="language-bash">flatpak install --user flathub org.mozilla.firefox
</code></pre>
<p>This means: use Flatpak, install for the current user, get the application from the <code>flathub</code> remote, and select the application with the ID <code>org.mozilla.firefox</code>.</p>
<h3>List installed Flatpaks</h3>
<pre><code class="language-bash">flatpak list
</code></pre>
<p>To show only applications and hide runtimes:</p>
<pre><code class="language-bash">flatpak list --app
</code></pre>
<h3>Run an application</h3>
<pre><code class="language-bash">flatpak run org.mozilla.firefox
</code></pre>
<p>Desktop environments normally add installed applications to the graphical application menu as well.</p>
<h3>Update applications and runtimes</h3>
<pre><code class="language-bash">flatpak update
</code></pre>
<h3>Uninstall an application</h3>
<pre><code class="language-bash">flatpak uninstall --user org.mozilla.firefox
</code></pre>
<h3>User installation vs system installation</h3>
<p>A Flatpak can be installed for one user or for the entire system:</p>
<pre><code class="language-bash"># Current user only
flatpak install --user flathub application-id

# System-wide
flatpak install --system flathub application-id
</code></pre>
<p>Using <code>--user</code> is often convenient for a personal desktop because it does not affect other users.</p>
<hr />
<h2>What Finally Clicked for Me</h2>
<p>The biggest lesson this week was that Linux problems are often made of multiple layers.</p>
<p>Installing <code>httpd</code> gives the system the required program. Starting it creates the running service. Enabling it controls what happens after reboot. The firewall decides whether remote traffic can reach it. Its configuration and content files decide how it behaves and what it serves.</p>
<p>Flatpak follows a different model: it focuses mainly on portable desktop applications, shared runtimes, remotes, and sandboxing. It complements the system package manager instead of replacing it.</p>
<p>Understanding what each layer is responsible for makes the commands much easier to remember—and makes troubleshooting feel far less random.</p>
<hr />
<h2>Quick Command Recap</h2>
<pre><code class="language-bash"># Manage services
systemctl enable --now httpd
systemctl status httpd
systemctl restart httpd
systemctl is-active httpd
systemctl is-enabled httpd

# Check logs
journalctl -u httpd --since today

# Allow HTTP through firewalld
firewall-cmd --permanent --add-service=http
firewall-cmd --reload

# Manage Flatpak applications
flatpak remotes
flatpak search application-name
flatpak install --user remote-name application-id
flatpak list --app
flatpak run application-id
flatpak update
flatpak uninstall --user application-id
</code></pre>
<h2>Detailed Notes on GitHub</h2>
<ul>
<li><a href="https://github.com/anousheh-hussain/cloud-devops-notes">Cloud and DevOps Notes</a></li>
</ul>
<h2>References</h2>
<ul>
<li><p><a href="https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/10/html/deploying_web_servers_and_reverse_proxies/setting-up-the-apache-http-web-server">Red Hat Enterprise Linux 10 — Setting up the Apache HTTP web server</a></p>
</li>
<li><p><a href="https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/10/html/administering_rhel_by_using_the_gnome_desktop_environment/installing-applications-by-using-flatpak">Red Hat Enterprise Linux 10 — Installing applications by using Flatpak</a></p>
</li>
<li><p><a href="https://docs.flatpak.org/en/latest/using-flatpak.html">Flatpak documentation — Using Flatpak</a></p>
</li>
</ul>
<hr />
<p><em>This post is part of</em> <em><strong>The Logbook</strong></em>, where I document what I learn while building practical Linux, cloud, and DevOps skills.</p>
]]></content:encoded></item><item><title><![CDATA[The Logbook #07 — Project : Production-Grade VPC on AWS]]></title><description><![CDATA[What I Built
A two-tier VPC architecture - (Public tier (ALB, internet-facing) + Private tier (EC2, application logic)) across two availability zones:

Public subnets with NAT Gateways and an Applicat]]></description><link>https://thelogbook.hashnode.dev/the-logbook-07-project-production-grade-vpc-on-aws</link><guid isPermaLink="true">https://thelogbook.hashnode.dev/the-logbook-07-project-production-grade-vpc-on-aws</guid><category><![CDATA[AWS]]></category><category><![CDATA[rhcsa]]></category><category><![CDATA[Cloud Computing]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Linux]]></category><dc:creator><![CDATA[Anousheh Hussain]]></dc:creator><pubDate>Mon, 31 Aug 2026 07:58:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a0b3c4c4e81b730487696bf/e15430ce-93f9-40df-8ef7-394a10065019.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>What I Built</h2>
<p>A <strong>two-tier VPC architecture</strong> - (Public tier (ALB, internet-facing) + Private tier (EC2, application logic)) across <strong>two availability zones</strong>:</p>
<ul>
<li><p><strong>Public subnets</strong> with NAT Gateways and an Application Load Balancer</p>
</li>
<li><p><strong>Private subnets</strong> with EC2 instances managed by an Auto Scaling Group</p>
</li>
<li><p>The whole thing isolated inside a custom VPC with layered security</p>
</li>
</ul>
<p>If that sounds like a lot of buzzwords, here's the simple version: I built a network where the servers running the application are <strong>hidden from the internet</strong>, but users can still reach them through a load balancer. And if one server dies, another one spins up automatically.</p>
<hr />
<h2>The Build: Component by Component</h2>
<h3>1. VPC and Subnets</h3>
<p>I created a custom VPC with a <code>/16</code> CIDR block. Then I carved it into:</p>
<ul>
<li><p>2 <strong>public subnets</strong> (one per AZ)</p>
</li>
<li><p>2 <strong>private subnets</strong> (one per AZ)</p>
</li>
</ul>
<p><strong>What I learned:</strong> CIDR block planning matters. If you make your subnets too small, you can't scale later. If you make them too big, you're wasting IP space. I kept it balanced — <code>/24</code> for each subnet, giving me 251 usable IPs per subnet. More than enough for a learning project, but the exercise of calculating it was valuable.</p>
<h3>2. Internet Gateway and NAT Gateways</h3>
<p>Attached an <strong>Internet Gateway (IGW)</strong> to the VPC so the public subnets could reach the internet. Then I created <strong>two NAT Gateways</strong> — one in each public subnet.</p>
<p><strong>What I learned:</strong> Private instances need internet too. They need to download updates, fetch packages, call external APIs. But you don't give them public IPs — that's a security risk. Instead, you route their outbound traffic through a <strong>NAT Gateway</strong> sitting in the public subnet. The private instances can reach out, but nothing from the internet can reach in.</p>
<h3>3. Application Load Balancer (ALB)</h3>
<p>Deployed an ALB across both public subnets. This is the <strong>single entry point</strong> for users. The ALB receives HTTP/HTTPS traffic and forwards it to healthy EC2 instances sitting in the private subnets.</p>
<p><strong>What I learned:</strong> The EC2 instances in private subnets have <strong>no public IP addresses</strong>. You can't SSH into them directly from your laptop. You can't reach them via their IP from a browser. The only way traffic gets in is through the ALB, which is configured to talk to a <strong>Target Group</strong> containing those instances.</p>
<p>This is the <strong>DMZ pattern</strong> — the load balancer lives in the danger zone (public internet), while the application servers live in the safe zone (private network).</p>
<h3>4. Auto Scaling Group (ASG)</h3>
<p>Created a <strong>Launch Template</strong> defining what each instance should look like (AMI, instance type, security group, key pair). Then attached it to an ASG that maintains a minimum number of instances across both AZs.</p>
<p><strong>What I learned:</strong> High availability isn't just having a backup. It's having <strong>automated recovery</strong>. If an instance fails its health check, the ASG terminates it and launches a replacement. If traffic spikes, the ASG can add more instances. If traffic drops, it removes them.</p>
<h3>5. Security Groups (Layered Defense)</h3>
<ul>
<li><p><strong>ALB Security Group:</strong> Allows ports 80 and 443 from anywhere (<code>0.0.0.0/0</code>)</p>
</li>
<li><p><strong>EC2 Security Group:</strong> Allows traffic <strong>only from the ALB's security group</strong>. Not from the internet. Not from my IP. Only from the load balancer.</p>
</li>
<li><p><strong>Bastion Security Group:</strong> Allowed SSH (port 22) only from <strong>my IP address</strong></p>
</li>
</ul>
<p><strong>What I learned:</strong> This is <strong>defense in depth</strong>. Even if someone somehow discovers the private IP of an EC2 instance, they can't reach it. The security group blocks everything except traffic from the ALB. And the ALB only forwards HTTP/HTTPS traffic. An attacker would need to compromise the ALB first, then the instance.</p>
<hr />
<h2>Validating from My RHEL 10 VM</h2>
<p>Here's where my Linux background came in handy. I didn't use PuTTY or some Windows SSH client. I did everything from my <strong>Red Hat Enterprise Linux 10 virtual machine</strong> running on VMware Workstation — the same environment I use for RHCSA practice.</p>
<p><strong>The workflow:</strong></p>
<ol>
<li><p>Downloaded the <code>.pem</code> key from AWS</p>
</li>
<li><p>Transferred it to my RHEL VM via VMware shared folder (<code>/mnt/hgfs/</code>)</p>
</li>
<li><p>Copied it to <code>/root/.ssh/</code> and set <code>chmod 400</code> (because shared folders don't preserve Linux permissions)</p>
</li>
<li><p>SSH'd into the <strong>public bastion</strong> instance first</p>
</li>
<li><p>From the bastion, SSH'd into the <strong>private instances</strong></p>
</li>
<li><p>Ran <code>curl http://&lt;alb-dns-name&gt;</code> to verify traffic flow</p>
</li>
<li><p>Tested outbound internet from private instances using <code>ping</code> and <code>yum update</code></p>
</li>
</ol>
<hr />
<h2>The Mistakes (Because That's Where Learning Happens)</h2>
<h3>Mistake 1: SSH Permission Denied (The .pem File)</h3>
<p>I kept getting <code>WARNING: UNPROTECTED PRIVATE KEY FILE!</code> because I was trying to use the <code>.pem</code> directly from <code>/mnt/hgfs/Downloads/</code> (the VMware shared folder). Shared folders are mounted with Windows permissions, so <code>chmod 400</code> doesn't actually stick.</p>
<p><strong>Fix:</strong> Copy the key to a native Linux directory first (<code>/root/.ssh/</code>), then <code>chmod 400</code> it there.</p>
<p><strong>Lesson:</strong> VMware shared folders are for file transfer, not for running Linux operations that depend on file permissions.</p>
<hr />
<h2>Resources</h2>
<ul>
<li><p><strong>GitHub Repo:</strong> <a href="https://github.com/anousheh-hussain/aws-prod-vpc-project/blob/main/README.md">[Production-Grade AWS VPC Architecture]</a> — Full screenshots, setup notes, and the architecture breakdown</p>
</li>
<li><p><strong>Local environment:</strong> RHEL 10 VM on VMware Workstation</p>
</li>
</ul>
<hr />
<h2>What I'd Do Differently Next Time</h2>
<ol>
<li><p><strong>Use Terraform or CloudFormation.</strong> Clicking through the console is fine for learning, but real teams use Infrastructure as Code. I want to be able to <code>terraform apply</code> and recreate this entire architecture in minutes.</p>
</li>
<li><p><strong>Add CloudWatch alarms.</strong> Right now I have no visibility into CPU, memory, or request latency. I'd add alarms so I know when ASG is actually scaling.</p>
</li>
<li><p><strong>Replace the bastion host with AWS Systems Manager Session Manager.</strong> SSH through a jump box works, but Session Manager is more secure (no open port 22) and doesn't require managing key pairs.</p>
</li>
<li><p><strong>Add a database tier.</strong> This is currently two-tier (web + app). A real application needs a database in a private subnet, possibly with RDS Multi-AZ for redundancy.</p>
</li>
</ol>
<hr />
<h2>About This Journey</h2>
<p>I'm documenting my learning path here — Linux, AWS, Python, and whatever breaks in between. Not polished tutorials. Just honest notes from someone figuring things out.</p>
<p>Currently studying: <strong>RHCSA, AWS core services, Python automation.</strong></p>
<hr />
]]></content:encoded></item><item><title><![CDATA[The Logbook #06 — Linux Special Permissions, ACLs, UMASK, su & Repo Config]]></title><description><![CDATA[Been a bit quiet here — RHCSA classroom training started alongside college and between the two, writing took a back seat. Posting will be once every 10 days or so for now, not weekly.
The learning its]]></description><link>https://thelogbook.hashnode.dev/the-logbook-06-linux-special-permissions-acls-umask-su-repo-config</link><guid isPermaLink="true">https://thelogbook.hashnode.dev/the-logbook-06-linux-special-permissions-acls-umask-su-repo-config</guid><category><![CDATA[Linux]]></category><category><![CDATA[rhcsa]]></category><category><![CDATA[Devops]]></category><category><![CDATA[sysadmin]]></category><category><![CDATA[Cloud Computing]]></category><dc:creator><![CDATA[Anousheh Hussain]]></dc:creator><pubDate>Thu, 13 Aug 2026 08:02:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a0b3c4c4e81b730487696bf/7c578fc1-9ffa-4809-af99-b2ea7cf910a4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Been a bit quiet here — RHCSA classroom training started alongside college and between the two, writing took a back seat. Posting will be once every 10 days or so for now, not weekly.</p>
<p>The learning itself is actually on fast track — almost done with the full RHCSA course. The past two weeks were all Linux, no AWS. And honestly some of the most interesting concepts so far. Special permissions, access control lists, repository setup — things that look intimidating at first but click really fast once you understand the problem they're solving.</p>
<hr />
<h2>SUID — Set User ID</h2>
<h3>The Problem It Solves</h3>
<p>Normal Linux permissions work like this: when you run a program, it runs with YOUR permissions. If you don't have access to a file, the program you're running doesn't either.</p>
<p>But there's a classic problem with this. Every user needs to be able to change their own password. Passwords are stored in <code>/etc/shadow</code> — a file readable only by root. So how does a regular user run <code>passwd</code> and update their own password if they can't read <code>/etc/shadow</code>?</p>
<p>The answer is SUID.</p>
<h3>What SUID Does</h3>
<p>When SUID is set on an executable file, that program runs with the permissions of the <strong>file's owner</strong> — not the person who ran it.</p>
<p>The <code>passwd</code> command is owned by root and has SUID set. So when you run it, it temporarily runs as root, which can access <code>/etc/shadow</code>. Once it finishes, those root privileges go away.</p>
<pre><code class="language-bash">ls -la /usr/bin/passwd
# -rwsr-xr-x. 1 root root ... /usr/bin/passwd
#    ^
#    's' here instead of 'x' = SUID is set
</code></pre>
<p>The lowercase <code>s</code> in the owner's execute position means SUID is set AND the file is executable. An uppercase <code>S</code> means SUID is set but the file is NOT executable (which is unusual and usually a mistake).</p>
<h3>Setting SUID</h3>
<pre><code class="language-bash">chmod u+s filename        # symbolic
chmod 4755 filename       # octal — the 4 at the front = SUID
</code></pre>
<h3>When You'd Use It</h3>
<p>SUID is for executables that need elevated access to do their job but should be available to regular users. Examples already on your system:</p>
<pre><code class="language-bash">ls -la /usr/bin/passwd
ls -la /usr/bin/su
ls -la /usr/bin/ping
</code></pre>
<p>All of these need root-level access internally but are meant for regular users to run.</p>
<p><strong>Security note:</strong> SUID is powerful and potentially dangerous. Setting it on the wrong binary could let users escalate their privileges. Never set SUID on scripts — only compiled binaries. On the RHCSA exam, finding files with SUID set is a common task:</p>
<pre><code class="language-bash">find / -perm /4000 -type f 2&gt;/dev/null     # find all SUID files
</code></pre>
<hr />
<h2>SGID — Set Group ID</h2>
<p>SGID works similarly to SUID but for groups, and it behaves differently depending on whether it's set on a file or a directory.</p>
<h3>SGID on Files</h3>
<p>When SGID is set on an executable, it runs with the permissions of the <strong>file's group</strong>, regardless of who runs it.</p>
<pre><code class="language-bash">ls -la /usr/bin/write
# -rwxr-sr-x ... tty /usr/bin/write
#        ^
#        's' in group execute position = SGID set
</code></pre>
<h3>SGID on Directories — More Commonly Used</h3>
<p>This is where SGID gets really useful. When SGID is set on a <strong>directory</strong>, any file created inside that directory automatically inherits the <strong>group of the directory</strong>, not the primary group of the person who created the file.</p>
<p><strong>Why this matters:</strong> In a team environment where multiple people work in the same directory, without SGID, every person's files get assigned to their own personal primary group. Other team members can't access them properly. With SGID on the shared directory, everything created inside belongs to the team's shared group.</p>
<pre><code class="language-bash">mkdir /shared/project
chown :devteam /shared/project       # set group to devteam
chmod g+s /shared/project            # set SGID
# Now any file anyone creates in /shared/project belongs to devteam group
</code></pre>
<h3>Setting SGID</h3>
<pre><code class="language-bash">chmod g+s filename_or_directory       # symbolic
chmod 2755 filename_or_directory      # octal — the 2 at the front = SGID
</code></pre>
<pre><code class="language-bash">find / -perm /2000 -type f 2&gt;/dev/null    # find SGID files
find / -perm /2000 -type d 2&gt;/dev/null    # find SGID directories
</code></pre>
<hr />
<h2>Sticky Bit</h2>
<h3>The Problem It Solves</h3>
<p><code>/tmp</code> is a directory everyone can write to. Everyone needs it to create temporary files. But if anyone can write to it, can anyone also delete files in it?</p>
<p>Without sticky bit: yes. Any user could delete any other user's files in <code>/tmp</code> — a serious problem.</p>
<p>Sticky bit fixes this.</p>
<h3>What Sticky Bit Does</h3>
<p>When sticky bit is set on a directory, only these people can delete files inside it:</p>
<ul>
<li><p>The file's owner</p>
</li>
<li><p>The directory's owner</p>
</li>
<li><p>Root</p>
</li>
</ul>
<p>Other users can still read and write files in the directory (if permissions allow), but they cannot delete files they don't own.</p>
<pre><code class="language-bash">ls -la /tmp
# drwxrwxrwt ... tmp
#          ^
#          't' in others execute position = sticky bit set
</code></pre>
<p>Lowercase <code>t</code> = sticky bit set AND others have execute permission. Uppercase <code>T</code> = sticky bit set but others don't have execute permission.</p>
<h3>Setting Sticky Bit</h3>
<pre><code class="language-bash">chmod +t /shared/directory            # symbolic
chmod 1777 /shared/directory          # octal — the 1 at the front = sticky bit
</code></pre>
<h3>Quick Summary — Special Permissions</h3>
<table>
<thead>
<tr>
<th>Permission</th>
<th>Octal</th>
<th>On File</th>
<th>On Directory</th>
</tr>
</thead>
<tbody><tr>
<td>SUID</td>
<td>4</td>
<td>Runs as file owner</td>
<td>No effect</td>
</tr>
<tr>
<td>SGID</td>
<td>2</td>
<td>Runs as file's group</td>
<td>New files inherit group</td>
</tr>
<tr>
<td>Sticky Bit</td>
<td>1</td>
<td>No effect</td>
<td>Only owner can delete their files</td>
</tr>
</tbody></table>
<pre><code class="language-bash"># Finding all special permissions at once:
find / -perm /7000 -type f 2&gt;/dev/null
</code></pre>
<hr />
<h2>UMASK — Default Permission Mask</h2>
<h3>What UMASK Is</h3>
<p>Every time you create a file or directory, Linux assigns it default permissions. UMASK controls what those defaults are by specifying which permissions to <strong>remove</strong> from the maximum.</p>
<p>Maximum permissions:</p>
<ul>
<li><p>Files: <code>666</code> (rw-rw-rw-) — execute is never given by default for security</p>
</li>
<li><p>Directories: <code>777</code> (rwxrwxrwx) — execute is needed to enter a directory</p>
</li>
</ul>
<p>UMASK subtracts from these. With a umask of <code>022</code>:</p>
<ul>
<li><p>Files: <code>666 - 022 = 644</code> (rw-r--r--)</p>
</li>
<li><p>Directories: <code>777 - 022 = 755</code> (rwxr-xr-x)</p>
</li>
</ul>
<h3>Checking and Setting UMASK</h3>
<pre><code class="language-bash">umask                    # show current umask value
umask 022                # set umask for current session
umask -S                 # show umask in symbolic form (u=rwx,g=rx,o=rx)
</code></pre>
<h3>Common UMASK Values</h3>
<table>
<thead>
<tr>
<th>UMASK</th>
<th>File permissions</th>
<th>Directory permissions</th>
<th>Use case</th>
</tr>
</thead>
<tbody><tr>
<td><code>022</code></td>
<td><code>644</code></td>
<td><code>755</code></td>
<td>Default, most systems</td>
</tr>
<tr>
<td><code>027</code></td>
<td><code>640</code></td>
<td><code>750</code></td>
<td>Stricter — group read, no others</td>
</tr>
<tr>
<td><code>077</code></td>
<td><code>600</code></td>
<td><code>700</code></td>
<td>Very strict — owner only</td>
</tr>
<tr>
<td><code>002</code></td>
<td><code>664</code></td>
<td><code>775</code></td>
<td>Collaborative — group can write</td>
</tr>
</tbody></table>
<h3>Making UMASK Permanent</h3>
<p>Setting <code>umask</code> in the terminal only affects the current session. To make it permanent:</p>
<pre><code class="language-bash"># For a specific user — edit their shell config:
vim ~/.bashrc
# Add at the bottom:
umask 027

# For all users system-wide:
vim /etc/profile
# or
vim /etc/bashrc
</code></pre>
<h3>UMASK on the RHCSA Exam</h3>
<p>Common exam task: "Set the default umask for user john so that new files are created with permissions 640."</p>
<pre><code class="language-bash"># 640 means: rw-r-----
# File max = 666
# 666 - 640 = 026 → umask should be 026

vim /home/john/.bashrc
# Add: umask 026
</code></pre>
<hr />
<h2>ACL — Access Control Lists</h2>
<h3>Why Standard Permissions Aren't Enough</h3>
<p>Standard Linux permissions give you three sets: owner, group, others. That's it. You can't say "user alice gets read access, user bob gets read+write, user charlie gets nothing, and the rest of the world gets read only" — there aren't enough slots.</p>
<p>ACLs solve this. They let you attach fine-grained permission rules to any file or directory, giving specific users or specific groups their own permission sets, beyond the standard three.</p>
<h3>Checking if ACL is Supported</h3>
<p>ACLs work on most modern Linux filesystems (ext4, xfs — which RHEL uses by default). If you see a <code>+</code> at the end of the permissions in <code>ls -l</code>, that file has an ACL set.</p>
<pre><code class="language-bash">ls -la file.txt
# -rw-r--r--+ 1 anousheh devops ... file.txt
#            ^
#            '+' = ACL is set on this file
</code></pre>
<h3>Viewing ACLs</h3>
<pre><code class="language-bash">getfacl filename           # show all ACL entries for a file
getfacl /shared/project    # works on directories too
</code></pre>
<p>Output looks like:</p>
<pre><code class="language-plaintext"># file: filename
# owner: anousheh
# group: devops
user::rw-              # owner permissions (standard)
user:alice:r--         # alice specifically gets read only
user:bob:rw-           # bob specifically gets read+write
group::r--             # group permissions (standard)
mask::rw-              # effective permission ceiling for named entries
other::r--             # others permissions (standard)
</code></pre>
<h3>Setting ACLs</h3>
<pre><code class="language-bash"># Give a specific user permissions:
setfacl -m u:alice:r-- file.txt          # alice gets read only
setfacl -m u:bob:rw- file.txt            # bob gets read+write
setfacl -m u:charlie:--- file.txt        # charlie gets nothing

# Give a specific group permissions:
setfacl -m g:developers:rwx /project     # developers group gets full access

# Set default ACL on a directory (inherited by new files/dirs created inside):
setfacl -m d:u:alice:rw- /shared/        # alice gets rw on everything created in /shared

# Apply ACL recursively to existing files:
setfacl -R -m u:alice:r-- /shared/       # -R = recursive
</code></pre>
<h3>Removing ACLs</h3>
<pre><code class="language-bash">setfacl -x u:alice file.txt      # remove alice's entry specifically
setfacl -x g:developers file.txt # remove developers group entry
setfacl -b file.txt              # remove ALL ACL entries from file
</code></pre>
<h3>The Mask</h3>
<p>The mask in ACL output defines the maximum effective permissions for all named users and groups (not the owner or others). Even if you give alice <code>rwx</code>, if the mask is <code>r--</code>, alice effectively only gets <code>r--</code>.</p>
<pre><code class="language-bash">setfacl -m m:rw- file.txt        # set the mask to rw-
</code></pre>
<h3>ACL on Directories — Default ACLs</h3>
<p>When you set a default ACL on a directory, any new files or subdirectories created inside automatically inherit those ACLs.</p>
<pre><code class="language-bash">setfacl -m d:u:alice:rw- /project     # d: prefix = default ACL
# Now any file created in /project automatically gives alice rw
</code></pre>
<p>Without default ACLs, you'd have to <code>setfacl</code> on every new file manually.</p>
<hr />
<h2>The su Command — Switch User</h2>
<h3>What su Does</h3>
<p><code>su</code> (switch user) lets you switch to another user account from the terminal without logging out. You authenticate as that user and get a shell running as them.</p>
<pre><code class="language-bash">su username              # switch to username
su                       # switch to root (same as su root)
su -                     # switch to root with full login environment
su - username            # switch to username with full login environment
</code></pre>
<h3>★ The Critical Difference: <code>su</code> vs <code>su -</code></h3>
<p>This is one of the most important things to understand about <code>su</code> and it's tested in interviews.</p>
<p><code>su username</code> (without dash):</p>
<ul>
<li><p>Switches to that user</p>
</li>
<li><p>Keeps your current environment — your current directory, your PATH, your environment variables</p>
</li>
<li><p>You're running as them but in your shell environment, not theirs</p>
</li>
</ul>
<p><code>su - username</code> (with dash):</p>
<ul>
<li><p>Switches to that user</p>
</li>
<li><p>Loads their full login environment — their home directory, their PATH, their <code>.bashrc</code>, their variables</p>
</li>
<li><p>It's as if that user just logged in fresh</p>
</li>
</ul>
<p><strong>Practical difference:</strong></p>
<pre><code class="language-bash">su - root
# You're now in /root, root's PATH includes /sbin, /usr/sbin etc.

su root
# You're still in your previous directory, root's PATH may not be fully loaded
# Commands like fdisk, useradd might not be found because /sbin isn't in PATH
</code></pre>
<p><strong>Rule of thumb:</strong> Almost always use <code>su -</code> with the dash. You want the full environment of the user you're switching to. Using <code>su</code> without the dash leads to subtle bugs where commands aren't found or configs don't load properly.</p>
<h3>su -c — Run a Single Command as Another User</h3>
<pre><code class="language-bash">su -c "command" username          # run one command as username, then return
su -c "cat /etc/shadow" root      # run as root, then drop back to current user
</code></pre>
<p>Useful when you just need to run one privileged command without fully switching sessions.</p>
<h3>Authentication</h3>
<p>When switching to another user with <code>su</code>, you need to know <strong>that user's password</strong>.</p>
<p>Exception: root can <code>su</code> to any user without a password — because root already has unlimited access.</p>
<pre><code class="language-bash"># As regular user: need to know target user's password
su - alice        # prompts for alice's password

# As root: no password needed
su - alice        # switches immediately, no prompt
</code></pre>
<h3>su vs sudo</h3>
<p><code>su</code> gives you a full shell as another user — you stay in that shell until you <code>exit</code>. <code>sudo</code> runs a single command with elevated permissions and returns immediately. Most modern systems prefer <code>sudo</code> because:</p>
<ul>
<li><p>No need to share root password — each user has their own password</p>
</li>
<li><p>Logs every command run with sudo</p>
</li>
<li><p>Can be configured to allow specific commands only</p>
</li>
</ul>
<p>But understanding <code>su</code> is still required for RHCSA.</p>
<h3>Exiting</h3>
<pre><code class="language-bash">exit               # return to your original user
# or Ctrl+D
</code></pre>
<hr />
<h2>Repository Configuration</h2>
<h3>What Repositories Are</h3>
<p>A repository is a structured storage location for packages — either online or local. When you run <code>dnf install httpd</code>, DNF connects to configured repos, finds the package and its dependencies, downloads them, and installs everything.</p>
<p>RHEL has two main repos:</p>
<ul>
<li><p><strong>BaseOS</strong> — core OS packages: kernel, glibc, systemd, core utilities</p>
</li>
<li><p><strong>AppStream</strong> — applications, runtimes, databases, web servers</p>
</li>
</ul>
<p>Both need to be configured. Without repos, <code>dnf install</code> has nowhere to look.</p>
<h3>★ Configuring a Local ISO Repository</h3>
<p>This is a standard RHCSA exam task — the exam machine has no internet access, so you configure the RHEL ISO itself as the package source.</p>
<p><strong>Step 1 — Mount the ISO</strong></p>
<p>In VM settings: attach the RHEL ISO to the CD drive. The system auto-mounts it.</p>
<pre><code class="language-bash">lsblk                          # find where it's mounted — look for sr0
ls /run/media/root/            # confirm ISO contents visible (AppStream and BaseOS)
</code></pre>
<p><strong>Step 2 — Create the repo file</strong></p>
<pre><code class="language-bash">cd /etc/yum.repos.d            # all repo files live here
vim rhel-local.repo            # create new file
</code></pre>
<p><strong>Step 3 — Write the repo file</strong></p>
<pre><code class="language-ini">[BaseOS]
name=BaseOS
baseurl=file:///run/media/root/RHEL-10-0-BaseOS-x86_64/BaseOS
gpgcheck=0
enabled=1

[AppStream]
name=AppStream
baseurl=file:///run/media/root/RHEL-10-0-BaseOS-x86_64/AppStream
gpgcheck=0
enabled=1
</code></pre>
<blockquote>
<p>The path after <code>file:///</code> must match exactly where the ISO is mounted. Use <code>lsblk</code> and <code>ls</code> to find the correct path before writing the file.</p>
</blockquote>
<p><strong>Step 4 — Verify</strong></p>
<pre><code class="language-bash">dnf repolist
# BaseOS and AppStream should appear as enabled

dnf install httpd -y
# Should install without errors
</code></pre>
<h3>Repo File Structure</h3>
<pre><code class="language-ini">[repo-id]          # unique ID — what you see in dnf repolist
name=Any Name      # human-readable label
baseurl=...        # where packages are — URL or file path
gpgcheck=0         # 0 = skip signature check, 1 = verify (needs gpgkey)
enabled=1          # 1 = active, 0 = configured but ignored
</code></pre>
<hr />
<h2>What's next</h2>
<p>LVM, disk partitioning, cron jobs</p>
<p>Full notes on GitHub: <a href="https://github.com/anousheh-hussain/cloud-devops-notes">https://github.com/anousheh-hussain/cloud-devops-notes</a></p>
]]></content:encoded></item><item><title><![CDATA[Cloud Girl Logs — Week 5: Computer Networking Fundamentals & Linux File Permissions]]></title><description><![CDATA[Week 5 is different. Instead of AWS, this week is networking — my exam syllabus covers it thoroughly and networking is just as foundational for DevOps as cloud is. Understanding how data actually move]]></description><link>https://thelogbook.hashnode.dev/week-5-networking-fundamentals-linux-file-permissions</link><guid isPermaLink="true">https://thelogbook.hashnode.dev/week-5-networking-fundamentals-linux-file-permissions</guid><category><![CDATA[networking]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Cloud Computing]]></category><category><![CDATA[rhcsa]]></category><category><![CDATA[Devops]]></category><dc:creator><![CDATA[Anousheh Hussain]]></dc:creator><pubDate>Wed, 22 Jul 2026 17:43:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a0b3c4c4e81b730487696bf/f4a9c2c0-2fc8-49e7-8008-0fa3ccd24cdc.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Week 5 is different. Instead of AWS, this week is networking — my exam syllabus covers it thoroughly and networking is just as foundational for DevOps as cloud is. Understanding how data actually moves across networks is what makes everything in AWS make sense. So this one doubles as exam prep and career prep at the same time.</p>
<hr />
<h2>Networking</h2>
<h3>Overview of Networks</h3>
<p>A network is simply a collection of devices connected together to share resources and communicate. Every time you open a browser, send a file, or SSH into a server — that's a network doing its job.</p>
<p>Key terms that come up everywhere:</p>
<ul>
<li><p><strong>Node</strong> — any device on a network (PC, server, router, switch)</p>
</li>
<li><p><strong>Link</strong> — the connection between nodes (wired or wireless)</p>
</li>
<li><p><strong>Bandwidth</strong> — how much data can be transferred per second</p>
</li>
<li><p><strong>Latency</strong> — delay between sending and receiving data</p>
</li>
<li><p><strong>Protocol</strong> — agreed-upon rules for how devices communicate</p>
</li>
</ul>
<hr />
<h3>Circuit Switching vs Packet Switching</h3>
<p><strong>Circuit Switching</strong> — a dedicated path is established before communication begins and held for the entire duration. Traditional telephone networks. The path is reserved even when no data is being sent — consistent but wasteful.</p>
<p><strong>Packet Switching</strong> — data is broken into packets, each routed independently, reassembled at the destination. The internet uses this. Efficient because bandwidth is only used when data is actually sent, but packets can arrive out of order.</p>
<hr />
<h3>Reference Models — OSI vs TCP/IP</h3>
<p><strong>OSI Model (7 layers):</strong></p>
<table>
<thead>
<tr>
<th>Layer</th>
<th>Name</th>
<th>What it does</th>
</tr>
</thead>
<tbody><tr>
<td>7</td>
<td>Application</td>
<td>User-facing protocols (HTTP, FTP, SMTP)</td>
</tr>
<tr>
<td>6</td>
<td>Presentation</td>
<td>Data formatting, encryption, compression</td>
</tr>
<tr>
<td>5</td>
<td>Session</td>
<td>Managing sessions between applications</td>
</tr>
<tr>
<td>4</td>
<td>Transport</td>
<td>End-to-end delivery, TCP/UDP</td>
</tr>
<tr>
<td>3</td>
<td>Network</td>
<td>Routing and IP addressing</td>
</tr>
<tr>
<td>2</td>
<td>Data Link</td>
<td>Node-to-node delivery, MAC addresses</td>
</tr>
<tr>
<td>1</td>
<td>Physical</td>
<td>Raw bits over physical medium</td>
</tr>
</tbody></table>
<p><strong>TCP/IP Model (4 layers):</strong></p>
<table>
<thead>
<tr>
<th>Layer</th>
<th>Equivalent OSI Layers</th>
</tr>
</thead>
<tbody><tr>
<td>Application</td>
<td>Application + Presentation + Session</td>
</tr>
<tr>
<td>Transport</td>
<td>Transport</td>
</tr>
<tr>
<td>Internet</td>
<td>Network</td>
</tr>
<tr>
<td>Network Access</td>
<td>Data Link + Physical</td>
</tr>
</tbody></table>
<p>OSI is theoretical and used for understanding. TCP/IP is what the internet actually runs on.</p>
<hr />
<h3>Network Topology</h3>
<ul>
<li><p><strong>Bus</strong> — all nodes share one cable. Simple but one failure affects everyone</p>
</li>
<li><p><strong>Star</strong> — all nodes connect to a central switch. Most common in LANs, single point of failure is the center</p>
</li>
<li><p><strong>Ring</strong> — nodes in a circle, data travels in one direction. One break breaks the network</p>
</li>
<li><p><strong>Mesh</strong> — every node connects to every other. Highly reliable, very expensive</p>
</li>
<li><p><strong>Hybrid</strong> — combination, most real networks</p>
</li>
</ul>
<hr />
<h2>Physical Layer</h2>
<h3>Transmission Media</h3>
<p><strong>Guided (wired):</strong></p>
<ul>
<li><p><strong>Twisted Pair</strong> — two copper wires twisted together. Cheapest, used in most ethernet</p>
</li>
<li><p><strong>Coaxial Cable</strong> — inner conductor with metal shield. Better noise resistance. Used in cable TV</p>
</li>
<li><p><strong>Fiber Optic</strong> — transmits light pulses. Immune to electromagnetic interference, fastest, longest distances. Expensive</p>
</li>
</ul>
<p><strong>Unguided (wireless):</strong></p>
<ul>
<li><p><strong>Microwave</strong> — line-of-sight transmission between towers</p>
</li>
<li><p><strong>Satellite</strong> — high latency due to distance</p>
</li>
<li><p><strong>Radio Waves</strong> — omnidirectional, used in WiFi and mobile networks</p>
</li>
<li><p><strong>Infrared</strong> — very short range, TV remotes</p>
</li>
</ul>
<h3>Transmission Modes</h3>
<ul>
<li><p><strong>Simplex</strong> — one direction only. TV broadcast</p>
</li>
<li><p><strong>Half Duplex</strong> — both directions but not simultaneously. Walkie-talkie</p>
</li>
<li><p><strong>Full Duplex</strong> — both directions simultaneously. Phone call, most network communication</p>
</li>
</ul>
<hr />
<h2>Data Link Layer</h2>
<h3>Flow Control</h3>
<p><strong>Stop and Wait</strong> — send one frame, wait for ACK, repeat. Simple but slow.</p>
<p><strong>Sliding Window</strong> — send multiple frames before needing an ACK. The window is how many unacknowledged frames can be in flight at once. Much more efficient.</p>
<h3>Error Control — ARQ Protocols</h3>
<p><strong>Stop and Wait ARQ</strong> — send one, wait for ACK. If ACK doesn't arrive, resend.</p>
<p><strong>Go-Back-N ARQ</strong> — if one frame is lost, retransmit that frame AND all frames sent after it, even correctly received ones. Simple receiver, wasteful retransmission.</p>
<p><strong>Selective Reject ARQ</strong> — only the specific damaged frame is retransmitted. More efficient, but receiver must buffer out-of-order frames.</p>
<h3>Error Detection</h3>
<p><strong>Parity Check</strong> — adds one bit so total 1s are always even or odd. Detects single-bit errors only.</p>
<p><strong>CRC (Cyclic Redundancy Check)</strong> — divides data by a polynomial, appends the remainder. Much stronger than parity. Used in Ethernet.</p>
<p><strong>Checksum</strong> — sum of all data segments. Simple, used in UDP and IP headers.</p>
<h3>Encoding Schemes</h3>
<ul>
<li><p><strong>NRZ</strong> — high voltage = 1, low voltage = 0. Simple but synchronization problems with long runs</p>
</li>
<li><p><strong>Manchester</strong> — transition in the middle of each bit period. Self-synchronizing, used in Ethernet</p>
</li>
<li><p><strong>4B/5B</strong> — maps 4-bit data to 5-bit codes to ensure synchronization transitions</p>
</li>
</ul>
<hr />
<h2>Network Layer</h2>
<h3>IPv4 and IPv6</h3>
<p><strong>IPv4</strong> — 32-bit addresses (192.168.1.1). About 4.3 billion unique addresses. We've run out.</p>
<p><strong>IPv6</strong> — 128-bit addresses in hexadecimal. 340 undecillion addresses. Built-in security, no broadcast.</p>
<h3>Ethernet and CSMA/CD</h3>
<p>CSMA/CD is how early shared Ethernet handled collisions:</p>
<ol>
<li><p>Listen before transmitting — if busy, wait</p>
</li>
<li><p>If free, transmit</p>
</li>
<li><p>If collision detected, stop, send jam signal, wait random backoff, retry</p>
</li>
</ol>
<p>Modern switched Ethernet is full duplex — switches eliminate collisions entirely.</p>
<h3>Routing</h3>
<p><strong>Distance Vector</strong> — routers tell neighbors what destinations they know and the cost. Simple, slow to converge. Used by RIP.</p>
<p><strong>Link State</strong> — each router broadcasts its link states to the whole network. Everyone builds a complete map, runs Dijkstra's shortest path. Faster convergence. Used by OSPF.</p>
<hr />
<h2>Transport and Application Layers</h2>
<h3>TCP vs UDP</h3>
<p><strong>TCP:</strong></p>
<ul>
<li><p>Connection-oriented — three-way handshake (SYN, SYN-ACK, ACK)</p>
</li>
<li><p>Reliable, ordered delivery</p>
</li>
<li><p>Flow and congestion control</p>
</li>
<li><p>Use for: HTTP, email, file transfer</p>
</li>
</ul>
<p><strong>UDP:</strong></p>
<ul>
<li><p>Connectionless — just sends packets</p>
</li>
<li><p>No reliability or ordering guarantees</p>
</li>
<li><p>Much faster, lower overhead</p>
</li>
<li><p>Use for: DNS, video streaming, gaming</p>
</li>
</ul>
<h3>Application Layer Protocols</h3>
<table>
<thead>
<tr>
<th>Protocol</th>
<th>Port</th>
<th>Use</th>
</tr>
</thead>
<tbody><tr>
<td>HTTP</td>
<td>80</td>
<td>Web browsing</td>
</tr>
<tr>
<td>HTTPS</td>
<td>443</td>
<td>Secure web</td>
</tr>
<tr>
<td>FTP</td>
<td>20/21</td>
<td>File transfer</td>
</tr>
<tr>
<td>SMTP</td>
<td>25</td>
<td>Sending email</td>
</tr>
<tr>
<td>POP3</td>
<td>110</td>
<td>Receiving email</td>
</tr>
<tr>
<td>DNS</td>
<td>53</td>
<td>Domain resolution</td>
</tr>
<tr>
<td>SNMP</td>
<td>161</td>
<td>Network management</td>
</tr>
</tbody></table>
<h3>DNS, Firewalls, Gateways</h3>
<p><strong>DNS</strong> — translates domain names to IPs through a hierarchy: root servers, TLD servers, authoritative servers.</p>
<p><strong>Firewall</strong> — filters traffic based on rules. Stateless checks each packet independently, stateful tracks connection state.</p>
<p><strong>Gateway</strong> — connects networks using different protocols. Your home router is a gateway between your LAN and the internet.</p>
<hr />
<h2>Linux Side</h2>
<h3>Group Management</h3>
<p>Groups let you apply permissions to multiple users at once.</p>
<pre><code class="language-bash">groupadd groupname              # create group
groupmod -n newname oldname     # rename group
groupdel groupname              # delete group
gpasswd -a username groupname   # add user to group
gpasswd -d username groupname   # remove user from group
groups username                 # see all groups a user belongs to
cat /etc/group                  # all group info stored here
</code></pre>
<p>Every user has one <strong>primary group</strong> (set at creation) and can have many <strong>supplementary groups</strong>. Files created by a user get assigned to their primary group by default.</p>
<pre><code class="language-bash">id username    # shows UID, primary GID, all supplementary groups
</code></pre>
<hr />
<h3>File Permissions</h3>
<p>Every file has three permission sets — owner, group, others.</p>
<pre><code class="language-bash">ls -l filename
# -rwxr-xr-- 1 anousheh devops 1024 Jul 10 script.sh
</code></pre>
<p>Breaking down <code>-rwxr-xr--</code>:</p>
<ul>
<li><p>First character: file type (<code>-</code> = file, <code>d</code> = directory, <code>l</code> = symlink)</p>
</li>
<li><p>Next 3: owner permissions (rwx)</p>
</li>
<li><p>Next 3: group permissions (r-x)</p>
</li>
<li><p>Last 3: others permissions (r--)</p>
</li>
</ul>
<table>
<thead>
<tr>
<th>Permission</th>
<th>File</th>
<th>Directory</th>
</tr>
</thead>
<tbody><tr>
<td>read (r)</td>
<td>View contents</td>
<td>List contents</td>
</tr>
<tr>
<td>write (w)</td>
<td>Modify file</td>
<td>Create/delete files inside</td>
</tr>
<tr>
<td>execute (x)</td>
<td>Run as program</td>
<td>Enter the directory</td>
</tr>
</tbody></table>
<hr />
<h3>chmod</h3>
<p><strong>Symbolic mode:</strong></p>
<pre><code class="language-bash">chmod u+x file       # add execute for owner
chmod g-w file       # remove write for group
chmod o=r file       # set others to read only
chmod a+r file       # add read for everyone
</code></pre>
<p><strong>Octal mode:</strong> read = 4, write = 2, execute = 1</p>
<pre><code class="language-bash">chmod 755 file    # rwxr-xr-x  (standard for scripts)
chmod 644 file    # rw-r--r--  (standard for files)
chmod 700 file    # rwx------  (owner only, nothing for anyone else)
chmod 777 file    # rwxrwxrwx  (everyone full access — avoid this)
</code></pre>
<hr />
<h3>chown</h3>
<pre><code class="language-bash">chown username file              # change owner
chown username:groupname file    # change owner and group
chown :groupname file            # change group only
chown -R username directory/     # change recursively
</code></pre>
<p>Only root can change file ownership. A regular user can change a file's group but only to a group they already belong to.</p>
<hr />
<h2>What's next?</h2>
<p>Next week will mostly focus on revision alongside a few new AWS topics. After a month of uni exams, I have a lot of ground to cover to get back up to speed.</p>
<p>Full notes on GitHub: <a href="https://github.com/anousheh-hussain/cloud-devops-notes"><strong>https://github.com/anousheh-hussain/cloud-devops-notes</strong></a><br />(Will updates the notes soon. Sorry for the delay as I got really busy with exams.)</p>
]]></content:encoded></item><item><title><![CDATA[Cloud Girl Logs — Week 4: S3 Storage Classes, Bucket Policies & Linux User Management]]></title><description><![CDATA[Week 4. S3 on the AWS side, user and password management on Linux. Uni exams are running for the next two weeks so progress will be slower than usual — but not stopped.
AWS Side
S3 — Simple Storage Se]]></description><link>https://thelogbook.hashnode.dev/week-4-s3-storage-classes-bucket-policies-linux-user-management</link><guid isPermaLink="true">https://thelogbook.hashnode.dev/week-4-s3-storage-classes-bucket-policies-linux-user-management</guid><category><![CDATA[rhcsa]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Cloud Computing]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Linux]]></category><dc:creator><![CDATA[Anousheh Hussain]]></dc:creator><pubDate>Sun, 12 Jul 2026 06:11:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a0b3c4c4e81b730487696bf/17e6abef-fe15-4ff3-a70e-65f086ceb016.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Week 4. S3 on the AWS side, user and password management on Linux. Uni exams are running for the next two weeks so progress will be slower than usual — but not stopped.</p>
<h2>AWS Side</h2>
<h3>S3 — Simple Storage Service</h3>
<p>S3 is AWS's object storage service. Unlike a file system where you have folders and files, S3 stores objects — any file, any size — inside containers called <strong>buckets</strong>. A bucket is globally unique, meaning no two AWS accounts anywhere in the world can have a bucket with the same name.</p>
<p>Key things to understand about how S3 works:</p>
<ul>
<li><p>You don't SSH into S3, you don't mount it like a drive — you access it through the AWS console, CLI, or API</p>
</li>
<li><p>Every object stored in S3 gets a unique URL</p>
</li>
<li><p>S3 is a regional service — you create a bucket in a specific region, but the bucket name itself has to be unique globally</p>
</li>
<li><p>Objects can be anywhere from 0 bytes to 5TB. For files larger than 5GB, S3 requires multipart upload</p>
</li>
</ul>
<p>S3 is used for almost everything in AWS — static website hosting, storing application logs, backup and archiving, sharing files between services, storing EC2 AMIs, and more.</p>
<hr />
<h3>S3 Storage Classes</h3>
<p>This is where S3 gets interesting. Not all data needs to be accessed the same way — some files you need instantly, others you haven't touched in years. S3 lets you choose different storage classes based on how often you actually need your data, with different pricing accordingly.</p>
<p><strong>S3 Standard</strong> Default class. High availability, instant access, replicated across at least 3 AZs. Use this for data you access regularly. Most expensive storage cost but no retrieval fee.</p>
<p><strong>S3 Intelligent-Tiering</strong> AWS monitors access patterns and automatically moves objects between frequent and infrequent access tiers. Small monthly monitoring fee per object. Good for data with unpredictable access patterns where you don't want to manually manage tiers.</p>
<p><strong>S3 Standard-IA (Infrequent Access)</strong> Cheaper storage than Standard, but you pay a retrieval fee every time you access the data. Minimum storage duration of 30 days. Use for data you need to keep but don't access often — backups, disaster recovery files.</p>
<p><strong>S3 One Zone-IA</strong> Same as Standard-IA but stored in only one Availability Zone instead of three. Cheaper, but if that AZ goes down you lose the data. Only use for easily reproducible data.</p>
<p><strong>S3 Glacier Instant Retrieval</strong> Archival storage with millisecond retrieval. 90 day minimum storage duration. Much cheaper than Standard, but higher retrieval cost. Good for compliance archives where you might need to pull something quickly but rarely do.</p>
<p><strong>S3 Glacier Flexible Retrieval</strong> Slower retrieval — minutes to hours depending on the tier you choose (Expedited, Standard, or Bulk). Even cheaper storage. Used for long-term archiving where waiting a few hours to retrieve is acceptable.</p>
<p><strong>S3 Glacier Deep Archive</strong> Cheapest S3 storage class. Retrieval takes 12–48 hours. 180 day minimum storage duration. For data you're legally required to keep but will almost certainly never look at — 7-year compliance archives, that kind of thing.</p>
<h3>S3 Bucket Policies</h3>
<p>By default, S3 buckets and everything in them are private. Nothing is publicly accessible unless you explicitly allow it. Bucket policies are JSON documents attached to the bucket that define who can do what with the bucket and its contents.</p>
<p>A simple example — making all objects in a bucket publicly readable:</p>
<pre><code class="language-json">{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::your-bucket-name/*"
    }
  ]
}
</code></pre>
<p>Breaking down the key parts of any bucket policy:</p>
<ul>
<li><p><strong>Effect</strong> — Allow or Deny</p>
</li>
<li><p><strong>Principal</strong> — who this applies to. <code>"*"</code> means everyone, or you can specify an IAM user/role ARN</p>
</li>
<li><p><strong>Action</strong> — what operation is being controlled. <code>s3:GetObject</code> is read, <code>s3:PutObject</code> is write, <code>s3:DeleteObject</code> is delete</p>
</li>
<li><p><strong>Resource</strong> — which bucket or objects this policy applies to</p>
</li>
</ul>
<p>Bucket policies apply at the bucket level and affect anyone accessing it, including other AWS accounts. This is different from IAM policies, which are attached to users/roles and apply to whatever AWS resources they interact with. Both can be used together — an IAM policy can allow S3 access AND the bucket policy can allow it, and both need to agree for access to be granted (unless there's an explicit deny, which always wins regardless).</p>
<hr />
<h2>Linux Side</h2>
<h3>User Management</h3>
<p>Linux is a multi-user system — multiple people or services can have accounts on the same machine, each with their own permissions. Managing these accounts properly is a core part of Linux administration and a heavy RHCSA exam topic.</p>
<p><strong>Creating a user:</strong></p>
<pre><code class="language-bash">useradd username                    # create user
useradd -m username                 # create user with home directory
useradd -m -s /bin/bash username    # specify shell
useradd -m -G groupname username    # add to a group at creation time
</code></pre>
<p><strong>Modifying an existing user:</strong></p>
<pre><code class="language-bash">usermod -aG groupname username    # add user to additional group
usermod -s /bin/bash username     # change login shell
usermod -l newname oldname        # rename user
usermod -L username               # lock user account
usermod -U username               # unlock user account
</code></pre>
<p>The <code>-aG</code> flag is important — the <code>a</code> means append. Without it, <code>usermod -G</code> replaces the user's groups entirely instead of adding to them.</p>
<p><strong>Deleting a user:</strong></p>
<pre><code class="language-bash">userdel username        # delete user, keep home directory
userdel -r username     # delete user and their home directory
</code></pre>
<p><strong>Checking user info:</strong></p>
<pre><code class="language-bash">id username             # shows UID, GID, and all groups
cat /etc/passwd         # user account info stored here
whoami                  # current logged-in user
</code></pre>
<p><code>/etc/passwd</code> stores user info — username, UID, GID, home directory, shell. Despite the name, it doesn't store passwords. That's a common misconception. Passwords are in <code>/etc/shadow</code>, which is root-readable only.</p>
<hr />
<h3>Password Management</h3>
<p><strong>Setting and changing passwords:</strong></p>
<pre><code class="language-bash">passwd username            # set or change a user's password
passwd                     # change your own password
passwd -l username         # lock account (disable password login)
passwd -u username         # unlock account
passwd -d username         # delete password (passwordless login — dangerous)
</code></pre>
<p><strong>Password aging with</strong> <code>chage</code><strong>:</strong></p>
<p>Password aging controls when a password expires, when the user gets warned, and how long they have to change it. This is tested in RHCSA.</p>
<pre><code class="language-bash">chage -l username              # list current aging settings for user
chage -M 90 username           # max password age = 90 days
chage -m 7 username            # min days before password can be changed = 7
chage -W 14 username           # warn user 14 days before expiry
chage -E 2025-12-31 username   # account expires on a specific date
chage -d 0 username            # force password change on next login
</code></pre>
<p><strong>Where passwords actually live:</strong></p>
<pre><code class="language-bash">cat /etc/shadow    # hashed passwords, root-only readable
</code></pre>
<p>Each line in <code>/etc/shadow</code> has 9 fields — username, hashed password, last changed date, minimum age, maximum age, warning period, inactivity period, expiry date, reserved field. The RHCSA exam tests whether you can read and interpret this file.</p>
<p><strong>Important files to know:</strong></p>
<pre><code class="language-bash">/etc/passwd    # user account info (readable by all)
/etc/shadow    # hashed passwords (root only)
/etc/group     # group info
/etc/gshadow   # group passwords (rare but exists)
</code></pre>
<hr />
<h2>What's next?</h2>
<p>Networking Basics<br />Linux: Group Management, File Permissions, chmod, chown</p>
<p>Full notes on GitHub: <a href="https://github.com/anousheh-hussain/cloud-devops-notes">https://github.com/anousheh-hussain/cloud-devops-notes</a></p>
]]></content:encoded></item><item><title><![CDATA[ Cloud Girl Logs — Week 3: Route 53, Auto Scaling, Target Groups, Bastion Host & SSH]]></title><description><![CDATA[This one's coming in a few days late — university exams ate up most of my week. Didn't want to skip it though, so here's Week 3, slightly delayed but complete.
This week was networking and high availa]]></description><link>https://thelogbook.hashnode.dev/week-3-route53-asg-bastion-host-ssh</link><guid isPermaLink="true">https://thelogbook.hashnode.dev/week-3-route53-asg-bastion-host-ssh</guid><category><![CDATA[AWS]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Cloud Computing]]></category><category><![CDATA[rhcsa]]></category><dc:creator><![CDATA[Anousheh Hussain]]></dc:creator><pubDate>Tue, 30 Jun 2026 13:09:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a0b3c4c4e81b730487696bf/88c86497-7f24-4017-87a7-79bb723ee90b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This one's coming in a few days late — university exams ate up most of my week. Didn't want to skip it though, so here's Week 3, slightly delayed but complete.</p>
<p>This week was networking and high availability on the AWS side, and text processing on the Linux side.</p>
<h2>AWS Side</h2>
<h3>Route 53 — DNS</h3>
<p>Route 53 is AWS's DNS service. Before getting into Route 53 specifically, had to actually understand DNS properly first — it's the system that translates domain names like <code>amazon.com</code> into IP addresses computers can use. Without it, you'd have to memorize IP addresses for every website you visit.</p>
<p>When you type a domain into your browser, the request goes through several layers — browser cache, OS cache, then out to a Recursive Resolver, which asks a Root server, which points to a TLD nameserver, which finally points to the Authoritative nameserver holding the actual record. That whole chain happens in milliseconds.</p>
<p>The part that actually confused me at first: Route 53 doesn't store your Load Balancer's IP address directly, because that IP can change anytime AWS scales it. Instead, Route 53 uses something called an <strong>ALIAS record</strong>, which points to the Load Balancer's DNS name instead of a fixed IP, and stays in sync automatically even as the underlying IP changes. A regular CNAME record can't even be used for a root domain like <code>amazon.com</code> — only ALIAS records can, which is one of the reasons Route 53 uses its own record type instead of just relying on standard CNAME.</p>
<p>Also learned about TTL — how long a DNS answer gets cached before being looked up again. Low TTL means changes propagate fast but costs more queries, high TTL means faster lookups but slower propagation if something changes.</p>
<h3>Auto Scaling Groups (ASG)</h3>
<p>ASG automatically manages how many EC2 instances are running based on traffic. Instead of manually deciding instance count, you define three numbers — minimum, maximum, and desired. ASG keeps the count at desired, scales up toward maximum when load increases, and never drops below minimum.</p>
<p>It uses a Launch Template as the blueprint for every new instance it creates — same AMI, same instance type, same security groups, same startup script, every time. Scaling itself is driven by policies, the most common being Target Tracking — for example "keep average CPU at 50%," and ASG handles the rest.</p>
<p>The part I found genuinely clever: ASG also handles its own healing. If an instance fails a health check, ASG kills it and replaces it automatically, no manual intervention needed.</p>
<h3>Target Groups</h3>
<p>A Target Group is what an Application Load Balancer actually routes traffic to — it doesn't send traffic to instances directly. The Target Group holds the list of instances and runs health checks against each one. Only instances that pass the health check get traffic. When ASG creates a new instance, it automatically registers it with the Target Group, and deregisters it before terminating, so in-flight requests aren't dropped mid-way.</p>
<h3>Bastion Host</h3>
<p>A Bastion Host is a small EC2 instance sitting in a public subnet, acting as the single controlled entry point into private infrastructure. Instances in private subnets have no public IP, so they can't be SSH'd into directly from the internet. You SSH into the Bastion first, then from the Bastion into the private instance. The private instance's security group only allows SSH traffic coming from the Bastion's security group — nothing else gets in.</p>
<h3>SSH</h3>
<p>Spent more time actually understanding SSH itself this week instead of just using it as a black box. It's the protocol used to securely connect to and control a remote machine over an encrypted channel, using a key pair instead of a password.</p>
<pre><code class="language-bash">ssh -i keyfile.pem username@ip-address
</code></pre>
<p>Also looked into SSH Agent Forwarding, which keeps your private key only on your local machine even when hopping through a Bastion — the key never actually sits on the Bastion server, which matters a lot if that server is ever compromised.</p>
<h2>Linux Side</h2>
<p>This week was all about working with file content and text processing — pipes, redirection, filters, search/compress utilities, regex, and the VI editor.</p>
<h3>I/O Redirection</h3>
<p>Redirection controls where command input comes from and where output goes.</p>
<pre><code class="language-bash">command &gt; file      # redirect output to file, overwrite
command &gt;&gt; file     # redirect output, append instead
command &lt; file      # use file as input
command 2&gt; errors.log   # redirect only error output
</code></pre>
<h3>Filters in Linux</h3>
<p>Filters are commands that take input, transform it in some way, and produce output. Used constantly when combined with pipes.</p>
<pre><code class="language-bash">sort file            # sort lines
uniq file             # remove duplicate lines
wc -l file            # count lines
cut -d',' -f1 file    # extract a column from delimited data
</code></pre>
<h3>Pipes</h3>
<p>A pipe (<code>|</code>) sends the output of one command directly into the input of another, without needing a temporary file in between.</p>
<pre><code class="language-bash">cat access.log | grep "error" | sort | uniq -c
</code></pre>
<p>This single line filters a log file down to just error lines, sorts them, and counts unique occurrences — chaining filters together is the actual point of the Linux command line.</p>
<h3>Bundle, Find, and Compress Data</h3>
<pre><code class="language-bash">tar -cvf archive.tar folder/      # bundle files into one archive
tar -xvf archive.tar              # extract
gzip file                         # compress
gunzip file.gz                    # decompress
find / -name "*.log"              # search for files by name
find / -size +100M                # search by size
</code></pre>
<h3>Regular Expressions (Regex)</h3>
<p>Regex lets you search for patterns in text rather than exact strings. Used heavily with <code>grep</code>.</p>
<pre><code class="language-bash">grep "^error" file        # lines starting with "error"
grep "fail$" file          # lines ending with "fail"
grep "[0-9]\{3\}" file     # three consecutive digits
grep -E "warn|error" file  # match either word
</code></pre>
<p>The biggest mental shift here was understanding that regex is a separate pattern language from the file globbing covered in week 2 — <code>*</code> means something completely different in each context, and mixing them up is an easy mistake.</p>
<h3>VI Editor</h3>
<p>VI (or VIM) is the default text editor on most Linux systems, including RHEL. No mouse, fully keyboard driven, and has two main modes.</p>
<pre><code class="language-plaintext">i        # enter insert mode (start typing)
Esc      # exit insert mode back to command mode
:wq      # save and quit
:q!      # quit without saving
dd       # delete current line
/word    # search for "word" in the file
</code></pre>
<p>It feels unnatural for the first while, but it's unavoidable for RHCSA since GUI editors usually aren't available on the exam environment.</p>
<h2>What's next?</h2>
<p>In my week 4, I will be covering:</p>
<p>AWS: S3, storage classes, bucket policies<br />Linux: User Management and Password Management</p>
<p>Full notes on GitHub: <a href="https://github.com/anousheh-hussain/cloud-devops-notes">https://github.com/anousheh-hussain/cloud-devops-notes</a></p>
]]></content:encoded></item><item><title><![CDATA[Cloud Girl Logs — Week 2: VPC, Security Groups, NACLs & Linux Shell Expansion]]></title><description><![CDATA[Week 2 done. This week felt heavier than week 1 — VPC on the AWS side took the most time, and shell expansion on the Linux side was more interesting than I expected.
AWS Side
VPC — Virtual Private Clo]]></description><link>https://thelogbook.hashnode.dev/cloud-girl-logs-week-2-vpc-security-groups-nacls-linux-shell-expansion</link><guid isPermaLink="true">https://thelogbook.hashnode.dev/cloud-girl-logs-week-2-vpc-security-groups-nacls-linux-shell-expansion</guid><category><![CDATA[AWS]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Cloud Computing]]></category><category><![CDATA[rhcsa]]></category><dc:creator><![CDATA[Anousheh Hussain]]></dc:creator><pubDate>Wed, 17 Jun 2026 09:06:20 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a0b3c4c4e81b730487696bf/8efc1e22-f421-4743-990d-3e0e8a22b856.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Week 2 done. This week felt heavier than week 1 — VPC on the AWS side took the most time, and shell expansion on the Linux side was more interesting than I expected.</p>
<h2>AWS Side</h2>
<h3>VPC — Virtual Private Cloud</h3>
<p>VPC is your own private, isolated network inside AWS. Everything you launch — EC2 instances, databases, anything — lives inside a VPC. Think of it as your own data center, but in the cloud.</p>
<p>When you create an AWS account, a default VPC already exists in every region. You can use it, but for real projects you always create a custom one.</p>
<p>Key components:</p>
<ul>
<li><p><strong>Subnets</strong> — divide your VPC into smaller networks. Public subnet = internet accessible, private subnet = internal only</p>
</li>
<li><p><strong>Internet Gateway</strong> — connects your VPC to the internet. Without this, nothing inside your VPC can reach the outside world, no matter how the rest is configured</p>
</li>
<li><p><strong>Route Tables</strong> — rules that decide where network traffic goes. Every subnet is associated with a route table, and this is usually the missing piece when something "should be reachable" but isn't</p>
</li>
</ul>
<h3>Security Groups</h3>
<p>Security groups are stateful firewalls attached at the instance level. Stateful means if inbound traffic is allowed, the response automatically goes out — no separate outbound rule needed.</p>
<p>Key things:</p>
<ul>
<li><p>Only allow rules exist, no deny rules</p>
</li>
<li><p>Attached to instances (or other resources), not subnets</p>
</li>
<li><p>Changes take effect immediately</p>
</li>
<li><p>Default security group allows all outbound, blocks all inbound</p>
</li>
</ul>
<p>Inbound rule example:</p>
<pre><code class="language-plaintext">Type: SSH | Protocol: TCP | Port: 22 | Source: My IP
</code></pre>
<h3>NACLs — Network Access Control Lists</h3>
<p>NACLs operate at the subnet level, not the instance level. Unlike security groups, they're stateless — both inbound AND outbound rules need to be explicitly defined.</p>
<p>They also support deny rules, which security groups don't have.</p>
<table>
<thead>
<tr>
<th></th>
<th>Security Group</th>
<th>NACL</th>
</tr>
</thead>
<tbody><tr>
<td>Level</td>
<td>Instance</td>
<td>Subnet</td>
</tr>
<tr>
<td>State</td>
<td>Stateful</td>
<td>Stateless</td>
</tr>
<tr>
<td>Deny rules</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Rule evaluation</td>
<td>All rules</td>
<td>In order by number</td>
</tr>
</tbody></table>
<p>Rule number order matters in NACLs — lower number gets evaluated first, and once a match is found, evaluation stops there.</p>
<h3>IP Addressing in AWS</h3>
<ul>
<li><p><strong>Private IP</strong> — assigned automatically, stays fixed within the VPC even after stop/start</p>
</li>
<li><p><strong>Public IP</strong> — assigned on launch if enabled, but changes every time the instance is stopped and started</p>
</li>
<li><p><strong>Elastic IP</strong> — a static public IP reserved separately and attached to an instance. Doesn't change. Free while attached to a running instance, costs money when idle — so release it when not in use</p>
</li>
</ul>
<p>CIDR notation controls how many IPs are in a subnet. <code>/24</code> gives 256 addresses, <code>/16</code> gives 65,536.</p>
<h2>Linux Side</h2>
<h3>Shell Expansion</h3>
<p>Shell expansion is what happens before a command actually runs — the shell processes and transforms parts of the command first. Understanding this makes the terminal feel a lot less mysterious.</p>
<h3>Control Operators</h3>
<p>These control how multiple commands run together:</p>
<pre><code class="language-bash">command1 ; command2      # run both, regardless of outcome
command1 &amp;&amp; command2     # run command2 only if command1 succeeds
command1 || command2     # run command2 only if command1 fails
command &amp;                # run command in background
</code></pre>
<p><code>&amp;&amp;</code> shows up constantly in real scripts — install something, then only configure it if the install actually succeeded.</p>
<h3>Shell Variables</h3>
<pre><code class="language-bash">NAME="Ziya"               # define variable
echo $NAME                # use variable
export NAME               # make it available to child processes
env                       # see all environment variables
unset NAME                # delete variable
</code></pre>
<p>Important built-in ones:</p>
<ul>
<li><p><code>$HOME</code> — your home directory</p>
</li>
<li><p><code>$PATH</code> — where the shell looks for commands</p>
</li>
<li><p><code>$USER</code> — current username</p>
</li>
<li><p><code>$PWD</code> — current directory</p>
</li>
</ul>
<h3>Shell Embedding (Command Substitution)</h3>
<p>Run a command inside another command — the output gets used inline:</p>
<pre><code class="language-bash">echo "Today is $(date)"
echo "You are logged in as $(whoami)"
FILES=$(ls /etc)       # store command output in a variable
</code></pre>
<p>The <code>$()</code> syntax is preferred over the older backtick style — cleaner and nestable.</p>
<h3>For Loops</h3>
<pre><code class="language-bash">for i in 1 2 3 4 5; 
do
    echo "Number $i"
done
</code></pre>
<p>Loop through files:</p>
<pre><code class="language-bash">for file in /etc/*.conf; 
do
    echo "$file"
done
</code></pre>
<p>C-style loop:</p>
<pre><code class="language-bash">for ((i=1; i&lt;=5; i++)); 
do
    echo $i
done
</code></pre>
<p>Loops matter for automation — creating multiple users, processing files in bulk, anything repetitive.</p>
<h3>File Globbing</h3>
<p>Globbing is pattern matching for filenames, expanded by the shell before the command runs:</p>
<pre><code class="language-plaintext">*          matches anything
?          matches exactly one character
[abc]      matches a, b, or c
[a-z]      matches any lowercase letter
[!abc]     matches anything except a, b, or c
</code></pre>
<p>Examples:</p>
<pre><code class="language-bash">ls *.txt           # all .txt files
ls file?.log       # file1.log, file2.log etc
ls [Rr]eadme*      # Readme or readme, anything after
rm temp[0-9].log   # temp1.log through temp9.log
</code></pre>
<h2>What's next?</h2>
<p>On my third week, I will be diving deep into:<br /><strong>AWS:</strong> Route53, Auto Scaling Group, Target Group, Bastion Host, SSH<br /><strong>Linux:</strong> I/O Redirection, Filters in Linux, bundle/find/compress data, Regex, VI Editor</p>
<p>Full notes on GitHub: <a href="https://github.com/anousheh-hussain/cloud-devops-notes">https://github.com/anousheh-hussain/cloud-devops-notes</a></p>
]]></content:encoded></item><item><title><![CDATA[Cloud Girl Logs — Week 1: AWS + Linux Foundations]]></title><description><![CDATA[This is week 1 of my Cloud + Linux learning log. I'm preparing for RHCSA and AWS SAA simultaneously — alternate days, one topic per session. Writing it down here so it sticks, and maybe it helps someo]]></description><link>https://thelogbook.hashnode.dev/cloud-girl-logs-week-1-aws-linux-foundations</link><guid isPermaLink="true">https://thelogbook.hashnode.dev/cloud-girl-logs-week-1-aws-linux-foundations</guid><category><![CDATA[AWS]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Cloud Computing]]></category><category><![CDATA[rhcsa]]></category><dc:creator><![CDATA[Anousheh Hussain]]></dc:creator><pubDate>Wed, 10 Jun 2026 12:05:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a0b3c4c4e81b730487696bf/4051a021-c21b-44c5-a0df-dee9335474d2.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is week 1 of my Cloud + Linux learning log. I'm preparing for RHCSA and AWS SAA simultaneously — alternate days, one topic per session. Writing it down here so it sticks, and maybe it helps someone else starting out.</p>
<hr />
<h3>AWS Side</h3>
<p><strong>IAM — Identity and Access Management</strong></p>
<p>IAM is how AWS controls who can do what inside your account. Every action — launching an EC2, reading S3, creating a user — goes through IAM first.</p>
<p>Things that actually clicked this week:</p>
<ul>
<li><p>Never use the root account for daily work. Create an IAM admin user and use that instead. Root is only for billing and account-level stuff</p>
</li>
<li><p>Attach policies to groups, not individual users. Much easier to manage when you scale</p>
</li>
<li><p>Least privilege — give only the permissions actually needed, nothing extra</p>
</li>
<li><p>Explicit deny always wins. If one policy allows S3 access and another explicitly denies it, the deny wins every time. No exceptions</p>
</li>
</ul>
<hr />
<p><strong>EC2 — Elastic Compute Cloud</strong></p>
<p>EC2 is basically a virtual machine running in AWS. You pick the OS, instance type, storage, and networking — it's running in minutes.</p>
<p>What I focused on:</p>
<ul>
<li><p>Instance types — t2.micro is free tier, but there are different families optimized for compute, memory, or storage depending on the workload</p>
</li>
<li><p>Key pairs — SSH access to your instance. You get one chance to download the private key when creating it. Lose it and you're locked out</p>
</li>
<li><p>Security groups — act as a virtual firewall. Control what traffic can come in and go out of your instance</p>
</li>
<li><p>Stopping vs terminating — stopping is like shutting down a PC, terminating deletes the instance completely</p>
</li>
</ul>
<hr />
<h3>Linux Side</h3>
<p><strong>What even is Linux</strong></p>
<p>Linux is an open source operating system kernel. The distributions (Ubuntu, RHEL, CentOS, Fedora) are built on top of it. For RHCSA specifically, everything is RHEL-based.</p>
<hr />
<p><strong>Firmware and Low-Level Software</strong></p>
<p>Before the OS even loads, firmware (BIOS or UEFI) runs first. It initializes hardware and hands control to the bootloader, which then loads Linux. Not something you touch daily but important to understand the boot chain.</p>
<hr />
<p><strong>Run-levels and Targets</strong></p>
<p>Older Linux used run-levels. Modern Linux uses systemd targets:</p>
<ul>
<li><p><a href="http://multi-user.target"><code>multi-user.target</code></a> — command line, no GUI (what servers use)</p>
</li>
<li><p><a href="http://graphical.target"><code>graphical.target</code></a> — desktop environment</p>
</li>
<li><p><a href="http://rescue.target"><code>rescue.target</code></a> — minimal mode for recovery</p>
</li>
</ul>
<p>bash</p>
<pre><code class="language-bash">systemctl get-default    # check current target
</code></pre>
<hr />
<p><strong>Linux File System Structure</strong></p>
<p>Everything in Linux starts from <code>/</code> (root). Key directories worth knowing:</p>
<ul>
<li><p><code>/etc</code> — configuration files</p>
</li>
<li><p><code>/var</code> — logs and variable data</p>
</li>
<li><p><code>/home</code> — user home directories</p>
</li>
<li><p><code>/bin</code> and <code>/usr/bin</code> — essential commands</p>
</li>
<li><p><code>/tmp</code> — temporary files, cleared on reboot</p>
</li>
<li><p><code>/root</code> — home directory for the root user specifically</p>
</li>
</ul>
<hr />
<p><strong>SSH Setup</strong></p>
<p>SSH lets you securely connect to a remote Linux machine:</p>
<p>bash</p>
<pre><code class="language-plaintext">ssh -i keyfile.pem username@ip-address
</code></pre>
<p>For RHCSA, <code>/etc/ssh/sshd_config</code> controls server behavior — changing default port, disabling root login, key-based vs password auth are all exam-relevant.</p>
<hr />
<p><strong>DOS vs Linux Terminal</strong></p>
<table>
<thead>
<tr>
<th>DOS/Windows</th>
<th>Linux</th>
</tr>
</thead>
<tbody><tr>
<td><code>dir</code></td>
<td><code>ls</code></td>
</tr>
<tr>
<td><code>copy</code></td>
<td><code>cp</code></td>
</tr>
<tr>
<td><code>del</code></td>
<td><code>rm</code></td>
</tr>
<tr>
<td><code>cls</code></td>
<td><code>clear</code></td>
</tr>
<tr>
<td><code>type</code></td>
<td><code>cat</code></td>
</tr>
</tbody></table>
<hr />
<p><strong>Working with Directories</strong></p>
<p>bash</p>
<pre><code class="language-bash">pwd             # where am I
ls -la          # list all including hidden files
mkdir name      # create directory
mkdir -p a/b/c  # create nested directories in one go
rm -rf name     # remove directory and everything in it
</code></pre>
<hr />
<p><strong>File Creation and Manipulation</strong></p>
<p>bash</p>
<pre><code class="language-bash">touch filename    # create empty file
cp file1 file2    # copy
mv file1 file2    # move or rename
rm filename       # delete
</code></pre>
<hr />
<p><strong>File Content Manipulation</strong></p>
<p>bash</p>
<pre><code class="language-bash">cat file          # print file content
head -n 5 file    # first 5 lines
tail -n 5 file    # last 5 lines
grep "word" file  # search for word inside file
</code></pre>
<p><code>grep</code> is something you'll use constantly. Worth spending extra time on it.</p>
<hr />
<p><strong>Getting Help and Man Pages</strong></p>
<p>bash</p>
<pre><code class="language-bash">man ls       # full manual
ls --help    # quick summary
whatis ls    # one line description
</code></pre>
<p>Man pages are allowed in the RHCSA exam. Get comfortable using them now.</p>
<hr />
<p><strong>Inodes, Hard Links and Soft Links</strong></p>
<p>An <strong>inode</strong> stores file metadata — permissions, owner, size, timestamps. Every file has one.</p>
<p>A <strong>hard link</strong> points to the same inode. Delete the original — the hard link still works.</p>
<p>A <strong>soft link (symlink)</strong> points to the filename. Delete the original — the symlink breaks.</p>
<p>bash</p>
<pre><code class="language-bash">ln file hardlink       # hard link
ln -s file softlink    # soft link
ls -li                 # see inode numbers
</code></pre>
<hr />
<p><strong>What's next?</strong><br />That’s a wrap on Week 1!<br />Next week, I’ll be diving into:<br />AWS: VPC, Security Groups, NACLs, IP Addressing<br />Linux: Shell Expansion(Shell Embedding, File Globbing, etc)</p>
<p>Full notes on GitHub: <a href="https://github.com/anousheh-hussain/cloud-devops-notes">https://github.com/anousheh-hussain/cloud-devops-notes</a></p>
<hr />
]]></content:encoded></item></channel></rss>