— Kiaasa Dhanori Pune

An AIX ACL (Access Control List) lets you deny a specific UNIX group permission to execute remote-access commands such as telnet, ftp, rsh and ssh on a single server, without touching the standard owner/group/other permission bits. This guide walks through using acledit and aclget to lock down login and remote-execution binaries for one group, plus the modern, more reliable controls you should pair with file ACLs.
The problem: limiting remote access for one group
On a shared AIX host you often have a category of accounts — batch users, application owners, vendor logins, or service identities — that should be able to do their job locally but must not be able to telnet out, FTP files, or open outbound SSH and SCP sessions. Removing the binaries entirely is too blunt: other users still need them. Changing the base others bit affects everyone.
This is exactly where AIX extended ACLs earn their place. AIX supports a richer permission model than the classic three-tier UNIX bits, letting you add explicit permit and deny entries for named users and groups on top of the base permissions. You create a restricted group, then add a deny entry for that group on each sensitive command.
Solution overview: a deny ACL per command
Assume the group you want to restrict is called ibmgr. The plan is straightforward:
- Identify every binary that can start an outbound login or remote-execution session.
- Back up the current ACL of each binary so you can roll back instantly.
- Add an extended ACL entry that denies execute to group
ibmgr. - Verify the change and confirm normal users are unaffected.
The commands most administrators target fall into two families. The legacy r-commands and clear-text tools are the highest priority because they transmit credentials in plaintext:
| Command | Typical path | Purpose |
telnet | /usr/bin/telnet | Clear-text interactive login |
ftp | /usr/bin/ftp | Clear-text file transfer |
rlogin | /usr/bin/rlogin | Remote login (r-command) |
rsh / remsh | /usr/bin/rsh | Remote shell command |
rcp | /usr/bin/rcp | Remote copy (r-command) |
rexec | /usr/bin/rexec | Remote command execution |
ssh | /usr/bin/ssh | Encrypted login (OpenSSH) |
sftp | /usr/bin/sftp | Encrypted file transfer |
scp | /usr/bin/scp | Encrypted copy |
Step-by-step: applying an AIX ACL with acledit
Perform every step as root on the target server. Work through one command at a time and verify before moving on.
- Log in as root on the server you are hardening.
- Locate the real binary so you ACL the actual file, not a symlink:
which telnetls -l /usr/bin/telnet - Set your editor —
acleditopens whateverEDITORpoints to:export EDITOR=/usr/bin/vi - Back up the current ACL before you change anything:
aclget /usr/bin/telnet > /tmp/telnet_acl.out
A default binary typically shows:attributes: SUIDbase permissionsowner(root): r-xgroup(system): r-xothers: r-xextended permissionsdisabled - Open the ACL for editing:
acledit /usr/bin/telnet - Enable extended permissions and add the deny rule. Change
disabledtoenabledand add adenyentry for the group. The result should read:attributes: SUIDbase permissionsowner(root): r-xgroup(system): r-xothers: r-xextended permissionsenableddeny --x g:ibmgr
Because the goal is to block execution, deny thexbit (--x). Denying read as well (r-x) is harmless for a binary but the execute denial is what stops the command from running. - Save and confirm. When you write and quit, AIX prompts:
Should the modified ACL be applied? (yes) or (no)
Typeyesonly when the entry is correct. - Verify the new ACL is live:
aclget /usr/bin/telnet
You should now seeenabledand yourdeny ... g:ibmgrline. - Repeat for every command in the table above, keeping a separate backup file for each (
/tmp/ftp_acl.out,/tmp/rsh_acl.out, and so on).
Scripting the AIX ACL rollout
Editing nine binaries by hand is error-prone. AIX provides aclput, the non-interactive counterpart to acledit, which reads an ACL definition from standard input. That makes the whole job repeatable:
- Create a reusable ACL fragment that you can append to each command's existing ACL. For a clean, fully specified ACL you can pipe a complete definition:
for cmd in telnet ftp rlogin rsh rcp rexec; dop=$(which $cmd 2>/dev/null) || continueaclget $p > /tmp/$cmd.acl.bak{ aclget $p | sed 's/disabled/enabled/'; echo ' deny --x g:ibmgr'; } | aclput $pdone - Confirm each result with
aclgetin the same loop, or runaclget $p | grep -E 'enabled|ibmgr'.
Keeping the .bak files means a one-line restore: aclput /usr/bin/telnet < /tmp/telnet.acl.bak.
Important: SSH, sftp and scp need more than a file ACL
This is the part the classic version of this procedure glosses over, and getting it wrong leaves a false sense of security. A deny ACL on /usr/bin/ssh, /usr/bin/sftp or /usr/bin/scp only stops a user from running that specific binary on this host as an outbound client. It does not:
- Stop the user from logging IN to this server over SSH — inbound sessions are handled by the
sshddaemon, not thesshclient binary. - Stop a user who can copy or compile their own
sshclient, or invoke one from another directory or their home folder. - Affect FTP/SFTP server access, which is controlled by
ftpd/sftp-serverand their config, not the client ACL.
To genuinely control inbound SSH for a group, edit /etc/ssh/sshd_config and use OpenSSH's own directives, then restart the daemon:
- Add a restriction — for example, block the group entirely:
DenyGroups ibmgr
or invert the logic and only permit known-good groups withAllowGroups. - Validate the config before reloading so you don't lock yourself out:
/usr/sbin/sshd -t - Restart the SSH subsystem:
stopsrc -s sshd && startsrc -s sshd
For inbound telnet, ftp, rlogin and rexec, the proper lever is the inetd subsystem and PAM/login controls, not a client-binary ACL. The cleanest, most defensible hardening is to disable the legacy services outright — comment them out in /etc/inetd.conf and run refresh -s inetd — and keep only SSH, since telnet/ftp/rsh send passwords in clear text.
Common pitfalls when using acledit and aclget
- ACLing a symlink instead of the binary. If
whichreturns a link, follow it withls -land apply the ACL to the real target, or the deny entry has no effect. - Forgetting to change
disabledtoenabled. A deny line is ignored while extended permissions are disabled. Always confirmenabledappears in the output. - Mis-aligned ACL syntax. AIX ACL entries are whitespace-sensitive. Use the form
deny --x g:ibmgrfor groups andu:usernamefor users. A typo makesaclputreject the file. - Assuming a client ACL blocks server access. As covered above, denying
sshdoes not stop inbound logins. Pair file ACLs withsshd_configandinetdcontrols. - Overwriting an existing extended ACL. If a binary already carries extended permissions, append your deny entry rather than replacing the whole block.
- JFS vs JFS2 and backup/restore. Extended ACLs are preserved by
backup/restoreandcp -pwithin the same filesystem, but an OS upgrade or fileset reinstall can replace a binary and wipe its ACL. Re-verify after maintenance and after applying TLs/SPs. - Group membership precedence. A user who belongs to multiple groups is denied if any applicable entry denies the permission — deny wins. Keep the restricted population in a dedicated group.
Verification: prove the AIX ACL actually works
Never trust a security change you haven't tested. Confirm both that the restriction bites and that ordinary users are untouched.
- Inspect the ACL:
aclget /usr/bin/telnet
Expectextended permissions enabledand yourdeny ... g:ibmgrline. - Confirm group membership of a test account:
id testuser
orlsuser -a groups testuser - Test as the restricted user. Log in (or
su - testuser) and try the command:telnet localhost
A correctly applied deny returns a permission error such astelnet: 0509-036 Cannot load program ... Permission deniedorksh: telnet: cannot execute. - Test as an unrestricted user to confirm normal operation is intact — the command should run as usual.
- Audit the whole set in one pass:
for c in telnet ftp rlogin rsh rcp rexec; do p=$(which $c); echo "== $p =="; aclget $p | grep -E 'enabled|ibmgr'; done
Document the final state and store the /tmp/*.acl.bak files in a safe location (they contain no secrets, but they are your rollback path). Record the change in your configuration-management or change-control system.
Key Takeaways
- AIX extended ACLs let you deny
executeon remote-access binaries to a single group usingacleditandaclget— without disturbing base permissions or other users. - Always run
aclget binary > /tmp/file.outas a backup and switch extended permissions fromdisabledtoenabledfor the deny line to take effect. - Use
aclputto script the rollout across all nine commands and to restore instantly from your backup files. - A file ACL on
ssh/sftp/scponly blocks the local client; control inbound SSH withDenyGroups/AllowGroupsinsshd_configand validate withsshd -t. - For real hardening, disable plaintext legacy services (telnet, ftp, rsh) in
/etc/inetd.confand standardize on SSH; verify every change by testing as both a restricted and an unrestricted user.
Frequently Asked Questions
What is the difference between acledit, aclget and aclput in AIX?
aclget displays an object's ACL, acledit opens it in your $EDITOR for interactive changes, and aclput writes an ACL non-interactively from standard input — ideal for scripting and bulk restores.
Does denying the ssh binary with an ACL stop a user from logging in over SSH?
No. The ssh client binary only matters for outbound connections from this host. Inbound logins are handled by the sshd daemon, so you must use DenyGroups or AllowGroups in /etc/ssh/sshd_config and restart sshd.
How do I undo an AIX ACL change?
Restore from the backup you captured, for example aclput /usr/bin/telnet < /tmp/telnet_acl.out, or run acledit again, change enabled back to disabled (or delete the deny line), and answer yes at the apply prompt.
Should I still bother restricting telnet and ftp in modern environments?
Restricting them is good, but disabling them is better. Telnet, FTP and the r-commands transmit credentials in clear text, so the recommended baseline is to remove them from /etc/inetd.conf, run refresh -s inetd, and route all access through SSH.
For more hands-on system administration and security walkthroughs, subscribe to @explorenystream on YouTube.