<?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" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Abdul-mu&#39;min Omotola on Medium]]></title>
        <description><![CDATA[Stories by Abdul-mu&#39;min Omotola on Medium]]></description>
        <link>https://medium.com/@abdul-mumin?source=rss-902a4c1fad89------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*3U-O9KVwVdCo3g9AQOF-0g.jpeg</url>
            <title>Stories by Abdul-mu&amp;#39;min Omotola on Medium</title>
            <link>https://medium.com/@abdul-mumin?source=rss-902a4c1fad89------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Tue, 10 Nov 2026 05:40:40 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@abdul-mumin/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Terraform vs. CloudFormation: Why Does Terraform Feel Faster?]]></title>
            <link>https://aws.plainenglish.io/terraform-vs-cloudformation-why-does-terraform-feel-faster-4469240a1cdb?source=rss-902a4c1fad89------2</link>
            <guid isPermaLink="false">https://medium.com/p/4469240a1cdb</guid>
            <category><![CDATA[terraform]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[cloudformation]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <dc:creator><![CDATA[Abdul-mu'min Omotola]]></dc:creator>
            <pubDate>Sun, 18 Oct 2026 16:11:54 GMT</pubDate>
            <atom:updated>2026-10-18T16:11:54.281Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bDCnm4XRtXixGHpoMPsjbg.png" /></figure><p>Both Terraform and AWS CloudFormation help automate infrastructure deployment on AWS. But why does Terraform sometimes <em>feel</em> faster?</p><p>The answer is not simply deployment speed. It comes down to how each tool plans, executes, and handles infrastructure changes.</p><h3>1. How they execute deployments</h3><p>Terraform builds a dependency graph to determine which resources can be created or updated independently. It can execute those operations in parallel while respecting dependencies.</p><p>CloudFormation also supports parallel resource creation. However, it coordinates deployments through a managed AWS service.</p><h4><strong>Parallel execution</strong></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uChXklPk99nkY0rG74gUCw.png" /></figure><ul><li>Terraform: Configuration → Dependency graph → Independent resource operations in parallel</li><li>CloudFormation: Template → Managed service → Independent resource operations in parallel</li></ul><p>Neither tool is automatically faster in every situation. Resource dependencies, AWS service provisioning times, and configuration all affect deployment speed.</p><h3>2. What happens when something fails?</h3><p>Failure handling can also affect the experience.</p><p>Terraform may leave successfully created resources in place when an operation fails, so you can inspect the error, correct the configuration, and run another plan.</p><p>CloudFormation commonly rolls back failed stack operations by default, although other failure-handling options are available.</p><h4><strong>Failure handling</strong></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*d5aL1VtGeT_Lbg3QeWvUdw.png" /></figure><ul><li>Terraform: Apply → Error → Inspect state and resources → Fix → Apply again</li><li>CloudFormation: Stack operation → Error → Rollback by default, or use configured alternatives</li></ul><p>Neither approach eliminates troubleshooting. The difference is how recovery is managed.</p><h3>The takeaway</h3><blockquote>I wouldn’t choose Terraform solely because it might finish a deployment sooner. I would consider the wider workflow: how infrastructure is reviewed, how changes are tracked, how failures are handled, and how easily the team can maintain the environment.</blockquote><p>Terraform is particularly attractive when managing infrastructure across multiple providers or when a team prefers its configuration, provider, and state workflow.</p><p>CloudFormation is an equally important tool to understand when working deeply within AWS, especially when native AWS integration and managed stack operations are priorities.</p><p><strong>At the end of the day, the real goal isn’t simply to deploy infrastructure faster.</strong></p><p><strong>It’s to make infrastructure repeatable, understandable, and reliable.</strong></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4469240a1cdb" width="1" height="1" alt=""><hr><p><a href="https://aws.plainenglish.io/terraform-vs-cloudformation-why-does-terraform-feel-faster-4469240a1cdb">Terraform vs. CloudFormation: Why Does Terraform Feel Faster?</a> was originally published in <a href="https://aws.plainenglish.io">AWS in Plain English</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What Happens When Your Web Server Goes Down in AWS Cloud?]]></title>
            <link>https://aws.plainenglish.io/what-happens-when-your-web-server-goes-down-in-aws-cloud-e984562bac00?source=rss-902a4c1fad89------2</link>
            <guid isPermaLink="false">https://medium.com/p/e984562bac00</guid>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[cloud-architec]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <dc:creator><![CDATA[Abdul-mu'min Omotola]]></dc:creator>
            <pubDate>Sun, 11 Oct 2026 12:11:03 GMT</pubDate>
            <atom:updated>2026-10-11T12:11:03.313Z</atom:updated>
            <content:encoded><![CDATA[<h4>Building a highly available application with an Application Load Balancer, EC2 Auto Scaling, and Amazon SNS.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*j0YWZ5EdwCtbctW34gTgJQ.png" /></figure><p>In <a href="https://medium.com/aws-in-plain-english/a-load-balancer-adds-latency-so-why-use-one-7ceccae50d93">the previous episodes of my AWS Solutions Architect journey</a>, I explored IAM, the networking behind cloud applications, and how applications use services such as Amazon S3 and DynamoDB.</p><p>This time, I focused on a question that every cloud architect eventually has to answer:</p><blockquote><strong>What happens when the server running your application becomes unavailable?</strong></blockquote><p>An application might work perfectly when everything is running as expected. But in a real environment, instances can fail, applications can stop responding, and traffic can increase beyond what a single server can comfortably handle.</p><p>Building an application that works is one thing. Designing one that can continue serving users when something goes wrong is another.</p><p>That was the focus of this lab: <strong>configuring high availability for a web application using an Application Load Balancer, Amazon EC2 Auto Scaling, and Amazon SNS.</strong></p><h3>1. Why high availability matters</h3><p>Imagine a web application running on a single EC2 instance.</p><p>A user sends a request, the instance processes it, and the application returns a response.</p><p>Simple enough.</p><p>But what happens if the instance fails?</p><p>What if its web server stops responding? What if the application experiences more traffic than the instance can handle?</p><p>In a single-server architecture, that instance becomes a potential single point of failure. If it becomes unavailable, users may lose access to the application.</p><p>One way to address this is to run multiple instances and introduce a mechanism that distributes incoming requests among them.</p><p>This is where high availability begins to take shape.</p><p>High availability is the ability of a system to remain accessible and operational despite certain component failures. It is achieved through a combination of redundancy, health monitoring, traffic management, and appropriate recovery mechanisms.</p><blockquote>On AWS, several services can work together to support this goal.</blockquote><p>For this lab, three were particularly important:</p><ul><li><strong>Application Load Balancer (ALB):</strong> distributes incoming application traffic across registered targets.</li><li><strong>Amazon EC2 Auto Scaling:</strong> maintains and adjusts the number of EC2 instances according to configured capacity and scaling policies.</li><li><strong>Amazon Simple Notification Service (SNS):</strong> sends notifications when configured events occur, such as Auto Scaling launching or terminating instances.</li></ul><p>Each service has a different responsibility. The real value comes from how they work together.</p><h3>2. Introducing the architecture</h3><p>Before configuring the individual services, it helps to understand the overall design.</p><p>The application runs on EC2 instances within an Amazon VPC. An internet-facing Application Load Balancer provides the entry point for incoming web traffic and forwards requests to registered instances.</p><p>An Auto Scaling Group manages the fleet of EC2 instances, while a target group provides the ALB with the targets to route requests to and the health checks used to evaluate their availability.</p><p>Amazon SNS adds an operational awareness layer by notifying subscribers about selected Auto Scaling events.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1017/1*TVmd8CpR5_Sc9hL-MXYCVA.png" /><figcaption><em>High-level architecture showing internet traffic entering through an Application Load Balancer, reaching EC2 instances across Availability Zones, with an Auto Scaling Group managing capacity and Amazon SNS providing event notifications.</em></figcaption></figure><p>The key idea is that the application no longer depends on a single server being available at all times.</p><p>Instead, several AWS components work together to distribute traffic, manage compute capacity, monitor target health, and communicate important events.</p><p>Let’s look at how each part fits into the design.</p><h3>3. Creating the Application Load Balancer</h3><p>The first major component was the Application Load Balancer.</p><p>An ALB operates at the application layer of the networking stack and is designed to distribute HTTP and HTTPS traffic to registered targets, such as EC2 instances.</p><p>Rather than asking users to connect directly to individual servers, we provide a common entry point through the load balancer.</p><p>I configured an internet-facing Application Load Balancer named Web-Application-ALB.</p><p>An internet-facing ALB is designed to receive requests from clients over the internet. It is associated with a VPC and requires suitable public subnets to provide that connectivity.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eYUvyZvuX7XAjT-eTs-D1Q.png" /><figcaption><em>Configuring an internet-facing Application Load Balancer in the AWS Management Console.</em></figcaption></figure><p>Why does this matter?</p><p>Suppose an application runs on three EC2 instances. Without a load-balancing layer, clients may need to know which server to contact, and traffic distribution becomes a separate concern.</p><p>With an ALB, clients use a single DNS endpoint. The load balancer then forwards requests to appropriate registered targets based on its listener and routing configuration.</p><p>This simplifies the entry point and provides a foundation for distributing traffic as the application grows.</p><h3>4. Understanding target groups and health checks</h3><p>Creating the load balancer is only part of the configuration. The ALB also needs to know where to send requests.</p><p>That is the role of a <strong>target group</strong>.</p><p>A target group defines the destinations to which the load balancer forwards traffic. In this lab, I worked with the target group named lab-app-target-group, configured to send HTTP traffic to registered EC2 instances on port 80.</p><p>Target groups also support health checks.</p><p>A health check periodically sends requests to a configured path on a target to determine whether it is responding as expected. The health-check configuration determines how the response is evaluated.</p><p>When a registered target is considered unhealthy, the load balancer can stop routing normal requests to it while it remains unhealthy, subject to the target group’s configuration and applicable routing behaviour.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*30J1YTDJjbMsnLl-YOTnoQ.png" /><figcaption><em>Inspecting the target group and the health status of registered EC2 instances.</em></figcaption></figure><p>One important distinction: a target can exist in the target group without being healthy or ready to receive traffic. Newly registered instances may initially appear as initial, while an unhealthy target indicates that the configured health checks are failing.</p><p>This makes target health worth monitoring during deployment and troubleshooting.</p><p>For example, if an EC2 instance is running but the application has not started correctly, the instance’s operating-system status alone does not guarantee that the web application is ready to serve requests.</p><p>The target group’s health checks provide another layer of information: whether the application endpoint is responding as expected.</p><p>That is a more useful signal than simply checking whether an instance is powered on.</p><h3>5. Launch templates: making instance deployment repeatable</h3><p>If an application needs several EC2 instances, configuring each one manually introduces unnecessary work and the possibility of inconsistent setups.</p><p>This is where <strong>EC2 launch templates</strong> become useful.</p><p>A launch template stores configuration information that Auto Scaling can use when launching instances. Depending on the template, this can include the Amazon Machine Image (AMI), instance type, security groups, storage settings, IAM instance profile, and user data.</p><p>In my lab, I created a launch template named lab-app-launch-template.</p><p>The template included user data for installing and configuring the application environment when an instance launches.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3SYZ90IZKjwWtNGZtnKkhQ.png" /><figcaption><em>Configuring instance bootstrap instructions through EC2 user data in the launch template.</em></figcaption></figure><p>The important concept here is automation.</p><p>Instead of logging into each new server and repeating the same setup steps, a bootstrap script can perform the required installation and configuration tasks during instance initialization.</p><p>This makes it easier to launch multiple instances with a consistent baseline.</p><p>However, user data is not a substitute for proper configuration management or ongoing patching. The script must also be tested, and its execution must be monitored so that failed initialization does not go unnoticed.</p><p>For a production architecture, I would also consider using versioned launch templates and controlled rollout strategies when changing the application image or startup configuration.</p><h3>6. Managing capacity with an Auto Scaling Group</h3><p>With the launch template defined, the next step was to configure an Auto Scaling Group.</p><p>An Auto Scaling Group manages a collection of EC2 instances and helps maintain the desired capacity of the application tier.</p><p>For this lab, the group was named app-asg.</p><p>The configuration shown in my screenshot used a desired capacity of two instances, with a minimum of two and a maximum of four.</p><p>These values define the intended capacity boundaries:</p><ul><li><strong>Minimum capacity: 2</strong> — the group should maintain at least two instances under normal Auto Scaling operation.</li><li><strong>Desired capacity: 2</strong> — the group aims to maintain two instances.</li><li><strong>Maximum capacity: 4</strong> — the group can scale out to four instances when scaling policies or other capacity changes call for it.</li></ul><p>The maximum value does not mean the group will automatically scale to four instances whenever traffic increases. Scaling behaviour depends on the policies, scheduled actions, or other mechanisms configured for the group.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mhTjQbHoZDuMBcU-4XFGoA.png" /><figcaption><em>Configuring the capacity boundaries for the application’s Auto Scaling Group.</em></figcaption></figure><p>This is where the architecture becomes more resilient to individual instance failures.</p><p>If an instance becomes unhealthy and the Auto Scaling Group detects that it is unhealthy according to its configured health-check mechanism, the group can replace it to maintain capacity.</p><p>The exact behaviour depends on the health checks enabled for the group and its configuration.</p><p>It is also important to distinguish two concepts:</p><p><strong>High availability is not the same as automatic scaling.</strong></p><p>High availability aims to keep the application accessible despite certain failures. Auto Scaling helps maintain and adjust the compute fleet. Scaling policies can respond to demand, but simply setting a maximum capacity does not configure a scaling policy by itself.</p><p>Together with the ALB and suitable health checks, Auto Scaling helps build an application tier that is not dependent on a fixed, manually managed set of servers.</p><h3>7. Distributing traffic across Availability Zones</h3><p>Running multiple instances is useful, but their placement matters too.</p><p>An Availability Zone is an isolated location within an AWS Region. Deploying resources across multiple Availability Zones can reduce dependence on a single zone.</p><p>For a highly available web tier, the architecture should distribute EC2 capacity across at least two Availability Zones, with the ALB configured to use suitable subnets in those zones.</p><p>This provides a better failure boundary than placing every application instance in a single zone.</p><p>The benefit is straightforward: if one instance fails, other healthy targets can continue serving requests. If an entire Availability Zone experiences a disruption, the remaining zone may continue serving traffic, provided it has sufficient healthy capacity and the rest of the architecture is configured appropriately.</p><p>That final qualification matters.</p><p>A multi-AZ design does not automatically guarantee uninterrupted service. The ALB must have healthy targets available, the application must be able to operate across the remaining capacity, and dependencies must not introduce another single point of failure.</p><p>High availability is a property of the overall architecture, not a feature delivered by one AWS service alone.</p><h3>8. Adding notifications with Amazon SNS</h3><p>The final part of the lab introduced Amazon Simple Notification Service (SNS).</p><p>SNS is a managed publish-and-subscribe messaging service. A publisher sends a message to a topic, and SNS delivers that message to its subscribed endpoints according to the subscription and delivery configuration.</p><p>For this lab, I used the SNS topic lab-app-sns-topic to receive notifications associated with Auto Scaling events.</p><p>During Auto Scaling Group configuration, I selected the notification topic and enabled event types such as instance launches, terminations, and relevant launch or termination failures.</p><p>I also subscribed an email endpoint to the topic and confirmed the subscription.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/762/1*zfmZjS_eUG_qGV1vYOTxJA.png" /><figcaption><em>Confirming the email subscription to the Amazon SNS topic.</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*THz4bGfIc-jRHIeetA3g1Q.png" /><figcaption>SNS notification found in inbox/spam</figcaption></figure><p>Why does this matter for high availability?</p><p>A system can recover from some failures automatically, but that does not mean operators should be unaware of what is happening.</p><p>Notifications can help teams identify changes in instance capacity, investigate failed launches, and understand when the application fleet is changing.</p><p>For example, repeated instance launch failures may indicate a problem with a launch template, permissions, resource limits, or application initialization.</p><p>An SNS notification does not fix those problems by itself. It provides a way to communicate configured events so that they can be investigated.</p><p>For a production environment, I would also consider CloudWatch metrics and alarms, centralized logs, and appropriate alerting thresholds. SNS can then be used as a notification destination for those alarms as well.</p><h3>9. Putting everything together</h3><p>At this point, the individual components begin to tell one story.</p><p>The Application Load Balancer receives application traffic and forwards it to registered targets.</p><p>The target group provides the destination configuration and health checks.</p><p>The EC2 Auto Scaling Group manages the application instances and maintains configured capacity.</p><p>The launch template provides a repeatable instance configuration.</p><p>Amazon SNS communicates selected Auto Scaling events to subscribers.</p><p>The architecture can be summarized as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/332/1*vlOAGpiKl2L47OAVy8jMpg.png" /><figcaption><em>Conceptual diagram: the load balancer routes traffic to registered instances, Auto Scaling manages capacity, and SNS communicates selected lifecycle events.</em></figcaption></figure><p>In a real multi-AZ deployment, the EC2 instances should be distributed across the selected Availability Zones. The diagram above focuses on the relationships between the services rather than showing every networking component.</p><p>The important lesson is that each component solves a different problem. The load balancer distributes traffic, Auto Scaling manages the fleet, health checks help identify unhealthy targets, and SNS provides event notifications.</p><p>The result is a more deliberate design than simply launching two EC2 instances and hoping both remain available.</p><h3>10. What I would consider before taking this into production</h3><p>A lab is useful for understanding how AWS services fit together. A production environment requires additional design decisions.</p><p>Here are several things I would consider before deploying this architecture for real users.</p><p><strong>1. Verify application health, not just instance health.</strong></p><p>An EC2 instance can be running while its application is broken. Health-check endpoints should reflect whether the application is ready to handle requests, without being so dependent on unrelated services that a minor dependency issue causes unnecessary target removal.</p><p><strong>2. Test actual failure scenarios.</strong></p><p>Do not assume an architecture is highly available just because it has multiple instances. Test what happens when a web process stops, an instance becomes unhealthy, or an Availability Zone becomes unavailable. Observe how the ALB, target group, and Auto Scaling Group respond.</p><p><strong>3. Configure scaling policies deliberately.</strong></p><p>Minimum, desired, and maximum capacity define the size boundaries of an Auto Scaling Group. They do not, on their own, determine when the application should scale out or scale in. Choose suitable metrics, thresholds, cooldown or warm-up behaviour, and scaling policies based on the workload.</p><p><strong>4. Protect the application tier.</strong></p><p>Where possible, keep application instances in private subnets and allow inbound application traffic from the ALB’s security group rather than exposing the instances directly to the internet. The ALB can use public subnets while the web tier remains private, provided routing, outbound access, and application dependencies are configured appropriately.</p><p><strong>5. Monitor and test recovery.</strong></p><p>SNS notifications are useful, but they are only one part of operations. CloudWatch metrics, logs, alarms, and regular recovery tests help determine whether the architecture is behaving as expected.</p><p><strong>6. Consider cost and capacity.</strong></p><p>Running multiple instances and a load balancer introduces costs. Capacity should be sufficient to handle expected traffic and the loss of a component, without keeping significantly more resources than the application requires.</p><p>These considerations turn a working lab into a more complete architectural design.</p><h3>Final thoughts</h3><p>This lab helped me see high availability as more than simply running multiple EC2 instances.</p><p>The real work lies in understanding how traffic reaches those instances, how their health is evaluated, how capacity is maintained, and how operators learn when something changes.</p><p>The Application Load Balancer, Auto Scaling Group, launch template, target group, and SNS topic each played a distinct role in that design.</p><p>And that is what I am increasingly looking for as I continue my AWS Solutions Architect journey: not just what an individual service does, but how it contributes to a larger system.</p><p>Because in cloud architecture, <strong>the goal is not merely to make an application work when everything is healthy. It is to design the system to respond intelligently when something is not.</strong></p><p>Another lab documented. Another piece of the architecture understood.</p><p>On to Episode 5.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e984562bac00" width="1" height="1" alt=""><hr><p><a href="https://aws.plainenglish.io/what-happens-when-your-web-server-goes-down-in-aws-cloud-e984562bac00">What Happens When Your Web Server Goes Down in AWS Cloud?</a> was originally published in <a href="https://aws.plainenglish.io">AWS in Plain English</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A Load Balancer Adds Latency. So Why Use One?]]></title>
            <link>https://aws.plainenglish.io/a-load-balancer-adds-latency-so-why-use-one-7ceccae50d93?source=rss-902a4c1fad89------2</link>
            <guid isPermaLink="false">https://medium.com/p/7ceccae50d93</guid>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[servers]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <category><![CDATA[solution-architect]]></category>
            <dc:creator><![CDATA[Abdul-mu'min Omotola]]></dc:creator>
            <pubDate>Fri, 02 Oct 2026 14:09:26 GMT</pubDate>
            <atom:updated>2026-10-12T01:18:51.666Z</atom:updated>
            <content:encoded><![CDATA[<h4>A practical look at traffic distribution and AWS Application ELB</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GOMz550ZO5X6qlcEqz2juQ.png" /></figure><p>When building applications in the cloud, it is tempting to think of performance in simple terms:</p><blockquote><strong><em>Fewer layers = less latency.</em></strong></blockquote><p>If an EC2 instance can respond directly to a request, why introduce another component between the user and the server?</p><p>That question became particularly interesting during one of my cloud networking projects.</p><p>I built an AWS environment with an <strong>Application Load Balancer (ALB)</strong>, EC2 instances distributed across Availability Zones, Auto Scaling, health checks, and Security Groups. I then compared requests sent directly to an EC2 instance with requests routed through the load balancer.</p><blockquote>The result was interesting.</blockquote><p>The first request through the ALB was measurably slower than direct access to the instance. But subsequent requests were almost identical in average latency.</p><p>So, if the load balancer introduces some overhead, <strong>why use one at all?</strong></p><p>The answer has less to do with making a single request faster and more to do with how an application behaves when you introduce <strong>multiple servers, failures, changing traffic, and the need for controlled access</strong>.</p><p>This article walks through that experiment and what it taught me about designing resilient AWS architectures.</p><h3>The architecture I built</h3><p>The practical deployment was built in the <strong>AWS Europe (Stockholm) Region (</strong><strong>eu-north-1)</strong> using a custom Amazon VPC spanning two Availability Zones.</p><h4>The architecture included:</h4><ul><li>An Amazon VPC</li><li>Two Availability Zones</li><li>EC2 instances</li><li>An EC2 Auto Scaling Group</li><li>An internet-facing Application Load Balancer</li><li>An ALB target group</li><li>Health checks</li><li>Security Groups</li><li>An Internet Gateway</li></ul><p>Instead of allowing users to connect directly to individual EC2 instances, the <strong>Application Load Balancer becomes the entry point for the application</strong>.</p><p>It receives incoming HTTP traffic and distributes requests to healthy instances in the target group.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qqiwQ9c7hru-amE4ofedBQ.png" /><figcaption>AWS architecture showing the Internet Gateway, Application Load Balancer, Availability Zones, EC2 instances, and Security Groups.</figcaption></figure><p>The important part of this architecture is that the EC2 instances are no longer treated as individual public endpoints.</p><p>The ALB sits in front of them and becomes the component responsible for distributing incoming application traffic.</p><h3>Why use a load balancer?</h3><p>At first glance, a load balancer might look like an unnecessary extra hop.</p><p>A simple architecture could look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/366/1*00sMBP2qhOvmi5KtsXCYyg.png" /></figure><p>There is very little between the client and the application.</p><p>But what happens when the application needs to run on multiple instances?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/705/1*4Ga9WebdeVco5b3bubEISQ.png" /></figure><p>Now something has to decide <strong>where each request should go</strong>.</p><p>This is where a load balancer becomes useful.</p><p>The architecture becomes:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/705/1*2yPswnSrzEWgh9H_CnJjBg.png" /></figure><p>The ALB provides a single entry point while distributing traffic across the available targets.</p><p>More importantly, it can use <strong>health checks</strong> to determine whether a target is healthy enough to receive traffic.</p><p>That distinction became important during my experiment.</p><h3>Building the web tier</h3><p>For the web tier, I configured an EC2 Auto Scaling Group across two Availability Zones.</p><p>The instances hosted a simple web application and were placed behind the Application Load Balancer.</p><p>The Security Group configuration was deliberately restrictive.</p><p>The instances were configured to accept HTTP traffic on <strong>port 80 from the load balancer</strong>, rather than treating the instances themselves as unrestricted public endpoints.</p><p>This creates a useful separation:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/251/1*Vz9pKIyscdpLAQ4UAZop3A.png" /></figure><p>The ALB acts as the public-facing entry point, while the instances form the application tier behind it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*gOarHxVNQqxufyt6JUH1mA.png" /><figcaption>EC2 instances participating in the web tier.</figcaption></figure><h3>Health checks: the part that changes the architecture</h3><p>One of the most important features of the setup was the <strong>target group health check</strong>.</p><p>The ALB continuously checks the registered instances.</p><p>In my configuration, the health check used HTTP requests to determine whether an instance was responding successfully.</p><p>If an instance failed to return the expected response — for example, because its web server had stopped responding — the load balancer could stop routing traffic to that unhealthy target.</p><p>This is important because the architecture is no longer simply:</p><blockquote><em>“Send traffic to a server.”</em></blockquote><p>It becomes:</p><blockquote><strong><em>“Send traffic to a healthy server.”</em></strong></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*f02IvlgY5T6NCtFh-RDH5w.png" /><figcaption>Target group showing the health status of the EC2 instances.</figcaption></figure><p>This is one of the reasons the load balancer should not be evaluated purely by asking whether it makes an individual request faster.</p><p>It is part of a larger availability strategy.</p><h3>Now for the interesting part: measuring latency</h3><p>This is where I wanted to move beyond simply configuring AWS services.</p><p>I wanted to see what the extra network layer actually meant for request latency.</p><p>I tested two paths.</p><h4>Test 1: Direct EC2 access</h4><p>The client connected directly to the EC2 instance through its public IP address.</p><h4>Test 2: Load-balanced access</h4><p>The client accessed the application through the ALB’s DNS name.</p><p><strong>The results were:</strong></p><p>Access pathAverage latencyDirect EC2 access — — — -&gt; <strong>0.320 seconds</strong></p><p>ALB — initial request<strong> — — — — — — — — -&gt;0.441 seconds</strong></p><p>ALB — subsequent requests — — — — — -&gt;<strong>0.321 seconds</strong></p><p>These numbers came from my particular coursework environment and test conditions, so they should not be interpreted as general AWS performance benchmarks.</p><p>But they were useful for understanding the architectural trade-off.</p><h3>Direct access was faster — initially</h3><p>The direct EC2 request averaged approximately <strong>0.320 seconds</strong>.</p><p>There was no load balancer between the client and the instance.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*1hmEQWzjLJSLzk2wKgfMtw.png" /><figcaption>Latency measurement when accessing the EC2 instance directly.</figcaption></figure><p>When I introduced the ALB, the first measured request increased to approximately <strong>0.441 seconds</strong>.</p><p>That’s a difference of around <strong>0.121 seconds</strong> compared with the direct request.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*JAGw5jLzCuHvHdVUzDcsJg.png" /><figcaption>Latency measurement when accessing the application through the Application Load Balancer.</figcaption></figure><p>At first, that seems to support a simple conclusion:</p><blockquote><em>The load balancer makes the application slower.</em></blockquote><p>But that would be an incomplete interpretation.</p><p>The subsequent requests settled at approximately <strong>0.321 seconds</strong>, almost the same as the direct-access measurement.</p><p>So the more interesting question became:</p><p><strong>What exactly are we optimizing for when we introduce a load balancer?</strong></p><h3>Performance is not the same as availability</h3><p>This was probably the most important lesson from the experiment.</p><p>A direct connection to one EC2 instance can be very simple and fast.</p><p>But that architecture also creates a dependency on that particular instance.</p><p>If that instance becomes unavailable, the application becomes unavailable.</p><p>With a load-balanced architecture, the application can operate across multiple instances.</p><p>The traffic path becomes:</p><pre>                         ┌── EC2 Instance A<br>                         │<br>User → ALB ──────────────┼── EC2 Instance B<br>                         │<br>                         └── EC2 Instance C</pre><p>If one of those targets becomes unhealthy, the ALB’s health-check mechanism can prevent traffic from being routed to that unhealthy target.</p><p>This is where the architectural value becomes clearer.</p><p>The purpose isn’t simply:</p><blockquote><strong><em>“Make this request faster.”</em></strong></blockquote><p>It is also:</p><blockquote><strong><em>“Give the application multiple healthy places to handle requests.”</em></strong></blockquote><h3>The role of Auto Scaling</h3><p>The load balancer was not operating alone.</p><p>The architecture also used an <strong>EC2 Auto Scaling Group</strong>.</p><p>This introduces another important cloud architecture concept.</p><p>Application demand can change over time.</p><p>Instead of permanently relying on a single server, an Auto Scaling Group can manage a fleet of EC2 instances according to the configured scaling behaviour.</p><p>The ALB then provides a consistent entry point to that fleet.</p><p>Conceptually:</p><pre>                    ┌── EC2<br>                    │<br>                    ├── EC2<br>User → ALB ─────────┤<br>                    ├── EC2<br>                    │<br>                    └── EC2<br>                         ▲<br>                         │<br>                    Auto Scaling</pre><p>The result is a separation of responsibilities:</p><p><strong>ALB</strong><br> Distributes incoming application traffic.</p><p><strong>Auto Scaling</strong><br> Manages the EC2 instance fleet according to scaling configuration.</p><p><strong>EC2</strong><br> Runs the application workload.</p><p><strong>Health checks</strong><br> Help determine whether registered targets are healthy.</p><p>This separation is one of the things I found particularly useful when thinking about AWS architecture as a system rather than a collection of individual services.</p><h3>Security is part of the traffic flow</h3><p>The networking configuration also reinforced something I have encountered repeatedly in cybersecurity:</p><p><strong>Connectivity and security cannot really be separated.</strong></p><p>The EC2 Security Group was configured so that HTTP traffic to the web tier was allowed from the load balancer rather than simply opening the application server broadly to the internet.</p><p>That gives us a traffic model closer to:</p><pre>Internet<br> │<br> ▼<br> ALB<br> │<br> │ Allowed application traffic<br> ▼<br>EC2 Web Tier</pre><p>This is more deliberate than giving every component unrestricted connectivity.</p><p>It also demonstrates an important cloud security principle:</p><blockquote><strong><em>Allow communication based on what actually needs to communicate.</em></strong></blockquote><p>A technically functional network is not automatically a well-designed network.</p><h3>What happens when something fails?</h3><p>This is where the architecture becomes more interesting than the latency measurement.</p><p>Imagine one of the EC2 instances stops responding.</p><p>Without a load balancer:</p><pre>User → Failed EC2 Instance</pre><p>The user is still attempting to reach the failed resource.</p><p>With the load-balanced architecture:</p><pre>                         ┌── Healthy EC2<br>                         │<br>User → ALB ──────────────┼── Unhealthy EC2 ✕<br>                         │<br>                         └── Healthy EC2</pre><p>The health check provides the information the load balancer needs to distinguish between healthy and unhealthy targets.</p><p>The traffic can therefore continue toward healthy targets rather than treating every instance as equally available.</p><p>This is where the additional architectural layer starts to justify its existence.</p><p>The health check provides the information the load balancer needs to distinguish between healthy and unhealthy targets.</p><p>The traffic can therefore continue toward healthy targets rather than treating every instance as equally available.</p><p>This is where the additional architectural layer starts to justify its existence.</p><h3>The trade-off: more architecture, more responsibility</h3><p>The experiment also reminded me that cloud architecture is rarely about finding a single “best” component.</p><p>Adding an ALB introduces another layer into the request path.</p><p>That means additional configuration, monitoring, troubleshooting, and potentially additional latency.</p><p>My experiment measured that difference in a very specific environment.</p><p>At the same time, the ALB provides capabilities that direct EC2 access does not provide by itself — particularly centralized traffic distribution and health-aware routing across multiple targets.</p><p>So the architectural decision should not be reduced to:</p><blockquote><strong><em>ALB = slower</em></strong></blockquote><p>or</p><blockquote><strong><em>ALB = better</em></strong></blockquote><p>The more useful question is:</p><blockquote><strong><em>What does the application need from its architecture?</em></strong></blockquote><p>For a simple development environment, direct access might be perfectly adequate.</p><p>For an application requiring multiple instances, traffic distribution, and health-aware routing, the architecture has different requirements.</p><h3>What I learned from building it</h3><p>The most valuable part of this project wasn’t configuring the load balancer.</p><p>It was seeing how several AWS components work together to solve a larger problem.</p><p>I started with individual services:</p><p><strong>VPC.</strong></p><p><strong>EC2.</strong></p><p><strong>Auto Scaling.</strong></p><p><strong>Application Load Balancer.</strong></p><p><strong>Security Groups.</strong></p><p><strong>Target Groups.</strong></p><p>But the actual architecture was the relationship between them.</p><p>The VPC provided the network foundation.</p><p>The EC2 instances provided compute.</p><p>The Auto Scaling Group managed the web-tier fleet.</p><p>The ALB provided the traffic entry point and distribution layer.</p><p>The target group and health checks provided awareness of target health.</p><p>And the Security Groups controlled which traffic was allowed to reach the application tier.</p><p>That is a very different way of looking at AWS.</p><p>Instead of asking:</p><blockquote>“What does this service do?”</blockquote><p>I am increasingly asking:</p><blockquote><strong><em>“What problem does this service solve, and what does it need to work with?”</em></strong></blockquote><p>That shift in thinking is one of the most useful things this project gave me.</p><h3>A final look at the architecture</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qqiwQ9c7hru-amE4ofedBQ.png" /><figcaption>Final AWS network topology showing external HTTP traffic entering through the Internet Gateway and Application Load Balancer before reaching EC2 instances across Availability Zones.</figcaption></figure><p>The architecture demonstrates a simple but important cloud design principle:</p><p><strong>High availability isn’t achieved simply by creating more servers.</strong></p><p>Those servers need to be placed within a properly designed network, monitored for health, protected by appropriate access controls, and connected through a traffic-distribution mechanism that understands the state of the application.</p><h3>Final thoughts</h3><p>This project started as a coursework exercise in cloud networking.</p><p>It ended up giving me a much better appreciation of the trade-offs involved in cloud architecture.</p><p>The latency experiment was particularly useful because it challenged a very simple assumption:</p><blockquote><strong><em>More infrastructure doesn’t necessarily mean better performance.</em></strong></blockquote><p>The ALB introduced an additional step in the request path, and my measurements captured that overhead during the initial request.</p><p>But the architecture was designed for something broader than a single fast request.</p><p>It was designed to distribute traffic across multiple compute resources, monitor their health, and provide a consistent entry point to the application.</p><p>That is perhaps the bigger lesson I took from the project:</p><p><strong>Good cloud architecture isn’t about removing every layer. It’s about understanding why each layer exists.</strong></p><p>And sometimes, the layer that adds a little overhead is the one that makes the whole system more resilient.</p><p><strong>If you liked what you just read, consider:</strong></p><p>◆ Dropping a comment to show your support</p><p>◆ Sharing the article with others who will find it useful</p><p>◆ Follow me on <a href="https://medium.com/@enigmatictola">medium</a> and <a href="https://www.linkedin.com/in/abdul-mu-min-rafiu-cc-546968252/">LinkedIn</a></p><p>Cheers.</p><p><strong>Before you go</strong></p><ul><li>Please take a moment to like the post and follow the writer!</li><li>Did you know that over 400,000 developers share what they’re building, learning, and discovering across our platforms every month? Learn how you can contribute <a href="https://plainenglish.io/write-for-us">here</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7ceccae50d93" width="1" height="1" alt=""><hr><p><a href="https://aws.plainenglish.io/a-load-balancer-adds-latency-so-why-use-one-7ceccae50d93">A Load Balancer Adds Latency. So Why Use One?</a> was originally published in <a href="https://aws.plainenglish.io">AWS in Plain English</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My AWS Solutions Architect Journey: Cloud Storage and Databases]]></title>
            <link>https://medium.com/@abdul-mumin/my-aws-solutions-architect-journey-cloud-storage-and-databases-365caf7deee9?source=rss-902a4c1fad89------2</link>
            <guid isPermaLink="false">https://medium.com/p/365caf7deee9</guid>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <dc:creator><![CDATA[Abdul-mu'min Omotola]]></dc:creator>
            <pubDate>Thu, 24 Sep 2026 18:48:05 GMT</pubDate>
            <atom:updated>2026-09-24T18:48:05.179Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*n8BhlJjLZ9n2FiCSP178LQ.png" /></figure><p>Hello,</p><p>In my previous AWS lab, I spent time with the networking foundation behind a cloud application; VPCs, subnets, routing, security groups, and how an EC2 instance fits into the picture.</p><p>This time, I moved one layer higher.</p><p>The application was already running.</p><p>But an application is only part of the architecture.</p><p>It also needs somewhere to <strong>store its data</strong>.</p><p>That was the focus of this lab: configuring a web-based employee directory to use <strong>Amazon S3 for employee images</strong> and <strong>Amazon DynamoDB for employee records</strong>.</p><p>And this was where the difference between <em>running an application</em> and <em>building an application architecture</em> became much clearer to me.</p><h3>An application needs more than compute</h3><p>A common way to visualize a web application is:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/630/1*K-2yYNUhJ6OBRD8tnUupjw.png" /></figure><p>But in a real cloud environment, the picture becomes more interesting.</p><p>The application may need different storage technologies for different types of data.</p><p>In this lab:</p><ul><li><strong>Amazon EC2</strong> hosted the employee directory application.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/860/0*whRyTE9L3wEZaXzo.png" /></figure><ul><li><strong>Amazon S3</strong> was used to store employee images.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/245/0*hOtT4DVECJWLg5xH.png" /></figure><ul><li><strong>Amazon DynamoDB</strong> was used to store employee information.</li><li><strong>IAM</strong> controlled what the application was allowed to access.</li></ul><p>The lab therefore became less about individual AWS services and more about <strong>how those services work together</strong>.</p><h3>First, I gave the application somewhere to store its images</h3><p>The first problem was Amazon S3.</p><p>The employee directory application initially reported that the employee images bucket could not be found.</p><p>So I created an S3 bucket specifically for the employee photos.</p><p>But creating the bucket wasn’t enough.</p><p>The application also needed permission to access it.</p><p>This brought IAM back into the picture.</p><p>The application was using an IAM role called EmployeeDirectoryAppRole, and I configured an S3 bucket policy that allowed that role to access the bucket.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/935/1*OFRfpeIh7gui8zJby39gew.png" /><figcaption><strong>S3 bucket policy granting the application role access to the bucket.</strong></figcaption></figure><p>This was a nice connection to the first episode of the series.</p><p>In Episode 1, I explored IAM from the perspective of <strong>who can access AWS resources</strong>.</p><p>Here, I saw that principle applied to an actual workload.</p><p>The application itself needs an identity too.</p><h3>S3: More than just a place to upload files</h3><p>Once the bucket was configured, I uploaded the employee images.</p><p>The lab used ten sample employee images, which were uploaded as objects into the S3 bucket.</p><p>What I found interesting here is the separation of responsibilities.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JTLuELz7xolcTI49sGrCdg.png" /><figcaption><strong>Uploading employee image objects into the S3 bucket.</strong></figcaption></figure><p>The application doesn’t need to keep employee images directly on the EC2 server.</p><p>Instead, the images can live in S3 while the application retrieves them when needed.</p><p>That separation is one of the ideas that makes cloud architectures so flexible.</p><p>The compute layer doesn’t necessarily have to be responsible for storing everything.</p><h3>Then the application actually started seeing the images</h3><p>After associating the S3 bucket with the application and uploading the objects, I returned to the employee directory.</p><p>The images were now being retrieved from S3 and displayed by the application.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_VuhrXOz7i6YZJIML17jeQ.png" /><figcaption><strong>Employee images successfully retrieved from Amazon S3 by the application.</strong></figcaption></figure><p>This was probably the most satisfying point in the lab because I could see the architecture working rather than simply configuring individual AWS services.</p><p>The flow was essentially:</p><blockquote><strong><em>Employee image → S3 → Application → User</em></strong></blockquote><h3>But images aren’t employee records</h3><p>There was still another problem.</p><p>The application needed somewhere to store information about the employees themselves:</p><ul><li>ID</li><li>Name</li><li>Location</li><li>Email</li><li>Photo reference</li></ul><p>This is where <strong>Amazon DynamoDB</strong> came in.</p><p>I created a DynamoDB table named Employees and configured id as the partition key.</p><p>Unlike S3, which was handling the image objects, DynamoDB was being used to store the structured employee information required by the application.</p><p>This gave me a practical example of why cloud applications often use <strong>different storage services for different data types</strong>.</p><h3>DynamoDB: Seeing the data behind the application</h3><p>After creating the table, the application could finally access the employee data.</p><p>I tested this through the application interface by creating employee records, then went directly into DynamoDB to inspect the data.</p><p>This was where the lab became particularly useful.</p><p>I wasn’t just creating a database table.</p><p>I was able to see the relationship between the <strong>application interface</strong> and the <strong>database underneath it</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hv4LxTHtIUmaqkXcVg411A.png" /><figcaption><strong>Inspecting and editing an employee record directly in DynamoDB.</strong></figcaption></figure><p>I could modify attributes such as the employee’s location and email and then verify those changes from the application.</p><p>That made the concept of CRUD operations much more tangible:</p><p><strong>Create → Read → Update → Delete</strong></p><p>The application becomes the interface.</p><p>DynamoDB becomes the data layer.</p><h3>Putting the architecture together</h3><p>By the end of the lab, the architecture started making much more sense.</p><p>At a high level:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/950/1*Ge8zKbOgG4uNAQUVN1Uk6w.png" /><figcaption><strong>The lab’s application architecture showing the VPC, EC2 web application, and supporting AWS infrastructure.</strong></figcaption></figure><p>And IAM sits across the architecture, determining what the application is allowed to access.</p><h3>My cybersecurity takeaway</h3><p>Coming from cybersecurity, there was one thing I kept noticing throughout this lab:</p><p><strong>Storage is also an access-control problem.</strong></p><p>It’s easy to think of S3 as simply “where files go” and DynamoDB as “where database records go.”</p><p>But the moment an application needs to access those resources, identity and permissions become part of the architecture.</p><p>The S3 bucket policy in this lab was a practical reminder of the principle I wrote about in Episode 1:</p><blockquote><strong><em>Don’t just ask where the data is. Ask who — or what — is allowed to access it.</em></strong></blockquote><p>That is where cloud architecture and cloud security begin to overlap.</p><h3>What this lab added to my AWS journey</h3><p>This lab connected several pieces I’ve been learning separately.</p><p><strong>IAM</strong> determines identity and permissions.</p><p><strong>EC2</strong> provides compute.</p><p><strong>S3</strong> provides object storage.</p><p><strong>DynamoDB</strong> provides a NoSQL data store.</p><p>And the <strong>VPC</strong> provides the networking environment around the application.</p><p>The interesting part isn’t knowing what each service does individually.</p><p>It’s understanding <strong>why you would use them together</strong>.</p><p>That’s the direction I’m trying to move toward as I continue this Solutions Architect journey.</p><h3>What’s next?</h3><p>Another lab, another piece of the architecture.</p><p>I’m continuing to document the journey — not simply to record the services I’m learning, but to understand how they fit together into secure and practical cloud solutions.</p><p><strong>One lab at a time. One architecture at a time.</strong></p><p><strong>If you liked what you just read, consider:</strong></p><p>◆ Dropping a comment to show your support</p><p>◆ Sharing the article with others who will find it useful</p><p>◆ Follow me on <a href="https://medium.com/@enigmatictola">medium</a> and <a href="https://www.linkedin.com/in/abdul-mu-min-rafiu-cc-546968252/">LinkedIn</a></p><p>Cheers.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=365caf7deee9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Building a Bulletproof Linux Server — Ep. #3: System Examination]]></title>
            <link>https://aws.plainenglish.io/building-a-bulletproof-linux-server-ep-3-system-examination-e40fa2922a03?source=rss-902a4c1fad89------2</link>
            <guid isPermaLink="false">https://medium.com/p/e40fa2922a03</guid>
            <category><![CDATA[linux]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[system-administration]]></category>
            <category><![CDATA[servers]]></category>
            <dc:creator><![CDATA[Abdul-mu'min Omotola]]></dc:creator>
            <pubDate>Sun, 23 Aug 2026 09:14:39 GMT</pubDate>
            <atom:updated>2026-09-09T01:24:18.874Z</atom:updated>
            <content:encoded><![CDATA[<h4>A hands-on guide to real-world Linux hardening in a virtual lab</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*CPhLSgPHkjZwet6P9Ph6Jg.jpeg" /><figcaption>Linux icon by <a href="https://www.flaticon.com/free-icon/linux_518713">flaticon</a></figcaption></figure><p>In the <a href="https://medium.com/aws-in-plain-english/building-a-bulletproof-linux-server-ep-2-initializing-the-lab-environment-a1331964fafd">previous episode</a>, we initialized the lab environment.</p><blockquote><strong>Before we </strong><a href="https://www.sophos.com/en-us/cybersecurity-explained/what-is-server-hardening"><strong>harden the server,</strong></a><strong> we need to know what is currently on it, what is running, who has access, and whether the current state matches what we expect.</strong></blockquote><p>Because this Ubuntu VM was prebuilt and we didn’t create it from scratch, we don’t have a trusted baseline.</p><blockquote>So <strong>System Examination becomes the process of creating that baseline</strong>.</blockquote><h4><strong>Defining the expected state</strong></h4><p><strong>We cannot determine whether a system is secure until we know what the system is supposed to contain and how it is supposed to behave.</strong></p><p>From <a href="https://medium.com/aws-in-plain-english/building-a-bulletproof-linux-server-ep-1-introduction-c815fae47d12">Episode 1</a>, we know the server is supposed to provide things such as: DNS; web services; database services; SSH; VPN; email; file sharing; printing services.</p><blockquote>Our job now is to compare that expected role against the <strong>actual state</strong> of the VM.</blockquote><p>Since there is no detailed baseline documentation, we’re going to build one ourselves.</p><h4>Module Content</h4><ol><li>Evaluating the Static State</li><li>Examining User Data</li><li>System Security Auditing with Lynis</li><li>File Integrity Monitoring with AIDE</li><li>Evaluating the Dynamic State</li><li>Examining Authentication Logs</li><li>Testing Failed Authentication Attempts</li></ol><h3>Evaluating the Static State</h3><p>Now that we have defined what the server is expected to provide, we can begin examining what is actually present on the system.</p><p>We will start with the <strong>static state</strong> — the software, files, users, permissions, and other information that describes the current state of the server.</p><h4>What Software Is Installed?</h4><p>The first question is simple:</p><blockquote><strong>What software is installed on this server, and does it belong here?</strong></blockquote><p>Since the server is prebuilt, we should not assume that every installed package is required.</p><p>We can get a list of installed packages with:</p><pre>apt list --installed</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*zqugaN5Ev-o3Q29tOr123Q.png" /></figure><p>You can also use:</p><pre>dpkg --get-selections</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*gYxXxkZw01lSliV-eZNzAg.png" /></figure><p>The output may contain a large number of packages, so we are mainly interested in identifying software that has security significance.</p><p>For example:</p><ul><li>Web servers</li><li>Database servers</li><li>SSH</li><li>DNS services</li><li>Mail services</li><li>File-sharing services</li><li>Network utilities</li><li>Administrative tools</li></ul><p>The goal is not simply to create a list.</p><p>We want to identify <strong>unnecessary software</strong>, because every unnecessary service or package can increase the system’s attack surface.</p><h4><strong>Are the Installed Packages Up to Date?</strong></h4><p>Knowing what is installed is only half of the picture.</p><p>We also need to determine whether the installed software is current.</p><p>First, refresh the package information:</p><pre>sudo apt update</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*Un-zyhpsOTf-6il-V_pA2Q.png" /></figure><p>Then check whether updates are available:</p><p>apt list — upgradable</p><p>This gives us an initial view of packages that may require updates.</p><p>For security purposes, outdated software deserves particular attention because known vulnerabilities may exist for older versions.</p><p>This leads to our next question:</p><blockquote><strong>Does any of the installed software have known security vulnerabilities?</strong></blockquote><h4>Check for Known Vulnerabilities</h4><p>Once we identify important packages, we can investigate their versions and check whether they are associated with known <strong>Common Vulnerabilities and Exposures (CVEs)</strong>.</p><p>For example, we can check the installed OpenSSH packages with:</p><pre>dpkg -l | grep openssh</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*JfYdpaJ7RL0klKSWeiNvGA.png" /></figure><p>Record the installed version and investigate whether that specific version has known vulnerabilities.</p><p>The important point here is that finding a CVE associated with a piece of software does not automatically mean the server is vulnerable.</p><p>We need to consider:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/993/1*yVJ8U0FYYGwGUohsyAXdtg.png" /></figure><p>This is the mindset we want to develop throughout this project.</p><h4>Is the Software’s Integrity Intact?</h4><p>Knowing what software is installed does not tell us whether those files have been modified.</p><p>A package may be installed legitimately, but one of its files could have been changed after installation.</p><p>To examine this, we will use <strong>debsums</strong>.</p><p>Install it with:</p><pre>sudo apt install debsums</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*H0gxB2QOQkSWkRJoNYyqUQ.png" /></figure><p>Once installed, we can use it to verify files belonging to installed Debian packages.</p><h4>Check the Integrity of OpenSSH</h4><p>The lab specifically asks us to examine the openssh-client package.</p><p>Run:</p><pre>sudo debsums -a openssh-client</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*MvHQriVwgurtUb5C2Q2PyQ.png" /></figure><p>The command compares the files against the checksums recorded for the package.</p><p>The important thing to understand here is that we are establishing whether the files currently on the system match what the package manager expects.</p><h4>Check for Packages Without Checksums</h4><p>Not every package necessarily has checksum information available.</p><p>We can identify packages without checksum files using:</p><pre>sudo debsums –l</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/599/1*QFsyDnbJACtOOTxIaRvb-Q.png" /></figure><p>This is useful because it also shows us one of the limitations of relying on a single integrity-checking tool.</p><p>A security examination should always consider <strong>what the tool can and cannot verify</strong>.</p><h4>Can debsums Detect a Modified Configuration File?</h4><p>Let’s test it ourselves.</p><p>First, create a backup of the SSH client configuration:</p><pre>sudo cp /etc/ssh/ssh_config /etc/ssh/ssh_config.bak</pre><p>Now make a small, harmless modification:</p><pre>sudo nano /etc/ssh/ssh_config</pre><p>Add a comment such as:</p><p># Test modification</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*J3IBH4EEtx3PEv6JGUUnUA.png" /></figure><p>Save the file and run:</p><pre>sudo debsums -a openssh-client</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*SRBCjgKA-IN72hRWSK4ynw.png" /></figure><p>We can also specifically check changed configuration files with:</p><pre>sudo debsums –ce</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/599/1*eWfPQZVGc1gzwYU8-lWp_A.png" /></figure><p>Now we can answer an important question:</p><blockquote><strong>Does the integrity-checking tool detect the change we introduced?</strong></blockquote><p>This small experiment helps us understand how file-integrity checking works rather than simply trusting the output of a tool.</p><h4>What Happens When a Package File Is Missing?</h4><p>First, locate scp:</p><p>We’re examining this on the Secure Copy Protocol</p><pre>which scp</pre><p>We should see something similar to:</p><p>/usr/bin/scp</p><p>Rename the file:</p><pre>sudo mv /usr/bin/scp /usr/bin/scp.orig</pre><p>Now run:</p><pre>sudo debsums -a openssh-client</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*Crz9exu94RrGMnVzAuW0_Q.png" /></figure><p>Observe the result.</p><p>debsums was able to detect the missing file</p><p>After the test, restore the file:</p><pre>sudo mv /usr/bin/scp.orig /usr/bin/scp</pre><p>Run the integrity check again.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*2nnX9MRT8cDe3dQ9dAbMHQ.png" /></figure><p>This gives us another practical example of how integrity monitoring can identify changes to package-managed files.</p><h4>What Configuration Files Have Changed?</h4><p>Now we can broaden our examination.</p><p>Run:</p><pre>sudo debsums -ce</pre><p>This helps identify package-installed configuration files whose recorded checksums no longer match.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/553/1*wgnbLlmewF5S31yVui23Vg.png" /></figure><p>But there is an important question:</p><p><strong>Are there configuration files that have changed but are not reported by debsums?</strong></p><p>The answer can be yes.</p><p>This is why debsums should be viewed as <strong>one examination tool</strong>, rather than a complete system-integrity solution.</p><blockquote>📝: Later in this project, we will look at tools designed specifically for broader file-integrity monitoring.</blockquote><h4>Who Can Obtain Elevated Privileges?</h4><p>Next, we examine privileged access.</p><p>We already created the admin account during the lab initialization, so we need to determine who can use sudo and what privileges they have.</p><p>Start by checking membership of the sudo group:</p><pre>getent group sudo</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*eUIcr6xcLMuWigqnoEhArg.png" /></figure><p>Then examine the privileges assigned to a particular user:</p><pre>sudo -l -U admin</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*u0_RutDq3MvLwnC1YR2Dkg.png" /></figure><p>We can also examine the sudo configuration:</p><pre>sudo visudo</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*NEAgl9OlCU3YxlpFbm3J4g.png" /></figure><p>And check additional configuration files:</p><pre>sudo ls -la /etc/sudoers.d/</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/569/1*9ky7F50wlxbT2WntcuM_ig.png" /></figure><p>The question we are trying to answer is:</p><blockquote><strong>Who can become privileged on this system, and how?</strong></blockquote><p>This will become particularly important when we begin hardening access controls.</p><h3>Examining User Data</h3><p>Software is only one part of the system.</p><p>We also need to examine the data and accounts belonging to users.</p><h4>What User Accounts Exist?</h4><p>Start by looking at the account database:</p><pre>cat /etc/passwd</pre><p>There may be many entries because Linux uses accounts for both human users and system services.</p><p>To focus on regular users, we can examine accounts with higher UIDs:</p><pre>awk -F: &#39;$3 &gt;= 1000 &amp;&amp; $3 &lt; 65534 {print $1, $3, $6, $7}&#39; /etc/passwd</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*igdB_1_1yclHggez_u1JZA.png" /></figure><p>We are interested in questions such as:</p><ul><li>What user accounts exist?</li><li>Which accounts belong to actual users?</li><li>Which accounts have interactive login shells?</li><li>Are there accounts we do not expect?</li></ul><p>An account that exists without a legitimate purpose is worth investigating.</p><h4>What Files Exist in User Directories?</h4><p>Next, we examine the contents of user directories.</p><p>For example:</p><pre>sudo find /home -type f -exec file {} \;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*PikqtF2L6f-QN3nYSBtVFw.png" /></figure><p>This helps us identify different types of files stored by users, including documents, scripts, executables, archives, and other data.</p><p>We are not looking for anything simply because it is unusual.</p><p>We are looking for files that <strong>do not make sense for the role of the user or the server</strong>.</p><h4>Check for Resource Limits and Quotas</h4><p>A system can also be examined from the perspective of resource usage.</p><p>Check the current resource limits with:</p><pre>ulimit -a</pre><p>We can also examine the system’s limits configuration:</p><pre>cat /etc/security/limits.conf</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/565/1*tO4NIdyjBAQJrE9OxERANw.png" /></figure><p>And:</p><pre>ls -la /etc/security/limits.d/</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*ehPKqZiSQD5Ex08RLgsZsQ.png" /></figure><p>For filesystem quotas, check whether quota tools or quota-related mount options are configured.</p><p>The purpose is to determine whether users have restrictions on the amount of system resources they can consume.</p><p>This matters because uncontrolled resource usage can affect system availability.</p><h4>Look for Bad or Unexpected Files</h4><p>Now we start looking for files that may represent poor security practices or unexpected activity.</p><h4>1. World-writable files</h4><p>Search user directories for files or directories that anyone can write to:</p><pre>sudo find /home -xdev -perm -0002 -ls</pre><p>A world-writable file is not automatically malicious, but it should be investigated.</p><p>The question here is:</p><blockquote><strong>Does this file actually need to be writable by everyone?</strong></blockquote><p><strong>Everything is perfect on our server in this regard.</strong></p><h4>2. Hidden files</h4><p>Linux makes extensive use of hidden files, so finding one does not automatically indicate a problem.</p><p>We can examine hidden files in user directories with:</p><pre>sudo find /home -mindepth 1 -name &#39;.*&#39; –print</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*9H_m1caSEz3KJhx3U0PstA.png" /></figure><p>Files such as .bashrc, .profile, and .ssh may be completely legitimate.</p><p>We are looking for anything unexpected.</p><h4>Search for SetUID and SetGID Files</h4><p>SetUID and SetGID files deserve special attention because they can execute with the privileges of their owner or group.</p><p>Search user directories with:</p><pre>sudo find /home -xdev \( -perm -4000 -o -perm -2000 \) -ls</pre><p>If an ordinary user owns a SetUID or SetGID executable, that should be investigated carefully.</p><p>This is especially relevant to our later work because incorrectly configured privileged binaries can contribute to privilege-escalation risks.</p><h4>Check for Incorrect File Ownership</h4><p>We should also verify whether files inside users’ home directories actually belong to the expected users.</p><p>For example:</p><pre>sudo find /home/admin -xdev ! -user admin -ls</pre><p>This searches for files inside admin&#39;s home directory that are owned by someone else.</p><p>Unexpected ownership can indicate:</p><ul><li>Poor administration</li><li>Incorrect permissions</li><li>Files copied by another account</li><li>Or, in some cases, suspicious activity</li></ul><p>Again, <strong>finding something unusual is not the same as proving compromise</strong>. It simply gives us something to investigate.</p><h4>Examine System Directories</h4><p>The lab also asks us to look for end-user-owned files inside system directories such as:</p><p>/</p><p>/etc</p><p>/bin</p><p>/sbin</p><p>/usr</p><p>For example:</p><pre>sudo find /etc /bin /sbin /usr -xdev -user admin -ls</pre><p>A normal user-owned file inside locations such as /etc or /usr would be unusual and should be investigated.</p><p>We are essentially asking:</p><blockquote><strong>Does ownership match the purpose of the directory?</strong></blockquote><h3>Establishing a Security Baseline with Lynis</h3><p>At this point, we have manually examined several aspects of the system.</p><p>Now we can use a security auditing tool to help us identify additional areas that deserve attention.</p><p>Install <strong>Lynis</strong>:</p><pre>sudo apt install lynis</pre><p>Run a system audit:</p><pre>sudo lynis audit system</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*YAmn8d6rV-BZENzkLgED8g.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*owlmXRBHgcLtj_66M_ydaA.png" /></figure><p>Lynis will examine different areas of the system and provide findings and recommendations.</p><p>In my scan, for example, Lynis identified <strong>37 running services and 67 enabled services</strong>, and flagged services such as apache2, avahi-daemon, and cockpit as <strong>UNSAFE</strong>.</p><p><strong>Your tast is to </strong>review the Lynis output carefully. Don’t immediately apply every recommendation. Instead, identify the findings that are relevant to this server’s intended role and <strong>record them as potential hardening tasks</strong> for later episodes.</p><p>This gives us another valuable part of our baseline: <strong>what an automated security audit thinks needs attention.</strong></p><p>The more useful part is understanding <strong>why</strong> Lynis recommends a particular change.</p><blockquote>📝<strong>:</strong> A Lynis warning is not automatically a vulnerability. Treat each finding as something to investigate and validate against the actual purpose and configuration of the server.</blockquote><h3>File Integrity Monitoring with AIDE</h3><p>Another useful tool for system examination is <strong>AIDE (Advanced Intrusion Detection Environment)</strong>.</p><p>Install it with:</p><pre>sudo apt install aide</pre><p>AIDE works by creating a baseline of selected files and later comparing the current state against that baseline.</p><p>Initialize the database:</p><pre>sudo aide --init</pre><p>Then check the generated database:</p><pre>ls -l /var/lib/aide/</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/520/1*xzHf7Wc8FfXdft-xuK4sjw.png" /></figure><p>Once the baseline has been established, AIDE can be used to identify changes to monitored files.</p><p>This is different from our earlier debsums experiment.</p><p>debsums primarily verifies package-managed files against their recorded checksums, while AIDE provides a broader file-integrity monitoring approach.</p><p>If a monitored system file changes later, will we be able to detect it?</p><blockquote>📝<strong>:</strong> At this stage, we are not trying to fix anything. We are simply establishing how AIDE sees the current state of the system.</blockquote><h3>Evaluating the Dynamic State</h3><p>So far, we have examined what <strong>exists</strong> on the system.</p><p>Now we need to examine what the system is <strong>doing</strong>.</p><p>This is the dynamic state.</p><p>We want to understand:</p><ul><li>What processes are running?</li><li>What services are listening?</li><li>Who is currently logged in?</li><li>What network connections exist?</li><li>What security-related activity is being recorded?</li></ul><p>Some useful commands include:</p><p>ps aux</p><p>ss -tulpn</p><p>who</p><p>w</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*rpRuLVwhDZPwLTRKo9emRg.png" /></figure><p>We are no longer looking at the server as a collection of files and packages.</p><p>We are observing it as a <strong>running system</strong>.</p><h3>Examining Authentication Logs</h3><p>One of the most useful sources of information about system activity is the authentication log.</p><p>On Ubuntu, examine:</p><pre>sudo less /var/log/auth.log</pre><p>We can search for failed authentication attempts:</p><pre>sudo grep &quot;Failed&quot; /var/log/auth.log</pre><p>Successful SSH logins can be reviewed with:</p><pre>sudo grep &quot;Accepted&quot; /var/log/auth.log</pre><p>And sudo-related activity with:</p><pre>sudo grep &quot;sudo&quot; /var/log/auth.log</pre><p>But rather than simply reading old entries, let’s generate some known events ourselves.</p><h4>Generate Failed Authentication Events</h4><p><strong>Test </strong><strong>sudo</strong></p><p>Run:</p><pre>sudo -k</pre><pre>sudo whoami</pre><p>When prompted, intentionally enter the wrong password.</p><p>Then check the log:</p><pre>sudo grep -a &quot;incorrect password&quot; /var/log/auth.log</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*AZdnRGvLGqLEPvnI0IJJfA.png" /></figure><p>Observe how the failed attempt was recorded.</p><p><strong>Test </strong><strong>su</strong></p><p>Run:</p><pre>su -</pre><p>Enter an incorrect password.</p><p>Then examine:</p><pre>sudo grep -a &quot;su&quot; /var/log/auth.log | tail</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*MZcDa-__UYrMfUMo7FlkRA.png" /></figure><p>Compare the entry with the failed sudo attempt.</p><h4><strong>Test SSH with an Incorrect Password</strong></h4><p>From the host machine, attempt to connect using SSH:</p><pre>ssh admin@&lt;server-ip&gt;</pre><p>Enter an incorrect password.</p><p>Then return to the server and check:</p><pre>sudo grep -a “sshd” /var/log/auth.log | tail</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*suWP6P1WbRknCshXaFxPIQ.png" /></figure><h4>Test SSH With an Invalid Username</h4><p>Now try connecting with a username that does not exist:</p><pre>ssh fakeuser@&lt;server-ip&gt;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*7-mFHTNKTCCeUqHOTEBHzg.png" /></figure><p>After the failed attempt, check the authentication log again:</p><pre>sudo grep –a &quot;sshd&quot; /var/log/auth.log | tail</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*OxZVpdE5yBnMcJE-mVDNmA.png" /></figure><p>Compare the different entries.</p><p>This exercise helps us become familiar with what failed authentication attempts actually look like from the system’s perspective.</p><p>That knowledge becomes extremely useful when we move into <strong>logging, monitoring, and detection</strong> later in the project.</p><h3>What Have We Learned?</h3><p>At this point, we have examined the server from several different angles.</p><p>We looked at:</p><ul><li>Installed software and packages</li><li>Outdated software</li><li>Potential CVEs</li><li>File ownership and permissions</li><li>Security auditing with Lynis</li><li>File integrity monitoring with AIDE and more…</li></ul><p>The important part is not the number of commands we ran.</p><p>It is the <strong>baseline we are building</strong>.</p><p>We now have a much clearer picture of what exists on this server, what it is doing, and where we need to pay attention.</p><h3>What’s Next?</h3><p>We have examined the system.</p><blockquote>Now we can start changing it</blockquote><p>In the next episode, we move from <strong>examination to configuration and hardening</strong>, where we begin addressing the weaknesses and unnecessary exposure identified during this assessment.</p><p><strong>If you liked what you just read, consider:</strong></p><p>◆ Liking the article</p><p>◆ Dropping a comment to show your support</p><p>◆ Sharing the article with others who will find it useful</p><p>◆ Follow me on <a href="https://medium.com/@abdul-mumin">Medium</a> and <a href="https://www.linkedin.com/in/abdul-mu-min-rafiu-cc-546968252/">LinkedIn</a></p><h3>Before you go</h3><ul><li>Please take a moment to like the post and follow the writer!</li><li>Did you know that over 400,000 developers share what they’re building, learning, and discovering across our platforms every month? Learn how you can contribute <a href="https://plainenglish.io/write-for-us"><strong>here</strong></a>.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e40fa2922a03" width="1" height="1" alt=""><hr><p><a href="https://aws.plainenglish.io/building-a-bulletproof-linux-server-ep-3-system-examination-e40fa2922a03">Building a Bulletproof Linux Server — Ep. #3: System Examination</a> was originally published in <a href="https://aws.plainenglish.io">AWS in Plain English</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Last Normal Man]]></title>
            <link>https://medium.com/@abdul-mumin/the-last-normal-man-3aff4ec425b1?source=rss-902a4c1fad89------2</link>
            <guid isPermaLink="false">https://medium.com/p/3aff4ec425b1</guid>
            <category><![CDATA[allah]]></category>
            <category><![CDATA[life-lessons]]></category>
            <category><![CDATA[islam]]></category>
            <category><![CDATA[life]]></category>
            <category><![CDATA[faith]]></category>
            <dc:creator><![CDATA[Abdul-mu'min Omotola]]></dc:creator>
            <pubDate>Tue, 11 Aug 2026 11:01:30 GMT</pubDate>
            <atom:updated>2026-08-11T11:01:30.438Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*M7SvDkT0b9mnFrS8YTl4mQ.jpeg" /><figcaption><a href="https://unsplash.com/photos/man-standing-front-of-roller-up-gate-jkyyu_cvq9I">Photo by Kelli McClintock on Unsplash</a></figcaption></figure><p>There is a dry cleaner I know.</p><p>He has a small shop.</p><p>Small enough to wash in it…</p><p>Sleep and eat in it.</p><p>He’s in his forties now; never married.</p><p>A good man, I think.</p><p>At least, he wants to be.</p><p>But there is one thing that keeps stealing from him.</p><p>Drink.</p><p>Some days he promises to deliver clothes.</p><p>Mostly, he forgets.<br>And some days he crashes before the day is done.</p><p>Each time I see him, I don’t laugh.</p><p>I don’t judge him.</p><p>I just wonder how many dreams alcohol has buried without anyone holding a funeral for them.</p><p>Sad;</p><p>The thing about sin is that it rarely destroys a man in one night.<br>It takes its time.</p><p>One drink becomes a habit.</p><p>One habit becomes a name.</p><p>Then one day, people stop saying,</p><blockquote>“He’s struggling.”</blockquote><p>They simply say,</p><blockquote>“That’s just who he is.”</blockquote><p>I think that’s the part that scares me the most.</p><p>And… hmm, drink is only one face of the story.<br>There are young men whose addiction isn’t in a bottle.</p><p>It’s in women.<br>Some cannot spend a week without chasing one.</p><p>Others boast about zina as though it were an achievement.</p><p>Some have built an entire personality around the sins they once tried to hide.</p><p>It’s strange.</p><p>The very things that should break a man’s heart now earn him applause.</p><p>May Allah protect us.</p><p>Not all sins make headlines though.</p><p>Even so, some are quiet that only Allah knows they exist.</p><p>The gaze you refused to lower.</p><p>The song you promised would be the last.</p><p>The handshakes you know you shouldn’t have.</p><p>The prayer you keep delaying.</p><p>Sometimes a man isn’t falling off a cliff.</p><p>He’s drifting.</p><p>And drifting is dangerous because it doesn’t feel like falling.</p><p>But perhaps…</p><p>As you’ve been reading all this my friend, you’ve quietly been saying,</p><blockquote>“Alhamdulillah, Alhamdulillah… Allah has protected me from much of it.”</blockquote><p>Maybe you’ve never tasted alcohol.</p><p>Maybe you feel uneasy when music fills the air. Or you fear one sin more than you fear being called “boring.”</p><p>Dear reader..</p><p>Don’t let the numbers fool you.</p><p>Truth has never needed a crowd.</p><p>If everyone around you is running toward the edge, it doesn’t make the edge any safer.</p><p>So if obeying Allah sometimes makes you feel out of place…</p><p>Or saying “no” has made you lose friends…</p><p>Maybe you are not the one who is odd.</p><p>The world around you has simply forgotten what normal looks like</p><p>Now listen closely…</p><p>The world may look at you and see someone “missing out.”</p><p>The Prophet ﷺ looked at you and saw something else.</p><p>A stranger.</p><p>Yes, he literally called you a stranger.</p><p>Because you refused to fit into what displeases Allah.</p><p>So wear your strangeness with gratitude.</p><p>Because here is the thing; some people are strangers to the world.</p><p>Others are strangers to Jannah.</p><p>Choose carefully which one you would rather be.</p><blockquote><strong>طُوبَى لِلْغُرَبَاءِ</strong></blockquote><p>Glad tidings to the strangers.</p><p>By: Abdul-mumin<br>Editor-in-chief</p><p>©️ Editorial Board, MSSN FUTMINNA</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3aff4ec425b1" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My AWS Solutions Architect Journey: Everything in AWS Needs a Network]]></title>
            <link>https://medium.com/@abdul-mumin/my-aws-solutions-architect-journey-everything-in-aws-needs-a-network-7cbf601672e5?source=rss-902a4c1fad89------2</link>
            <guid isPermaLink="false">https://medium.com/p/7cbf601672e5</guid>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[learning]]></category>
            <dc:creator><![CDATA[Abdul-mu'min Omotola]]></dc:creator>
            <pubDate>Thu, 30 Jul 2026 20:19:27 GMT</pubDate>
            <atom:updated>2026-07-30T20:19:27.571Z</atom:updated>
            <content:encoded><![CDATA[<h4>Almost Everything</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vHcFQxchxpJTl7SsEUwnhQ.png" /></figure><p>In the previous episode, I learned that before anyone can use AWS resources, AWS first needs to know <strong>who they are</strong> through Identity and Access Management (IAM).</p><p>This time, the focus shifted from <strong>identity</strong> to <strong>infrastructure</strong>.</p><p>Before learning how applications are deployed in the cloud, I wanted to understand the environment they run in.</p><p>That environment is the <strong>Amazon Virtual Private Cloud (Amazon VPC)</strong>.</p><p>Along the way, I also explored two cloud-native approaches to running applications; <strong>serverless computing</strong> and <strong>containers</strong>.</p><p>Although the hands-on lab focused primarily on networking, understanding these concepts helped me see how everything fits together.</p><h3>Three ways applications run in AWS</h3><p>When I first started learning AWS, I thought every application simply ran on a virtual machine.</p><blockquote>That’s only one option.</blockquote><p>AWS provides several ways to run applications, depending on the level of control you need.</p><h4>Amazon EC2</h4><p>You manage the server yourself.</p><ul><li>Install software</li><li>Patch the operating system</li><li>Configure networking</li><li>Scale resources</li></ul><p>Maximum flexibility.</p><p>Maximum responsibility.</p><h4>Containers</h4><p>Containers package an application together with everything it needs to run.</p><p>Instead of worrying about whether an application works on another machine, containers ensure consistency across different environments.</p><p>AWS provides services such as:</p><ul><li>Amazon ECS</li><li>Amazon EKS</li><li>AWS Fargate</li></ul><p>to run containerized workloads.</p><h4>Serverless</h4><p>Serverless removes server management completely.</p><p>You simply upload your code, and AWS automatically provisions infrastructure, scales your application, and charges only for actual usage.</p><p>Popular serverless services include:</p><ul><li>AWS Lambda</li><li>Amazon API Gateway</li><li>Amazon DynamoDB</li></ul><p>No servers to patch.</p><p>No infrastructure to manage.</p><p>Regardless of whether an application runs on an EC2 instance, inside a container, or as a serverless function, it still needs a network to communicate securely.</p><p>That’s why we need to talk about VPC.</p><h3>Understanding Amazon VPC</h3><p>Think of an Amazon VPC as your own private section of the AWS cloud.</p><p>Just as organizations design their own corporate networks, AWS allows customers to create isolated virtual networks where they control IP addressing, routing, internet connectivity, and security.</p><p>In this lab, I explored a pre-configured VPC hosting a web application and examined the networking components that made communication possible.</p><h3>Components explored in the lab</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/990/1*ErbhMsdVngNBrDyURo9XrA.png" /><figcaption>Lab diagram</figcaption></figure><h4>Internet Gateway</h4><p>What gives internet access.</p><h4>Public Subnet</h4><p>Where internet-facing resources live.</p><h4>Route Table</h4><p>How traffic knows where to go.</p><h4>Security Groups</h4><p>Virtual firewall.</p><h4>EC2</h4><p>The web server.</p><h3><strong>Lab Activities</strong></h3><p>The lab began by examining an existing Amazon VPC configured with a public subnet, route table, and Internet Gateway.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*n-H6LHOUxQ1bnVF06dhQPw.png" /></figure><p>I reviewed how traffic was routed from the subnet to the internet and how Security Groups acted as virtual firewalls controlling inbound and outbound communication.</p><p>Afterwards, I launched an Amazon EC2 instance into the VPC, associated it with the existing security group, and used a user data script to automatically install Node.js, retrieve the application package from Amazon S3, install dependencies, and start the web application.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Aazlkmy3OAixfr5KIFq4Uw.png" /></figure><h3>The coolest thing I learned</h3><p>My favorite takeaway wasn’t launching the EC2 instance.</p><p>It was the <strong>User Data script</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Z0ttaA_mJkH_Xy9_Qwkguw.png" /><figcaption>The user user data script that prepares the web application</figcaption></figure><p>Instead of manually logging into the server to install software, AWS automatically executed the bootstrap script during launch.</p><p>That small feature demonstrated one of the biggest ideas in cloud computing:</p><blockquote><strong>Infrastructure should be automated whenever possible.</strong></blockquote><p>In future episodes, I will be configuring DNS. To access the web app, I used the public address 43.207.78.152</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NI9bK087PvEZ7IvDLT2qpA.png" /></figure><h3><strong>Cybersecurity Perspective</strong></h3><p>Coming from cybersecurity, I immediately looked at the Security Group differently.</p><p>Rather than thinking of it as just another AWS feature, I saw it as a cloud-native firewall implementing the Principle of Least Privilege.</p><p>Only HTTP (80) and HTTPS (443) traffic were allowed into the web server, while outbound traffic was limited to only what the application required.</p><p>Security in AWS begins long before an application is deployed — it begins with how the network itself is designed.</p><h4>Key Takeaways</h4><ul><li>Serverless removes server management.</li><li>Containers package applic+ations consistently.</li><li>Amazon VPC provides network isolation.</li><li>Security Groups function as virtual firewalls.</li><li>Infrastructure automation saves time and reduces manual errors.</li><li>Cloud security begins with proper network design.</li></ul><h3>What’s Next?</h3><p>In the next episode, I’ll continue documenting my AWS Solutions Architect journey as I build a deeper understanding of the services that make modern cloud architectures secure, scalable, and highly available.</p><p><strong>If you liked what you just read, consider:</strong></p><p>◆ Dropping a comment to show your support</p><p>◆ Sharing the article with others who will find it useful</p><p>◆ Follow me on <a href="https://medium.com/@enigmatictola">medium</a> and <a href="https://www.linkedin.com/in/abdul-mu-min-rafiu-cc-546968252/">LinkedIn</a></p><p>Cheers.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7cbf601672e5" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Building a Virtual Ethical Hacking Home Lab — Part 7: Password Cracking and Vulnerability…]]></title>
            <link>https://infosecwriteups.com/building-a-virtual-ethical-hacking-home-lab-part-7-password-cracking-and-vulnerability-0d067592480d?source=rss-902a4c1fad89------2</link>
            <guid isPermaLink="false">https://medium.com/p/0d067592480d</guid>
            <category><![CDATA[homelab]]></category>
            <category><![CDATA[hacking]]></category>
            <category><![CDATA[ethical-hacking]]></category>
            <category><![CDATA[passwords]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <dc:creator><![CDATA[Abdul-mu'min Omotola]]></dc:creator>
            <pubDate>Sat, 11 Jul 2026 22:29:28 GMT</pubDate>
            <atom:updated>2026-07-11T22:29:28.634Z</atom:updated>
            <content:encoded><![CDATA[<h3>Building a Virtual Ethical Hacking Home Lab — Part 7: Password Cracking and Vulnerability Assessment</h3><h4>An interactive guide for building your very own ethical hacking home lab using VMware</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dCst9iaO6WkIpAacxQOgiA.jpeg" /><figcaption>Banner background by <a href="http://hacker%20cartoon%20by%20designer29%20on%20freepik/">Logturnal on Freepik</a> | Hacker cartoon by <a href="https://www.freepik.com/premium-vector/hacker-operating-laptop-cartoon-icon-illustration-isolated-flat-cartoon-style-technology-icon_353802661.htm#from_view=detail_alsolike">Designer29 on Freepik</a></figcaption></figure><p>Banner Inspired by: <a href="https://medium.com/u/aa69ce38c982">David Varghese</a></p><p>In this episode, we shift from system exploitation to what attackers do <a href="https://medium.com/bugbountywriteup/building-a-virtual-ethical-hacking-home-lab-part-6-system-exploitation-55e50ffb2a3b"><strong>after gaining access</strong>:</a> extracting credentials and identifying system weaknesses at scale.</p><h4>This lab focuses on:</h4><ol><li>Hashcat Benchmark</li><li>Creating NTLM Hashes</li><li>Mask Attacks (When Pattern Is Known)</li><li>Dictionary Attacks</li><li>Cracking Without a Wordlist</li><li>Hash Identification &amp; Strategy</li><li>Dumping Real Hashes</li><li>Dumping Windows Account Hashes</li><li>OpenVAS (Greenbone) Vulnerability Assessment</li></ol><h3>Hashcat Benchmark</h3><p>Before cracking passwords, we measure system cracking performance.</p><pre>hashcat -b -m 5600</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*SoOkKfpSUD5WiLwSEw2cPQ.png" /></figure><ul><li>-b → benchmark mode</li><li>-m 5600 → NetNTLMv2</li></ul><p>The output shows speeds such as <strong>MH/s, </strong><strong>KH/s, </strong><strong>GH/s</strong>, representing how many hashes can be tested per second. Higher speed = faster cracking capability.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*qD0-RLjJK_yoxyPxfrzcDg.png" /></figure><h3>Creating NTLM Hashes</h3><p>We simulate stolen Windows credentials.</p><p><a href="https://www.browserling.com/tools/ntlm-hash">Use an NTLM hash generator and create hashes for:</a></p><ul><li>Password04$</li><li>house123</li><li>Password</li><li>hacker</li><li>Meatballs1</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*0Lu8wCyDIZJsDw0tnb-ljQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*BJeyJhmCrxWISRcOLyOJlA.png" /></figure><p>Save them:</p><pre>nano ntlm_hashes.txt</pre><p>Each line = one hash.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*sIlHssO8lcT0vZvPsGab7A.png" /></figure><p>NTLM is used in Windows authentication and is common in breaches.</p><h3>Mask Attacks (When Pattern Is Known)</h3><p>Mask attacks are used when we know password structure.</p><h4>Crack “Password04$”</h4><p>Run Command</p><pre>hashcat -m 1000 -a 3 ntlm_hashes.txt ?u?l?l?l?l?l?l?d?d$</pre><p>So instead of trying <strong>billions of random guesses</strong>, it only tries combinations that look like:</p><h4>What You See in the Output</h4><p>Example:</p><pre>Speed.#1.........: 820.5 MH/s<br>Progress.........: 456789012/1820000000<br>Recovered........: 1/5 (20.00%)Meaning:</pre><h4>When It Succeeds</h4><p>You’ll see:</p><pre>5f4dcc3b5aa765d61d8327deb882cf99:Password04$</pre><p>This means:</p><p><strong>Hash → Password mapping is complete.</strong></p><p>Hashcat then stores it in:</p><pre>hashcat.potfile</pre><p>You can confirm later with:</p><pre>hashcat -m 1000 ntlm_hashes.txt --show</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*cNLDobBjtRXvWhiCqOFUTg.png" /></figure><p>Note: I cracked a password with a very weak policy (1234) to reduce the cracking time for the purpose of demonstration. You will leave hascat to run much longer in order to crack Password04$</p><p>Mask attacks are extremely powerful when password policy is known.</p><h4>Crack “house123” Using Full Charset</h4><pre>hashcat -m 1000 -a 3 ntlm_hashes.txt ?a?a?a?a?a?a?a?a</pre><p>?a = all characters (letters, numbers, symbols)</p><p>This is slower that but flexible.</p><h3>Dictionary Attacks</h3><p>Dictionary attacks use real leaked passwords.</p><p>First, <a href="https://weakpass.com/wordlists/rockyou.txt">download rockyou</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*8mfUwEOQ1nCa4eOR4eqCHw.png" /></figure><p>Decompress the .gz file with the following commands:</p><pre>gzip –d /home/attacker/Downloads/rockyou.txt</pre><h4>Using Hashcat</h4><pre>hashcat -m 1000 ntlm_hashes.txt /home/attacker/Downloads/rockyou.txt</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*ZJNL4tAKIFJJhP0QVQZz2w.png" /></figure><blockquote>ℹ️: Rockyou contains millions of real passwords from breaches.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*GoJPhFCeI5XZ9wcaDb-idQ.png" /></figure><p>As you can see, it already cracked the passwords.</p><p>If passwords don’t crack:</p><pre>echo &quot;Password&quot; &gt;&gt; /home/attacker/Downloads/rockyou.txt<br>echo &quot;Meatballs1&quot; &gt;&gt; /home/attacker/Downloads/rockyou.txt</pre><p>This will append the passwords to the list</p><h4>Using John the Ripper</h4><pre>john --format=NT ntlm_hashes.txt<br>john --show ntlm_hashes.txt</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*QjTN1MjsZwse_fpyl0GvVQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*r_e_vgalMXa6G3pH8fUoIg.png" /></figure><p>John applies mutation rules automatically (like Password → Password1).</p><h3>Cracking Without a Wordlist</h3><p>For hacker:</p><pre>john --format=NT ntlm_hashes.txt</pre><p>John uses incremental brute force + rules.</p><h3>Hash Identification &amp; Strategy</h3><pre>hashid 06DDC11A1EA340A47E8EDC44D42EA716</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*zjmaPCEyFAUfkvwzmjTBXw.png" /></figure><p>We are given pattern clues. Instead of brute force, we design a mask:</p><pre>hashcat -a 3 -m 1000 ntlm_hashes.txt ?u?l?l?l?li?l2?d?d?d?d</pre><p>This shows how attackers reduce cracking time using intelligence.</p><h3><strong>Dumping Real Hashes</strong></h3><p>In <a href="http://exploitation">the previous episode</a>, we successfully exploited the target and established a <strong>Meterpreter session</strong> on the Windows machine.</p><p>At that stage, we had <strong>code execution… </strong>but not full control.</p><p>There’s an important distinction:</p><ul><li>Access ≠ Control</li><li>Shell ≠ SYSTEM</li></ul><p>So, to extract credentials and truly own the machine,</p><blockquote>we needed <strong>privilege escalation</strong>.</blockquote><h4>Step 1: Understanding Our Current Privilege Level</h4><p>After gaining our Meterpreter session, we verified our access level:</p><pre>getuid</pre><p>Output showed:</p><pre>NT AUTHORITY\LOCAL SERVICE</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*B5kUvI8Qa5JGQShY_09y6w.png" /></figure><p>This is a <strong>low-privileged service account</strong>.</p><p>Why this is concerning:</p><ul><li>Cannot dump SAM database</li><li>Cannot access LSASS memory</li><li>Cannot migrate into SYSTEM processes</li><li>Cannot perform hashdump</li></ul><p>And when we attempted migrating to a System process ID</p><p>Let’s choose smss.exe with PID 224</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*CXTwAEp6zlN1OMIJdy5dNA.png" /></figure><pre>migrate &lt;PID&gt;</pre><p>We received:</p><pre>Cannot migrate into this process (insufficient privileges)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*hrC-WprELrt4VPQ15rNVHg.png" /></figure><p>This confirmed that escalation was required.</p><h4>Step 2: Enumerating Privileges</h4><p>We checked available privileges:</p><pre>getprivs</pre><p>The key privilege we were looking for:</p><pre>SeImpersonatePrivilege</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*lZEtYs1eO18MSbZibx5leQ.png" /></figure><p>This privilege allows a process to impersonate tokens of higher-privileged accounts — and it is commonly abused in Windows privilege escalation attacks.</p><h4>Step 3: Identifying Exploitable Vectors</h4><p>We then used Metasploit’s local exploit suggester:</p><p>Let’s background the session and use the suggester exploit</p><pre>background<br>use post/multi/recon/local_exploit_suggester</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*P3cbMq-64tc5wZfsq7wtNQ.png" /></figure><p>Set session to 1 and run the exploit</p><pre>set SESSION 1<br>run</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*NYhzAFXjCfNPzfX6jz6f9Q.png" /></figure><p>The module analyzed:</p><ul><li>OS version</li><li>Patch level</li><li>Running services</li><li>Token privileges</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*6K2-Ap-3D4JJUMxAPpBn3g.png" /></figure><p>It identified multiple potential vulnerabilities.</p><p>Since the target was <strong>Windows 2008</strong>, older kernel exploits were unreliable. We selected a token impersonation attack suitable for this version.</p><h4>Step 4: Exploiting MS16–075 (Juicy Potato Variant)</h4><p>Initial attempts with:</p><pre>exploit/windows/local/ms16_075_reflection</pre><p>failed due to timeout issues.</p><p>We adapted and used the Juicy Potato variant:</p><pre>use exploit/windows/local/ms16_075_reflection_juicy</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*58mhiiecOJV_iBIBMYUjhw.png" /></figure><pre>set SESSION 1<br>run</pre><blockquote>📝: I set to session 2 because that is the ID on my side. Use the corresponding session ID.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*2Ysfh1FwA6WTU7tWKp1hwQ.png" /></figure><p>This exploit abuses:</p><ul><li>SeImpersonatePrivilege</li><li>Windows COM service authentication</li><li>SYSTEM token impersonation</li></ul><p>Let us verify elevation:</p><pre>getuid</pre><p>Output:</p><pre>NT AUTHORITY\SYSTEM</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*kgrZVzSXAsaPDrNcp7i7bw.png" /></figure><p>We now had <strong>full SYSTEM-level control</strong>.</p><h3>Dumping Windows Account Hashes</h3><p>With SYSTEM privileges obtained, we could now access credential storage.</p><h4>Step 1: Dumping Hashes from SAM</h4><p>Inside the SYSTEM session:</p><pre>hashdump</pre><p>This extracts:</p><ul><li>Local account usernames</li><li>NTLM password hashes</li><li>Relative IDs (RIDs)</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*iIbqxeP52MURJR9ik2dmwQ.png" /></figure><p>The NTLM hash is the target for offline cracking.</p><h4>Step 2: Using Kiwi (Mimikatz Integration)</h4><p>If deeper extraction is required:</p><pre>load kiwi<br>lsa_dump_sam</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*TmZiln2a74AzfUEe9xZgIA.png" /></figure><p>This method is more powerful and flexible than basic hashdump.</p><h4>Step 3: Preparing for Offline Cracking</h4><p>We saved the extracted hashes:</p><pre>nano hashes.txt</pre><p>Then cracked them offline using Hashcat:</p><pre>hashcat -m 1000 hashes.txt rockyou.txt</pre><p>Where:</p><ul><li>-m 1000 = NTLM</li><li>hashes.txt = dumped hashes</li><li>rockyou.txt = wordlist</li></ul><p>Follow the above commands and use the steps we did in part 3 &amp; 4</p><h3>OpenVAS (Greenbone)</h3><p>This is automated vulnerability scanning. Greenbone is another tool we use for that purpose.</p><h4>Setup</h4><p><a href="https://www.greenbone.net/en/openvas-free/">Download Greenbone VM</a><br> It is 7GB</p><p>Import into VMware</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*hgsbAmaLeUAXAOiddK2hfg.png" /></figure><p>On your Workstation, navigate to Edit virtual machine settings and change the network adapter to Host-only</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*Dqt2uSfG3HH_4VQ7eVGiIg.png" /></figure><p>Start Greenbone and get IP</p><p>Here, the IP is 192.168.52.137</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*5UB4fBv91ktbbXope-FPrQ.png" /></figure><p>On your Kali, open web browser and type in the IP address of Greenbone</p><p>The browser shows a security risk warning</p><p>Click Advanced…</p><p>Accept the Risk and Continue</p><p>This takes us to the web interface</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*nJw4K50Z3iBxK0D3D2IC6A.png" /></figure><p>Login with the default credentials</p><p>Username: admin | Password: admin</p><p>On the Greenbone dashboard, click Tasks</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*xp3rJur7TEzs7D-h6VCcRg.png" /></figure><p>Click the magic wand symbol</p><p>Select Advanced Task Wizard</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*NeQS11rN-m0-YwAi77ADRQ.png" /></figure><p>It will open the task window</p><p>Select the Full and fast scan and type your Metasploitable3 IP address</p><p>Click Create</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*tTp-MLUklbJbnbftPJTKeA.png" /></figure><p>The scan is now queued</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*6DAuvoN755U-3w4EXcBiFw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*6mPb1JuIT19VDT1MFgow2Q.png" /></figure><p>So, we’ve come to the end of password cracking episode</p><p>This lab demonstrated how quickly weak passwords can be recovered once hashes are obtained. Using tools like Hashcat and John the Ripper, we transformed NTLM hashes into plaintext credentials through structured attack strategies such as dictionary and rule-based attacks.</p><p>The key takeaway is clear:</p><blockquote>password strength is a critical security control. Once hashes are extracted, offline cracking bypasses account lockouts and monitoring, making weak credentials a serious risk.</blockquote><p>Understanding how passwords are cracked is essential to understanding how they should be defended; through strong password policies, multi-factor authentication, and proper credential management.</p><p>See you in the next episode.</p><p><strong>If you liked what you just read, consider:</strong></p><p>◆ Dropping a comment to show your support</p><p>◆ Sharing the article with others who will find it useful</p><p>◆ Follow me on <a href="https://medium.com/@enigmatictola">medium</a> and <a href="https://www.linkedin.com/in/abdul-mu-min-rafiu-cc-546968252/">LinkedIn</a></p><p>◆ If you’re following the setup for this lab and you come across any technical issue, feel free to reach me through <a href="https://wa.me/qr/GZNTBEPE4XFMA1">WhatsApp</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=0d067592480d" width="1" height="1" alt=""><hr><p><a href="https://infosecwriteups.com/building-a-virtual-ethical-hacking-home-lab-part-7-password-cracking-and-vulnerability-0d067592480d">Building a Virtual Ethical Hacking Home Lab — Part 7: Password Cracking and Vulnerability…</a> was originally published in <a href="https://infosecwriteups.com">InfoSec Write-ups</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How Sony Scaled for 100 Million+ Gamers Using AWS]]></title>
            <link>https://aws.plainenglish.io/how-sony-scaled-for-100-million-gamers-using-aws-f2f734f147ac?source=rss-902a4c1fad89------2</link>
            <guid isPermaLink="false">https://medium.com/p/f2f734f147ac</guid>
            <category><![CDATA[cloud]]></category>
            <category><![CDATA[games]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <dc:creator><![CDATA[Abdul-mu'min Omotola]]></dc:creator>
            <pubDate>Fri, 10 Jul 2026 17:27:33 GMT</pubDate>
            <atom:updated>2026-07-13T06:35:40.907Z</atom:updated>
            <content:encoded><![CDATA[<h4>A Simple Breakdown of How Cloud Architecture Solves Massive Problems</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gZ6SmiPLXsWbLwPYmkIpvw.png" /></figure><blockquote>“Do you even care? Yours is just to have fun 🎮”</blockquote><p>And honestly…</p><p>You shouldn’t have to.</p><p>Remember the chaotic launch of the PlayStation 5 in late 2020?</p><p>The world was locked down, everyone was desperate for entertainment, and the demand for the new gaming console was high.</p><p>Millions of gamers were logging on simultaneously, demanding zero lag and seamless downloads.</p><p>For the players, it was a paradise on earth. After all, COVID had retired everyone to the comfort of their homes.</p><p>But behind the scenes at Sony Interactive Entertainment (SIE), it was an infrastructure nightmare waiting to happen.</p><h3><strong>The “Too Many Kitchens” Problem</strong></h3><p>To understand the problem, imagine the PlayStation Network isn’t a digital service, but a massive, global restaurant chain.</p><p>Before 2020, Sony’s backend was a mess of different “kitchens.”</p><p>Some developers were cooking on their own local servers, others were using random cloud tools, and everyone had their own weird recipes (programming languages) and schedules.</p><p>When things went wrong like a player’s friends list not loading; it was a scramble to figure out <em>which</em> kitchen messed up the order.</p><p>Highly skilled developers were spending half their time just fixing the plumbing rather than designing new games and features.</p><h4>So how did Sony go about this?</h4><p>Sony realized they needed to standardize. They couldn’t have 50 different kitchens operating under different rules. They needed one massive, highly efficient, unified mega-kitchen.</p><p>They built something called the <a href="https://aws.amazon.com/solutions/case-studies/sony-eks-case-study/"><strong>Unified Kubernetes Service (UKS)</strong>,</a> and the entire thing is powered by <a href="https://aws.amazon.com/eks/"><strong>Amazon EKS (Elastic Kubernetes Service)</strong></a>.</p><h3><strong>Why EKS?</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/249/1*fYD6tO1ROPfndnqSRdpclw.png" /><figcaption>Amazon EKS symbol</figcaption></figure><p>By choosing <strong>Amazon EKS (Elastic Kubernetes Service)</strong>, Sony offloaded that burden to AWS.</p><ul><li><strong>The Control Plane (Managed by AWS):</strong> AWS provisions, scales, and secures the Kubernetes API servers and the <em>etcd</em> backend database across multiple Availability Zones (AZs) for high availability. Sony doesn’t have to touch it.</li><li><strong>The Data Plane / Worker Nodes (Managed by Sony):</strong> Sony only has to worry about the actual compute instances (Amazon EC2 instances) where their game services run. EKS links these nodes directly to the Control Plane.</li></ul><h4>They Implemented Microservices</h4><p>Sony migrated over 400 different backend services to this unified platform. Instead of one massive application, PSN is broken into independent <strong>microservices</strong> (e.g., a service just for trophies, a service just for party chat).</p><p>Here is how the EKS ecosystem powers them:</p><ol><li><strong>Amazon ECR (Elastic Container Registry):</strong> Before a microservice can run, its code is packaged into a “container image” (a lightweight, standalone executable package). Sony stores these images securely in ECR. When EKS needs to launch a new instance of the party chat service, it pulls the blueprint directly from ECR.</li><li><strong>AWS Secrets Manager:</strong> You never want to hardcode passwords or database keys into your software. Sony integrated AWS Secrets Manager natively into their cluster. When a microservice boots up, it securely asks Secrets Manager for its credentials on the fly.</li><li><strong>Auto Scaling via EKS:</strong> Let’s say a new <em>Spider-Man</em> game drops and traffic spikes 1,000%. EKS monitors the CPU and memory load. It automatically tells AWS to spin up more EC2 <strong>Worker Nodes</strong> and deploys cloned containers across them to absorb the traffic. Once the spike ends, EKS terminates the extra nodes to save money.</li></ol><p>The best part is that Sony didn’t have to build the manager from scratch. AWS handles the heavy lifting of keeping the Kubernetes manager healthy and secure.</p><h4>The CI/CD Pipeline</h4><p>Because everything was now unified on one EKS platform, Sony’s platform engineering team built a massive, automated <strong>CI/CD (Continuous Integration / Continuous Delivery)</strong> pipeline.</p><p>Instead of developers manually configuring servers, they just write their code. The CI/CD pipeline automatically tests the code, runs security scans across it, and deploys it to the EKS cluster. By enforcing these uniform security scans at the runtime level, Sony went from having four different, fragmented security setups to just <em>one</em> ironclad standard.</p><h3>The High Score</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*lGFFAMhJf4PMQmLl8U42Qw.png" /><figcaption><a href="https://aws.amazon.com/solutions/case-studies/sony-eks-case-study/">AWS Case-studies</a></figcaption></figure><p>By moving everything onto this one unified AWS platform, Sony crushed their high score:</p><ul><li><strong>Saved Serious Cash:</strong> They reduced their operational costs by <strong>60%</strong> because they stopped paying for redundant, overlapping tools.</li><li><strong>Speed Demon:</strong> Developers can now deploy new features <strong>5x faster</strong>. Training new developers dropped from a grueling 16 hours down to just 3.</li><li><strong>Zero Downtime:</strong> They migrated over 400 vital services to this new system without any major crashes. You probably didn’t even notice it happened while you were gaming.</li></ul><p>So, the next time you instantly join a party chat or download an update at lightning speed, you can thank Amazon EKS for keeping the kitchen running smoothly.</p><p><strong>If you liked what you just read, consider:</strong></p><p>◆ Dropping a comment to show your support</p><p>◆ Sharing the article with others who will find it useful</p><p>◆ Follow me on <a href="https://medium.com/@enigmatictola">medium</a> and <a href="https://www.linkedin.com/in/abdul-mu-min-rafiu-cc-546968252/">LinkedIn</a></p><p>Cheers.</p><h3>Before you go</h3><ul><li>Please take a moment to like the post and follow the writer!</li><li>Did you know that over 400,000 developers share what they’re building, learning, and discovering across our platforms every month? Learn how you can contribute <a href="https://plainenglish.io/write-for-us">here</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f2f734f147ac" width="1" height="1" alt=""><hr><p><a href="https://aws.plainenglish.io/how-sony-scaled-for-100-million-gamers-using-aws-f2f734f147ac">How Sony Scaled for 100 Million+ Gamers Using AWS</a> was originally published in <a href="https://aws.plainenglish.io">AWS in Plain English</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My AWS Solutions Architect Journey — The First Lesson Wasn’t EC2, It Was Identity]]></title>
            <link>https://medium.com/@abdul-mumin/my-aws-solutions-architect-journey-the-first-lesson-wasnt-ec2-it-was-identity-c9a02d9012d9?source=rss-902a4c1fad89------2</link>
            <guid isPermaLink="false">https://medium.com/p/c9a02d9012d9</guid>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[cloud-security]]></category>
            <dc:creator><![CDATA[Abdul-mu'min Omotola]]></dc:creator>
            <pubDate>Fri, 03 Jul 2026 05:29:24 GMT</pubDate>
            <atom:updated>2026-07-03T05:29:24.880Z</atom:updated>
            <content:encoded><![CDATA[<h4>Understanding IAM</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jkcHsCJgLXrpsbaXdvBH2Q.png" /></figure><blockquote>Hello, amiable reader. I’m Abdul-Mumin.</blockquote><p>I’ve spent the last few years building cybersecurity labs, exploiting vulnerable systems, hardening Linux servers, and studying digital forensics.</p><p>But one thing became obvious:</p><blockquote>modern infrastructure is moving to the cloud.</blockquote><p>So after <a href="https://medium.com/aws-in-plain-english/how-i-passed-my-aws-cloud-practitioner-exam-clf-c02-e9861f30cbde?sharedUserId=abdul-mumin">passing the AWS Cloud Practitioner certification</a>, I began the <a href="https://www.coursera.org/professional-certificates/aws-cloud-solutions-architect"><strong>AWS Cloud Solutions Architect Specialization</strong> on Coursera</a> to better understand how cloud environments are designed, deployed, and secured.</p><p>Interestingly, AWS didn’t begin by teaching me EC2; the service most people associate with AWS.</p><p>Instead, the first module focused entirely on <strong>Identity and Access Management (IAM)</strong>.</p><p>At first, I wondered why.</p><p>By the end of the lab, the answer was obvious: before anyone can deploy infrastructure, AWS first needs to know <strong>who they are</strong> and <strong>what they’re allowed to do.</strong></p><h3><strong>What is IAM?</strong></h3><p>Identity and Access Management (IAM) is the AWS service responsible for controlling authentication and authorization. Simply put, it ensures that the right identities have the right level of access to AWS resources.</p><p>Throughout the lab, one thing became very clear:</p><ul><li>Every request made to AWS is tied to an identity.</li><li>Permissions are never granted automatically.</li><li>Users should only receive the permissions they need to perform their jobs.</li><li>The root account should only be used for administrative tasks that require it — not for everyday operations.</li></ul><h3><strong>What happened in the lab?</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/546/1*ZL-_jrf8T39J8AXaNC3gdg.png" /></figure><p>The lab introduced the core building blocks of AWS IAM:</p><ul><li>Users</li><li>User Groups</li><li>Roles</li><li>Policies</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*FzlkmQqd07H6qJFvOfDpNQ.png" /></figure><p>At its core, an IAM user is simply an identity that is granted permission to perform specific actions on specific AWS resources. Rather than assigning permissions directly to every individual user, AWS encourages administrators to manage permissions through groups and policies.</p><p>For example, in the case of User-1 — EC2 Admin</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*Ob8ZIU5h9NUwmexFD019VA.png" /></figure><blockquote>There is no individual permission</blockquote><p>You may notice that <strong>User 1 (S3 Support)</strong> doesn’t have any permissions directly assigned.</p><p>Instead, the user inherits permissions from the IAM group they belong to.</p><p>You might also notice a policy named <strong>RegionPinningPolicy</strong>.</p><p>This is a customer-managed IAM policy that restricts users or workloads to operating within a specific AWS Region (for example, <em>us-east-1</em>).</p><p>Since this lab runs inside a controlled learning environment, the policy prevents users from accidentally launching resources in other regions — helping control costs and maintain consistency throughout the exercises.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*6-zHo3VJnMYTB91xjNCAtw.png" /></figure><p>Assigning permissions to groups instead of individual users isn’t just convenient — it’s a cloud security best practice.</p><p>It reduces administrative overhead, minimizes the risk of permission creep, and helps organizations maintain consistent access controls as teams grow.</p><h4><strong>The Business scenario</strong></h4><p>According to the lab:</p><blockquote>Your company’s use of Amazon Web Services grows over time. The company uses many Amazon EC2 instances and a significant amount of Amazon S3 storage. You want to grant access to new staff members based on their job functions, as shown in the table.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/519/1*J5lyR50CwlwFhNhDcyCjNA.png" /></figure><p>Each user was assigned to its respective group</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*jZB8OvN1RxdYCoPGG2Q0UQ.png" /></figure><h4>Using the IAM sign-in URL for the IAM Users</h4><p>Navigation: IAM &gt;&gt; Dashboard &gt;&gt; AWS Account</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/421/1*ICb9IZmGjyAJk5ppfUcx5g.png" /></figure><p>Then I used the URL to login with different users 1,2 and 3; tested what each account was allowed — and not allowed — to do.</p><p>For example for user-1 who is not allowed to <strong>View</strong>, <strong>Start</strong>, and <strong>Stop</strong> Amazon EC2 instances is tested here:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*PeWSFdhMzKBBVcBvu9W33A.png" /></figure><p>This demonstrated <strong>Role-Based Access Control (RBAC)</strong> in practice.</p><blockquote>Each user’s permissions were determined by the IAM group they belonged to, rather than by permissions assigned directly to the user.</blockquote><h3><strong>What’s Next?</strong></h3><p>That is all for the lab!</p><p>.</p><p>This is only the beginning.</p><p>Over the coming weeks I’ll be documenting each major AWS lab as I work toward becoming a Cloud Solutions Architect.</p><p>The goal isn’t just to finish a course.</p><p>It’s to build enough practical understanding to confidently design secure cloud environments.</p><p><strong>If you liked what you just read, consider:</strong></p><p>◆ Dropping a comment to show your support</p><p>◆ Sharing the article with others who will find it useful</p><p>◆ Follow me on <a href="https://medium.com/@enigmatictola">medium</a> and <a href="https://www.linkedin.com/in/abdul-mu-min-rafiu-cc-546968252/">LinkedIn</a></p><p>Cheers.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c9a02d9012d9" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>