SMB Admin

Sunday, June 24, 2018

It seems a somewhat common scenario that a small
business running all Windows gets to a point where something, some software
package for whatever reason, is better suited to a Linux-based server. It would
be simple to create the required server as a standalone and move along to other
things, but wouldn’t it be better to let your users use their everyday Active
Directory domain credentials to interact with Linux-based services like they
already do for Windows?

I had just such a scenario occur on a project recently,
to migrate our Windows-based VisualSVN repositories to a Linux-based Git
server. Glossing over the significant differences between Subversion and Git,
this is how I went about building a domain-joined Ubuntu Linux server
supporting authentication via both username/password and SSH keypairs, all
managed in Active Directory.To be successful with this guide you should have
some basic familiarity with managing a Linux server on the command line, but
I’ve included as much detail as reasonably possible. You’ll need to use sudo
for most of the commands presented here.

Installing Ubuntu

First thing’s first; Download and install the
Ubuntu Server 18.04 LTS image from the official website, here: https://www.ubuntu.com/download/server. If you’re not familiar with Ubuntu installations, you can
essentially take all of the default options and you’ll end up with a working
server, ready for the next steps. You’ll just need to supply a username and
password for the initial user account. Be sure to configure the networking
options as well if you’re not planning to use DHCP. Ensuring that DNS points to
your AD domain controller is critical so be sure the configuration is correct.

Once the installation has completed, access the
server command line with an admin account via virtual console or SSH in order
to continue.

Network Configuration

Before anything else, we need to confirm that
the network configuration is correct so Ubuntu can find our domain controllers when
we’re ready to join the domain. To do that review the interface configuration
with the following command:

ifconfig

I’m using VMware Workstation here and this
address is on the same network with my domain controller, so this looks good.

As of Ubuntu 17.10 we can work with Netplan,
which reads yaml configuration files and generates the necessary network
configurations. We can check the post-install configuration in the
50-cloud-init.yaml file:

cat /etc/netplan/50-cloud-init.yaml

I did a manual configuration of my network
interface during installation, and this matches what I configured so I should
be good to go. Note that 192.168.146.132 in the image above is the IP of the
DNS server/domain controller that holds the domain I’ll be joining. You can
edit this file manually if needed. Be sure to use spaces in groups of four for
indentation as Netplan does not appreciate tabs in its yaml files.

Package Installation

In order to accomplish what we’re trying to do
here, we’ll need to install a few additional packages. We’ll start by updating
our Ubuntu install. apt-getupdate will update the list of
packages and apt-getupgrade will actually perform the update.

apt update && apt upgrade

This may take several minutes to run. When
finished, we’re ready to install the additional packages that we need.

During the installation process you’ll be prompted
to provide some information about your domain and domain controllers. Enter the
domain name and DC server names as needed.

Configuration

With the packages installed, we can get to the
configuration. First, we’ll configure Kerberos by editing the krb5.conf file. I
like Nano for editing text files but feel free to use Vim or whatever you may
prefer.

nano /etc/krb5.conf

Once we have the file open in our text editor,
we want to add the following two configuration lines under the section for our
realm.

dns_lookup_kdc = true

dns_lookup_realm = true

Save and exit the file (In Nano, Ctrl + X, then
Yes, then Enter).

Next, we’ll configure NTP so our server is
syncing time with the domain controller. Open /etc/systemd/timesyncd.conf in
your editor.

nano /etc/systemd/timesyncd.conf

Uncomment the #NTP= line (remove the hash sign)
and type the fully qualified domain name of your domain controller after the
equals sign.

Save and exit the file. Now, we’ll force a time
sync by running the following commands at the prompt.

timedatectl set-ntp true

systemctl restart systemd-timesyncd.service

timedatectl --adjust-system-clock

After the final command, be sure that the output
matches the current time. If it doesn’t, go back and review your NTP settings,
and validate that Ubuntu can contact your domain controller.

Now it’s time to setup our realm configuration.
We’ll use realmd to configure our domain connectivity for us using sssd
instead of winbind. If you don’t know what any of that means I encourage
you to do a bit of research for your own understanding, but it isn’t material
to this process.

We actually need to create the realmd.conf file
from scratch. We’ll start by creating the file (opening it in a text editor).

nano /etc/realmd.conf

