What to do when an HSM token with a large number of stored certificates (or more than one HSM tokens are connected) prevents the SSH agent from using the correct key for SSH authentication on Linux

Many advanced Linux users have been struggling to get rid of one quite annoying situation - the interference between multiple HSM tokens connected to one system. Think about the situation when one token is only needed for SSH authentication and the other token is only needed for S/MIME and web authentication. If each of the tokens contains only one X.509v3 certificate and its private key, things should be fine and in that particular case the command line:

ssh-add -s /usr/lib64/opensc-pkcs11.so

will connect only two of the keys to the SSH agent.

But what if the HSM token hosts four certificates or more than one HSM token is services by the same PKCS#11 library? In that case, during the SSH authentication process, the SSH agent will try the available private keys one after another until the server accepts any of the keys as the proper authentication token. If you have too many keys in the HSM token, the ssh client will be involved in too many authentication attempts, and as a result, the SSH server will terminate the user's authentication. Of course, the latter also depends on the SSH server-side configuration, but the defaults are not in favour of executing multiple key tests.

How to solve this issue?

First, let's start with brining forward the bad news - there exists no definitive resolution in all instances. A workaround is only available. The workaround is not something compex - simply attach the HSM token that contains the key used for SSH authentication before the other HSM tokens, and execute:

ssh-add -s /usr/lib64/opensc-pkcs11.so

Afterwards, you may add as many HSM tokens as you wish to the Linux system. But only the first hinted HSM token will be used to operate with the SSH agent.

Now some details and more information about the process of using HSM tokens for authentication/signing. Read the information below if you are interested in those details.

The X.509v3 certificates get installed inside the HSM protected memory slots along with their private keys. To help the application with the access to that slots, a dedicated PKCS#11 module (library) is needed. In most cases, we employ the PKCS#11 module as a low-level backend in both direction. First, we transfer each X.509v3 certificate along with its private key to the protected memory inside the HMS token, reading that information from PKCS#12 files. Once the keys are stored inside the protected memory of the HSM token, we employ the PKCS#11 module to point the applications to the location of the installed private keys. Note that the applications never obtain direct access to the private keys. Instead, they send some computed hash to the crypto processor inside the HSM token, asking it to sign (encrypt) that hash with a private key with a certain ID (PKCS#12 module communicates those IDs to the application in advance).

Storing multiple keys inside HSM tokens always depends on the token model itself. Some tokens allow the use of multiple slots for signing and authentication, while some do not. The link below shows a good example of tokens that can store multiple X.509v3 certificates in their protected memory:

https://www.cardomatic.de/c/smartcard-hsm

Those brand of tokens can be programmed by using Smart Card Shell 3.

Even though the Yubico PIV tokens are popular, they cannot store multiple X.509v3 certificates and their corresponding private keys. While it is true that those PIV devices come with four slots, each slot has a different purpose, and only one of them can be employed for authentication. Which does not mean Yubico PIV tokens are not as good as the others. They just cannot store more than one certificate/key per dedicated slot. You may try to examine that by running the YubiKey Manager (Ykman) - it shows the four slots and reveals their purpose.

