Migrate SAMBA AD DC to Proxmox

I wanted to take a more resilient approach to my home network and therefore decided to move off of the Raspberry PI’s that run Pi-hole and Samba AD DC.

I decided to virtualize the Samba installations in a container, and separate the Pi-hole from the Active Directory instances. This in itself provides a more resilient situation, but in the virtualized case I can also create regular backups for the nodes, and maybe later move towards a cluster.

This post will focus on the steps from the Samba AD DC side, it will not detail the Proxmox-setup – I will cover that in a separate post!

The TL:DR; summary of this process is as follows:

  • Backup the domain controller (I know I won’t do this, but it is the prudent thing to do)
  • Join the new domain controller to the domain
  • Sync the sysvol ACL
  • Transfer FSMO roles
  • Demote “old” domain controller
Continue reading

Default Raspberry PI install: prevent SD-card wear

Although featured in other blogposts in this blog, I decided to start out the new year by summarizing my steps to install a new Raspberry PI with my defaults. It will give you a headless pi, no wireless (wifi/bluetooth) SSH-accessible, that limits syslogging to 50MB, creates a log in RAM and disables journaling. Here goes:

  1. Place emtpy file on boot volume named “ssh”. This will enable SSH access
  2. Place “userconf” file on boot volume, containing your default user and password. Should you like the “old” pi/raspberry, use this:
    pi:$6$c70VpvPsVNCG0YR5$l5vWWLsLko9Kj65gcQ8qvMkuOoRkEagI90qi3F/Y7rm8eNYZHW8CY6BOIKwMH7a3YYzZYL90zf304cAHLFaZE0
    This will make sure you can login to the new raspberry.
    Should you use pi/raspberry then PLEASE change it immediately after logging in for the first time over SSH. They did not remove this default set for no reason…
  3. Edit the config.txt and add:
    gpu_mem=16
    dtoverlay=disable-bt
    dtoverlay=disable-wifi
    This will reduce graphical memory to 16M (we’re headless)
    And it will disable the bluetooth and wifi radios.
  4. Boot up your Raspberry with the new SD-card.
  5. Run sudo apt update and sudo apt -y full-upgrade
    To ensure you have the latest packages.
  6. Run raspi-config, setting hostname, expanding filesystem, disabling predictable interface names
    Making your raspberry have a proper hostname, ensuring it uses the full SD-card and that it uses “eth0” for interface names, which I like
  7. Reboot
  8. Create /var/permanentlog
    This will hold the persisted logging (/var/log)
  9. Create /etc/init.d/setup-tmpfs contents listed below
    This is the file that handles the persisting to and from permanentlog, and is installable as a service
  10. Make it executable (chmod +x setup-tmpfs)
    Because it needs to execute on startup and shutdown
  11. Run sudo systemctl enable setup-tmpfs
    sudo systemctl start setup-tmpfs
    sudo systemctl unmask setup-tmpfs
    This will install it as a service, and make it survive reboots
  12. in /etc/systemd/journald.conf, uncomment/change SystemMaxUse=50M
    To limit the journaling files to 50MB
  13. Restart journaling daemon with sudo systemctl restart systemd-journald
  14. As proper root (sudo su), run:
    echo u > /proc/sysrq-trigger
    echo u > /proc/sysrq-trigger
    tune2fs -O ^has_journal /dev/mmcblk0p2
    e2fsck -fy /dev/mmcblk0p2
    echo s > /proc/sysrq-trigger
    echo b > /proc/sysrq-trigger
    This will make changes to the file-system, disabling EXT4-journaling

This concludes my list of pre-install and install steps. You now have a fresh Raspberry PI that has some of the preconditions set to ensure maximum life out of your SD-card!

Contents of setup-tmpfs:

Copy/paste this as-is into your file created in step 9:

#!/bin/sh
### BEGIN INIT INFO
# Provides: setup-tmpfs
# X-Start-Before:       $syslog
# X-Stop-After:         $syslog
# X-Interactive:        yes
# Default-Start:        2 3 4 5
# Default-Stop:         0 1 6
# Short-Description:    Keeps /var/log in RAM
# Description: Moves the contents of /var/log to RAM during boot
#              and keeps it there until shutdown/reboot, when it
#              copies the contents back to permanent storage.
### END INIT INFO

PATH=/sbin:/bin:/usr/sbin:/usr/bin
NAME=setup-tmpfs
DESC="Transient log directory"
LOCKFILE=/var/lock/$NAME.lock
VARLOG=/var/log
SIZE=250M
MODE=0755

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

VERBOSE=true
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

if [ -z "$VARLOGPERM" ]; then
        var=`dirname $VARLOG`
        log=`basename $VARLOG`
        VARLOGPERM="$var/permanent$log"
        unset var log
fi


