Add a user that only has access to computer via ssh

I'd like to have a user on my local computer to only have access via ssh. I don't want (don't need) this user to have the ability to login in to the laptop as a standard user.

The only purpose for this user is for some web development testing.

I've already added a user and given Remote login rights to the user ~~but now I'd like to revoke local login rights~~. I'm trying to remove this user from the initial login screen when I boot up but still allow them to ssh in.

Basically, I want to remove this "other" user from the macOS Login Window as a choice of users to log in as but still allow them to log in via SSH. I want to remove them from this screen enter image description here so all that is left is my "standard" user.

From what I can find, this does not seem possible but I thought there might be a trick to hide the user from the login window.

Is something like this possible and if so, how would I go about doing it? I've found ho to manage a number of remote login parameters (ssh key setup, default directory, etc) but can't seem to find out how to disable local login.


There is a very similar question here: How can I create a user that can login through SSH but not on the local desktop in MacOS X El Capitan? but it is for an older version of the OS. They try to use a "Sharing only" user with no luck.


Solution 1:

It’s not clear what you gain by preventing log in, but I’ll assume you’ve for a good reason to complicate things.

Removing “other” from the graphical login screen is easy to do and easy to reverse on Catalina and below. Same with ssh, it’s easy to change the log in method and show the username/password or put back “other“.

If you can’t prevent a person with those credentials from sitting in front of the Mac, the first thing that comes to mind is you make a log in item that is a script that logs them out. It will be difficult for them to fix that if you deny them any other credentials to that Mac.

To ssh, you need a home folder and the system to have credentials to validate the password and assign UID/GID etc..

You can set up LDAP or use a network server and have remote accounts, but the design isn’t likely to work for your case or make sense logistically.

  • https://support.apple.com/guide/server/intro-to-accounts-apdcb06a828/mac

The matrix covers the differences between where a home folder is stored and how local versus network server vs external account validation happens.

The other easy way to have ssh log in without any chance of GUI log in or compromising security is a container. Fire up Docker for Mac and your ssh container is well isolated from the local user accounts.

Solution 2:

This is actually very possible and Mac SysAdmins need to do it in corporate environments all the time. You cannot use the Apple Users & Groups GUI to accomplish it. You need to create the account via the /Applications/Utiltiies/Terminal App at the command line using dscl (Directory Service) commands.

There's another AskDifferent answer Here: There are many ways to do this. I'll add a different trick into the mix. We decided to hide all users with UID number below 500 as we have several specialty accounts. MacOS by default starts creating user accounts with a UID at 501 and increments from there.

You might be better off deleting the existing user account and recreating it. Remember to backup any data the user has saved. It's trickier to convert an account to be hidden.

How to create a hidden user account on macOS (current as of Catalina):

Open the Terminal App and type these commands carefully and precisely. You are going to need to run these commands using either sudo in front of each or type sudo -s to enter into a root like mode first.

Replace <username> <password> and <human name> with your specific values. Yes this is a lot of typing but that's why we script it and push it with an MDM like JAMF Pro. Also I am placing the hidden home folder in /var but there are other places to put it. You could create an actual /home folder off the root if you wish. Don't confuse the /Users on the dscl command that's where user accounts go in the dscl directory (similar to LDAP) and it has nothing to do with the NFSHomeDirectory which is the actual home directory for the user account. (Again, this comes from OpenDirectory, Apple's LDAP).

dscl . -create /Users/<username> UniqueID 401
dscl . -create /Users/<username> PrimaryGroupID 20
dscl . -create /Users/<username> NFSHomeDirectory "/var/<username>"
dscl . -create /Users/<username> UserShell /bin/bash
dscl . -create /Users/<username> RealName "<human name>"
dscl . -passwd /Users/<username> <password>
mkdir /var/<username>
chown -R <username> /var/<username>

Optional: Grant this user admin rights

dscl . append /Groups/admin Groupmembership <username>

Now we enable to Hide users under 500 UID

defaults write /Library/Preferences/com.apple.loginwindow Hide500Users -bool yes

This is optional. When you hide a user there's an Others added to your login screen where you can manually type the username and password to login as the hidden user. However, you can hide it with the command below by changing it to FALSE.

defaults write /Library/Preferences/com.apple.loginwindow SHOWOTHERUSERS_MANAGED -bool TRUE

Now we create an SSH group

dseditgroup -o create -q com.apple.access_ssh

The we make our hidden user a member of that group

dseditgroup -o edit -a <username> -t user com.apple.access_ssh

In addition, you can try some of these commands to convert an existing account and hide them. Primarily the create command with the IsHidden 1 and then hide all users under 500 command and finally change the users UID to say 401 and reboot. That will hide the user from the GUI and the Fast User Switching and in the Users & Groups. They will still be able to SSH. Unless the user requires admin rights you should remove that. You can also lock down the SSH account to only access the Home folder but that depends on a /etc/sshd_config entry and home folder permissions and ownership by root. Would also apply to SFTP access. If this user is doing webserver code you could setup Apache subsites for each user so this user doesn't need to get to global /Library/Webserver path. Could access $HOME/Sites/ instead. Many options available.