[{"content":"It has been a while since I have posted anything publicly and I think its time to bring it back!\nMy last public post on here was 2018 where I had slowed down on a satellite tracking project. I remember having a ton of fun working on that and learning A LOT about tracking satellites using TLE data and about embedded development.\nSince 2018 a lot has happened in life and my career. I won\u0026rsquo;t get into that here, but I have a lot of technology experiences to share. Hopefully, on a more reasonable cadence.\n","permalink":"https://bost.dev/posts/2025-back-to-blog/","summary":"\u003cp\u003eIt has been a while since I have posted anything publicly and I think its time to bring it back!\u003c/p\u003e\n\u003cp\u003eMy last public post on here was 2018 where I had slowed down on a \u003ca href=\"https://bost.dev/posts/update-on-pocket-sized-satellite-tracker-2/\"\u003esatellite tracking project\u003c/a\u003e. I remember having a ton of fun working on that and learning A LOT about tracking satellites using \u003ca href=\"https://en.wikipedia.org/wiki/Two-line_element_set\"\u003eTLE\u003c/a\u003e data and about embedded development.\u003c/p\u003e\n\u003cp\u003eSince 2018 a lot has happened in life and my career. I won\u0026rsquo;t get into that here, but I have a lot of technology experiences to share. Hopefully, on a more reasonable cadence.\u003c/p\u003e","title":"2025 Back to Blogging"},{"content":"I\u0026rsquo;m Robert Bost, a software engineer at Red Hat specializing in Linux systems, cloud platforms, and open source infrastructure. My work focuses on building reliable cloud-native environments and writing the software that helps teams understand and operate complex systems.\nAt Red Hat, I support internal teams through technical enablement, troubleshooting, and scalable solution development. I stay close to both the code and the systems.\nThis blog is where I share what I\u0026rsquo;m building, learning, and exploring — from backend code and architecture to automation and tooling.\n","permalink":"https://bost.dev/about/","summary":"\u003cp\u003eI\u0026rsquo;m Robert Bost, a software engineer at Red Hat specializing in Linux systems, cloud platforms, and open source infrastructure. My work focuses on building reliable cloud-native environments and writing the software that helps teams understand and operate complex systems.\u003c/p\u003e\n\u003cp\u003eAt Red Hat, I support internal teams through technical enablement, troubleshooting, and scalable solution development. I stay close to both the code and the systems.\u003c/p\u003e\n\u003cp\u003eThis blog is where I share what I\u0026rsquo;m building, learning, and exploring — from backend code and architecture to automation and tooling.\u003c/p\u003e","title":"About"},{"content":"Quikey 0.1.3 was released today and includes interactive editing and removal of phrases. This solves the problem with having to know the phrase name/key at time of edit or removal. It also solve a problem where typing the phrase name/key itself performs the text expansion!\nHere\u0026rsquo;s a brief demo showing the new feature: https://asciinema.org/a/FWxBE5bolPRW75eYsD78xvVUC\nIn addition to the new feature above, the --help output is now more helpful. Also, you can no longer create a phrase name/key that is an empty since that led to zero usability of your keyboard.\n","permalink":"https://bost.dev/posts/release-0_1_3/","summary":"\u003cp\u003eQuikey 0.1.3 was released today and includes interactive editing and removal of phrases. This solves the problem with having to know the phrase name/key at time of edit or removal. It also solve a problem where typing the phrase name/key itself performs the text expansion!\u003c/p\u003e\n\u003cp\u003eHere\u0026rsquo;s a brief demo showing the new feature: \u003ca href=\"https://asciinema.org/a/FWxBE5bolPRW75eYsD78xvVUC\"\u003ehttps://asciinema.org/a/FWxBE5bolPRW75eYsD78xvVUC\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eIn addition to the new feature above, the \u003ccode\u003e--help\u003c/code\u003e output is now more helpful. Also, you can no longer create a phrase name/key that is an empty since that led to zero usability of your keyboard.\u003c/p\u003e","title":"Quikey Release 0.1.3"},{"content":"Quikey 0.1.2 was released yesterday and includes the following:\nA feature to import from AutoKey. See qk keyimport --help for a quick reference on how to use. Autostart for the Quikey daemon so there\u0026rsquo;s no need to run qk start after a reboot or login. This should work on GNOME, Xfce, KDE, and other desktop environments following the XDG Desktop Entry standard. Added a lot of unit tests. A few more minor bug fixes. ","permalink":"https://bost.dev/posts/release-0_1_2/","summary":"\u003cp\u003eQuikey 0.1.2 was released yesterday and includes the following:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eA feature to import from \u003ca href=\"https://github.com/autokey/autokey\"\u003eAutoKey\u003c/a\u003e. See \u003ccode\u003eqk keyimport --help\u003c/code\u003e for a quick reference on how to use.\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/bostrt/quikey/pull/37\"\u003eAutostart for the Quikey daemon\u003c/a\u003e so there\u0026rsquo;s no need to run \u003ccode\u003eqk start\u003c/code\u003e after a reboot or login. This should work on GNOME, Xfce, KDE, and other desktop environments following the XDG Desktop Entry standard.\u003c/li\u003e\n\u003cli\u003eAdded a lot of \u003ca href=\"https://github.com/bostrt/quikey/pull/34\"\u003eunit tests\u003c/a\u003e.\u003c/li\u003e\n\u003cli\u003eA few more minor bug fixes.\u003c/li\u003e\n\u003c/ul\u003e","title":"Quikey Release 0.1.2"},{"content":"There\u0026rsquo;s some good work being done here to add import functionality for AutoKey users. This should ease migration for someone with a large AutoKey database. Of course, AutoKey has way more functionality than Quikey so we\u0026rsquo;ll only be importing key phrases (no mouse or scripting will be migrated).\nHope everyone is staying safe, healthy, and active. \u0026lt;3\n","permalink":"https://bost.dev/posts/auto-key-import/","summary":"\u003cp\u003eThere\u0026rsquo;s some good work being done \u003ca href=\"https://github.com/bostrt/quikey/pull/42\"\u003ehere\u003c/a\u003e to add import functionality for \u003ca href=\"https://github.com/autokey/autokey\"\u003eAutoKey\u003c/a\u003e users. This should ease migration for someone with a large AutoKey database. Of course, AutoKey has way more functionality than Quikey so we\u0026rsquo;ll only be importing key phrases (no mouse or scripting will be migrated).\u003c/p\u003e\n\u003cp\u003eHope everyone is staying safe, healthy, and active. \u0026lt;3\u003c/p\u003e","title":"Auto Key Import"},{"content":"I\u0026rsquo;ll be hosting a blog here to track development of an application I develop called Quikey, a keyboard macro tool. Content on this blog will be about new and old features, design, and future plans for Quikey.\n","permalink":"https://bost.dev/posts/start-of-quikey-blog/","summary":"\u003cp\u003eI\u0026rsquo;ll be hosting a blog here to track development of an application I develop called \u003ca href=\"https://github.com/bostrt/quikey\"\u003eQuikey\u003c/a\u003e, a keyboard macro tool. Content on this blog will be about new and old features, design, and future plans for Quikey.\u003c/p\u003e","title":"Start of Quikey Blog"},{"content":"I haven\u0026rsquo;t updated much on the satellite tracker but I figured I would make the repo public since it is just sitting there at the moment. :)\nhttps://github.com/bostrt/sattrack\nhttps://github.com/bostrt/libpredict-arduino-lib\nI plan to work on this some more before upcoming DEF CON 26.\n","permalink":"https://bost.dev/posts/update-on-pocket-sized-satellite-tracker-2/","summary":"\u003cp\u003eI haven\u0026rsquo;t updated much on the satellite tracker but I figured I would make the repo public since it is just sitting there at the moment. :)\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/bostrt/sattrack\"\u003ehttps://github.com/bostrt/sattrack\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/bostrt/libpredict-arduino-lib\"\u003ehttps://github.com/bostrt/libpredict-arduino-lib\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eI plan to work on this some more before upcoming DEF CON 26.\u003c/p\u003e","title":"Update #3 on Pocket-Sized Satellite Tracker"},{"content":"Things are progressing nicely on the satellite tracker. The following is functional:\nlibpredict modified to work on Adafruit Feather M0 Real-time clock with battery backup complete Storage for configs complete OLED display working and displaying data calculated by libpredict USB Serial interface for configuring location, callsign, TLE\u0026rsquo;s, and time (in case RTC loses battery power) Current tasks Develop a dev pcb to replace bread-board. Just something that all the breakout boards above solder onto Finish display graphics code-cleanup Screenshot \u0026amp; Photos Serial interface All components Polar chart that will display relative satellite position Missing photo of the satellite position data due to being in middle of display code rewrite.\n","permalink":"https://bost.dev/posts/update-on-pocket-sized-satellite-tracker-1/","summary":"\u003cp\u003eThings are progressing nicely on the satellite tracker. The following is functional:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/la1k/libpredict/\"\u003elibpredict\u003c/a\u003e modified to work on \u003ca href=\"https://www.adafruit.com/product/2772\"\u003eAdafruit Feather M0\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.adafruit.com/product/3295\"\u003eReal-time clock\u003c/a\u003e with battery backup complete\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.adafruit.com/product/1895\"\u003eStorage\u003c/a\u003e for configs complete\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.amazon.com/Diymall-Serial-128x64-Display-Arduino/dp/B01HHOETIA\"\u003eOLED display\u003c/a\u003e working and displaying data calculated by libpredict\u003c/li\u003e\n\u003cli\u003eUSB Serial interface for configuring location, callsign, TLE\u0026rsquo;s, and time (in case RTC loses battery power)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"current-tasks\"\u003eCurrent tasks\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eDevelop a dev pcb to replace bread-board. Just something that all the breakout boards above solder onto\u003c/li\u003e\n\u003cli\u003eFinish display graphics\u003c/li\u003e\n\u003cli\u003ecode-cleanup\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"screenshot--photos\"\u003eScreenshot \u0026amp; Photos\u003c/h3\u003e\n\u003cp\u003e\u003cem\u003eSerial interface\u003c/em\u003e\u003cimg alt=\"Screenshot from 2017-10-28 11-10-24.png\" loading=\"lazy\" src=\"/wp-content/uploads/2017/10/screenshot-from-2017-10-28-11-10-24.png\"\u003e \u003cem\u003eAll components\u003c/em\u003e\u003cimg alt=\"IMG_20171028_105906851.jpg\" loading=\"lazy\" src=\"/wp-content/uploads/2017/10/img_20171028_105906851.jpg\"\u003e \u003cem\u003ePolar chart that will display relative satellite position\u003c/em\u003e\u003cimg alt=\"IMG_20171028_105938349.jpg\" loading=\"lazy\" src=\"/wp-content/uploads/2017/10/img_20171028_105938349.jpg\"\u003e \u003cem\u003eMissing photo of the satellite position data due to being in middle of display code rewrite.\u003c/em\u003e\u003c/p\u003e","title":"Update #2 on Pocket-Sized Satellite Tracker"},{"content":"After some fighting with libpredict, I found that I am going to need a microcontroller with better floating-point support. The Atmega series of microcontrollers do not have an FPU which means any floating-point support is hard (either inaccurate, slow, or hacked).\nI found that some of the ARM Cortex processors do indeed have an FPU and their also come in similar form as Arduinos or other development boards:\nhttps://www.adafruit.com/product/2772\nOr\nhttps://www.adafruit.com/product/2756\nAbove is Adafruit\u0026rsquo;s Feather which I\u0026rsquo;m going to give a shot. It hosts a Cortex M0 which actually does not have an FPU but would handle floating point much better than Atmega due to 32-bit arch.\nThe Teensy 3.2 hosts a Cortex M4 which actually does have an FPU which might be the winner.\nI\u0026rsquo;ll be experimenting with both to see which one better suits my needs.\n","permalink":"https://bost.dev/posts/update-on-pocket-sized-satellite-tracker/","summary":"\u003cp\u003eAfter some fighting with \u003ca href=\"https://github.com/la1k/libpredict/\"\u003elibpredict\u003c/a\u003e, I found that I am going to need a microcontroller with better floating-point support. The Atmega series of microcontrollers do not have an \u003ca href=\"https://en.wikipedia.org/wiki/Floating-point_unit\"\u003eFPU\u003c/a\u003e which means any floating-point support is hard (either inaccurate, slow, or hacked).\u003c/p\u003e\n\u003cp\u003eI found that some of the ARM Cortex processors do indeed have an FPU and their also come in  similar form as Arduinos or other development boards:\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Adafruit Feather M0 Basic Proto - ATSAMD21 Cortex M0\" loading=\"lazy\" src=\"https://cdn-shop.adafruit.com/970x728/2772-01.jpg\"\u003e\u003ca href=\"https://www.adafruit.com/product/2772\"\u003ehttps://www.adafruit.com/product/2772\u003c/a\u003e\u003c/p\u003e","title":"Update on Pocket-Sized Satellite Tracker"},{"content":"A couple months ago, I worked on putting a satellite tracking application on a Raspberry Pi. This worked okay but I have to use a keyboard to select the satellite I want to track before going outside to find it. I also have to lug around an external battery outside which isn\u0026rsquo;t fun. I could really use something more compact.\nHard Requirements\nScreen + Buttons Tracking multiple satellites (not hundreds, just a few) Display Azimuth Display Elevation Display transponder frequency with Doppler shift Polar plot (sky plot) Button to switch between satellites Ability to set the time and timezone on device (RTC required) Soft Requirements\nButton to toggle between screens for a single satellite (if Polar plot and transponder data cannot fit in same screen) Ability to update TLE\u0026rsquo;s when plugging into computer I have one of these pockeTETRIS things and love the little OLED screen. I will probably end up using the same screen. I\u0026rsquo;d like to just re-purpose my already built pockeTETRIS, but, I still need the RTC and definitely a microcontroller with more program space for largest library I will need, libpredict, which comes out to around 40k when I drop features I don\u0026rsquo;t need. The ATtiny85 in pocketTETRIS only has 8K. Pretty sure I am going with ATmega1284 a whopping 128k; plenty of room for libpredict, RTC library, OLED library, and my own code.\n","permalink":"https://bost.dev/posts/beginning-pocket-sized-satellite-tracking/","summary":"\u003cp\u003eA couple months ago, I worked on putting a \u003ca href=\"/2017/07/22/flyby-satellite-tracking-on-raspberry-pi/\"\u003esatellite tracking application on a Raspberry Pi\u003c/a\u003e. This worked okay but I have to use a keyboard to select the satellite I want to track before going outside to find it. I also have to lug around an external battery outside which isn\u0026rsquo;t fun. I could really use something more compact.\u003c/p\u003e\n\u003cp\u003eHard Requirements\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eScreen + Buttons\u003c/li\u003e\n\u003cli\u003eTracking multiple satellites (not hundreds, just a few)\u003c/li\u003e\n\u003cli\u003eDisplay Azimuth\u003c/li\u003e\n\u003cli\u003eDisplay Elevation\u003c/li\u003e\n\u003cli\u003eDisplay transponder frequency with Doppler shift\u003c/li\u003e\n\u003cli\u003ePolar plot (sky plot)\u003c/li\u003e\n\u003cli\u003eButton to switch between satellites\u003c/li\u003e\n\u003cli\u003eAbility to set the time and timezone on device (RTC required)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eSoft Requirements\u003c/p\u003e","title":"Beginning Pocket-Sized Satellite Tracking"},{"content":"Flyby is a satellite tracking application that runs in a terminal (no GUI required). I wanted to run it on my Raspberry Pi that has a display attached to it so I can carry it outside with me when tracking amateur satellites. This is much easier to move around than a laptop or even my phone where I have to keep the screen from going to sleep or touching something on the screen.Setting up Flyby on a Raspberry Pi was a bit of a challenge but it is now working fine. Here’s my setup steps:\nInstall Raspbian I am using Adafruit’s 3.5” TFT display so I used their custom image with the drivers already configured. You can find that here: https://learn.adafruit.com/adafruit-pitft-3-dot-5-touch-screen-for-raspberry-pi/easy-install.\nInstall Dependencies Once you have Raspbian setup, you will need to get the device networked and install some dependencies of flyby:\n# apt-get install libncurses-dev cmake gcc make git Get latest Flyby and libpredict source code Check out the source code for both projects using git:\n# git clone https://github.com/la1k/libpredict.git # git clone https://github.com/la1k/flyby.git At the time of writing this, I ran into a few issues with crashes while starting up flyby. A patch has been filed here: https://github.com/la1k/flyby/pull/74\nPatch If you run into problems when trying to do the initial QTH setup (that’s later on in this post), then my fix may not have been merged yet. You can checkout the patch using, rebuild, and re-try:\n# cd flyby # git fetch origin pull/74/head:qth-setup-segfault # git checkout qth-setup-segfault Update: patch above has been accepted.\nBuild After you have checked out the sources, run the build process for libpredict:\n# cd ~/libpredict # mkdir build; cd build # cmake .. # make # sudo make install # sudo ldconfig Then, build flyby:\n# cd ~/flyby # mkdir build; cd build # cmake .. # make # sudo make install A few final tweaks before running The default font in Raspbian is too big to render flyby properly. Change the terminal by doing this:\n# sudo dpkg-reconfigure console-setup Choose the following options in each prompt:\nUTF-8 “Guess optimal character set” Terminus 6x12 (framebuffer only) The screen may hang for a moment while the settings are applied. After it completes, you will be sent back to a shell with your new font visible.\nRun it! Finally, start up flyby simply by executing:\n# flyby Your screen should look something like below. Fill in your details and you are good to go :)\nRemeber, if you are not able to save your settings above and experience a Segmentation Fault, then follow the steps in the Patch section earlier in this post.Finally, proceed with the normal setup steps provided in flyby’s Wiki: https://github.com/la1k/flyby/blob/master/docs/usage_guide.md#obtaining-and-updating-tlesUpdate (again): patch above has been accepted.\n","permalink":"https://bost.dev/posts/flyby-satellite-tracking-on-raspberry-pi/","summary":"\u003cp\u003e\u003cimg alt=\"qth\" loading=\"lazy\" src=\"/wp-content/uploads/2017/07/qth.png\"\u003e\u003ca href=\"https://github.com/la1k/flyby\"\u003eFlyby\u003c/a\u003e is a satellite tracking application that runs in a terminal (no GUI required). I wanted to run it on my Raspberry Pi that has a display attached to it so I can carry it outside with me when tracking amateur satellites. This is much easier to move around than a laptop or even my phone where I have to keep the screen from going to sleep or touching something on the screen.Setting up Flyby on a Raspberry Pi was a bit of a challenge but it is now working fine. Here’s my setup steps:\u003c/p\u003e","title":"Flyby Satellite Tracking on Raspberry Pi"},{"content":"mod_serverheader project site In my work, I have seen people performing security scans, going through audits, and stumbling upon information they wish they could hide about their webservers.\nOne of the simplest questions that comes up over-and-over is regarding the Server header in Apache HTTPD responses; the thing with the arrows are pointing to below:\n# curl -I http://localhost/ HTTP/1.1 200 OK Date: Tue, 28 Feb 2017 20:56:24 EST Server: Apache/2.4.25 (Fedora) OpenSSL/1.0.2k-fips ◀◀◀◀◀◀◀◀ Content-Type: text/html; charset=UTF-8 There are a couple ways to reduce what is disclosed in the Server header.\nConfigure your ServerTokens directive to be ProductOnly. Use ModSecurity’s SecServerSignature directive to overwrite the Server header with custom contents. Each of the options are backed by opposing opinions. The Apache HTTPD documentation claims there is no advantage to hiding/altering the contents of the Server header because a malicious user could just throw all their attacks at a webserver, no matter what the webserver product actual is.\nSetting ServerTokens to less than minimal is not recommended because it makes it more difficult to debug interoperational problems. Also note that disabling the Server: header does nothing at all to make your server more secure. The idea of “security through obscurity” is a myth and leads to a false sense of safety. 1\nAnd, as far as I know, the motivation behind ModSecurity’s SecServerSignature directive is the because of a not in the HTTP/1.1 RFC 2068:\nRevealing the specific software version of the server may allow the server machine to become more vulnerable to attacks against software that is known to contain security holes. Implementers SHOULD make the Server header field a configurable option. 2\nI’m not going to take sides in the matter, becaues I think both points have merits. However, I think our battles must be chosen carefully. Should time be spent deciding whether or not to obfuscate your Server header or should time be spent on more significant security matters? Why not satisfy this simple concern to satisfy the request of security professionals or security auditors?\nModSecurity has solved this issue with the SecServerSignature directive. However, I’ve seen people use ModSecurity only for this header. I think the module is completely overkill to use just for this one directive. So, I worked up a simple module who’s only purpose is to overwrite the Server header: https://github.com/bostrt/mod_serverheader\nhttps://httpd.apache.org/docs/current/mod/core.html#servertokens https://www.ietf.org/rfc/rfc2068.txt ","permalink":"https://bost.dev/posts/introducing-mod-serverheader/","summary":"\u003cp\u003e\u003ca href=\"https://github.com/bostrt/mod_serverheader\"\u003emod_serverheader project site\u003c/a\u003e In my work, I have seen people performing security scans, going through audits, and stumbling upon information they wish they could hide about their webservers.\u003c/p\u003e\n\u003cp\u003eOne of the simplest questions that comes up over-and-over is regarding the Server header in Apache HTTPD responses; the thing with the arrows are pointing to below:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e# curl -I http://localhost/\nHTTP/1.1 200 OK\nDate: Tue, 28 Feb 2017 20:56:24 EST\nServer: Apache/2.4.25 (Fedora) OpenSSL/1.0.2k-fips  ◀◀◀◀◀◀◀◀\nContent-Type: text/html; charset=UTF-8\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eThere are a couple ways to reduce what is disclosed in the Server header.\u003c/p\u003e","title":"Introducing mod_serverheader"},{"content":"There are just a few fundamental pieces to learn in order to get started with ModSecurity.\nPhases Actions and Rules Collections Phases There are 5 phases of request processing in ModSecurity 1. You can hook into any one these phases using the phase keyword when writing ModSecurity Actions and Rules. The 5 phases occur in this order:\nRequest Headers Phase Request Body Phase Response Headers Phase Response Body Phase Logging Phase As you pass through the phases, you can still access the information from the previous phases. So, if you are not sure where to begin, start with Logging Phase 5.\nActions and Rules ModSecurity configurations are built around Actions ( SecAction) and Rules ( SecRule). We’ll start with SecAction since it is the same as a SecRule, just without a conditional. In other words, SecAction will always execute a list of actions, while a SecRule will only execute a list of actions if a certain condition is met.\nExample SecRuleEngine On SecAction id:100,phase:1,deny SecRuleEngine enables the ModSecurity engine. If you do not enable it, none of your actions/rules will apply.\nThe SecAction above is about as simple as it gets. It always denies a request, sending a 403 status to client.\nThe id:100,phase:1,deny is known as the action list. Let’s work through it now. Every action must include an id and it must be unique amongst all your SecAction and SecRule 2. After the id is the phase:1 which means this rule will run in the Request Headers phase. Finally, the deny is the part that actually says this SecAction will send a 403 status.\nModified Example If you want to send something besides the default deny status of 403, you can change it by using the status action like this:\nSecAction id:100,phase:1,deny,status:451 The action above would deny the client access and send a “451 Unavailable For Legal Reasons” status.\nAction List Order The ordering of items in an action list is not always important. If you are using things like Transformation Functions 3 (e.g. base64Encode, hexEncode, trim, etc) you need to pay attention to order, especially when you use multiple Transformation Functions in a single action or rule. Transformation Functions will change the input for the following functions and actions.\nThe example from the previous section does not have any actions that are sensitive to ordering. For instance, the following would execute in exact same manner as in previous section:\nSecAction status:451,deny,phase:1,id:100 More Useful Example In the previous sections we used an example that simply denies every request. This isn’t very useful so we will add a condition to the action, making it a SecRule. The condition will be this: if someone requests the page and is from the IP address 192.168.100.200, then we want to deny them with the 451 status:\nSecRule REMOTE_ADDR \u0026#34;192\\.168\\.100\\.200\u0026#34; id:100,phase:1,deny,status:451 The REMOTE_ADDR 4 is the value we are testing and the “192.168.100.200” is value that needs to match. If the test passes then the action list is executed.\nCollections Collections (a.k.a. Persistent Storage) are an important feature of ModSecurity because they give you the ability to store information over multiple requests. There are a few different types of collections5 but we will focus on GLOBAL and SESSION collections in this guide. A GLOBAL collection is not associated with any single request, session, or anything really; it is just a general collection that can be accessed from anywhere. A SESSION collection is different in that it is associated with a specific session and initialized differently than a GLOBAL collection.\nLet’s take a look at some example configuration.\nGlobal Collection Example SecDataDir /var/cache/mod_security/ SecAction id:150,phase:1,initcol:reindeer=rudolph SecAction id:152,phase:1,setvar:reindeer.antlers=+2 SecAction id:153,phase:1,setvar:reindeer.hoofs=+4 SecDataDir is the directory where the persistent database files will be kept. Make sure this is writable by your Apache HTTPD user.\nThe first SecAction initializes the collection ( initcol stands for initialize collection). The last two SecActions are setting the variables inside of the collection. So, in the example above, the collection is called rudolph and and it has two attributes: antlers and hoofs. The antlers are incremented by 2 for each request and the hoofs are incremented by 4 for each request.\nThe collection has a structure like this:\nFile name: reindeer rudolph =\u0026gt; { antlers: 2, hoofs: 4 } Something imporatnt to note is that you can only call initcol once in your configuration since it is a GLOBAL collection. However, you can use SecRule in combination with initcol in the event you need to conditionally initialize a GLOBAL collection to use throughout a request’s lifecycle. For example, you can do:\nSecRule REQUEST_URI rudolph id:150,phase:1,initcol:reindeer=rudolph SecRule REQUEST_URI dancer id:151,phase:1,initcol:reindeer=dancer SecAction id:152,phase:1,setvar:reindeer.antlers=+2 Session Collection Example Instead of tracking things globally, you may want to associate a counter or variable with a specific session or request cookie. Let’s track how many people send requests from a specific session ID.\nSecAction id:154,phase:1,setsid:%{REQUEST_COOKIES.SESSIONID} SecAction id:155,phase:1,setvar:SESSION.requests=+1 In the configuration above, a counter called requests will be incremented for each request from the user with a specific session ID.\nThe collection will have a structure like this:\nFile name: default_SESSION e0d47ef20 =\u0026gt; { requests: 100 }, a303b3cc7 =\u0026gt; { requests: 93 }, 146f5a98e =\u0026gt; { requests: 174 } e0d47ef20, a303b3cc7, and 146f5a98e are just example session ID’s which are the “keys” for each collection.\nAfter reading this article, you will be ready to get started with writing your own rules and actions for ModSecurity. Maybe even dive into the complex set of prebuilt rules in the OWASP ModSecurity Core Rule Set 6.\nReferences:\nhttps://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#Processing_Phases https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#id https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#transformation-functions https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#remote_addr https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#Persistent_Storage https://github.com/SpiderLabs/owasp-modsecurity-crs/ ","permalink":"https://bost.dev/posts/modsecurity-x-in-minutes/","summary":"\u003cp\u003eThere are just a few fundamental pieces to learn in order to get started with ModSecurity.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ePhases\u003c/li\u003e\n\u003cli\u003eActions and Rules\u003c/li\u003e\n\u003cli\u003eCollections\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"phases\"\u003ePhases\u003c/h2\u003e\n\u003cp\u003eThere are 5 phases of request processing in ModSecurity \u003ca href=\"https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#Processing_Phases\"\u003e1\u003c/a\u003e. You can hook into any one these phases using the \u003ccode\u003ephase\u003c/code\u003e keyword when writing ModSecurity Actions and Rules. The 5 phases occur in this order:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eRequest Headers Phase\u003c/li\u003e\n\u003cli\u003eRequest Body Phase\u003c/li\u003e\n\u003cli\u003eResponse Headers Phase\u003c/li\u003e\n\u003cli\u003eResponse Body Phase\u003c/li\u003e\n\u003cli\u003eLogging Phase\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eAs you pass through the phases, you can still access the information from the previous phases. So, if you are not sure where to begin, start with Logging Phase 5.\u003c/p\u003e","title":"ModSecurity 2.9.x in 5 minutes"}]