Then we’ll add the following lines to the file.
Note that you should replace “smblab.net” with your own domain name. Everything
else can stay the same.

Save and exit the file.

Next, we’ll configure pam (pluggable
authentication modules) and set it to create home directories for domain users
when they first log in (so they don’t need to be created in advance by an
admin). Be sure to sudo for this command or it may fail in the background and create some confusion later.

pam-auth-update

Select the option to Create home directory on
login, then select OK.

Now let’s make sure that realmd can see our
Active Directory domain with the discover command.

realm discover -v smblab.net

If your networking is configured properly and
Ubuntu can see the SRV record for your domain controller in DNS, you should see
something like this:

If you get an error message here, go back and
review your interface/netplan settings. If you see something similar to the
above, you’re ready to continue.

Now we’ll use the realm join command to
actually join the domain and configure sssd to communicate with it. For this
step, we’ll need to know which OU we want to initially place this server into.
I’m going to put it into my site’s Computers OU.

Note that the --user parameter must be a domain
admin or other domain user with permission to join computers to the domain and
place them into the specified OU.

The --install=/ switch at the end tells realm
to install any necessary dependencies when the command is run. I found that
more often than not the command would error out without it.

Notice when running the command you’re prompted
first for your current account credentials in order to elevate to sudo, then
prompted for the password for the domain account that you provided in the
--user parameter.

If all has gone well, you’ll get a success
message from realmd:

You’ll see the Ubuntu server name listed in
ADUC within the OU specified in --computer-ou. Mine is named SMB-GIT1, as I mentioned a Subversion to Git migration was the impetus for this project.

Next we’ll open up the sssd config file
in our text editor.

nano /etc/sssd/sssd.conf

We want to do four things here:

Add ssh to the services = section.

Verify that ldap_id_mapping = True is set (this
is the default)

Change use_fully_qualified_names to False.

Add ldap_user_ssh_public_key = altSecurityIdentities

The third item is a quality of life change that
I applied but it isn’t required. It allows domain users to login to Ubuntu with
just their username instead of the UPN (<user> instead of
<user>@<domain>). The final item specifies the
altSecurityIdentities attribute within an AD user account that we’re going to
use to store our SSH public key. Here’s what my file looks like after making
the necessary changes.

Save and exit the sssd.conf file. Do a
quick reboot at this point to make sure everything reloads with the updated
config files.

At this stage, all of the AD parts are connected
and we should be able to log in to the console with a domain username. I’ll log
in with my domain user “murphy”.

The login is successful and in addition to the
MOTD info I can see that my home directory for the domain user was created
automatically in /home/SMBLab.net/murphy.

Since we haven’t done anything to restrict SSH access yet, logging in via SSH from a remote machine should also work for
any valid account. I verified this by connecting through PuTTy from the domain
controller.

With everything working for username/password
authentication, we can move on to authenticating via SSH keys.

A quick note on this for the sake of
understanding what’s going on; Typically when we want to use key-based authentication for SSH we’ll put our public key in our Ubuntu home directory in the
~/.ssh/authorized_keys file. When we attempt to connect over SSH with our
private key, the SSH server service knows to check the authorized_keys file for
the matching public key and approves our authentication attempt. What we want to do instead is have SSH
check Active Directory for the altSecurityIdentities attribute on the
authenticating user account. To that end, we’ll configure ssh to check
AD instead of the local authorized_keys file.

Open the SSH config file:

nano /etc/ssh/sshd_config

Uncomment the AuthorizedKeysCommand and AuthorizedKeysCommandUser
values. Set the values as follows

AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys %u

AuthorizedKeysCommandUser root

This configuration tells ssh to run the
sss_ssh_authorizedkeys executable with the %u (username) parameter instead of
directly checking the ~/.ssh/authorized_keys, and you remember that we
configured sssd to check the altSecurityIdentities attribute within AD,
which is what will be returned by this lookup. Great, right?

Save and exit the sshd_config file. Restart the ssh service (systemctl restart ssh.service) or reboot the server, to ensure that the new configuration is loaded.

All that’s left now is to create our SSH key pair and test the connectivity. To do that I’ll use PuttyGen to create a key pair for myself
to work with. Within the PuTTy Key Generator I left the default options and
clicked Generate to create a key pair for myself.

Since I’ll be using PuTTy from my Windows
machine to connect to Ubuntu, I saved the private key in PuTTy’s ppk format.
I also saved a copy of the public key as a text file for future reference.

