rubysecurity.org

Cloud Architect / DevOps Engineer / SRE / Developer | /root

Home About Books Blog Portfolio Archive

Tag Cloud


Currently Reading

Certified Kubernetes Administrator (CKA) Study Guide
Certified Kubernetes Administrator (CKA) Study Guide
38 / 155 Pages


Latest Book Reviews

Latest Posts


March 28, 2021

Deploying a 389 Directory Server

by Alpha01

So it’s been roughly nine months since I created a useful technical post on this site. So what better way to than to post the information about the newly deployed LDAP 389 Directory Server I just did on my homelab.

Ever since Red Hat announced that RHEL was going to be of no cost for developer and testing personal use (with limits, of course). This was perfect occasion for me to start using RHEL 8.

Install

1). Disable SELinux (yes, I know. I should do better..)

sudo setenforce 0

2). Update firewall

firewall-cmd --permanent --add-port={389/tcp,636/tcp,9830/tcp}
firewall-cmd --reload
firewall-cmd --list-all 

3). Install epel repo

yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
yum module install 389-directory-server:stable/default

4). Create LDAP instance

[general]
config_version = 2

[slapd]
root_password = MY_SUPER_ULTRA_SECURE_PASSWORD_HERE

[backend-userroot]
sample_entries = yes
suffix = dc=rubyninja,dc=org

5). Create 389 DS instance

dscreate from-file nstance.inf

6). Create ~/.dsrc config

[localhost]
# Note that '/' is replaced to '%%2f'.
uri = ldapi://%%2fvar%%2frun%%2fslapd-localhost.socket
basedn = dc=rubyninja,dc=org
binddn = cn=Directory Manager

7). Afterwards, I’m able to verify my installation

[root@ldap ldap]# dsctl localhost status
Instance "localhost" is running

8). Since, I kept the default settings when I created the Create 389 DS instance, my server received the name “localhost”. Hence why my ~/.dsrc config also has the instance configured as “localhost”. The corresponding systemd service and dirsrv@localhost and with the config files stored in /etc/dirsrv/slapd-localhost

systemctl status dirsrv@localhost

ls -l /etc/dirsrv/slapd-localhost/

SSL Configuration

By default the ds-389 setup is using self-sign certificates. The following was used to install my self-sign cert for ldap.rubyninja.org.

1). Create private root CA key ssh signed cert

openssl genrsa -out rootCA.key 4096
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 4096 -out rootCA.pem

2). I created the following script to easily generate a certificate key-pair signed by my custom local CA.

#!/bin/bash
SAN="DNS:ldap.rubyninja.org,DNS:login.rubyninja.org"

[[ ! -d "./certs" ]] && mkdir certs

cat \
/etc/pki/tls/openssl.cnf \
- \
<<-CONFIG > certs/ca-selfsign-ssl.cnf

[ san ]
subjectAltName="${SAN:-root@localhost.localdomain}"
CONFIG

# generate client key
openssl genrsa -out certs/ssl.key 4096

# generate csr
openssl req \
-sha256 \
-new \
-key certs/ssl.key \
-reqexts san \
-extensions san \
-subj "/CN=ldap.rubyninja.org" \
-config certs/ca-selfsign-ssl.cnf \
-out certs/ssl.csr

# sign cert
openssl x509 -req -in certs/ssl.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -days 2048 -sha256 -extensions san -extfile certs/ca-selfsign-ssl.cnf -out certs/ssl.crt

3). Then I had to certutil utility to view the names and attributes the default SSL certs had.

[root@ldap]# certutil -L -d /etc/dirsrv/slapd-localhost/ -f /etc/dirsrv/slapd-localhost/pwdfile.txt

Certificate Nickname                                         Trust Attributes
                                                             SSL,S/MIME,JAR/XPI

ca_cert                                                      CT,,
Server-Cert                                                  u,u,u

4). Once I made note of the name and attributes of the SSL certificates, we will first need to delete them before replacing them with my custom SSL certs. Deletion:

certutil -d /etc/dirsrv/slapd-localhost/ -n Server-Cert -f /etc/dirsrv/slapd-localhost/pwdfile.txt -D Server-Cert.crt
certutil -d /etc/dirsrv/slapd-localhost/ -n Self-Signed-CA -f /etc/dirsrv/slapd-localhost/pwdfile.txt -D Self-Signed-CA.pem

5). Adding new SSL certs:

certutil -A -d /etc/dirsrv/slapd-localhost/ -n "ca_cert" -t "CT,," -i rootCA.pem -f /etc/dirsrv/slapd-localhost/pwdfile.txt
certutil -A -d /etc/dirsrv/slapd-localhost/ -n "Server-Cert" -t ",," -i ssl/ssl.crt -f /etc/dirsrv/slapd-localhost/pwdfile.txt

6). While the certutil utility manages signed public and CA certificates. Private SSL certificates are managed by the pk12util utility. However, before we use this tool, we must covert the X.509 private ssl certificate to a pkcs12 format.

openssl pkcs12 -export -out certs/ssl.pfx -inkey certs/ssl.key -in certs/ssl.crt -certfile /root/ssl/rootCA.pem

7). Afterwards, we can added it to our LDAP SSL database.

pk12util -d /etc/dirsrv/slapd-localhost/ -i certs/ssl.pfx

