Trace the actions performed by a sudoer.

1. Install the auditd package.

apt install auditd

2. Configure the rules.

auditctl -a always,exit -F arch=b64 -F euid=$(id -u user3) -F auid!=$(id -u user3) -S execve -k actions_as_user3
auditctl -a always,exit -F arch=b64 -F euid=$(id -u user4) -F auid!=$(id -u user4) -S execve -k actions_as_user4

3. List the rules.

auditctl -l

4. Add the rules permanently. The restart of the auditd service will re-read the rules from the configuration file.

echo "-a always,exit -F arch=b64 -F euid=$(id -u user3) -F auid!=$(id -u user3) -S execve -k actions_as_user3" >>/etc/audit/rules.d/user3_sudo.rules
echo "-a always,exit -F arch=b64 -F euid=$(id -u user4) -F auid!=$(id -u user4) -S execve -k actions_as_user4" >>/etc/audit/rules.d/user4_sudo.rules

5. Show the logs.

ausearch -k actions_as_user3 -i
ausearch -k actions_as_user4 -i

BONUS!!!

6. Send the log to stackdriver. If the OP agent is already active in your GCP compute engine, add the following to the file /etc/google-cloud-ops-agent/config.yaml

logging:
receivers:
auditd:
type: files
include_paths:
- /var/log/audit/audit.log
# optionally parse lines, assign severity, etc.
service:
pipelines:
audit_pipeline:
receivers: [auditd]

7. Restart the service.

service google-cloud-ops-agent restart

Install Windows 11 VM (guest) on Debian 13 Trixie (host)

VirtualBox is not available on Debian 13 Trixie, so I’m using KVM + QEMU + virt-manager this time.

1. Install required packages

sudo apt update

sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager

2. Add user to the group(s).

sudo usermod -aG libvirt $(whoami)

sudo usermod -aG kvm $(whoami)

Log out and log in so that the new groups are in effect.

3. Download the Windows ISO.

Download the Windows 11 ISO from https://www.microsoft.com/software-download/windows11

4. Create a new VM using virt-manager.

RAM: 6GB
CPU: 4
DISK: 64GB
Enable shared memory: checked
Video: Model=Virtio
3D acceleration = unchecked
SATA CDROM 1: Source path = <location of the downloaded Windows ISO>

Begin installation.

5. Auto start the virtual network.

Go to Virt-manager -> Edit -> Connection Details, check “Autostart: On Boot” for every network.

6. Enable a shared folder between Linux host and Windows guest.

Install additional packages:

sudo apt install qemu-system qemu-utils libvirt-daemon virt-manager virtiofsd

Set up a shared folder:

mkdir -p ~/winshare

chmod 777 ~/winshare

Configure the shared directory in virt-manager:

virt-manager -> Add Hardware -> Filesystem
Driver: virtiofs
Source path: ~/winshare
Target path: winshare

Start up the Windows guest. Install the WinFsp by downloading the installer from the following site:

https://winfsp.dev/rel/

Download the latest virtio-win ISO from the following site:

https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/

Mount the ISO (assume it is mounted at drive D), then install all drivers provided in it by running the following application:

D:\virtio-win-gt-x64.msi

Reboot the Windows guest. Once rebooted, run the following command to enable Windows guest to access the shared folder in the Linux host:

"C:\Program Files\Virtio-Win\VioFS\virtiofs.exe"

The above application will not exit by itself. When it runs, the shared folder shows up as Z: drive in my Windows guest. Use ctrl+c if you want to stop it. Once stopped, the Z: drive will be gone and the shared folder will not be accessible. The above command needs to be run every time the Windows guest starts up. Add it to the scheduler and run upon log in?

7. Enable two-ways copy/paste.

Run the following installer in the virtio ISO image:

D:\virtio-win-guest-tools.exe

Use sftp like scp

scp a.txt user@host:/folder/

Many system may not permit the use of scp, but only sftp. So the equivalent one liner is:

sftp user@host:/folder/ <<<"put a.txt"

See here https://askubuntu.com/questions/678915/whats-the-difference-between-and-in-bash for an explanation for <<<. TLDR; It’s like a single line <<EOF construct.

Removing docker builder cache

My laptop ran out of disk space after failing to build a docker image multiple times.

[~] docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 23 1 14.05GB 11.03GB (78%)
Containers 1 1 243MB 0B (0%)
Local Volumes 0 0 0B 0B
Build Cache 1190 0 41.44GB 41.44GB

The command above show there was over 40GB of cache. To remove them, use the following command:

docker builder prune

Then let’s check the disk space used by docker again.

[~] docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 23 1 14.05GB 11.03GB (78%)
Containers 1 1 243MB 0B (0%)
Local Volumes 0 0 0B 0B
Build Cache 141 0 0B 0B

ProFTPd with Virtual Users

Install the required packages

apt update
apt install proftpd-core proftpd-mod-crypto

Modify the “/etc/proftpd/modules.conf” by uncomment the following line

LoadModule mod_sftp.c