do_start()
{
        # Return
        #   0 if transient log has been started
        #   1 if transient log was already running
        #   2 if transient log could not be started

        [ -f $LOCKFILE ] && return 1

        # Check if I'm root
        [ `id -u` -eq 0 ] || return 2

        # If VARLOG does not exist?
        [ -d $VARLOG ] || return 2

        # VARLOGPERM either does not exist (first invocation)
        # or is empty (left from previous invocation).
        #
        [ -d $VARLOGPERM ] || mkdir -p $VARLOGPERM || return 2

        # Mount a tmpfs over VARLOG.
        # The mount will shadow the current contents of VARLOG.
        # So, before, make a bind mount so that looking into VARLOGPERM
        # we'll see the current contents of VARLOG, which
        # will not be available anymore as soon as we mount
        # a tmpfs over it.
        #
        mount --bind $VARLOG $VARLOGPERM
        #ANDRE bugfix 15-12-2017: add mount --make-private $VARLOGPERM to prevent
        # them from being the same...
        mount --make-private $VARLOGPERM
        mount -t tmpfs -o nosuid,noexec,nodev,mode=$MODE,size=$SIZE $NAME $VARLOG
        if [ $? -eq 0 ]; then
                # Populate the tmpfs
                if cp -rfp $VARLOGPERM -T $VARLOG; then
                        # Success!
                        touch $LOCKFILE
                        return 0
                fi

                # Something went wrong...

                # Rollback the mount
                umount -l $VARLOG
        fi

        # Rollback the directory mangling
        umount $VARLOGPERM

        return 2
}

do_stop() {
        # Return
        #   0 if daemon has been stopped
        #   1 if daemon was already stopped
        #   2 if daemon could not be stopped
        #   other if a failure occurred

        [ -f $LOCKFILE ] || return 1

        # Check if I am root
        [ `id -u` -eq 0 ] || return 2

        # Merge back to permanent storage
        cp -rfup $VARLOG -T $VARLOGPERM

        # The following cannot fail... or can it?
        umount -l $VARLOG
        umount -l $VARLOGPERM
        rm -f $LOCKFILE
        return 0
}

do_reload() {
        # Return
        #   0 if transient log has been reloaded
        #   1 if transient log was not running
        #   2 if transient log could not be reloaded

        [ -f $LOCKFILE ] || return 1

        # Check if I am root
        [ `id -u` -eq 0 ] || return 2

        # Merge back to permanent storage
        cp -rfup $VARLOG -T $VARLOGPERM
        touch $LOCKFILE
        return 0
}






case "$1" in
  start)
        [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
        do_start
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  stop)
        [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
        do_stop
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  status)
        if [ -f $LOCKFILE ]; then
                echo "$DESC is running"
        else
                echo "$DESC is stopped"
                exit 1
        fi
        ;;
  reload)
        log_daemon_msg "Reloading $DESC" "$NAME"
        do_reload
        log_end_msg $?
        ;;
  *)
        echo "Usage: $0 {start|stop|status|reload}" >&2
        exit 3
        ;;
esac

Unifi WPA Enterprise EAP-TLS and USG

On the continued quest for more security on my home network, I wanted to implement WPA2-Enterprise on my home network. This post details how.

I have a USG (the “old” three port version); a Cloud Key (not relevant) and several AP from Unifi. The USG is running the RADIUS server.

The TL:DR; is as follows:

  • Create and generate certificates for your own Certificate Authority. This blog has details in this post: Create an SSL certificate chain and your own root certificate authority
  • Use your CA certificate, place it on the USG
  • Edit Freeradius’ eap.conf
  • Make it permanent by creating a post-config.d script
  • Generate client certificates for all devices that need to connect wirelessly
  • Link the CN from the client certificate to an entry in the RADIUS users

For details, read more, but be warned: this is a long read!

Continue reading

Migrating Samba AD DC from Pi 3B+ to Raspberry Pi 4

As you know, I have been running a Samba-based Active Directory for quite some time now. My two Raspberry Pi’s are happily chugging along in my redundant set-up.

Since a while, the new Pi model 4 is out. Boasting better performance and overall more headroom, I wanted to upgrade. As the hardware is different, it is not simply a matter of swapping over the SD-card, but rather a different process. Read on to see how I got along…

TL;DR:

sudo samba-tool fsmo show
sudo samba-tool fsmo transfer --role=all
sudo samba-tool domain demote -U<administrator-user>

Continue reading

Synology shared folder sync and permissions

My home setup has two Synology NAS machines. I use Shared Folder Sync to maintain some sort of backup and redundancy between the two. Furthermore, I only have SAMBA-shares to share folders with my Windows computers.

However, as Synology state:

15. Advanced Shared Folder Permissions at the source will not be synced to the destination. Furthermore, a read-only rule for administrators group will be created at the destination.

16. To ensure the functionality of Shared Folder Sync, the system automatically overwrites the privilege settings in Control Panel > Shared Folder > Edit > Advanced Permissions > Advanced Share Permissions every time a sync task is carried out. The privilege settings for the current user account on the destination will be changed to Read Only. All other users on the destination that have Read Only privilege will have their privilege revoked (unticked).

…which means you lose all configured ACLs. My workaround for this is as follows:

  • Pause or disable any active shared folder sync
  • Set permissions on the target folder as you would like them to be
  • SSH into the target machine, and navigate to /etc/samba
  • Copy the smb.share.conf to smb.share.conf.default
  • On the target machine, in DSM, create a new (repeating) scheduled task
  • Run it as root, and have the user defined script read:
    cp /etc/samba/smb.share.conf.default /etc/samba/smb.share.conf
  • Have it execute at an interval that makes sense to you, I have mine set to 10 mins.
  • Re-enable the shared folder syncs

