Categories
Linux Security Windows

Securing SSH with Yubikey using WSL

If using Windows, start with downloading Gpg4Win and Kleopatra. As i use Windows Terminal I wont be downloading Putty. After the installation of these two, open the configuration files of the gpg-agent and scdaemon and append the following:

# C:\Users\<username>\AppData\Roaming\gnupg\gpg-agent.conf
enable-putty-support
enable-ssh-support

You can also to this with powershell, using the following command:

Add-Content $env:APPDATA\gnupg\gpg-agent.conf "enable-putty-support"
Add-Content $env:APPDATA\gnupg\gpg-agent.conf "enable-ssh-support"

Add-Content $env:APPDATA\gnupg\scdaemon.conf "debug-level guru"
Add-Content $env:APPDATA\gnupg\scdaemon.conf "log-file scdaemon.log"
Add-Content $env:APPDATA\gnupg\scdaemon.conf "reader-port Yubico Yubi"

Restart the agent with the following commands:

gpgconf --kill gpg-agent
gpg-connect-agent /bye

Open up Powershell and check if the Yubikey is visible to the system. You should get output similair to this:

PS C:\Users\wiege> gpg --card-status
Reader ...........: Yubico YubiKey OTP FIDO CCID 0
Application ID ...: < .... >
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: Yubico
Serial number ....: < .... >
Name of cardholder: < .... >
Language prefs ...: < .... >
Salutation .......: < .... >
URL of public key : [not set]
Login data .......: < .... >
Signature PIN ....: not forced
Key attributes ...: < .... >
Max. PIN lengths .: < .... >
PIN retry counter : 3 3 3
Signature counter : 0
KDF setting ......: off

When you open Kleopatra and go to Smartcards, you should also see your Yubikey present. If your Yubikey is new, there are no keys listed and you need to create them. This can be done several ways, through Kleopatra or on CLI (i prefer CLI as it provides more options).

Open up CMD or Powershell and use gpg to generate your new key:

$ gpg --expert --full-generate-key

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
   (9) ECC and ECC
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (13) Existing key
Your selection? 11

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Sign Certify Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? E

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Sign Certify

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? S

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Certify

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? Q

Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 0
Key does not expire at all
Is this correct? (y/N) y

It will ask you for your name and emailadress, fill those in and conform with (O). Verify if your key has been generated:

$ gpg --list-keys
------------------------------------------------
pub   ed25519 2022-11-15 [C]
      E6444634F7318577BA18F43201A0XXXXXXXXXX

If you use Linux, you can export the key id (to be used for later)

export KEYID=E6444634F7318577BA18F43201A0XXXXXXXXXX

Now edit the master key and start adding sub-keys for encryption/signing and authentication:

$  gpg --expert --edit-key  E6444634F7318577BA18F43201A0XXXXXXXXXX
gpg (GnuPG) 2.3.8; Copyright (C) 2021 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  ed25519/01A0XXXXXXXXX
     created: 2022-11-15  expires: never       usage: C
     trust: ultimate      validity: ultimate

Add a new key for signing (and then repeat these for Encryption and Authentication):

gpg> addkey

gpg> addkey
Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
  (14) Existing key from card
Your selection? 10

Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at xxxxxxxxxxxxxxxxxxx
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.


Again: Repeat for Encryption and Authentication, then use 'save'.

If you wish to add more e-mail addresses, use adduid to them. End result should look like this:

$ gpg -K

sec   ed25519 2022-11-15 [C]
      E6444634F7318577BA18F4XXXXXXXXXXXXXXXXXX
uid           [ultimate] Wieger Bontekoe <[email protected]>
uid           [ultimate] Wieger Bontekoe <[email protected]>
ssb   ed25519 2022-11-15 [S] [expires: 2027-11-14]
ssb   cv25519 2022-11-15 [E] [expires: 2027-11-14]
ssb   ed25519 2022-11-15 [A] [expires: 2027-11-14]

Now export everything, once you have moved them to Yubikey you can't anymore.

$ gpg --armor --export-secret-keys E6444634F7318577BA18F4XXXXXXXXXXXXXXXXXX
 > ./master.key