Modify the “/etc/proftpd/proftpd.conf” by uncomment the following lines. Please note, there is a space between the ‘DefaultRoot’ and the ‘~’. Also, between ‘RequireValidShell’ and ‘off’.

DefaultRoot ~
AuthUserFile /etc/proftpd/ftpd.passwd
AuthOrder mod_auth_file.c
RequireValidShell off
Include /etc/proftpd/sftp.conf

Modify the “/etc/proftpd/sftp.conf” by uncomment the following lines.

SFTPEngine     on
Port           2222
SFTPLog        /var/log/proftpd/sftp.log
SFTPHostKey /etc/ssh/ssh_host_rsa_key
SFTPAuthMethods publickey password
SFTPAuthorizedUserKeys file:/etc/proftpd/authorized_keys/%u
SFTPCompression delayed

Create the home directories for the virtual users.

mkdir -p /home/ftpusers/user1
chown -R proftpd:nogroup /home/ftpusers

Set up public key authentication.

ssh-keygen -e -f /user1/public/key/id_rsa.pub >/etc/proftpd/authorized_keys/user1

Set up password. Skip this if not needed.

ftpasswd --passwd \
                 --file=/etc/proftpd/ftpd.passwd \
                 --name=user1 \
                 --uid=`id -u proftpd` \
                 --gid=`id -g proftpd` \
                 --home=/home/ftpusers/user1 \
                 --shell=/bin/false

ldapsearch with custom ca certificate

A quick workaround is to tell ldapsearch to stop validating certificate:

export LDAPTLS_REQCERT=ALLOW
ldapsearch -H ldaps://$LDAP_HOST:636 \
           -b 'DC=example,DC=ad' \
           -D 'CN=SVC_USER,OU=SERVICE ACCOUNTS,DC=example,DC=ad' \
           -w 'somepassword' \
           -v \
           -d3 \
           SAMaccountName=someUserId

To support the custom ca certificate, we need to add it to the system list of trusted ca:

cp custom-ca.pem /usr/share/ca-certificates/custom-ca.crt
echo "custom-ca.crt" >>/etc/ca-certificates.conf
update-ca-certificates

The custom ca certificate will be added to /etc/ssl/certs and the content will be added to the file ca-certificates.crt

