Here is my webpage if you wish to see the README in web form - https://laoluadewoye.github.io/PKI_Practice_Python/
Hi! This Project is under development. Back in version 0, I was talking about how I spent most of the time just planning and writing notes and making sure everything is laid out before me before actually doing code. Back in version 1, I then focused mainly on setting up the automation with GitHub actions, creating releases, tightening up deployment environments, and then finally developing some of the actual classes I need for the project.
We are now in version 2! I have a working network (without all the communication yet) and it is fully realized, tested, and ready for several versions of Python. It was a pain to get it all together, but we are full steam ahead on code! One of my main goals is to "get it right the first time." Even if I wind up working in a place that prides itself on CI, being able to fully realize a project without mistakes is just satisfying as heck, and has forced me to learn alot more about programming than I knew just a month ago.
For now, here is a basic idea of the project. I wanted to learn PKI architecture, how it's used, and do that while doing some more advanced stuff with the project in Python. The final goal for the program is that, given a configuration file in one of the supported formats, it would create a simulation of a network of Certificate Authorities and End-Certificate devices where communication between end devices are encrypted, signed, and supported by a Public Key Infrastructure. The supported formats are YAML, JSON, TOML, and XML. The final output of this program is a CSV log file saved in a dedicated "output" folder, but during it's run time you should be able to view all the action printed out in the terminal (and maybe even a GUI once I finish the program itself).
This program is developed in Python 3.12, but has support for Python 3.8-3.14. Currently, the only drawback is that any interpreter that is earlier than Python 3.10 is unable to use YAML files for configuration, and will have to use one of the other three supported formats. The code will let you know that.
Use the NOTES.md file to get a deeper idea about what this project is about, and the CONFIG_GUIDE.md file to understand how to create the configuration files yourself.
Below are basic instructions on how to install the project and use it, whether that be from the command line, a Python IDE, or a Docker container. As you can see, I put alot of work into making this easy for future me and anyone else. "It runs on my laptop," amirite?
Also, for a sense of structure, auto configurations create the underlying environment, and manual configurations are to specify the information about specific authorities and end devices. Always pass the autoconfiguration first, or else it will yell at you. The manual configuration is optional if you don't want to use customization.
The instructions below does assume you know what Python, Pip, IDEs, and Docker are.
You can download the repo from GitHub and work with the project in your desired IDE. PKIPractice has a file called RunConfig.py which can be used to run the program. However, if you wish to use the installed command line program, then the following sections show you how to install to either your local environment or a docker image storage.
pip install PyPkiPractice
docker pull laoluade/pypkipractice:latest
No worries! There are some options you can pass instead of the files I use for examples below.
-h
or--help
: Get help on how to use the program.-d
or--default
: Run the program using a default configuration built into the program.
There is also a folder of default configurations added to the project called "Default_Configs." In it, are annotated examples of autoconfiguration and manual configuration files in JSON, YAML, TOML, and XML. You can pass those files as arguments and experiment with them to your heart's content.
Other options you can pass into the program are-
-t
or--test
: Run the program in test mode, which caps what parts of the program run to only the ones needed for automated testing. You can try it, but it's really only for use in pytest and nox.
Command Structure: python PKIPractice/RunConfig.py (arguments)
Command Example: python PKIPractice/RunConfig.py config_files/config_auto.json config_files/config_manual.json
If you're in an IDE, chances are you can just set up a run configuration in your app. Make sure to add arguments in whatever field you need as I told my program to yell at you if you don't.
Command Structure: run-pki-practice (arguments)
Command Example: run-pki-practice config_files/config_auto.json config_files/config_manual.json
If you have docker installed, you are able to run the program as a container without installing anything. However, to see the output yourself on your local storage, you will have to do a few extra things.
First, there is running the docker container "naked" without any additional options passed to the run command.
Command Structure: docker run laoluade/pypkipractice:(tag)
Command Example: docker run laoluade/pypkipractice:latest
The docker container is automatically to use the "--default" option if no arguments are passed to the container environment. This way, you are able to see the example of what it would look like for the program to run.
Next, there is mounting a folder as a volume to the docker. This way, you can save the CSV log file locally and access it.
By default, the docker container is configured to create an output
folder on build. This way, the simplest way to
save information is to first connect a volume to the /usr/local/app/output
directory that the container operates in.
Command Structure: docker run -v (docker_volume):/usr/local/app/ laoluade/pypkipractice:(tag)
Let's say for example, that you want to create a persistent volume called "output" you would want to save the output. Use the following command:
Command Example: docker run -v output:/usr/local/app/output laoluade/pypkipractice:latest
Afterward, you can then get the name of the container that was created to run the pypkipractice image and use that to copy the results to your local computer.
First, get the list of containers you have:
Command Example: docker ps -a
Then, Use the name of your desired container below:
Command Example: docker cp container_name:/usr/local/app/output/saved_network_logs.csv .
If you get an error saying that the volume is inaccessible due to it not being used, you can run a container like
busybox to list its data, or start it up again with the docker start
command which should keep the volume alive a bit
longer, so you can try the cp command again. A better tutorial is available by
GeeksForGeeks.
Lastly, there is mounting a local folder that also contains configuration files for the program that you want to send
into the container. The strategy is the same, but for safety, made the container folder a subdirectory of the app
directory. You can even write the log filepath in a way where the log saves in the subdirectory, making it accessible
to you on your hard drive. To access it, your best bet would be binding to a volume that exists on build, like app or
output
Command Structure: docker run -v {local_config_folder_path}:/usr/local/app/{container_config_folder_path} laoluade/pypkipractice:(tag) (arguments)
Let's say that you had a folder called config_files, which had a file called config_auto.json and config_manual.json. You wished to expose this information to the docker container, so you can run your own custom configuration.
Command Example: docker run -v config_files:/usr/local/app/config_files laoluade/pypkipractice:latest config_files/config_auto.json config_files/config_manual.json
In this example-
- "docker run" is the basic subcommand that will be used to run the chosen image.
- The "-v" flag is used to mount the local config folder as a volume to the container's config folder.
- "config_files" is the name of the local config folder.
- "/usr/local/app/config_files" is the path to the container's config folder.
- The container is run in /usr/local/app, so be cognisant of that when deciding where to mount your files.
- "laoluade/pypkipractice:latest" is the name of the image you would pull.
- "latest" is the tag of the image you would pull, which defaults to the most recent image in the repo.
- The last part of the command is the arguments you passed to the command line after stating your image. The container
will take care of handling the arguments for you. Filepaths must be from the perspective of the container working in
the app directory.
- "config_files/config_auto.json" is the path to the autoconfiguration file.
- "config_files/config_manual.json" is the path to the manual configuration file.
Here is a table comparing how each strategy compares. These are my opinions of how easy it would be for someone to use an option if they didn't have any experience. I hope this table helps you decide which one to try.
Metric | Python Interpreter | Installed CLI | Docker Container |
---|---|---|---|
GUI App Usage | Best | Worst | Medium |
Simple to Use | Best | Best | Worst |
Machine Independent | Medium | Medium | Best |
Source Code Access | Best | Medium | Worst |
Secure Run | Medium | Worst | Best |
Reproducible Result | Worst | Medium | Best |
Uses Few Resources | Medium | Medium | Best |