Regardless of the HSM management application, installation of X.509v3 certificates into the HSM tokens does not bring therein the corresponding certificate chains (even if those chains are stored in the original PKCS#12 blocks). The S/MIME client or browser that uses HSM tokens for signing or authentication is responsible for bringing the missing chain certificates into the signing or authentication process. Certificates included in chains are usually installed into special local files accessible and manageable by processing software cryptographic storage. Different programs rely on different file backends for saving and accessing the certificates needed to finish the chains when asked. For instance, Firefox, regardless of the OS environment, always employs Mozilla's NSS Shared DB files for that purpose. While running on Linux, Brave and Chrome for Linux also rely on Mozilla's NSS Shared DB. However, in the event that they are running on Windows, the Windows Certificate Store is utilized as a means of searching for certificates to complete the chain.

If you possess an HSM token that contains more than three X.509v3 certificates installed and accessible through PKCS#11 library, it is not recommended to use that token for SSH authentication. That advice is based on the way the ssh client utilizes the private keys during the authentication process.

What is the good practice to follow when preparing an HSM token, which will be used for SSH authentication only? Store only one certificate, which should be self-signed one. That self-signed X.509v3 certificate must be based on the originally generated SSH key pair stored under the ~/.ssh folder, and should be created and then inserted into the HSM token based on a PKCS#12 file. To create the self-signed certificate, simply run the command line:

openssl req -sha384 -x509 -key ~/.ssh/id_ecdsa -out ~/vesso@ssh-ecdsa.crt -subj "/CN=vesso@ssh-ecdsa" -days 3650

The self-signed certificate will be stored in ~/vesso@ssh-ecdsa.crt. Then compiose the PKCS#12 file:

openssl pkcs12 -export -legacy -key ~/.ssh/id_ecdsa -in ~/vesso@ssh-ecdsa.crt -name "vesso@ssh-ecdsa" -out vesso@ssh-ecdsa.p12

If you want to store that certificate and its private key onto your HSM key, use the appropriate device manager to import the content of the PKCS#12 file into the protected memory of the HSM token. If that is one of the HSM tokens mentioned above, adopt Smart Card Shell 3 for the import. In case you would like to use Yubico PIV token, then rely on the Yukman.

How to fix a problem with running the latest AppImage version of YubiKey Manager on Rocky Linux 9.4

Yubico provides an easy to run YubiKey Manager (Ykman), packed as an AppImage. One can download that image by following the download URL provided at:

https://www.yubico.com/support/download/yubikey-manager/

To obtain and use Ykman as an AppImage, open a terminal window, use wget to download the AppImage file, and then set the right permissions (chmod) for executing it:

wget https://developers.yubico.com/yubikey-manager-qt/Releases/yubikey-manager-qt-latest-linux.AppImage
chmod 755 yubikey-manager-qt-latest-linux.AppImage
./yubikey-manager-qt-latest-linux.AppImage

It may sound easy and convenient. However, if you try running Ykman as an AppImage on Rocky Linux 9.4, the app won't start. This is due to the latest implemented SELinux policy.

To prevent that failure from happening, create a new file called ykman.avc and store inside the following content (as a single line):

type=AVC msg=audit(1717919286.134:498): avc:  denied  { execmod } for  pid=17549 comm="ykman-gui" path=2F6D656D66643A4A4954436F64653A5174516D6C202864656C6574656429 dev="tmpfs" ino=161080 scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:user_tmp_t:s0 tclass=file permissive=0

Afterwards, compile a new module:

sudo audit2allow -M ykman < ykman.avc

and install it:

semodule -i ykman.pp

That should solve the issue.

What to do if Smart Card Shell (scsh) cannot detect HSM tokens connected to RHEL9 or Rocky 9 installation

The HSM management through scsh on RHEL9 (incl Rocky 9) may pose a challenge due to an issue with the manner in which that Linux distribution installs PCSC Lite components. Consequently, neither the scsh command line tool nor scsh3gui are capable of recognizing the HSM tokens that have already been connected to the system.

The problem is caused by the set of libraries that are installed by default when smart card support is enabled on the distribution through the package system. That support implies the installation of libpcsclite.so.1 instead of libpcsclite.so. To make scsh recognize the connected HSM tokens, one should find a way to bring libpcsclite.so into the system, which is required by Java OpenJDK for successful execution of scsh classes.

Now, in greater details. By enabling smart card support, the package management system installs those two packages:

pcsc-lite
pcsc-lite-libs

as well as their dependencies. Here pcsc-lite-libs only provides:

/usr/lib64/libpcsclite.so.1

None of the above provides:

/usr/lib64/libpcsclite.so

At this juncture, it is advised to refrain from creating manually libpcsclite.so as a symlink to libpcsclite.so.1, as it may result in interference with the package system. There is a much more proper way to bring libpcsclite.so to the system:

dnf install pcsc-lite-devel

Installing pcsc-lite-devel just creates the necessary symlink and registers it in the RPM database.

Vivacom's Mobix dual-stack (IPv4/IPv6) LTE router configuration for LTE routers running OpenWRT

This document demonstrates the configuration of a dual-stack (IPv4/IPv6) subscription to Viacom service "Mobix" (Internet home access over LTE) on OpenWRT LTE routers.

Vivacom, which is valid for any other LTE operator in the vicinity, provides its customers outside the big cities with 4G/LTE home routers. They are not without their disadvantages. The biggest disadvantage is the low speed you get if your location is not well covered. Even mounting an external antenna to the router doesn't make the speed go up if the device resides inside a building. Furthermore, the RTT average fluctuates a lot, resulting in a dreadful SSH shell-typing encounter.

The only viable approach to resolving the issues associated with the RTT deviation is to procure a superior 4G/LTE router running OpenWRT that is capable of supporting MIMO. You might also want to get an external MIMO antenna to improve the router's reception and transmission capabilities.

Another benefit of using OpenWRT-based 4G/LTE routers is the possibility of obtaining an IPv6 /64 Internet connectivity for the devices connected to your home network. Vivacom operates a dual-stack IPv4/IPv6 network. It assigns to the external network interface of the customer's LTE router one public IPv4 address and one IPv6 address if the router supports IPv6 subscription. Furthermore, that router is assigned a /64 IPv6 address segment for addressing devices within the internal (home) network. That's a significant step forward in implementing IPv6 at the end-user level. Sadly, most of the routers given to customers are incapable of performing IPv6 LTE subscriptions. The latter is yet another reason to buy and adopt modern OpenWRT LTE routers at home.

The LTE OpenWRT routers provided by Teltonika are very robust and durable devices. I like those devices because they are easy to manage and do not heat up. What I have at home is a pair of RUT-series LTE routers:

RUT241

RUT901

Below, I'm showing how to set up RUT241, but the same procedure works for RUT901. Both have what you need to work with MIMO and IPv6 LTE subscriptions. Note that they are equipped with MIMO antennas by default. If you have a place to mount the antennas, you may want to consider using outdoor LTE antennas to increase signal reception and transmission efficiency. I use this one:

MIMO 4G/5G Log Periodic Antenna

Insert the SIM card into the router and switch it on. Use a browser to connect to the router and set it up initially (if the setup is not done already). Go to "Network" > "Mobile" and set there manually B3 frequency band (that band provides better coverage and higher speed):

Then go to "Status" > "Overview" and set there a profile that uses the "mobix-static" APN (it provides the static IPv4/IPv6 address subscription). In the web interface, go to "Network" > "WAN" and edit the settings for the network interface mob1s1a1. Select "Custom" from the "APN" dropdown menu, then type "mobix-static" into the "Custom APN" text box. Press the "SAVE & APPLY" button to save and apply those settings:

At that moment, the LTE router will re-subscribe to Vivacom's network and obtain its static public IPv4 address. No IPv6 address will be configured at this time. To configure the IPv6 subscription, you need to use the command-line interface for editing the dual-stack subscription settings (the web interface does not offer a menu for managing the IPv6 subscription). Use an SSH client to connect to the router. Then open the file /etc/config/networks and find the entry section for the interface mob1s1a1. Be sure the "pdtptype" is set to "ipv4v6". That's a must-have for requesting a dual-platform subscription. It is recommended that the option 'ipv6' be set to 1.

  config interface 'mob1s1a1'
        option proto 'wwan'
        option modem '1-1'
        option metric '2'
        option sim '1'
        option pdp '1'
        option username 'vivacom'
        option password 'vivacom'
        option auth 'pap'
        option pdptype 'ipv4v6'
        option force_apn '-1'
        option auto_apn '0'
        option apn 'mobix-static'
        option delegate '1'
        option force_link '0'
        option dhcpv6 '0'
        option method 'nat'
        option ipv6 '1'
  

Then save and close the file, and execute:

ifup mob1s1a1

Wait for 10–15 seconds. Afterwards, you will be able to see information about the success of the requested dual-stack configuration on mob1s1a1. Simply execute:

ip addr show

and find there in the output information about the addresses configured on the mobile network interface (in my case, that interface has the name wwan0).

11: wwan0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
    link/none
    inet 95.3.65.17/32 brd 255.255.255.255 scope global wwan0
       valid_lft forever preferred_lft forever
    inet6 2a01:5a8:1a4:14c:6c78:f01f:daf3:4150/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::c965:519:7205:f216/64 scope link stable-privacy
       valid_lft forever preferred_lft forever
12: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:1e:42:4f:74:72 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 brd 192.168.1.255 scope global br-lan
       valid_lft forever preferred_lft forever
    inet6 2a01:5a8:1a4:fff::1/64 scope global noprefixroute
       valid_lft forever preferred_lft forever
    inet6 fdb5:99f7:fdfa::1/60 scope global noprefixroute
       valid_lft forever preferred_lft forever
    inet6 fe80::21e:42ff:fe4f:7472/64 scope link
       valid_lft forever preferred_lft forever

Pay attention to the configuration shown. The public IPv4 is assigned to the interface wwan0. The same interface has a dynamically generated IPv6 address that isn't fixed (static). In fact, you get a static IPv6 subnet—the one that is configured on the LAN interface. Which means that your static IPv6 address on the LTE router is 2a01:5a8:1a4:fff::1/64 (assigned to br-lan), not 2a01:5a8:1a4:14c:6c78:f01f:daf3:4150 (assigned to wwan0).

What's left is to enable DHCP6 and router advertising in the home network (connect to the br-lan interface of the LTE router). That is necessary if the device connected to the home network should be given an IPv6 address and an IPv6 default route. Open the file /etc/config/dhcp and add to the "config dhcp lan" section the following set of instructions:

  
    option dhcpv6 server
    option ra server
    option ra_flags 'managed-config other-config'
  

Finally, restart the router and enjoy the dual-stack connectivity.


Using OpenSSL "ec" tool to encrypt the just-generated EC keys with ciphers stronger than 3DES

It is considered prudent to store the EC keys securely, to prevent OpenSSL library and tools from writing the keys unencrypted to the local file system. While it is possible to encrypt the generated key afterwards, it is considered important to prevent the key from appearing in its unencrypted form in any file. Such disclosure of the key will definitely occur if openssl ecparam -genkey is used with -out (that implies storing the unencrypted key in a file). The root cause of the issue is due to the inability to enable password protection when openssl ecparam -genkey is invoked to generate EC keys. That inability is what makes necessary the subsequent use of the "ec" tool to encrypt the generated EC keys. On the other side, the OpenSSL man pages that come with the OpenSSL installation on Red Hat Enterprise Linux 8/9 (and its derivatives), do not mention the use of a cipher other than 3DES with "ec". This ambiguity causes considerable confusion. This short post explains how to use strong AES encryption to protect the just-generated EC key with a password.

Generate an EC key, but instead of storing the result in a file, send it to the "ec" tool. Even if both the help information and man page of "ec" do not provide any information on how to request AES encryption, specify the corresponding AES cipher in the command line:

openssl ecparam -genkey -name secp384r1 | openssl ec -aes-256-cbc -out my.key

But can we employ a cipher different than 3DES and aes-256-cbc? You can answer that question by checking what is supported by your OpenSSL installation. To do that just type:

openssl --help

and analyze the output. For example, the following ciphers are supported on Red Hat Enterprise Linux 9:

aes-128-cbc       aes-128-ecb       aes-192-cbc       aes-192-ecb       
aes-256-cbc       aes-256-ecb       aria-128-cbc      aria-128-cfb      
aria-128-cfb1     aria-128-cfb8     aria-128-ctr      aria-128-ecb      
aria-128-ofb      aria-192-cbc      aria-192-cfb      aria-192-cfb1     
aria-192-cfb8     aria-192-ctr      aria-192-ecb      aria-192-ofb      
aria-256-cbc      aria-256-cfb      aria-256-cfb1     aria-256-cfb8     
aria-256-ctr      aria-256-ecb      aria-256-ofb      base64            
bf                bf-cbc            bf-cfb            bf-ecb            
bf-ofb            camellia-128-cbc  camellia-128-ecb  camellia-192-cbc  
camellia-192-ecb  camellia-256-cbc  camellia-256-ecb  cast              
cast-cbc          cast5-cbc         cast5-cfb         cast5-ecb         
cast5-ofb         des               des-cbc           des-cfb           
des-ecb           des-ede           des-ede-cbc       des-ede-cfb       
des-ede-ofb       des-ede3          des-ede3-cbc      des-ede3-cfb      
des-ede3-ofb      des-ofb           des3              desx              
idea              idea-cbc          idea-cfb          idea-ecb          
idea-ofb          rc2               rc2-40-cbc        rc2-64-cbc        
rc2-cbc           rc2-cfb           rc2-ecb           rc2-ofb           
rc4               rc4-40            rc5               rc5-cbc           
rc5-cfb           rc5-ecb           rc5-ofb           seed              
seed-cbc          seed-cfb          seed-ecb          seed-ofb          
zlib  

If you're moving a file with an encrypted EC key from one system to another, make sure that the OpenSSL installation there supports the cipher you used. Otherwise, the EC key won't be decrypted.


How to enable the screen/window sharing (screen casting) on Rocky Linux 9 (GNOME)

By default (fresh installation of the distribution and the apps) the desktop applications available on Rocky Linux 9 (GNOME desktop) cannot share the entire screen, a window, or a browser tab.

That problem appears due to a combination of a missing package (xdg-desktop-portal-gnome), which might not be installed by default, and systemd services (xdg-desktop-portal and/or pipewire), which are either missing or not enabled.

To solve the issue you need to install xdg-desktop-portal-gnome

sudo dnf -y install xdg-desktop-portal-gnome

and enable/start/restart the required services (as user):

systemctl --user enable --now pipewire
systemctl --user restart xdg-desktop-portal.service

Opening a collection of build recipes for compiling software for simulations and data analysis (HPC-related)

Those build recipe prototypes are siple bash scripts but they could be easily converted into Jenkins jobs:

https://gitlab.discoverer.bg/vkolev/recipes

Creative Commons - Attribution 2.5 Generic. Powered by Blogger.

Implementing LUKS Encryption on Software RAID Arrays with LVM2 Management

A comprehensive guide to partition-level encryption for maximum security ...

Search This Blog

Translate