如何限制SSH登录EC2的用户访问EC2应用所用的跨账号S3 Bucket?
Absolutely, there are reliable ways to ensure User A can SSH into your EC2 instance for debugging without gaining any access to the cross-account S3 bucket that your application uses via the EC2 Instance Role. The core of the solution is isolating User A's session from the Instance Role's credentials, which are fetched via the EC2 Instance Metadata Service (IMDS). Here's how to implement it step-by-step:
1. Restrict User A's Access to the EC2 Instance Metadata Service (IMDS)
The IMDS (at http://169.254.169.254) is where the instance retrieves temporary credentials for the Instance Role. Blocking User A from accessing this endpoint is the most direct way to prevent them from obtaining bucket access.
- OS-level Firewall Rule: Use
iptablesorfirewalldto block User A's UID from reaching the IMDS IP.# First, find User A's UID (replace userA with their username) id -u userA # Add an iptables rule to drop outgoing traffic from User A to IMDS iptables -A OUTPUT -m owner --uid-owner <USER_A_UID> -d 169.254.169.254 -j DROP # Save the rule to persist across reboots (depends on your OS) # For RHEL/CentOS: service iptables save # For Ubuntu: netfilter-persistent save - Enforce IMDSv2: Enable and require IMDSv2 on your EC2 instance. IMDSv2 requires a session token to retrieve credentials, making it harder for unauthorized users to fetch them even if they bypass basic IP restrictions. You can enable this via the EC2 Console or CLI:
aws ec2 modify-instance-metadata-options --instance-id <YOUR_INSTANCE_ID> --http-tokens required --http-endpoint enabled
2. Use a Restricted Shell for User A
Limit the commands User A can execute to prevent them from using tools like curl, wget, or the AWS CLI to interact with IMDS or S3.
- Set up Restricted Bash (rbash):
- Change User A's shell to
rbash:chsh -s /bin/rbash userA - Create a restricted command directory for User A:
mkdir -p /home/userA/bin # Copy only allowed commands (e.g., tail, top, cat) to this directory cp /bin/tail /home/userA/bin/ cp /bin/top /home/userA/bin/ cp /bin/cat /home/userA/bin/ - Modify User A's
.bashrcto lock down their environment:echo "PATH=/home/userA/bin" >> /home/userA/.bashrc echo "readonly PATH" >> /home/userA/.bashrc echo "unset HISTFILE" >> /home/userA/.bashrc - Remove write permissions from User A's
.bashrcto prevent modifications:chmod 555 /home/userA/.bashrc
- Change User A's shell to
3. Separate Application and User Execution Contexts
Run your application under a dedicated system user that has access to IMDS, while denying access to all other users (including User A).
- Create a dedicated application user:
useradd -r -s /sbin/nologin appuser - Configure your application to run as
appuser:
For systemd-managed apps, update your service file to includeUser=appuser:[Service] User=appuser ExecStart=/path/to/your/application - Firewall rules to allow only
appuseraccess to IMDS:# Allow appuser to access IMDS iptables -A OUTPUT -m owner --uid-owner appuser -d 169.254.169.254 -j ACCEPT # Block all other users from accessing IMDS iptables -A OUTPUT -d 169.254.169.254 -j DROP - Ensure User A can't switch to
appuser: Remove any sudo privileges for User A related to switching users, and setappuserto have no login shell (as done above).
Verification Steps
To confirm the setup works:
- SSH into the instance as User A.
- Try to access IMDS:
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/— this should fail (timeout or connection refused). - Attempt to run AWS CLI commands against the cross-account bucket:
aws s3 ls s3://your-cross-account-bucket— this should return an access denied error.
内容的提问来源于stack exchange,提问作者Haixiao Yang