# Also do all the subs like this, repeat for all of them!
$ gpg --armor --export-secret-subkeys < SUBKEYID > ./sub1.key

You can also do this from Kleopatra if using windows, that is a lot simpler. Just go to 'certificates', right click the certificate and go to 'Details'. Under details go to 'more details'. Here you will see 4 certificates that you can export using right click.

Backup these files, you should never loose them. Now, transfer the keys to Yubikey!

$ gpg --edit-key E6444634F7318577BA18F4XXXXXXXXXXXXXXXXXX
gpg> key 1
gpg> keytocard
Please select where to store the key:
   (1) Signature key
   (3) Authentication key
Your selection? 1
gpg> key 1
gpg> key 2
gpg> keytocard
Please select where to store the key:
   (2) Encryption key
Your selection? 2
gpg> key 2
gpg> key 3
Please select where to store the key:
   (3) Authentication key
Your selection? 3

gpg> save

Now verify if the sub-keys were really moved

$ gpg --card-status
Reader ...........: Yubico YubiKey OTP FIDO CCID 0
Application ID ...: < .... >
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: Yubico
Serial number ....: < .... >
Name of cardholder: < .... >
Language prefs ...: < .... >
Salutation .......: < .... >
URL of public key : [not set]
Login data .......: < .... >
Signature PIN ....: not forced
Key attributes ...: < .... >
Max. PIN lengths .: < .... >
PIN retry counter : 3 3 3
Signature counter : 0
KDF setting ......: off
UIF setting ......: Sign=off Decrypt=off Auth=off
Signature key ....: 4B3C 6B30 B22F 9C3E F196  D72D DE7D 3E9F XXXX XXXX
      created ....: 2022-11-15 07:14:18
Encryption key....: 30CE FB8F 54E6 0E63 93D3  9D6B A29B E406 XXXX XXXX
      created ....: 2022-11-15 07:14:48
Authentication key: 2477 02D2 511B 5407 F9A3  6005 DF86 A2D3 XXXX XXXX
      created ....: 2022-11-15 07:15:07

PGP Part, all set! Let's check if we have an up to date version of openssh that supports ecdsa-sk:

$ ssh-keygen --help
unknown option -- -
usage: ssh-keygen [-q] [-a rounds] [-b bits] [-C comment] [-f output_keyfile]
                  [-m format] [-N new_passphrase] [-O option]
                  [-t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa]
                  [-w provider] [-Z cipher]

If you do not see the '-sk' option you need to upgrade openssh. Generate a new key using ed25519-sk and it will ask your verification using Yubikey:

$ ssh-keygen -t ed25519-sk -f ~/.ssh/mynewkey
Generating public/private ed25519-sk key pair
You may need to touch your authenticator to authorize key generation.

Just touch the metal circle and it’ll bind the SSH key pair to your Yubikey.