Looks like, it is also possible to ask `ldapsearch’ to make use of a custom ca certificate without adding it to the system list:

export LDAPTLS_CACERT=/somewhere/custom-ca.crt
ldapsearch -H ldaps://$LDAP_HOST:636 \
           -b 'DC=example,DC=ad' \
           -D 'CN=SVC_USER,OU=SERVICE ACCOUNTS,DC=example,DC=ad' \
           -w 'somepassword' \
           -v \
           -d3 \
           SAMaccountName=someUserId

Retrieve SSL Certificate

User the following command to retrieve the SSL connection info and the certificate (or the chain of certificates).

openssl s_client -showcerts -connect <ip or fqdn>:443 </dev/null

For example:

$ openssl s_client -showcerts -connect www.google.com:443
CONNECTED(00000003)
depth=2 C = US, O = Google Trust Services LLC, CN = GTS Root R1
verify return:1
depth=1 C = US, O = Google Trust Services, CN = WR2
verify return:1
depth=0 CN = www.google.com
verify return:1
---
Certificate chain
 0 s:CN = www.google.com
   i:C = US, O = Google Trust Services, CN = WR2
-----BEGIN CERTIFICATE-----
MIIEVzCCAz+gAwIBAgIRAIqsaBCWH6ZQEKoBk/n97LUwDQYJKoZIhvcNAQELBQAw
OzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczEM
MAoGA1UEAxMDV1IyMB4XDTI0MDYxMzE2MzYxMFoXDTI0MDkwNTE2MzYwOVowGTEX
MBUGA1UEAxMOd3d3Lmdvb2dsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
AASzwPkkuZT4PPFgs05Jg8aq/OC8uvz04joHeDtY2qte3Tmy/LquWRvnCge545pE
WHvAxtpwY4bhcaj5SuW+c5Pco4ICQTCCAj0wDgYDVR0PAQH/BAQDAgeAMBMGA1Ud
JQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFKfXg0H+37Xh
MsEQ2PSCM6wR6wctMB8GA1UdIwQYMBaAFN4bHu15FdQ+NyTDIbvsNDltQrIwMFgG
CCsGAQUFBwEBBEwwSjAhBggrBgEFBQcwAYYVaHR0cDovL28ucGtpLmdvb2cvd3Iy
MCUGCCsGAQUFBzAChhlodHRwOi8vaS5wa2kuZ29vZy93cjIuY3J0MBkGA1UdEQQS
MBCCDnd3dy5nb29nbGUuY29tMBMGA1UdIAQMMAowCAYGZ4EMAQIBMDYGA1UdHwQv
MC0wK6ApoCeGJWh0dHA6Ly9jLnBraS5nb29nL3dyMi9vUTZueXI4RjBtMC5jcmww
ggEEBgorBgEEAdZ5AgQCBIH1BIHyAPAAdQDuzdBk1dsazsVct520zROiModGfLzs
3sNRSFlGcR+1mwAAAZASq96AAAAEAwBGMEQCIF0BgHtwtoqA6X18zVH6sYYyyhni
cXBDQgA9wfvq5kPgAiBcHdmtOY6nbbsy3GWEP4sfv1h/DEPvBVzMpv3gpStbqAB3
ABmYEHEJ8NZSLjCA0p4/ZLuDbijM+Q9Sju7fzko/FrTKAAABkBKr320AAAQDAEgw
RgIhAPEBlTmc8mrI2oSakd7k9MKLX6RyHoSsxk8D34M5WqEEAiEA7kc1n9FYz3S7
qR+sHO2f9iDusdyTw0yA7uWAJWTPvyIwDQYJKoZIhvcNAQELBQADggEBAID3ckhU
DZKjJ9AoC5C+hozFh1x9AQIAFC0QzsST0bBk4ebxr9+TMfY7ZY+ky/azqtzAACrN
r/FDm7ZEMc8DC7VhU0O9fxIJZ8YvuJIlZhHmHdblQG4iOGoX6nUWw8sLroD3F72Q
5bCcwY+6+EWEQls/FTOITLAO3Oy+f/d7mzdwH8fYQ06ZMifjZWopD4CTHZkwG1P2
jRgVQo035fPqpE0ntHYxgda4mCG40c8Ayq3oeu5sV32FsUmRqF0ph6Ved7VcAknp
D8wj7FTuyGpo/JdNZYivMrluppafDreKfcHLBIhxK23fQIhvLwxdamzFnAnMh5mS
Qnb3r1lsDR4GUAs=
-----END CERTIFICATE-----
 1 s:C = US, O = Google Trust Services, CN = WR2
   i:C = US, O = Google Trust Services LLC, CN = GTS Root R1
-----BEGIN CERTIFICATE-----
MIIFCzCCAvOgAwIBAgIQf/AFoHxM3tEArZ1mpRB7mDANBgkqhkiG9w0BAQsFADBH
MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjMxMjEzMDkwMDAwWhcNMjkwMjIw
MTQwMDAwWjA7MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVR29vZ2xlIFRydXN0IFNl
cnZpY2VzMQwwCgYDVQQDEwNXUjIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
...

Import PGP private key.

Try to import a PGP private key and got the following error:

root@debian:~/vms# gpg --import privateKey.asc 
gpg: key 78E100CF64CB8443: 1 bad signature
gpg: sig issued by 78E100CF64CB8443 with class 3 (digest: 15 d6) is not valid over a user id or a key id, ignoring.
gpg: key 78E100CF64CB8443: new key but contains no user ID - skipped
gpg: key 78E100CF64CB8443: failed to re-lookup public key: No public key
gpg: error reading 'privateKey.asc': No public key
gpg: import from 'privateKey.asc' failed: No public key
gpg: Total number processed: 0
gpg:           w/o user IDs: 1
gpg:       secret keys read: 1
root@debian:~/vms# 

Using the pgpdump to check the key content:

root@debian:~/vms# pgpdump privateKey.priv 
[...snipped...]
Old: Signature Packet(tag 2)(303 bytes)
	Ver 4 - new
	Sig type - unknown(03)
	Pub alg - RSA Sign-Only(pub 3)
	Hash alg - SHA256(hash 8)
	Hashed Sub: signature creation time(sub 2)(4 bytes)
		Time - Thu Jun  2 16:17:25 +08 2022
[...snipped...]

The “Sig type – unknown(03)” is probably the reason for the import failure. To workaround the issue, use the “–allow-non-selfsigned-uid” option:

root@debian:~/vms# gpg --import --allow-non-selfsigned-uid privateKey.asc 
gpg: key 78E100CF64CB8443: 1 bad signature
gpg: sig issued by 78E100CF64CB8443 with class 3 (digest: 15 d6) is not valid over a user id or a key id, ignoring.
gpg: key 78E100CF64CB8443: accepted non self-signed user ID "abc@gmail.com"
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key 78E100CF64CB8443: public key "abc@gmail.com" imported
gpg: key 78E100CF64CB8443: secret key imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg:       secret keys read: 1
gpg:   secret keys imported: 1
root@debian:~/vms# 

Verify key, certificate and CSR matches.

$ openssl x509 -noout -modulus -in CERTIFICATE.crt | openssl md5
$ openssl req -noout -modulus -in CSR.csr | openssl md5
$ openssl rsa -noout -modulus -in PRIVATEKEY.key | openssl md5

The output should be the same if they PRIVATE.key is used to generate the CSR.csr and the corresponding CERTIFICATE.crt

Add subtitle to a movie file

ffmpeg -i 'movie.mp4' \
       -f srt -i  'movie.srt' \
       -map 0:0 -map 0:1 -map 1:0 -c:v copy -c:a copy \
       -c:s srt 'movie.mkv'
Design a site like this with WordPress.com
Get started