<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: DoiT International</title>
    <description>The latest articles on Forem by DoiT International (@doitintl).</description>
    <link>https://forem.com/doitintl</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F919%2F0154cc8b-9a1d-4c52-8570-849bea18cbda.png</url>
      <title>Forem: DoiT International</title>
      <link>https://forem.com/doitintl</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/doitintl"/>
    <language>en</language>
    <item>
      <title>Preconfigured Nexus Repository Manager (NXRM) Docker container</title>
      <dc:creator>Meir Gabay</dc:creator>
      <pubDate>Thu, 10 Jun 2021 10:48:31 +0000</pubDate>
      <link>https://forem.com/doitintl/preconfigured-nexus-repository-manager-nxrm-docker-container-5am</link>
      <guid>https://forem.com/doitintl/preconfigured-nexus-repository-manager-nxrm-docker-container-5am</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: Link To Project @ &lt;a href="https://github.com/unfor19/nexus-ops"&gt;GitHub - unfor19/nexus-ops&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Recently, I've been looking for a way to avoid hitting &lt;a href="https://docs.docker.com/docker-hub/download-rate-limit/"&gt;DockerHub rate limits&lt;/a&gt;. One of the solutions that I came up with was deploying &lt;a href="https://www.sonatype.com/products/repository-oss"&gt;Nexus Repository Manager OSS&lt;/a&gt; (NXRM) as part of my CI/CD environment, so the CI/CD runners hit NXRM instead of &lt;a href="http://dockerhub.com/"&gt;DockerHub&lt;/a&gt; when attempting to pull public Docker images.&lt;/p&gt;

&lt;p&gt;As always, I Googled a lot on how to get started with NXRM, and it seemed like it's best just to run it locally and see how it goes.&lt;/p&gt;

&lt;p&gt;Ladies and gents, I give you my hands-on experience with provisioning a preconfigured NXRM Docker container.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Goal
&lt;/h2&gt;

&lt;p&gt;NXRM Docker container that is preconfigured with &lt;a href="http://dockerhub.com/"&gt;DockerHub&lt;/a&gt; and &lt;a href="https://gallery.ecr.aws/"&gt;AWS ECR Public Gallery&lt;/a&gt;. Here's what I found in Google:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.mimacom.com/automate-nexus/"&gt;Automated Setup of Sonatype Nexus Repository Manager
&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/sonatype-nexus-community/nexus-scripting-examples/tree/master/complex-script"&gt;NXRM Integration API Scripting Examples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://community.sonatype.com/t/automated-provisioning-of-nexus/2544"&gt;Nexus Community - Automated provisioning of nexus&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My Issue With Existing Solutions
&lt;/h2&gt;

&lt;p&gt;I want to run the &lt;code&gt;init-script&lt;/code&gt; immediately when NXRM is ready and part of the NXRM startup. I don't want to execute any script manually on my machine; everything should be done as part of NXRM's startup process. Most existing solutions describe running something on your machine that will communicate with NXRM; I'm looking for something different.&lt;/p&gt;

&lt;h2&gt;
  
  
  Desired Outcome
&lt;/h2&gt;

&lt;p&gt;Let's break it into a few bullet points that will describe the desired output.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;init-script&lt;/code&gt; is readable and easy to maintain.&lt;/li&gt;
&lt;li&gt;Restarting the NXRM container should be idempotent; the &lt;code&gt;init-script&lt;/code&gt; should not attempt to create existing resources.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;init-script&lt;/code&gt; should be written in a popular scripting language, like &lt;a href="https://www.gnu.org/software/bash/"&gt;Bash&lt;/a&gt; (so I chose Bash).&lt;/li&gt;
&lt;li&gt;Automated actions should be done using &lt;a href="https://help.sonatype.com/repomanager3/rest-and-integration-api"&gt;NXRM REST API&lt;/a&gt;, to support adding more features easily. Since I chose Bash, I'm using &lt;a href="https://curl.se/"&gt;curl&lt;/a&gt; to make HTTP requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Designing The Init Script
&lt;/h2&gt;