When it says “Enter passphrase (empty for no passphrase)”, you can just press enter to leave it empty. If you use linux, now copy your private key to your server (Windows doesn't support this, you have to do that by hand).

Now when you would ssh to that host it should ask verification:

Categories
Linux

Regenerate Dockerfile from a Docker Image

It may happen that you have accidentally deleted your Dockerfile, or that you want to know how a Docker was built to learn from it. In this case it is useful to see what the Dockerfile looked like, which files have been modified or copied, and which packages have been installed.

With the command below you can easily view the Docker file of an image (run as root):

alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm alpine/dfimage"
dfimage -sV=1.36 nginx:latest

The above commands show the steps from the Dockerfile:

[email protected]:~# alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm alpine/dfimage"
[email protected]:~# dfimage -sV=1.36 nginx:latest
Unable to find image 'alpine/dfimage:latest' locally
latest: Pulling from alpine/dfimage
Status: Downloaded newer image for alpine/dfimage:latest
latest: Pulling from library/nginx
[..]
Status: Downloaded newer image for nginx:latest
Analyzing nginx:latest
Docker Version: 20.10.7
GraphDriver: overlay2
Environment Variables
|PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|NGINX_VERSION=1.21.5
|NJS_VERSION=0.7.1
|PKG_RELEASE=1~bullseye

Open Ports
|80

Image user
|User is root

Potential secrets:
Dockerfile:
CMD ["bash"]
LABEL maintainer=NGINX Docker Maintainers <[email protected]>
ENV NGINX_VERSION=1.21.5
ENV NJS_VERSION=0.7.1
ENV PKG_RELEASE=1~bullseye

COPY file:65504f71f5855ca017fb64d502ce873a31b2e0decd75297a8fb0a287f97acf92 in /
        docker-entrypoint.sh

COPY file:0b866ff3fc1ef5b03c4e6c8c513ae014f691fb05d530257dfffd07035c1b75da in /docker-entrypoint.d
        docker-entrypoint.d/
        docker-entrypoint.d/10-listen-on-ipv6-by-default.sh

COPY file:0fd5fca330dcd6a7de297435e32af634f29f7132ed0550d342cad9fd20158258 in /docker-entrypoint.d
        docker-entrypoint.d/
        docker-entrypoint.d/20-envsubst-on-templates.sh

COPY file:09a214a3e07c919af2fb2d7c749ccbc446b8c10eb217366e5a65640ee9edcc25 in /docker-entrypoint.d
        docker-entrypoint.d/
        docker-entrypoint.d/30-tune-worker-processes.sh

ENTRYPOINT ["/docker-entrypoint.sh"]
EXPOSE 80
STOPSIGNAL SIGQUIT
CMD ["nginx" "-g" "daemon off;"]

[email protected]:~#

To keep it readable I've cut bits out of the output, but I suspect the idea is clear. This cannot be copied 1 on 1, but a Dockerfile can simply be rebuilt on the basis of this.

Categories
Linux

Clear and wipe all docker containers

docker update --restart=no $(docker ps -a -q)
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
Categories
Linux

SPF and DKIM with Postfix

SPF (Sender Policy Framework) record specifies which hosts or IP addresses are allowed to send emails on behalf of a domain. You should allow only your own email server or your ISP’s server to send emails for your domain.

DKIM (DomainKeys Identified Mail) uses a private key to add a signature to emails sent from your domain. Receiving SMTP servers verify the signature by using the corresponding public key, which is published in your DNS manager.

Create SPF record in DNS zone

n your DNS management interface, create a new TXT record like below.

TXT  @   v=spf1 mx ~all

Some DNS managers require you to wrap the SPF record with quotes like below.

TXT  @   "v=spf1 mx ~all"

Keep in mind that it can take up to an hour for the new record to be available.

Configure Postfix for SPF

First, install required packages:

sudo apt install postfix-policyd-spf-python

Edit the Postfix master process configuration file located at /etc/postfix/master.cf. Add these lines to the end:

policyd-spf  unix  -       n       n       -       0       spawn
    user=policyd-spf argv=/usr/bin/policyd-spf

Now open up the configuration file at /etc/postfix/main.cf. Add these lines to the end of the file:

policyd-spf_time_limit = 3600
smtpd_recipient_restrictions =
   permit_mynetworks,
   permit_sasl_authenticated,
   reject_unauth_destination,
   check_policy_service unix:private/policyd-spf

Now restart postfix

sudo systemctl restart postfix

Configure DKIM

sudo apt install opendkim opendkim-tools

Add the Postfix user to the OpenDKIM group

sudo gpasswd -a postfix opendkim

Now open the configuration of OpenDKIM and enable or add these lines:

Canonicalization   simple
Mode               sv
SubDomains         no
AutoRestart         yes
AutoRestartRate     10/1M
Background          yes
DNSTimeout          5
SignatureAlgorithm  rsa-sha256

Go to the end of the file and add these lines:

#OpenDKIM user
# Remember to add user postfix to group opendkim
UserID             opendkim

# Map domains in From addresses to keys used to sign messages
KeyTable           refile:/etc/opendkim/key.table
SigningTable       refile:/etc/opendkim/signing.table

# Hosts to ignore when verifying signatures
ExternalIgnoreList  /etc/opendkim/trusted.hosts

# A set of internal hosts whose mail should be signed
InternalHosts       /etc/opendkim/trusted.hosts

We will need to create the signing table, key table and the trusted hosts file.

sudo mkdir /etc/opendkim
sudo mkdir /etc/opendkim/keys
sudo chown -R opendkim:opendkim /etc/opendkim
sudo chmod go-rw /etc/opendkim/keys

Now create the signing table, using your domain. Open the file and add the second line in it:

sudo nano /etc/opendkim/signing.table
*@bontekoe.technology    default._domainkey.bontekoe.technology

Now create the key table

sudo nano /etc/opendkim/key.table
default._domainkey.bontekoe.technology     bontekoe.technology:default:/etc/opendkim/keys/bontekoe.technology/default.private

Now create the trusted hosts file:

sudo nano /etc/opendkim/trusted.hosts
127.0.0.1
localhost

*.bontekoe.technology

Generating DKIM Keypair

Create a separate folder for the domain.

sudo mkdir /etc/opendkim/keys/bontekoe.technology

Generate keys using opendkim-genkey tool.

sudo opendkim-genkey -b 2048 -d bontekoe.technology -D /etc/opendkim/keys/bontekoe.technology -s default -v
sudo chown opendkim:opendkim /etc/opendkim/keys/bontekoe.technology/default.private

Display the public key that was generated:

sudo cat /etc/opendkim/keys/bontekoe.technology/default.txt

This file contains the entire DNS record that should be published. Copy everything, startking with the v=DKIM1 and in your DNS record. After 15 minutes, test is the record has been successfully published:

sudo opendkim-testkey -d bontekoe.technology -s default -vvv

Result:

opendkim-testkey: using default configfile /etc/opendkim.conf
opendkim-testkey: checking key 'default._domainkey.bontekoe.technology'
opendkim-testkey: key secure
opendkim-testkey: key OK

Connecting Postfix to OpenDKIM

sudo mkdir /var/spool/postfix/opendkim
sudo chown opendkim:postfix /var/spool/postfix/opendkim

Open the configuration file at /etc/opendkim.conf, replace the socket (if defined, or add it):

Socket    local:/var/spool/postfix/opendkim/opendkim.sock

Open /etc/postfix/main.cf and add the following to the end:

# Milter configuration
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters

Now restart Postfix and OpenDKIM:

sudo systemctl restart opendkim postfix

Categories
Linux

Apply Database Partitions to a live Zabbix database – without downtime

Due to the growth of our database (> 1TB), the 'housekeeper' no longer worked properly. The best solution to this problem is to apply Database Partitioning, however with a database of this size this takes a lot of time if you want to keep the data. We tried this action in several ways, the one below was the only way we were able to implement partitioning without downtime.

The example below must be repeated for each table and takes several hours per table.

# Create temporary partition 
CREATE TABLE `history_log_tmp` LIKE `history_log`;
# Apply partitioning
CALL partition_maintenance('zabbix', 'history_log_tmp', 30, 24, 3);

# Rename tables so the new empty table will be used by Zabbix. Leaving the old one as backup
BEGIN;
RENAME TABLE history_log TO history_backup_log;
RENAME TABLE history_log_tmp TO history_log;
COMMIT;

# Output all data from backup table to file
SELECT * INTO OUTFILE '/var/lib/mysql-files/history_backup_log.sql' FROM history_backup_log;

# Open MySQL Shell and start import
mysqlsh
shell.connect('localhost:3306')
util.importTable("/var/lib/mysql-files/history_backup_log.sql", {schema: "zabbix", table: "history_log", columns: ["itemid","clock","value","ns"], dialect: "default", skipRows: 0, showProgress: true, fieldsOptionallyEnclosed: false, linesTerminatedBy: "\n",threads: 2, bytesPerChunk: "50M", maxRate: "10M"})
Categories
Linux

How to Get the Size of all tables in a MySQL Database

SELECT
  TABLE_NAME AS `Table`,
  ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024) AS `Size (MB)`