Next, let’s load our public
key into Active Directory. Once again I’m using my “murphy” account. We’ll need
to get to the Attribute Editor tab on the AD user account, and in order to do that
we need to enable Advanced Features within ADUC.

With Advanced Features enabled, open the user
account properties and navigate to the Attribute Editor tab. On the
Attribute Editor tab click on the Attribute altSecurityIdentities, then
click Edit.

This is where we’ll add the public key that we
created with PuttyGen. Note that the key needs to be one continuous line and
must be prefixed with ssh-rsa.

Once you’ve added the public key and clicked OK
(and OK again on the user account), we can load up PuTTy and try it out. Note
that we haven’t touched ~/.ssh/authorized_keys on the Ubuntu server so there
are no keys loaded directly onto the server.

Launch PuTTy and provide the IP address of your
Ubuntu server:

Next, go to the Connection > Data options and
add the username that you setup in AD with your public key. I used the “murphy”
account so that is what I’m configuring here.

Lastly, go to the Connection > SSH > Auth
options to add the private key file that matches the public key we configured
in AD.

Now when we click Open, PuTTy will
provide the username and private key to Ubuntu, which will lookup the matching
public key in AD and authenticate the login. Since I set a passphrase on my private
key, I’m prompted to enter that here:

If key authentication fails, you’ll be prompted
for the matching user password:

If that’s the case, review your configurations
and verify things are set properly. If you’ve configured any services since the
last reboot, reboot again. One useful thing to note is that sssd will
cache domain login information just like many other services. To forcibly
expire that cache and tell sssd to go back to the source (AD), use this command:

sss_cache -E

At this point we’re effectively done. We’ve:

Installed Ubuntu and setup networking to talk to
DNS/Active Directory.

Configured Kerberos to recognize our domain.

Used realmd to configure sssd and join the AD domain.

Configured sssd to let ssh use AD authentication.

Configured ssh to lookup public keys stored in an AD
attribute via sssd.

To take it a step further you can configure
AllowGroups within ssh to ensure that only authorized AD users can connect over
SSH. I created an AD security group named Role-G-LinuxAdmins and added my
“murphy” user to that group, then configured it within sshd_config.

You’ll need to restart the SSH service or reboot Ubuntu for that change to take
effect. You may also need to expire the sss_cache per the above if you’ve just
added your user to the new group.

That’s it! Now you can log in with AD
credentials or with a public key stored in AD. You can control access to SSH
with AD groups, and you can even set file/folder ACLs with AD users and groups.

Sunday, November 26, 2017

Before diving into the deployment options for network printers on our domain, let’s understand that normal users who are not local administrators on their computers may not be able to install our print drivers on their own. To get around this, we’ll deploy a Group Policy Object to configure Point and Print Restrictions for our domain computers.

Configure Point and Print Restrictions via GPO

To start, I’ve launched the Group Policy Management console on my domain controller, and right-clicked on Group Policy Objects. Select New.

Provide a descriptive name in the box that pops up. I’ve named mine Configure Point and Print Restrictions. Right-click on your new GPO and select Edit…

In the Group Policy editor window, browse to Computer Configuration, Policies, Administrative Templates, and click Printers. In the list of available settings locate Point and Print Restrictions. Right-click on it and select Edit.

Enable the policy. If you wish to restrict your users to only add printers from authorized print servers, check the box for Users can only point and print to these servers, then add the fully qualified domain name for your approved print servers. Configure the Security Prompts section in the When installing drivers for a new connection box by selecting Do not show warning or elevation prompt, and in the When updating drivers for an existing connection box by selecting Show warning only. Click OK to save your edits.

Next, while still in our new GPO, browse to Computer Configuration, Policies, Administrative Templates, System, and click Driver Installation. In the list of available settings locate Allow non-administrators to install drivers for these device setup classes. Right-click on it and select Edit. Enable the policy and click Show…

Then, paste the following string into the Value column: {4D36E979-E325-11CE-BFC1-08002BE10318}

Click OK to save the value, and OK again to save your edits to this setting. This has added the printers setup class to the list of device drivers that regular users are allowed to install.

Lastly, link the new GPO to your computers OU. Now that we’ve granted the required permissions for installing drivers, let’s move on to deployment.

