diceline-chartmagnifierquestion-marktwitter-whiteTwitter_Logo_Blue

Today I Learned

Use TouchID on MacBook Pro for Terminal sudo prompts

In order to use TouchID on MacBook Pro for Terminal sudo prompts, we need to enable Apple's Touch ID PAM module pam_tid.so (https://opensource.apple.com/source/pam_modules/pam_modules-173.1.1/modules/pam_tid/pam_tid.c.auto.html).

Just edit /etc/pam.d/sudo and add

auth sufficient pam_tid.so

Heads up, when you do a system update this change will be most probably overwritten. In order to make it persistent, you need to create a launchd daemon.

Create a new file called pam-tid.sh in a shared path

vim /Users/Shared/pam-tid.sh
#!/bin/bash

if ! grep 'pam_tid.so' /etc/pam.d/sudo --silent; then
  sed -i -e '1s;^;auth       sufficient     pam_tid.so\n;' /etc/pam.d/sudo
fi

Create a new com.graffino.pam.plist file:

vim /Users/Shared/com.graffino.pam.plist`

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.graffino.pam</string>

    <key>KeepAlive</key>
    <false/>

    <key>LaunchOnlyOnce</key>
    <true/>

    <key>RunAtLoad</key>
    <true/>

    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/pam-tid.sh</string>
    </array>
</dict>
</plist>

Start the daemon

Password-less SSH authentication on UniFi Dream Machine / Unifi Deam Machine Pro

Step 1. Make cron persist on restarts

unifi-os shell
curl -L https://github.com/unifi-utilities/unifios-utilities/raw/main/on-boot-script/packages/udm-boot_1.0.5_all.deb -o udm-boot.deb
dpkg -i udm-boot.deb
rm udm-boot.deb
exit

Step 2. Add root ssh keys on restart

cd /mnt/data/on_boot.d
vi 15-add-root-ssh-key.sh

File contents

#!/bin/sh

#####################################################
# ADD RSA KEYS AS BELOW - CHANGE BEFORE RUNNING     #
#####################################################
# set -- "ssh-rsa first key here all keys quoted" \ #
#        "ssh-rsa each line appended with slash " \ #
# 	 "ssh-rsa last one has no backslash"        #
#####################################################
set -- "ssh-rsa ..." \
        "ssh-rsa ...."

KEYS_FILE="/root/.ssh/authorized_keys"

counter=0
for key in "$@"
do
	# Places public key in ~/.ssh/authorized_keys if not present
	if ! grep -Fxq "$key" "$KEYS_FILE"; then
		let counter++
		echo "$key" >> "$KEYS_FILE"
	fi
done

echo $counter keys added to $KEYS_FILE

Make file executable and run it

chmod +x 15-add-root-ssh-key.sh 
./15-add-root-ssh-key.sh 

Step 3. Update banner

cat /dev/null > /issue
cat /dev/null > /etc/issue
cat /dev/null > /etc/motd

vi /etc/motd

# Insert your own banner 

Step 4. Update ssh configuration

UDM uses dropbear as ssh server and therefore the configuration is done on init.

Edit the dropbear configuration file

vi /etc/default/dropbear 
 
// See https://wiki.gentoo.org/wiki/Dropbear
DROPBEAR_OPTS="-sg"

Restart the dropbear service

/etc/init.d/dropbear restart

macOS asks for a PIN instead of a password

Whenever you try to athenticate macOS asks for a PIN instead of a password. This happens if you paired your key at some point with macOS.

Just open Terminal.app and unpair it:

sudo /usr/sbin/sc_auth unpair -u YourUserName

or simply

sudo /usr/sbin/sc_auth unpair

Take out your key if you have it plugged in and reboot.

Your key should be unpaired from your username. Remember you don't have to pair your key to use it. You only have to pair it if you want to use it for macOS authentication.

Automate the creation and deletion of EC2 snapshots via AWS CLI 2

We're heavily using AWS and we're scripting everything we can. As AWS CLI 2 came out recently we needed to update our scripts.

This script creates a new snapshot and deletes all snapshots older than 2 weeks, for a specific volume.

create-snapshot-and-cleanup.sh

#!/bin/bash

DESCRIPTION="example.com"
VOLUME="vol-xxxxxxxxxx"

SNAPSHOT_AGE=$(date +%Y-%m-%d --date '2 weeks ago')
TODAY=$(date +%d-%m-%Y)

echo "Creating new snapshot of volume $VOLUME."
aws ec2 create-snapshot --output text --description "$DESCRIPTION - AutoSnapshot $TODAY" --volume-id $VOLUME >> /dev/null

echo "Deleting snapshots older than: $SNAPSHOT_AGE"

snapshots=$(aws ec2 describe-snapshots --output text --filters Name=volume-id,Values=$VOLUME --query "Snapshots[?StartTime<'$SNAPSHOT_AGE'].SnapshotId")

echo "Snapshots sheduled for deletion: $snapshots"

for snapshot in $snapshots; do
  echo "Deleting $snapshot ..."
  aws ec2 delete-snapshot --snapshot-id $snapshot
done

Automatically add and remove SSH keys from remote hosts

Managing multiple hosts is a pain when using SSH key authentication. There are a lot of solutions out there for managing SSH keys, there's Ansible, Puppet, or other paid solutions.

There's also another option, to use a script to do the job for you.

Here's how

1. Create a targets file containing your hosts and usernames

# Host
hostname.example.com username

2. Create a add-keys.sh file

#!/bin/bash
keys=${1:-*.pub}
echo update ssh-keys: ${keys}

cat targets | grep -vE '^(\s*$|#)' | sed 's/#.*$//g' | while read host user
do
   echo "# Adding public ssh-keys for $user@$host"
   for k in ${keys};
   do
      echo "# Adding public key $k"
      touch ${k%\.pub}
      ssh-copy-id -f -i $k $user@$host
   done
done

3. Create a remove-keys.sh file


#!/bin/bash

keys=${1:-*.pub}
echo update ssh-keys: ${keys}

cat targets | grep -vE '^(\s*$|#)' | sed 's/#.*$//g' | while read host user
do
   echo "# Remove public ssh-keys for $user@$host"
   for k in ${keys};
   do
      echo "# Remove public key $k"
      key=$(<$k)
      ssh $user@$host 'bash -s' <<EOT
sed -i "/$key/d" ~/.ssh/authorized_keys
EOT
      echo "# Key removed"
   done
done

4. Add the public keys you want to add as .pub files in the same folder

5. Run one of the scripts. Done.

How to solve an issue that depends on other people's actions in a big company

Have you ever been in a situation where you're a cog in a big company your work depends on other people's action and you can't get them to do their part so that you can finish your own tasks?

If the answer is yes, you know how frustrating this can be. This happens because the other people involved have their own priorities and you're at the very bottom.

In order to get things done, you have to get to the top of their list and the solution is rather simple:

Create a carefully non-personal, non-emotional email in which you explain the situation, place the person responsibile in the "To:" field and add their direct manager, your own manager, and anyone remotely responsible in the "Cc" field.

I guarantee your problem will be solved in no time. :D

You can even escalate this further up the chain with a follow-up email where you add more managers up the chain in the "Cc:" field.

Don't forget to thank everyone involved after your issue is solved.

Remove a non-removable MDM profile from macOS without a complete wipe

Non-removable MDM profiles cannot officially removed without doing a full system wipe. This is a problem when you restore a system from Time Machine after you enrolled it into the MDM, as the MDM will break, leaving you unable to re-enroll the machine.

Here's how to remove a non-removable MDM profile

  1. Boot the Mac into Recovery Mode (hold down command+R during startup).
  2. Go to the Utilities menu and open Terminal and type: csrutil disable. This will disable SIP (System Integrity Protection).
  3. Reboot into the OS.
  4. Open the integrated terminal and type:
cd /var/db/ConfigurationProfiles
rm -rf *
mkdir Settings
touch Settings/.profilesAreInstalled
  1. Reboot.
  2. Boot the Mac into Recovery Mode (hold down command+R during startup).
  3. Go to the Utilities menu and open Terminal and type: csrutil enable. This will re-enable SIP.
  4. Reboot into the OS.

The profile will be now removed and you will be able to re-enroll the Mac to your MDM.

How to remove a VPN profile on a MDM enrolled macOS

Restoring from a Time Machine backup can create duplicate MDM VPN profiles.

To manually remove a profile on your macOS, follow these steps:

  • Go to System Preferences and select Profiles.
  • Delete the VPN profile, and enter the user password if requested.
  • Then, go to Network Connections.
  • If you see any connections which start with or include “VPN”, delete them.

Note

If the Button isn’t available,you have to use a terminal command to remove it. Open the integrated Terminal and type

networksetup -removenetworkservice "duplicateVPNProfile"

Prepare NuxtJS for static deployment

In order to deploy Nuxt as a static website you need to:

  1. Upgrade nuxt to 2.14.0
  2. Set target: 'static' in your nuxt.config.js
  3. Set fallback 404 page:generate: { fallback: '404.html' }
  4. Run nuxt generate

You then need to tell Nginx to properly handle slashes for subpages:


    location /.
    {
        # Remove trailing slash and redirect it
        rewrite ^(.+)/+$ $1 permanent;
        
        # Redirect index.html
        rewrite ^(.+)/index.html$ $1 permanent;
        
        # Serve folder path via index.html
        try_files $uri $uri/index.html =404;
        
        # Serve a custom static error page
        error_page 404 /404.html;
    }

Follow URL redirects from the Terminal

Sometimes you need to follow an url trough multiple redirects. I've created a simple script you can alias into your .bashrc or .zshrc file and then just use it as a regular shell command:

Add this line to .zshrc or .bashrc

# Follow URL
alias checkurl='_checkurl() { curl -v -L $1 2>&1 | egrep "^(> Host:|> GET|> Code|< HTTP|\* SSL)"}; _checkurl'

Then you can use it like so:

checkurl google.com

it will output this:

> GET / HTTP/1.1
> Host: google.com
< HTTP/1.1 301 Moved Permanently
> GET / HTTP/1.1
> Host: www.google.com
< HTTP/1.1 200 OK

Really useful when debugging URLs.

How to delete multiple databases using MYSQL

When you have to delete 100+ databases created by a botched deployment script you have a few options available:

1. Plain SQL

You'll have to run this query and then copy paste the result into a second query.


SELECT
	GROUP_CONCAT( CONCAT( 'DROP DATABASE `', SCHEMA_NAME, '`;' ) SEPARATOR ' ' ) AS DELETE_QUERY
FROM
	information_schema.SCHEMATA 
WHERE
	SCHEMA_NAME LIKE '{DBNAME}%'

2. Stored procedure

This allows you to create a stored procedure that will run your query in one go.

CREATE PROCEDURE clean () BEGIN

	SET @QUERY := (
		SELECT
			CONCAT( 'DROP DATABASE `', SCHEMA_NAME, '`;' ) 
		FROM
			`information_schema`.`SCHEMATA` 
		WHERE
			SCHEMA_NAME LIKE '{DBNAME}%' 
			LIMIT 1 
		);
	PREPARE stmt 
	FROM
		@QUERY;
	EXECUTE stmt;
	DEALLOCATE PREPARE stmt;
	
END;
CALL clean ();
DROP PROCEDURE clean;

Use F12 as "Insert" in macOS terminal

On Apple keyboards we don't have an Insert key, and this is most annoying when using the command line or CLI tools like Midnight Commander.

We can fix this by re-assigning the F12 key:

  • Remove F12 as key from System Settings->Mission Control
  • Enable Use F1, F2, etc. keys as standard function keys in System Settings->Keyboard->Keyboard
  • Go to Terminal->Preferences and set the default profile as Pro
  • Go to Terminal->Preferences->Profiles->Keyboard and Replace F12 code with \033[2~

Make macOS remember your SSH keys after restart

We need to tell macOS to add the keys to the agent, in order to make them persistent after reboot.

We have to create new file in ~/.ssh/ called config

vi ~/.ssh/config

with the following content:

Host *
   AddKeysToAgent yes
   UseKeychain yes   

Then, we need to add our keys to the agent and macOS keychain (so your private key password is remembered).

ssh-add -D
ssh-add -K ~/.ssh/*

To verify that our keys are present in the agent:

ssh-add -l