Kushal Das

FOSS and life. Kushal Das talks here.


Securing via systemd, a story

Last night I deployed a https://writefreely.org based blog and secured it with systemd by adding DynamicUser=yes. But the service itself could not write to the sqlite database.

Feb 28 21:37:52 kushaldas.se writefreely[1652088]: ERROR: 2024/02/28 21:37:52 database.go:3000: Couldn't insert into posts: attempt to write a readonly database

Today morning I realized that the settings blocked writing to all paths except few temporary ones. I had to add a StateDirectory and used the same in WorkingDirectory so that the service works correctly.

Mullvad VPN repository for Fedora

desktop client

Mullvad VPN now has proper rpm repository for their desktop client. You can use it in the following way on you Fedora system:

sudo dnf config-manager --add-repo https://repository.mullvad.net/rpm/stable/mullvad.repo
sudo dnf install mullvad-vpn

Remember to verify the OpenPGP key Fingerprint:

Importing GPG key 0x66DE8DDF:
 Userid     : "Mullvad (code signing) <admin@mullvad.net>"
 Fingerprint: A119 8702 FC3E 0A09 A9AE 5B75 D5A1 D4F2 66DE 8DDF
 From       : https://repository.mullvad.net/rpm/mullvad-keyring.asc

django-ca, HSM and PoC

django-ca is a feature rich certificate authority written in Python, using the django framework. The project exists for long, have great documentation and code comments all around. As I was looking around for possible CAs which can be used in multiple projects at work, django-ca seems to be a good base fit. Though it has still a few missing parts (which are important for us), for example HSM support and Certificate Management over CMS.

I started looking into the codebase of django-ca more and meanwhile also started cleaning up (along with Magnus Svensson) another library written at work for HSM support. I also started having conversion with Mathias (who is the author of django-ca) about this feature.

Thanks to the amazing design of the Python Cryptography team, I could just add several Private key implementations in our library, which in turn can be used as a normal private key.

I worked on a proof of concept branch (PoC), while getting a lot of tests also working.

===== 107 failed, 1654 passed, 32 skipped, 274 errors in 286.03s (0:04:46) =====

Meanwhile Mathias also started writing a separate feature branch where he is moving the key operations encapsulated inside of backends, and different backends can be implemented to deal with HSM or normal file based storage. He then chatted with me on Signal over 2 hours explaining the code and design of the branch he is working on. He also taught me many other django/typing things which I never knew before in the same call. His backend based approach makes my original intention of adding HSM support very easy. But, it also means at first he has to modify the codebase (and the thousands of test cases) first.

I am writing this blog post also to remind folks that not every piece of code needs to go to production (or even merged). I worked on a PoC, that validates the idea. And then we have a better and completely different design. It is perfectly okay to work hard for a PoC and later use a different approach.

As some friends asked on Mastodon, I will do a separate post about the cleanup of the other library.

Documentation of Puppet code using sphinx

Sphinx is the primary documentation tooling for most of my projects. I use it for the Linux command line book too. Last Friday while in a chat with Leif about documenting all of our puppet codebase, I thought of mixing these too.

Now puppet already has a tool to generate documentation from it's code, called puppet strings. We can use that to generate markdown output and then use the same in sphix for the final HTML output.

I am using https://github.com/simp/pupmod-simp-simplib as the example puppet code as it comes with good amount of reference documentation.

Install puppet strings and the dependencies

$ gem install yard puppet-strings

Then cloning puppet codebase.

$ git clone https://github.com/simp/pupmod-simp-simplib

Finally generating the initial markdown output.

$ puppet strings generate --format markdown --out simplib.md
Files                     161
Modules                   3 (3 undocumented)
Classes                   0 (0 undocumented)
Constants                 0 (0 undocumented)
Attributes                0 (0 undocumented)
Methods                   5 (0 undocumented)
Puppet Tasks              0 (0 undocumented)
Puppet Types              7 (0 undocumented)
Puppet Providers          8 (0 undocumented)
Puppet Plans              0 (0 undocumented)
Puppet Classes            2 (0 undocumented)
Puppet Data Type Aliases  73 (0 undocumented)
Puppet Defined Types      1 (0 undocumented)
Puppet Data Types         0 (0 undocumented)
Puppet Functions          68 (0 undocumented)
 98.20% documented

sphinx setup

python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install sphinx myst_parser

After that create a standard sphinx project or use your existing one, and update the conf.py with the following.