8). Lastly, restart the service

systemctl restart dirsrv@localhost

Resources

Tags: [ 389-directoryserver rhel ldap ]
March 28, 2021

Creating an LDAP read-only service account

by Alpha01

So now that I have an LDAP server up and running. I can finally start creating ldap clients to authenticate to my ldap.rubyninja.org server. Before I can start configuring applications or even adding normal LDAP users, I need to start creating a generic read-only service account.

1). Creating the service account

dsidm localhost user create \
--uid binduser \
--uidNumber 1001 \
--gidNumber 1001 \
--cn binduser \
--displayName binduser 

2). Create a password for the service account

dsidm localhost account reset_password uid=binduser,ou=people,dc=rubyninja,dc=org

3). To Modify/add permissions of the binduser service account. I created a file called binduser.ldif with the following contents:

dn: ou=people,dc=rubyninja,dc=org
changetype: modify
add: aci
aci: (targetattr="*") (version 3.0; acl "Allow uid=binduser reading to everything";
 allow (search, read) userdn = "ldap:///uid=binduser,ou=people,dc=rubyninja,dc=org";)

Apply the changes

ldapmodify -H ldaps://localhost -D "cn=Directory Manager" -W -x -f binduser.ldif

NOTE: A fair warning, although I’ve worked with LDAP and had some experience with it. Even at some point one of my job responsibilities was managing an enterprise OpenLDAP infrastructure. LDAP is not quite one of my forté, so in no way shape or form are these best practices! These is just a mere POC for my homelab.

Resources

Tags: [ 389-directoryserver ldap ]
March 28, 2021

Configure BIND to support DDNS updates

by Alpha01

I use BIND on my home network for both authoritative and forwarding name resolution. In it I have a few private DNS zones I use for testing and for my homelab setup. The main primary dns zone I use for my homelab is rubyninja.org. Previously when I wanted to make DNS changes, I just ssh into my master nameserver, I update the zone file, and reload. While this worked great for me these last 10+ years that I’ve running BIND. It obviously doesn’t follow good DevOps practices.

If you’re in a normal BIND environment where you already using rndc, to administer your server, then you’re almost quite there.

BIND Configuration

1). Secret Key Transaction Authentication (TSIG) key. (Where ddnskey. is the name of the key) Approach A: Using dnssec-keygen

mkdir ddns
dnssec-keygen -a hmac-md5 -b 512 -n HOST -r /dev/urandom ddnskey.

The above command will create two Kddnskey files. One ending *.private while the other *.key.

Approach A: Using tsig-keygen

tsig-keygen -a hmac-md5 ddnskey.

Either approach is fine, for this example I opted to use dnssec-keygen since I’ll be using the created key file to test a dynamic dns update.

2). Update named.conf file. Include the newly created key configuration:

key "ddnskey." {
        algorithm      "hmac-md5";
        secret          "PRIVATEKEYHERE==";
};

Now, it’s just a matter of setting the allow-update configuration to allow updates using our newly created key.

zone "rubyninja.org." IN {
        type master;
        file "etc/zones/db.rubyninja.org";
        allow-transfer { trusted-servers; };
        allow-query { any; };
        allow-update { key rndckey; };
};

zone "k8s.rubyninja.org." IN {
        type master;
        file "etc/zones/db.k8s.rubyninja.org";
        allow-transfer { trusted-servers; };
        allow-query { any; };
        allow-update { key "ddnskey."; };
};

It is worth indicating that BIND also includes the update-policy option for more finer-grained options for the type of updates that we want to allow.

3). Testing using the tool dnsupdate (part of bind-utils) we can easily test doing an update to verify the setup works as expected.

$  nsupdate -d -k Kddnskey.+157+06602.key
Creating key...
> server ns1.rubyninja.org
> zone k8s.rubyninja.org.
> update add tonytest.k8s.rubyninja.org. 3600 A 192.168.1.25
> send

Resources

Tags: [ bind ]
March 28, 2021

389 Directory Server GUI with Cockpit

by Alpha01

So I have a 389 Directory Server up and running. The next step to ease administration was to find a GUI. My first logical approach was to use Apache Studio, however I’m trying to the keep number of non ARM applications on my shiny Apple M1 MacBook Pro to an absolute minimum, so I opted to not install Apache Studio. At least not yet. Luckily, I learned that RedHat has a Webmin equivalent called Cockpit that comes with built-in support for 389 Directory Server Management.

The Cockpit application was already installed on my base RHEL 8 system, I simply just copied over my fullchain Let’s Encrypt SSL certificate to /etc/cockpit/ws-certs.d/ssl.cert and restart the service.

systemctl restart cockpit

Then it was just a matter of updating firewalld

firewall-cmd --add-port=9090/tcp
firewall-cmd --permanent --add-port=9090/tcp
firewall-cmd --reload

The Cockpit application runs by default on port :9090

Cockpit web interface

Tags: [ 389-directoryserver rhel cockpit ]
May 24, 2020

Exclude comments and empty lines from file

by Alpha01

Every so often theirs the need to view a configuration (usually a large one), and you want an easy way to exclude all comments and empty lines:

egrep -v '^(#|$)' your-config-file.cfg
Tags: [ bash ]