Setting sights on a new baseline

Last modified by Mitchell on 2022/01/25 07:22

I haven't been completely idle for the past several years, for all that I've done a really bad job of writing new entries. One thing I've worked on during this time is learning a fair amount about Kubernetes, which (along with Docker) has been instrumental in popularizing Alpine Linux, a lightweight Linux distribution that focuses on security. When working with more of a service-oriented infrastructure instead of a monolithic one, keeping the overhead of virtual machines low leaves more resources for the actual services. Running services in containers also helps, but that's not a great approach for core services.

The standard Alpine Linux installation documentation covers all of the basics. A couple of additional minor notes:

  • I use the the Virtual image from the Downloads page, since I don't need to worry about a variety of hardware-related packages.
  • To be rid of the process '/sbin/getty -L 0 ttyS0 vt100' exited messages from /var/log/messages, I recommend commenting out this line from /etc/inittab (explanation provided here):
/etc/inittab
# enable login on alternative console
ttyS0::respawn:/sbin/getty -L 0 ttyS0 vt100
  • Installing open-vm-tools for ESXi integration comes down to a matter of personal taste. It registers information at boot-time, so starting the service immediately after installation doesn't update ESXi. So it's up to you if you think it's worth spending the 50MB of disk space for that.

I'm a proponent of having service users that are controlled centrally (in my case, via Active Directory). For Alpine Linux, since it doesn't natively use NSS (as it uses musl instead of glibc), integration comes in at the password authentication level via PAM, but not at the user verification level. This requires a little bit of extra work.

First off, install several packages after enabling the community repository:

$ apk add cyrus-sasl-gssapiv2 nss-pam-ldapd openssh-server-pam shadow]]

There's a bunch of documentation on how to set up nslcd on this Samba page, and how to set up the pam.d files on this nss-pam-ldapd page. The former is useful for how much detail it goes into for configuration, even if it's not on the main project site. In my case, I opt to go with the Kerberos authentication route, to avoid having the credentials left on the system in plaintext. If you're using Samba, running this on a domain controller should do the job:

$ samba-tool domain exportkeytab <keytab> --principal=<user>

This file then needs to be copied over to the client in question. For this purpose, that file on the client will be /etc/krb5.nslcd.keytab, with ownership by nslcd:nslcd and permissions 0600. After that, create an initial Kerberos ticket to work with for now (you'll need to figure out how to have it regularly renewed):

k5start isn't available on Alpine Linux by default. You can either build it yourself (fairly straightforward), follow the Samba username/password instructions, or wait for me to provide a package (in which k5start is configured as a service for automated renewal).

$ k5start -f /etc/krb5.nslcd.keytab -U -o nslcd -K 360 -b -k /tmp/nslcd.tkt

At this point, you can then make changes to /etc/nslcd.conf to hook up your directory server (most as per the Samba page, with some additional explanation for differences).

/etc/nslcd.conf
.
.
.
# We put both ldaps:// and ldap:// because they get used at slightly different times -
# ldap:// for querying the user details via the keytab, and ldaps:// for verifying the
# password. We put ldaps:// before ldap:// so that when verifying the password, the
# LDAP bind doesn't happen over cleartext.
uri ldaps://<LDAP server address>
uri ldap://<LDAP server address>

base <LDAP base>

# For the ldaps:// connection, don't blindly accept the certificate. Validate it.
tls_cacertfile <root certificate file>

pagesize 1000
referrals off
nss_nested_groups yes
sasl_mech GSSAPI
sasl_realm <Kerberos realm>
# nss-pam-ldapd is much happier being able to pass in the ticket's user.
sasl_authzid u:<user>
krb5_ccname /tmp/nslcd.tkt

# Uncomment the various "Mappings for Active Directory" lines.
.
.
.

You should be able to start the nslcd daemon and enable it on boot:

$ rc-service nslcd start
$ rc-update add nslcd

From here, in order to have PAM query nslcd, edit /etc/pam.d/base-auth to add the nss-pam-ldapd library:

/etc/pam.d/base-auth
# basic PAM configuration for Alpine.
auth    required        pam_env.so
auth    sufficient      pam_unix.so     nullok_secure
auth    required        pam_nologin.so  successok

auth    sufficient      pam_unix.so     nullok try_first_pass
auth    sufficient      pam_ldap.so     minimum_uid=1000 use_first_pass
# Required, since pam_unix.so has been downgraded from required to sufficient
auth    required        pam_deny.so

account required        pam_nologin.so
account sufficient      pam_unix.so
account sufficient      pam_ldap.so     minimum_uid=1000

password        sufficient      pam_unix.so     nullok sha512 shadow try_first_pass use_authtok
password        sufficient      pam_ldap.so     minimum_uid=1000 try_first_pass

-session        optional        pam_loginuid.so
-session        optional        pam_elogind.so
session sufficient      pam_unix.so
session optional        pam_ldap.so     minimum_uid=1000

Enabling OpenSSH logins from here is pretty simple:

/etc/ssh/sshd_config
.
.
.
UsePAM yes
.
.
.

As noted before, this is a PAM-only solution. As a result, any user that needs login capability will need a local user created, and that local user will dictate everything other than the password (e.g. the user ID, group ID, etc.). So ensure you do that for every user you need login permissions for (adjust options as you see fit):

$ useradd --create-home <user>

At this point, you should now be able to log in (via either console or ssh) to the system. Congratulations!

Note: Unfortunately, sudo won't work with your logged-in users, as it queries NSS by default, and the Alpine Linux version doesn't have LDAP-querying capabilities. So this is primarily useful for having distributed intermediate users.

Bonus! If you're interested in better SSH encryption, it's probably better not to use the defaults for sshd_config, since that current defaults (for a modern SSH client) to ecdsa-sha2-nistp256, which has some issues. As a result, it's worth thinking about adding this to the end of sshd_config (taken from this page). At present, the moduli file doesn't need to be adjusted since none of the primes are less than 2000 bits.

/etc/ssh/sshd_config
Protocol 2
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
KexAlgorithms [email protected],diffie-hellman-group-exchange-sha256
Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr
MACs [email protected],[email protected],[email protected],hmac-sha2-512,hmac-sha2-256,[email protected]