extensions = ["myst_parser"]
source_suffix = {
    '.rst': 'restructuredtext',
    '.txt': 'markdown',
    '.md': 'markdown',

Then copy over the generated markdown from the previous step and use sed command to update the title of the document to something better.

$ sed -i '1 s/^.*$/SIMPLIB Documenation/' simplib.md

Don't forget to add the simplib.md file to your index.rst and then build the HTML documentation.

$ make html

We can still improve the markdown generated by the puppet strings command, have to figure out simpler ways to do that part.

Example output

SBOM and vulnerability scanning

Software Bill of Materials became one of the latest buzzword. A lot of people and companies talking about it like a magical thing, if you use it then all of your security problems will be solved, just like what happened with Blockchain!!.

Though a hand full of projects (or companies building those projects) focused on the actual tooling part. Things we can use and see some useful output than blogposts/presentations with fancy graphics.

In this post we will try to see how can we use these tools today (2023/09/20).

SBOM currently comes in two major flavors, SPDX aka Software Package Data Index and CycloneDX. There are existing tooling to convert in between.


We will use syft from Anchore to generate our SBOM(s).

This tool can generate from various sources, starting from container images to Python projects, RPM/Debian dbs, Rust or Go projects.

Let us generate the SBOM for a Debian 12 VM.

$ syft /var/lib/dpkg -o spdx-json=server.spdx.json --source-name debian12 
 ✔ Indexed file system                                                                                         /var/lib/dpkg
 ✔ Cataloged packages              [395 packages]  

For for a Rust project:

$ syft /home/kdas/code/johnnycanencrypt/Cargo.lock -o spdx-json=jce.spdx.json
 ✔ Indexed file system                                                                      /home/kdas/code/johnnycanencrypt
 ✔ Cataloged packages              [203 packages]

We generated the SBOMs. Now this should solve the security issues, isn't?

SBOM joke

I found the above in Matthew Martin's timeline.


This is where Grype comes handy, it is a vulnerability scanner for container images and filesystems and works with the SBOM(s) generated by syft.

$ grype jce.spdx.json 
 ✔ Vulnerability DB                [updated]  
 ✔ Scanned for vulnerabilities     [1 vulnerability matches]  
   ├── by severity: 0 critical, 0 high, 1 medium, 0 low, 0 negligible
   └── by status:   1 fixed, 0 not-fixed, 0 ignored 
time  0.1.45     0.2.23    rust-crate  GHSA-wcg3-cvx6-7396  Medium


grype server.spdx.json 
 ✔ Vulnerability DB                [no update available]  
 ✔ Scanned for vulnerabilities     [178 vulnerability matches]  
   ├── by severity: 6 critical, 136 high, 34 medium, 2 low, 0 negligible
   └── by status:   0 fixed, 178 not-fixed, 0 ignored 
file     1:5.44-3                      CVE-2007-1536     High      
git      1:2.39.2-1.1                  CVE-2020-5260     High      
gnupg    2.2.40-1.1                    CVE-2022-3515     Critical  
gnupg    2.2.40-1.1                    CVE-2022-34903    Medium    
gnupg    2.2.40-1.1                    CVE-2022-3219     Low       
openssl  3.0.9-1                       CVE-2023-4807     High      
openssl  3.0.9-1                       CVE-2023-3817     Medium    
openssl  3.0.9-1                       CVE-2023-2975     Medium    
openssl  3.0.9-1                       CVE-2023-1255     Medium    
perl     5.36.0-7                      CVE-2023-31486    High      
perl     5.36.0-7                      CVE-2023-31484    High      
vim      2:9.0.1378-2                  CVE-2022-3520     Critical  
vim      2:9.0.1378-2                  CVE-2022-0318     Critical  
vim      2:9.0.1378-2                  CVE-2017-6350     Critical  
vim      2:9.0.1378-2                  CVE-2017-6349     Critical  
vim      2:9.0.1378-2                  CVE-2017-5953     Critical  
vim      2:9.0.1378-2                  CVE-2023-4781     High      
vim      2:9.0.1378-2                  CVE-2023-4752     High      


Now it is on your team members to decide how to react to information we gather from these tools. The tools themselves will not solve the problems at hand. You have to decide the update steps and if that is at all required or not.

Also please remember, there is and will be a lot of false positives (not in Grype output yet, but other tools in the SBOM ecosystem). The projects (I am talking about in general most of the tooling in this field) are trying hard to reduce these, but not possible always to remove every such edge case.