Users

A user on Unix-like systems does not necessarily correspond to a human person who logs in and types commands, although it sometimes does. A user is simply a named entity that can own files and run commands with certain permissions and that may or may not have permission to read or modify other users' files. It's very common, for sound security reasons, to run each service on a system with its own user account. This simply means that the service runs with the identity and permissions of that user.

For example, a web server will often run as the www-data user, which exists solely to own files the web server needs to read and write. This limits the danger of a security breach via the web server, because the attacker would only have the www-data user's permissions, which are very limited, rather than the root user's, which can modify any aspect of the system. It is generally a bad idea to run services exposed to the public Internet as the root user. The service user should have only the minimum permissions it needs to operate the service.

Given this, an important part of system configuration involves creating and managing users, and Puppet's user resource provides a model for doing just that. Just as we saw with packages and services, the details of implementation and the commands used to manage users vary widely from one operating system to another, but Puppet provides an abstraction which hides those details behind a common set of attributes for users.

Creating users

The following example shows a typical user and group declaration in Puppet (user.pp):

group { 'devs':
  ensure => present,
  gid    => 3000,
}

user { 'hsing-hui':
  ensure => present,
  uid    => '3001',
  home   => '/home/hsing-hui',
  shell  => '/bin/bash',
  groups => ['devs'],
}

The user resource

The title of the resource is the username (login name) of the user; in this example, hsing-hui. The ensure => present attribute says that the user should exist on the system.

The uid attribute needs a little more explanation. On Unix-like systems, each user has an individual numerical id, known as the uid. The text name associated with the user is merely a convenience for those (mere humans, for example) who prefer strings to numbers. Access permissions are in fact based on the uid and not the username.

Tip

Why set the uid attribute? Often, when creating users manually, we don't specify a uid, so the system will assign one automatically. The problem with this is that if you create the same user (hsing-hui, for example) on three different nodes, you may end up with three different uids. This would be fine as long as you have never shared files between nodes, or copied data from one place to another. But in fact, this happens all the time, so it's important to make sure that a given user's uid is the same across all the nodes in your infrastructure. That's why we specify the uid attribute in the Puppet manifest.

The home attribute sets the user's home directory (this will be the current working directory when the user logs in, if she does log in, and also the default working directory for cron jobs that run as the user).

The shell attribute specifies the command-line shell to run when the user logs in interactively. For humans, this will generally be a user shell, such as /bin/bash or /bin/sh. For service users, such as www-data, the shell should be set to /usr/sbin/nologin (on Ubuntu systems), which does not allow interactive access, and prints a message saying This account is currently not available. All users who do not need to log in interactively should have the nologin shell.

If the user needs to be a member of certain groups, you can pass the groups attribute an array of the group names (just devs in this example).

Although Puppet supports a password attribute for user resources, I don't advise you to use it. Service users don't need passwords, and interactive users should be logging in with SSH keys. In fact, you should configure SSH to disable password logins altogether (set PasswordAuthentication no in sshd_config).

The group resource

The title of the resource is the name of the group (devs). You need not specify a gid attribute but, for the same reasons as the uid attribute, it's a good idea to do so.

Managing SSH keys

I like to have as few interactive logins as possible on production nodes, because it reduces the attack surface. Fortunately, with configuration management, it should rarely be necessary to actually log in to a node. The most common reasons for needing an interactive login are for system maintenance and troubleshooting, and for deployment. In both cases there should be a single account named for this specific purpose (for example, admin or deploy), and it should be configured with the SSH keys of any users or systems that need to log in to it.

Puppet provides the ssh_authorized_key resource to control the SSH keys associated with a user account. The following example shows how to use ssh_authorized_key to add an SSH key (mine, in this instance) to the ubuntu user on our Vagrant VM (ssh_authorized_key.pp):

ssh_authorized_key { '[email protected]':
  user => 'ubuntu',
  type => 'ssh-rsa',
  key  => 'AAAAB3NzaC1yc2EAAAABIwAAAIEA3ATqENg+GWACa2BzeqTdGnJhNoBer8x6pfWkzNzeM8Zx7/2Tf2pl7kHdbsiTXEUawqzXZQtZzt/j3Oya+PZjcRpWNRzprSmd2UxEEPTqDw9LqY5S2B8og/NyzWaIYPsKoatcgC7VgYHplcTbzEhGu8BsoEVBGYu3IRy5RkAcZik=',
}

The title of the resource is the SSH key comment, which reminds us who the key belongs to. The user attribute specifies the user account which this key should be authorized for. The type attribute identifies the SSH key type, usually ssh-rsa or ssh-dss. Finally, the key attribute sets the key itself. When this manifest is applied, it adds the following to the ubuntu user's authorized_keys file:

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA3ATqENg+GWACa2BzeqTdGnJhNoBer8x6pfWkzNzeM8Zx7/2Tf2pl7kHdbsiTXEUawqzXZQtZzt/j3Oya+PZjcRpWNRzprSmd2UxEEPTqDw9LqY5S2B8og/NyzWaIYPsKoatcgC7VgYHplcTbzEhGu8BsoEVBGYu3IRy5RkAcZik= [email protected]

A user account can have multiple SSH keys associated with it, and anyone holding one of the corresponding private keys and its passphrase will be able to log in as that user.

Removing users

If you need to have Puppet remove user accounts (for example, as part of an employee leaving process), it's not enough to simply remove the user resource from the Puppet manifest. Puppet will ignore any users on the system that it doesn't know about, and it certainly will not remove anything it finds on the system that isn't mentioned in the Puppet manifest; that would be extremely undesirable (almost everything would be removed). So we need to retain the user declaration for a while, but set the ensure attribute to absent (user_remove.pp):

user { 'godot':
  ensure => absent,
}

Once Puppet has run everywhere, you can remove the user resource if you like, but it does no harm to simply leave it in place, and in fact, it's a good idea to do this, unless you can verify manually that the user has been deleted from every affected system.

Tip

If you need to prevent a user logging in, but want to retain the account and any files owned by the user, for archival or compliance purposes, you can set their shell to /usr/sbin/nologin. You can also remove any ssh_authorized_key resources associated with their account, and set the purge_ssh_keys attribute to true on the user resource. This will remove any authorized keys for the user that are not managed by Puppet.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.170.92