&lt;p&gt;The desired outcome is clear; now, I need to declare the actions that the &lt;code&gt;init-script&lt;/code&gt; will perform when starting the NXRM container. Here's the list of actions (in order):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Changes the &lt;a href="https://help.sonatype.com/repomanager3/system-configuration/access-control/users"&gt;initial random password&lt;/a&gt; that is in &lt;code&gt;/nexus-data/admin.password&lt;/code&gt; to &lt;code&gt;admin&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Enables &lt;a href="https://help.sonatype.com/repomanager3/system-configuration/user-authentication/anonymous-access"&gt;anonymous access&lt;/a&gt; - allows anonymous users to access &lt;code&gt;localhost:8081&lt;/code&gt; with &lt;code&gt;READ&lt;/code&gt; permissions&lt;/li&gt;
&lt;li&gt;Adds &lt;a href="https://help.sonatype.com/repomanager3/formats/docker-registry/docker-authentication#DockerAuthentication-AuthenticatedAccesstoDockerRepositories"&gt;Docker Bearer Token Realm&lt;/a&gt; - allows anonymous pulls from local Nexus registry &lt;code&gt;localhost:8081&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Creates two Docker repository of type &lt;a href="https://help.sonatype.com/repomanager3/formats/docker-registry/proxy-repository-for-docker"&gt;proxy&lt;/a&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;docker-hub&lt;/code&gt; - DockerHub&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docker-ecrpublic&lt;/code&gt; - AWS ECR Public&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Creates a Docker repository of type &lt;a href="https://help.sonatype.com/repomanager3/formats/docker-registry/grouping-docker-repositories"&gt;group&lt;/a&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;docker-group&lt;/code&gt; - The above Docker repositories are members of this Docker group&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Creating A Custom Docker Image
&lt;/h2&gt;

&lt;p&gt;I've created a Docker image based on &lt;a href="https://hub.docker.com/r/sonatype/nexus3/"&gt;NXRM official Docker image&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's is how the Dockerfile looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; NEXUS_VERSION="3.30.1"&lt;/span&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;sonatype/nexus3:${NEXUS_VERSION}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;app&lt;/span&gt;
&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; root&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;curl &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /usr/local/bin/jq https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;chmod&lt;/span&gt; +x /usr/local/bin/jq

&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; nexus&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; NEXUS_DATA_PATH="/nexus-data" \&lt;/span&gt;
    NEXUS_ADMIN_USERNAME="admin" \
    NEXUS_ADMIN_PASSWORD="admin" \
    NEXUS_API_PATH="service/rest/v1" \
    NEXUS_BASE_PATH="http://localhost:8081" \
    NEXUS_OPS_VERBOSE="false"
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /"${NEXUS_DATA_PATH}/nexus-ops/"&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; provision/ .&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; /nexus-data/nexus-ops/entrypoint.sh&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: I added &lt;a href="https://stedolan.github.io/jq/download/"&gt;jq&lt;/a&gt; to the mix because I intend to use more APIs, and I'll need to analyze some JSON data. I find it best to analyze JSON data with &lt;code&gt;jq&lt;/code&gt; when using &lt;code&gt;Bash&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As you can see from the &lt;a href="https://github.com/unfor19/nexus-ops/blob/master/Dockerfile"&gt;Dockerfile&lt;/a&gt; above, I'm copying the directory &lt;a href="https://github.com/unfor19/nexus-ops/tree/master/provision"&gt;provision/&lt;/a&gt; to the NXRM image, and instead of running &lt;a href="https://github.com/sonatype/docker-nexus3/blob/master/Dockerfile#L78"&gt;/opt/sonatype/start-nexus-repository-manager.sh&lt;/a&gt; as the &lt;code&gt;CMD&lt;/code&gt;, I wrapped it with the &lt;a href="https://github.com/unfor19/nexus-ops/tree/master/provision/entrypoint.sh"&gt;provision/entrypoint.sh&lt;/a&gt; script.&lt;/p&gt;