Configure Network Printer Deployment Options

There are two primary methods of deploying printers to your workstations via Active Directory; Deployed Printers and Group Policy Preferences.

Deployed Printers is the legacy capability which may fit the requirement in very small environments, but its limited feature set makes it a poor choice in most cases. For example, it isn’t possible to set a default printer using this feature. It is, however, extremely simple to setup.

Configure an Active Directory “Deployed Printer”

On my domain controller I’ve opened Group Policy Management and created a new GPO, linked to my Computers OU, called Deploy Printer.

In the Deploy Printer GPO I’ve configured my printer under Computer Configuration, Policies, Windows Settings, Deployed Printers. To do that, just right-click on Deployed Printers and choose Deploy Printer. Then, type the path to the shared printer (SMB-INF1\Lexmark E120n in my case), click the Add>> button, then click OK. Close the GPO and that’s it. The configured printer will be deployed to all of the computers in the linked OU. There’s certainly more you could do with Deployed Printers, and you could probably get fancy with delegation on the new GPO to target the printer deployment a bit, but there’s really no reason to. Microsoft recommends using Group Policy Preferences to deploy printers instead, so let’s look at that.

Configure Shared Printers with Group Policy Preferences

We’ve come this far and now we have another decision to make, because Group Policy Preferences (GPP) can be set for either the User or the Computer. In larger environments it’s recommended to use a Computer policy because it processes during computer startup instead of during user logon, reducing logon time/improving user experience. If you have a lot of printers, the delay during logon can be very noticeable. One notable downside of using a computer GPP in this instance is that it’s not straightforward to set a user’s default printer. It may also be more difficult to use item-level targeting depending on how you have your computer objects organized (assuming that you have them organized).

Let’s take a look at deploying shared printer with a user GPP and some basic item-level targeting configured. To start, I’ll create a new GPO called Deploy Printers, linked to my Users OU.

Edit the settings for the new GPO and browse to User Configuration, Preferences, Control Panel Settings, Printers. Right-click on Printers and select New > Shared Printer.

In the New Shared Printer Properties box, I’m going to leave the default action of Update*. In the Share path: box, type the path to the share name of your network printer or click the ellipsis button to find it in the directory.

Click the box to Set this printer as the default printer… if desired. That’s it for the configuration on the General tab.

*One caveat to using the Update action instead of Create along with the Set this printer as the default printer option is that the user’s default printer will change back to this printer every time group policy refreshes on the machine. If the user has changed their default printer for some reason, this could be annoying. Consider using Create if you think this may be an issue in your environment.

Click the Common tab next and have a look at the available options. Select the options to Run in logged-on user’s security context, and Item-level targeting. Note that item-level targeting isn’t necessary in all scenarios. If you leave it unchecked the GPO will apply to every user account within the OU that you link the GPO to. This may be perfectly reasonable in many scenarios. Since I want to configure targeting for this demo, I’ll check the box and click the Targeting… button.

Within the Targeting Editor click the New Item drop-down list. If you’re unfamiliar with item-level targeting, you’ll notice there are a large number of parameters that you can choose to target a group policy preference against. For this demo, let’s choose Security Group. The editor populates the basic filter and asks us to define the security group that we’re going to target.

Since this is a user policy we’ll leave User in group checked, and click the ellipsis button next to the empty Group box. I previously used ADUC to create a new security group called Dept-Finance, and I’ve selected that here.

Now I can click OK to close the Targeting Editor and OK again to save the New Shared Printer settings. With the printer configured, this GPO is ready to go. The yellow triangle next to the printer name simply indicates that this is an Update action. If you selected Create instead, you'll see a green triangle.

Note that you can (and in many cases should) configure all of your printers within this one GPP GPO, using item-level targeting on each preference item to sort out who gets what. Exceptions arise when you have a large number of printers or special circumstances that require multiple GPOs. Personally, in a small environment I like to have a single GPO per site for printer deployment.

To test all of this, I’ve logged in to a different domain computer with a user account that is located within my Users container in ADUC, and is also a member of the Dept-Finance group that I assigned in item-level targeting. If you decided not to use item-level targeting, any user within the OU that your GPO is linked to should receive the printer mapping.

Here I can see that the printer has successfully mapped to my end-user account, and has also set as the default printer as I specified in the GPP.

That concludes this two-part series on basic domain printer deployment.