# Ensure no Network ACLs allow SSH port 22 from the internet

- Source: https://support.icompaas.com/support/solutions/articles/a_1793292202911437-ensure-no-network-acls-allow-ssh-port-22-from-the-internet
- Section: [Solutions](https://support.icompaas.com/support/solutions) › [AWS_Checks_v5.39.1](https://support.icompaas.com/support/solutions/c_1793285913477877) › [AWS Checks](https://support.icompaas.com/support/solutions/folders/f_1793287194371224)
- Last updated: 2026-10-29
- Publisher: iCompaas, Inc. (https://www.icompaas.com)

**Description**

Ensure that no VPC network ACL allows inbound traffic from the Internet (0.0.0.0/0 or ::/0) to SSH (TCP port 22). Network ACLs control traffic at the subnet boundary, and their inbound rules are evaluated in order of rule number, starting with the lowest.

**Rationale**

Network ACLs are a subnet-level layer of defense in depth in front of security groups. If a network ACL allows SSH from the whole Internet, a single misconfigured security group or route can expose instances to brute-force, credential stuffing and SSH exploit attempts. Denying SSH from 0.0.0.0/0 and ::/0 at the subnet boundary, and using AWS Systems Manager Session Manager or a bastion host behind a VPN for administration, keeps this layer effective.

**Impact**

-   Blocks SSH from the Internet at the subnet level, in addition to security groups
    
-   Reduces the impact of a misconfigured security group
    
-   Administrators currently connecting to SSH over the Internet will lose access and must use Session Manager, a VPN or a bastion host in an allowed range
    
-   Because network ACLs are stateless, a rule that is too broad can block legitimate traffic, so changes should be tested on a non-critical subnet first
    

**Default Value**

The default network ACL of a VPC allows all inbound traffic from 0.0.0.0/0 (rule 100), and also from ::/0 if the VPC has an IPv6 CIDR block, so it allows SSH from the Internet unless a deny rule is added. A newly created custom network ACL denies all inbound traffic until rules are added.

**Pre-Requisites**

-   IAM permissions: ec2:DescribeNetworkAcls, ec2:CreateNetworkAclEntry, ec2:ReplaceNetworkAclEntry and ec2:DeleteNetworkAclEntry
    
-   The subnets associated with the network ACL and any trusted ranges that legitimately need SSH access
    
-   A free rule number lower than the rule that currently allows the traffic
    

**Remediation**

**Test Plan**

**Console:**

1.  Sign in to the AWS Management Console at [https://console.aws.amazon.com](https://console.aws.amazon.com/).
    
2.  Open the Amazon VPC console and select **Network ACLs**.
    
3.  Select a network ACL and open the **Inbound rules** tab.
    
4.  Read the rules in order of rule number. For each source 0.0.0.0/0 and ::/0, find the first rule that matches port 22, meaning:
    
    -   type **All traffic**, or
        
    -   protocol TCP with a port range that includes 22.
        
5.  Repeat for each network ACL in each region in use.
    
6.  If that first matching rule is **Allow** for either source, follow the implementation steps.
    

**CLI:**

List the network ACLs:

aws ec2 describe-network-acls --region <REGION> --query "NetworkAcls\[\].\[NetworkAclId,VpcId,IsDefault\]" --output table

List the inbound rules of a network ACL:

aws ec2 describe-network-acls --region <REGION> --network-acl-ids <NETWORK\_ACL\_ID> --query "NetworkAcls\[\].Entries\[?Egress==\\\`false\\\`\].\[RuleNumber,Protocol,RuleAction,CidrBlock,Ipv6CidrBlock,PortRange.From,PortRange.To\]" --output table

The network ACL fails if, for source 0.0.0.0/0 or ::/0, the lowest-numbered rule with protocol -1 (all traffic), or protocol 6 (TCP) with a port range that includes 22, has the action allow.

**Implementation Steps**

**Console:**

1.  Sign in to the AWS Management Console at [https://console.aws.amazon.com](https://console.aws.amazon.com/).
    
2.  Open the Amazon VPC console and select **Network ACLs**.
    
3.  Select the network ACL found in the Test Plan and open the **Inbound rules** tab.
    
4.  Choose **Edit inbound rules**.
    
5.  If the matching allow rule is a rule only for port 22, delete it.
    
6.  If the matching allow rule is broader (for example **All traffic**), choose **Add new rule** and create a deny rule with a lower rule number:
    
    -   **Type**: **Custom TCP**, **Port range**: 22,
        
    -   **Source**: 0.0.0.0/0,
        
    -   **Allow/Deny**: **Deny**.
        
7.  If the network ACL has an IPv6 allow rule, add the same deny rule with source ::/0.
    
8.  If SSH is needed from trusted ranges, add allow rules for those ranges with rule numbers lower than the deny rules.
    
9.  Choose **Save changes**.
    
10.  Repeat for each affected network ACL in each region in use.
     

**CLI:**

The provided command replaces an existing rule with a deny rule; use it only when that rule number is a rule specifically for port 22, because replacing a broad allow rule (such as rule 100 of the default network ACL) blocks all traffic it allowed.

aws ec2 replace-network-acl-entry --network-acl-id <NETWORK\_ACL\_ID> --ingress --rule-number <RULE\_NUMBER> --protocol 6 --rule-action deny --cidr-block 0.0.0.0/0 --port-range From=22,To=22

In most cases, add deny rules for port 22 with a rule number lower than the allow rule instead (one for IPv4 and one for IPv6):

aws ec2 create-network-acl-entry --network-acl-id <NETWORK\_ACL\_ID> --ingress --rule-number <RULE\_NUMBER> --protocol 6 --port-range From=22,To=22 --cidr-block 0.0.0.0/0 --rule-action deny  
aws ec2 create-network-acl-entry --network-acl-id <NETWORK\_ACL\_ID> --ingress --rule-number <IPV6\_RULE\_NUMBER> --protocol 6 --port-range From=22,To=22 --ipv6-cidr-block ::/0 --rule-action deny

**Backout Plan**

Before making changes, save the current network ACL rules:

aws ec2 describe-network-acls --network-acl-ids <NETWORK\_ACL\_ID> > <NETWORK\_ACL\_ID>-backup.json

To roll back:

1.  Sign in to the AWS Management Console at [https://console.aws.amazon.com](https://console.aws.amazon.com/).
    
2.  Open the Amazon VPC console, select **Network ACLs** and select the network ACL.
    
3.  On the **Inbound rules** tab, choose **Edit inbound rules**.
    
4.  Remove the deny rules that were added, and re-add any removed rules using the saved backup (rule number, type, port range, source and action).
    
5.  Choose **Save changes**.
    

**CLI:**

aws ec2 delete-network-acl-entry --network-acl-id <NETWORK\_ACL\_ID> --ingress --rule-number <RULE\_NUMBER>

Note: rolling back allows SSH from the Internet at the subnet level again. Use it only as a temporary measure.

**Reference**

-   [https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html)
    
-   [https://docs.aws.amazon.com/vpc/latest/userguide/nacl-rules.html](https://docs.aws.amazon.com/vpc/latest/userguide/nacl-rules.html)
    
-   [https://docs.aws.amazon.com/cli/latest/reference/ec2/create-network-acl-entry.html](https://docs.aws.amazon.com/cli/latest/reference/ec2/create-network-acl-entry.html)

## Related compliance guidance

- [SOC 2 compliance: a practical implementation guide for cloud-native SaaS teams](https://support.icompaas.com/compliance/soc-2-trust-services-criteria): Configuration checks like this one are the technical half of a SOC 2 / ISO 27001 programme — the guide shows where they fit, what else an auditor expects, and how to evidence them.
- [ISO/IEC 27001:2022 compliance: a practical implementation guide](https://support.icompaas.com/compliance/iso-27001-2022): ISO 27001 Annex A.8 (technological controls) is where cloud hardening evidence lands; the guide shows how to run the ISMS around it.