&lt;p&gt;Bottom line, the whole logic is maintained in the &lt;code&gt;init-script&lt;/code&gt; called &lt;a href="https://github.com/unfor19/nexus-ops/blob/master/provision/entrypoint.sh"&gt;entrypoint.sh&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's how the &lt;code&gt;main&lt;/code&gt; function looks like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;main&lt;span class="o"&gt;(){&lt;/span&gt;
    start_nexus
    set_global_variables
    wait_for_healthy_response
    set_credentials
    change_initial_password
    enable_anonymous_access
    realms_enable_docker_token
    repositories_create_repository_wrapper &lt;span class="s2"&gt;"proxy"&lt;/span&gt; &lt;span class="s2"&gt;"docker-hub"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;_NEXUS_OPS_PATH&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/repositories/docker-proxy-dockerhub.json"&lt;/span&gt;
    repositories_create_repository_wrapper &lt;span class="s2"&gt;"proxy"&lt;/span&gt; &lt;span class="s2"&gt;"docker-ecrpublic"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;_NEXUS_OPS_PATH&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/repositories/docker-proxy-ecrpublic.json"&lt;/span&gt;
    repositories_create_repository_wrapper &lt;span class="s2"&gt;"group"&lt;/span&gt; &lt;span class="s2"&gt;"docker-group"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;_NEXUS_OPS_PATH&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/repositories/docker-group.json"&lt;/span&gt;
    log_msg &lt;span class="s2"&gt;"Finished executing - &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;_NEXUS_OPS_PATH&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/entrypoint.sh"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Result
&lt;/h2&gt;

&lt;p&gt;Here's my project @ &lt;a href="https://github.com/unfor19/nexus-ops"&gt;GitHub - unfor19/nexus-ops&lt;/a&gt;. To understand how it all works, check the &lt;a href="https://github.com/unfor19/nexus-ops/tree/master/provision/entrypoint.sh"&gt;provision/entrypoint.sh&lt;/a&gt; file; I tried to make it as neat as possible.&lt;/p&gt;

&lt;p&gt;One more thing; you'll find the directory &lt;a href="https://github.com/unfor19/nexus-ops/tree/master/provision/repositories"&gt;provision/repositories&lt;/a&gt; in my project. That directory contains the JSON structure of the provisioned repositories. As an example, here's the command for creating the &lt;a href="https://github.com/unfor19/nexus-ops/blob/master/provision/repositories/docker-proxy-dockerhub.json"&gt;DockerHub repository&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;repositories_create_repository_wrapper &lt;span class="s2"&gt;"proxy"&lt;/span&gt; &lt;span class="s2"&gt;"docker-hub"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;_NEXUS_OPS_PATH&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/repositories/docker-proxy-dockerhub.json"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Words
&lt;/h2&gt;

&lt;p&gt;Initially, I was slightly intimidated by NXRM; it seemed complex to proxy Docker requests via NXRM. However, after creating this project, I think I got the idea, and I hope you did too.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>nexus</category>
      <category>proxy</category>
      <category>cache</category>
    </item>
    <item>
      <title>AWS Security Groups - Once And For All</title>
      <dc:creator>Meir Gabay</dc:creator>
      <pubDate>Wed, 02 Jun 2021 19:03:59 +0000</pubDate>
      <link>https://forem.com/doitintl/aws-security-groups-once-and-for-all-176f</link>
      <guid>https://forem.com/doitintl/aws-security-groups-once-and-for-all-176f</guid>
      <description>&lt;p&gt;As part of securing applications in the cloud, it's important to set the proper network rules, for maximum security and to minimize collateral damage.&lt;/p&gt;

&lt;p&gt;Here's a quote from the &lt;a href="https://www.hhs.gov/hipaa/for-professionals/security/laws-regulations/index.html"&gt;official HIPAA&lt;/a&gt; requirement for &lt;em&gt;Transmission Security&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A covered entity must implement &lt;strong&gt;technical security measures&lt;/strong&gt; that &lt;strong&gt;guard&lt;/strong&gt; against unauthorized access to e-PHI that is being transmitted over an electronic &lt;strong&gt;network&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  HIPAA
&lt;/h2&gt;

&lt;p&gt;For those of you who are not familiar with HIPAA, it's a very strict regulation that requires protecting medical records and other &lt;strong&gt;p&lt;/strong&gt;ersonal &lt;strong&gt;h&lt;/strong&gt;ealth &lt;strong&gt;i&lt;/strong&gt;nformation (PHI). &lt;/p&gt;

