Locked out of SSH after enabling UFW on Ubuntu EC2 instance?

The solution is to stop the instance and instruct it to disable the firewall program upon restart.

WARNING: Before starting this procedure, review the following:

  1. Stop your instance. (Do not terminate)

  2. In the console, select your instance and go to Actions -> Instance Settings -> Edit user data

  3. Select Modify user data as text and paste the following:

    Content-Type: multipart/mixed; boundary="//"
    MIME-Version: 1.0
    --//
    Content-Type: text/cloud-config; charset="us-ascii"
    MIME-Version: 1.0
    Content-Transfer-Encoding: 7bit
    Content-Disposition: attachment; filename="cloud-config.txt"
    #cloud-config
    cloud_final_modules:
    - [scripts-user, always]
    --//
    Content-Type: text/x-shellscript; charset="us-ascii"
    MIME-Version: 1.0
    Content-Transfer-Encoding: 7bit
    Content-Disposition: attachment; filename="userdata.txt"
    #!/bin/bash
    ufw disable
    iptables -L
    iptables -F
    --//
    
  4. Save and Restart the instance and SSH should work. The user data disables UFW and flushes any iptable rules blocking SSH access.

  5. After successfully connecting via SSH, you may reset the user data by following previous steps. Select Modify user data as text, delete all text and save.

When a user data script is processed, it is copied to and run from /var/lib/cloud/instances/instance-id/. The script is not deleted after it is run. Be sure to delete the user data scripts from /var/lib/cloud/instances/instance-id/ before you create an AMI from the instance. Otherwise, the script will exist in this directory on any instance launched from the AMI.

Reference

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html

https://aws.amazon.com/premiumsupport/knowledge-center/execute-user-data-ec2/