FROM
  information_schema.TABLES
WHERE
  TABLE_SCHEMA = "zabbix"
ORDER BY
  (DATA_LENGTH + INDEX_LENGTH)
DESC;

Categories
Linux

Mysql Clear Diskspace

When you are running out of diskspace you can purge the MySQL binary logs to free up some space

mysql> PURGE BINARY LOGS BEFORE 'yyyy-mm-dd hh:mm:ss';

Sometimes you are already on 99% disk space and need more drastic methods. This requires manually removing the logfiles.

systemctl stop mysql
cd /var/llog/mysql && a=`ls |grep -v relay |grep bin.index` && b=`wc -l <$a` ; c=`echo $(($b/2))` |xargs -l rm ; echo $c | head -n $b $a |cut -d "/" -f2 && sed 1,$c\d $a -i
systemctl start mysql
Categories
Linux

Check nvme health and temperature – nvme-cli

Make sure nvme-cli is installed:

$ sudo apt install nvme-cli

Check for availible nvme disks:

$ sudo nvme list
Node             SN                   Model                                    Namespace Usage                      Format           FW Rev  
---------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- --------
/dev/nvme0n1     S4EVNFXXXXXXXX9972H      Samsung SSD 970 EVO Plus 500GB           1          26,60  GB / 500,11  GB    512   B +  0 B   2B2XXXXXM7