&lt;p&gt;Most startup companies that develop a product for the medical-healthcare sector, aspire to become &lt;a href="https://www.hhs.gov/hipaa/for-professionals/regulatory-initiatives/index.html"&gt;HIPAA compliant&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Here's the question you need to ask yourself when it comes to &lt;em&gt;Transmission Security&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What security measures are currently used to protect e-PHI during&lt;br&gt;
transmission? &lt;a href="https://www.hhs.gov/sites/default/files/ocr/privacy/hipaa/administrative/securityrule/techsafeguards.pdf"&gt;HIPAA - Security Rule - Technical Safeguards&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Network Security Layers Overview
&lt;/h2&gt;

&lt;p&gt;I'd have to write a book to cover all the network security layers, so let's get a quick glance at the most common network security layers in AWS.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Application - &lt;a href="https://docs.aws.amazon.com/waf/latest/developerguide/waf-chapter.html"&gt;AWS Web Application Firewall (WAF)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Subnet - &lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html"&gt;AWS Network Access Lists (NACLs)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;(Virtual) Firewall - &lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html"&gt;AWS Security Groups&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Network - &lt;a href="https://docs.aws.amazon.com/network-firewall/latest/developerguide/what-is-aws-network-firewall.html"&gt;AWS Network Firewall&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this blog post, I'll focus on the &lt;strong&gt;Virtual Firewall&lt;/strong&gt; layer. In AWS, the implementation of a Virtual Firewall is done with AWS Security Groups.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stateful Vs. Stateless
&lt;/h2&gt;

&lt;p&gt;Security groups are &lt;strong&gt;stateful&lt;/strong&gt;, the &lt;a href="[stateful](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html)"&gt;official docs&lt;/a&gt;, describe it as follows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you send a request from your instance, the response traffic for that request is allowed to flow in regardless of inbound security group rules. Responses to allowed inbound traffic are allowed to flow out, regardless of outbound rules. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By default, a security group is created without any inbound rules. That means it doesn't accept traffic from any device that attempts to &lt;strong&gt;initiate&lt;/strong&gt; a connection. &lt;/p&gt;

&lt;p&gt;The default outbound rule is &lt;code&gt;0.0.0.0/0&lt;/code&gt; which allows devices to &lt;strong&gt;initiate&lt;/strong&gt; connections to anywhere. Once a connection is initiated, the security group rule is &lt;strong&gt;ignored&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So what is stateless? We'll cover that in the &lt;em&gt;Blocking Specific IPs&lt;/em&gt; section.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security Groups Ground Rules
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Once a connection is initiated, the security group rules are ignored and traffic is allowed for the new connection.&lt;/li&gt;
&lt;li&gt;There's no way to enforce security group rules on existing connections. Rules are applied to new connections only, so you must terminate existing connections, to force new security group rules.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Practical Example
&lt;/h3&gt;

&lt;p&gt;Let's say you want to SSH from your local machine to an EC2 instance, that has a public IP address.&lt;/p&gt;

&lt;p&gt;To achieve that, you'll add an inbound security rule that allows &lt;code&gt;SSH&lt;/code&gt; connections from &lt;code&gt;My IP&lt;/code&gt; (your IP). And then, you'll SSH to the EC2 and it'll work as expected.&lt;/p&gt;

&lt;p&gt;Here comes the tricky part; What would happen if, during your SSH session, someone removes your inbound security group rule? Nothing. As mentioned earlier, security group rules &lt;strong&gt;apply to new connections only&lt;/strong&gt;, since your SSH session is active, you can still continue with your work. If by any chance, you get disconnected for even a split second, the new security group rules will take place and you'll get disconnected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Allow Or Deny?
&lt;/h2&gt;