What this does, is overwrite the ACL permissions on the Samba shares. So, the reset by Shared Folder Sync will then be overwritten by your script.

Ugly as a workaround, yes, but it gets the job done!

accountsd and secd high CPU usage on Catalina

TL;DR:
Go into ~/Library/Keychains and delete the folder that represents your local keychain (the folder will have a GUID-style name). Restart your Mac and all should be dandy. Please note, you MAY lose the convenience of having (some) saved passwords, requiring you to re-enter those.

Longer read:
So it was upgrade time for my Macbook. I updated Mojave to Catalina. Coincidentally, I also had to renew my laptop’s user password (company policy) and meanwhile, also the new iOS came out (13.3).

This morning, my Macbook sounded like it was taking off. The fan was going berserk and checking the Activity Monitor, I saw that both the accountsd and the secd daemons were consistently using between 60% and 100% of CPU.

I tried enabling Keychain, as per forum posts, but it would not let me enable it. I got the spinning wheel and the process was just very slow.

I also tried signing in and out of iCloud, disabling iCloud on my iOS devices. Heck, I even changed the password for my Apple ID. All to no avail.

What eventually set me on the right track was opening Safari and going to the Passwords-tab in Preferences. It said passwords were locked and to enter the password for a user. To which I obliged, but it gave me the uh-oh shake, refusing to open the passwords.

I tried entering my old user passwords, but all to no avail. This ofcourse is very puzzling but led me to thinking that somewhere, something must be blocking access to keychain items. Could this be the reason the daemons were running amok?

So, I finally went into the terminal app and navigated to:

 ˜/Library/Keychains

In it, there were a couple of “keychain-db” files, but more importantly, a subfolder that had a GUID-like-name (ABCDE12-EFG2-21BA-……you get the idea). This folder represents your local keychain and holds your “local” items. It is a bit of a nuisance because of having to enter your passwords again, but it is safe to delete it.

Restarting the MAC then re-generated the GUID folder and the fans quieted down.

Hope this helps someone trying to fix this.

Discarding ‘permission denied’ or ‘operation not permitted’ while using find command

If you are like me, in your search for files, you will regularly use the ‘find’-command as non-root user.

Its usefulness is depreciated however, by a large number of “Permission denied” mentions.

TL;DR:
Redirect all error output to a non-displayable part, the immeasurable pit that is /dev/null:

find . -name 'somefile' 2>/dev/null

For the long read, please continue below.

Continue reading

Multiple VLANs on Windows 10

First, enable Hyper-V on your Windows 10 installation (Pro or Enterprise), by opening an elevated PowerShell:

 Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All

This will require a restart.

After restarting, go into the start menu and start the Hyper-V-management utility. Again, do this “As Administrator” because it will require elevated privileges.

Then, assuming your switch port is correctly configured, note your native VLAN and your tagged VLAN. In my case, the tagged VLAN is 29.

In Hyper-V-manager, go to the Virtual Switch Manager.

Create a new virtual switch of type “External”. Give it an appropriate name and tag the correct VLAN (in my case, 29).

Now, in the network control panel, you should have three adapters: one for your physical network card (the one you always had), a Default Switch and your newly created switch.

By default, only the latter two will be configured to receive IP addresses. This is why you need to go into the properties of the physical adapter, and re-enable the IPv4 and IPv6 protocols, configuring them as you like (in my case through DHCP).

Also, feel free to disable and enable the Hyper-V network switches as you like. Especially if you are not using the virtual machine aspect of Hyper-V, I leave mine disabled most of the time, until such case I need to have native access to the other VLAN.

Unifi 802.1x wired mac address based authentication with Windows clients

As an additional exercise in securing my home network, I decided to delve into how IEEE802.1x or dot1x works.

I have a unifi-based setup (USG, USW and UAP) and a lot of my setup is wired. I found setting this up for a wireless network is near to trivial (take care to choose the correct mac-address format and stick to it), I found configuring it for a Windows client somewhat less trivial. Read on if you want to know how I fared.

Continue reading

Upgrading to buster from stretch on raspberry pi running pi-hole and samba ad dc

Just a quick note to self on how to upgrade from stretch to buster on raspbian:

Before doing this, make sure your stretch installation is current & up-to-date by doing apt update / apt-upgrade

Then:

grep -rl stretch /etc/apt/ | sudo xargs sed -i 's/stretch/buster/g'

This command changes the repositories from stretch to buster.

Then:

sudo apt update
sudo apt dist-upgrade

This will take some time. In my case, not the hours that are “promised”, but more like 30 minutes.

Then, my IPv6 address appeared to have changed. So reflect the change by retrieving the /128 address and using this in:

/etc/hosts
/etc/pihole/setupVars.conf

Then, reboot your pi, and perform some maintenance:

sudo apt autoclean
sudo apt autoremove

pihole -g -up

If all’s well, everything should be dandy!