With nvme-cli you can now check the internal temperature, disk usage, power cycles, and much more:

$ sudo nvme smart-log /dev/nvme0
Smart Log for NVME device:nvme0 namespace-id:ffffffff
critical_warning                    : 0
temperature                         : 40 C
available_spare                     : 100%
available_spare_threshold           : 10%
percentage_used                     : 0%
data_units_read                     : 90935
data_units_written                  : 119679
host_read_commands                  : 4491381
host_write_commands                 : 2370351
controller_busy_time                : 8
power_cycles                        : 34
power_on_hours                      : 9
unsafe_shutdowns                    : 1
media_errors                        : 0
num_err_log_entries                 : 0
Warning Temperature Time            : 0
Critical Composite Temperature Time : 0
Temperature Sensor 1                : 40 C
Temperature Sensor 2                : 38 C
Thermal Management T1 Trans Count   : 0
Thermal Management T2 Trans Count   : 0
Thermal Management T1 Total Time    : 0
Thermal Management T2 Total Time    : 0
Categories
Linux Networking Security

Ubuntu 18.04 – OpenVPN Server in less then 5 minutes

OpenVPN provides flexible VPN solutions to secure your data communications, whether it's for Internet privacy, remote access for employees, securing IoT, or for networking Cloud data centers. Our VPN Server software solution can be deployed on-premises using standard servers or virtual appliances, or on the cloud.

Prepare your system

Make sure all latests packages and updates have been installed:

$ sudo apt update
$ sudo apt upgrade
$ sudo apt dist-upgrade

Download and run installation script

$ wget https://git.io/vpn -O openvpn-install.sh
$ sudo chmod +x openvpn-install.sh
$ sudo ./openvpn-install.sh 

The script will ask you some questions for it's basic configuration.
- When your IP address is asked, choose your WAN (public) address
- When protocol is asked, i recommend default UDP
- Port can be anything you want, i normally keep default
- When asked, pick 1.1.1.1 as your DNS server as this is one of the fastest currently online.

After this the installation will go ahead and inform you when it's done. You can verify if OpenVPN is running or not:

$ sudo systemctl status [email protected] # <--- get server status

You can start or stop OpenVPN with the following commands:

$ sudo systemctl stop [email protected] # <--- stop server
$ sudo systemctl start [email protected] # <--- start server

Client configuration

At the end of the installation you whould see a message like this:

Your client configuration is available at: /root/bontekoe.ovpn

As i am using Linux (Ubuntu) on my laptop, i can simply copy that ovpn file to my computer using scp.

$ sudo scp [email protected]:/root/bontekoe.ovpn /etc/openvpn/client.conf

This should be enough to connect! Check if everything is working by running:

$ sudo openvpn --client --config /etc/openvpn/client.conf

Now, by opening another terminal you should be able to ping 10.8.0.1 (the VPN host).

If you are running windows, there is a client here.

Categories
Linux

Ubuntu 18.04 – Laggy bluetooth

After installing this version my mouse became laggy and also my headphones. Here is the fix:

# HANDLE="$(hcitool con | grep '<Bluetooth Mouse mac address>' | awk '{print $5}')"  # get the device handle
# hcitool lecup --handle $HANDLE --latency 0 --min 6 --max 8