&lt;p&gt;This is very confusing; One might want to deny traffic from a known set of IP addresses. It is common to think that Security Groups can be used to &lt;strong&gt;block&lt;/strong&gt; traffic &lt;strong&gt;explicitly&lt;/strong&gt;, though it &lt;strong&gt;is impossible&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Security Groups are designed to &lt;strong&gt;Allow&lt;/strong&gt; access from/to sources, and &lt;strong&gt;implicitly&lt;/strong&gt; block unknown sources. When you add a security group rule, you don't have an option to set its type (Allow/Deny), it is &lt;strong&gt;Allowed&lt;/strong&gt; by design.&lt;/p&gt;

&lt;h3&gt;
  
  
  Blocking Specific IPs
&lt;/h3&gt;

&lt;p&gt;To address the need for explicitly blocking specific sources, you can use AWS Network Access Lists (NACLs), which are stateless, and as part of setting a Network Access Rule, you'll have the option to set its type (Allow/Deny). It's important to mention that NACLs operate at the Subnet level, while Security Groups operate at the VPC level.&lt;/p&gt;

&lt;p&gt;Reminding you that NACLs are stateless, which means you'll need to create a rule for both inbound and outbound for any source/target device. Unlike Security Groups, if you haven't &lt;strong&gt;explicitly&lt;/strong&gt; allowed a connection both inbound/outbound, it is denied by default. The default NACLs rules, for both inbound and outbound, are &lt;code&gt;All traffic, from/to: 0.0.0.0/0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: I rarely use NACLs, unless there's a specific need to block a set of IP addresses at the subnet's level, which in my experience, is quite rare and should be used with cautious.&lt;/p&gt;

&lt;h3&gt;
  
  
  Allow Access According To IP and Request URI-Path
&lt;/h3&gt;

&lt;p&gt;One might think "but hey, I want to allow access to &lt;code&gt;https://myapp.com/admin/dashboard&lt;/code&gt; from my IP only, how can I do that? Since HTTP requests are handled at the application layer, you can use the AWS Web Application Firewall. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a rule for &lt;a href="https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-fields.html"&gt;web request component settings&lt;/a&gt; with the required &lt;code&gt;URI Path&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create a set of IPs and add your IP, call this set &lt;code&gt;whitelisted&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Create another rule that whitelists your &lt;a href="https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-reusable-entities.html"&gt;IP address&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's the &lt;strong&gt;pseudo-code&lt;/strong&gt; of the set of rules that should be created&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;AND&lt;span class="o"&gt;(&lt;/span&gt;
URI-Path &lt;span class="o"&gt;==&lt;/span&gt; https://myapp.com/admin/dashboard,
SourceIP &lt;span class="o"&gt;!=&lt;/span&gt; Whitelisted-IPs
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;then &lt;/span&gt;Block
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Selecting The Right Defense
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Security Groups are designed to &lt;strong&gt;Allow&lt;/strong&gt; traffic from/to sources, at the VPC level.&lt;/li&gt;
&lt;li&gt;NACLs can be used for blocking a set of IP addresses (bots, bad reputation, etc.) at the Subnet level.&lt;/li&gt;
&lt;li&gt;AWS WAF can be used for blocking all traffic to a specific &lt;code&gt;URI-Path&lt;/code&gt;, and allowing traffic only from a specific set of IP addresses (whitelisted).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html"&gt;Security groups for your VPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/premiumsupport/knowledge-center/instance-vpc-troubleshoot/"&gt;How do I troubleshoot instance connection timeout errors in Amazon VPC?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/premiumsupport/knowledge-center/connect-endpoint-service-vpc/"&gt;Why can't I connect to an endpoint service from my interface endpoint in an Amazon VPC?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/premiumsupport/knowledge-center/vpc-peering-connectivity/"&gt;How do I resolve Amazon VPC peering network connectivity issues?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cover image - &lt;a href="http://123emoji.com/hacker-boy-sticker-5682/"&gt;Hackerboy Emoticons&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Words
&lt;/h2&gt;

&lt;p&gt;When I first started my journey with AWS, Security Groups were one of the first components that I encountered. I also didn't have any background with networks, so stateless and stateful didn't mean anything to me. Once I broke it down and found out which service should be used for each purpose, it was all clear. &lt;/p&gt;

</description>
      <category>aws</category>
      <category>network</category>
      <category>security</category>
      <category>hipaa</category>
    </item>
  </channel>
</rss>
