Solution for Reverse Engineering Linux Config Deltas Via System-wide Diffing

Search for a command to run...

No comments yet. Be the first to comment.
Everyone loves Linux for its ability to stick to fundamentals and common platform expectations. Except those of us who do a lot of deployment automation. Why? Two main reasons: In a world of stripped back distros (think containers), even fundamental ...
Why Least Privilege Security Engineering Is Frequently Skipped or Done Loosely In a previous life, I was on a team that reviewed the IAM policies specified by developers when they created new Cloud applications or required additional permissions for ...

Obscuring sensitive information like AWS account IDs in screenshots and videos is tedious and error-prone. Even with video editing tools that simplify the process, I still have to repeatedly add and remove blurring boxes as the view changes. You know...

AWS CloudShell joins the ranks of hostless shells for operating in your cloud environment. Cloud shells are a huge help to training and enablement scenarios because they remove the pain of fussy configuration of a user-owned endpoint - which can have...

This article is the third and final of a series. Part 1 justified that human-performed DevOps checklists are essentially source code, and according to GitOps principles, belong in Git just like any other code required for successfully managing a soft...

There are always those who feel checklists are an unnecessary waste of time because they think they can always remember the basics of the steps involved to complete a task. Many are also not aware of the huge, cross-discipline benefits that can come ...

For many years it was my main work to reverse engineer software installation and configuration for hyper-scaled deployment automation and for OS provisioning for Windows.
Early on it was evident that for OS and software provisioning it was extremely important to be able to prove that you had documented the exact checklist of ordered steps to take a system from “pristine OS deployment” to “working configuration” as an input to solid automation code.
Over time, I developed proficiency in this type of reverse engineering, explored the hundreds of available free and commercial tools, blogged about it and eventually developed a business around multiple advanced training courses on reverse engineering Windows OS and software installation for the purposes of provisioning and deployment automation.
There is an entire eco system of commercial and free tools for system-wide diffing on Windows, so it was a bit shocking to recently rediscover that comprehensive system-wide configuration diffing tools for Linux are rare indeed.
Whether you are porting Windows reverse engineering skills to Linux, or are a Linux Engineer that has not experienced the productivity benefits of system-wide config diffing for reverse engineering - this post is for you ;)
For a robotics control project, I was recently setting up Raspian (the Raspberry Pi distro) to enable Bluetooth audio access via a running service. Bluetooth audio on Raspian needed a lot of work just to be functional. The requirement to simultaneously using the GPIO serial port to control an ardruino based robot created some knock-on complexity in figuring things out. Linux Bluetooth audio is also very per-user oriented (e.g. uses a user based systemd service and config files) because Bluetooth audio devices are frequently personal to users. However, it needed to work from the context of a systemd service with a special user logon so that the Bluetooth speaker could appear to give the robot commands.
The end result worked great - so I began the work to build “from scratch” instructions so others could do the same. However, the path to getting it working was extremely unclear due to the many changes (including unrelated ones) made along the way.
The last few steps to get Bluetooth audio working under a service remained unclear no matter how many things I tried or compared or repeated.
I mistakenly thought there would be a couple obvious solutions available to do a system-wide diff to quickly isolate the differences between the working and from scratch build.
I was unable to find any obvious options, but eventually found configsnap - created by the venerable Rackspace support team.
While it looked very promising, I hit additional snags - the help and documentatoin did not cover whether the concept of comparing two different machines was a valid use case and the repository docs did not show compare commands at all. Searching the Internet did not yield any how to documents or videos.
Whenever there is a gap this large (lack of linux system-wide diffing solutions in general and lack of how to information for the one I found) I can’t help but create a bit of Mission Impossible Code to bridge the gap.
 Mission Objectives and Parameters articulate the final objectives that emerged from both the preplanning and build process. Code Summary gives an out line of the code fragments. Code Call Outs highlights significant constraints, innovations and possible alternatives in the code.
Using a Zero Footprint approach, use minimal code to bring down configsnap and run a before snapshot.
Perform a “known good” snapshot on the working reference system.
#Run this directly from this location with: curl https://gitlab.com/missionimpossiblecode/MissionImpossibleCode/-/raw/master/ConfigsnapCreateKnownGood.sh -O /tmp/ConfigsnapCreateKnownGood.sh ; sudo bash /tmp/ConfigsnapCreateKnownGood.sh
#Zerofootprint for both known good and compare-to systems - just delete /tmp/configsnap
if [[ -z "$(command -v python)" ]]; then
echo "Python must be installed and working, exiting..."
echo "If you cannot install python on this or the compare-to system, read here about building it in an isolated directory: https://stackoverflow.com/a/42903156"
exit 5
fi
mkdir -p /tmp/configsnap
curl https://raw.githubusercontent.com/rackerlabs/configsnap/master/configsnap -o /tmp/configsnap/configsnap
chmod +x /tmp/configsnap/configsnap
cat > /tmp/configsnap/additional.conf <<'EOF_CONFIG'
[allmachineconfig]
Type: directory
Directory: /etc/
[userconfigs]
Type: directory
Directory: /home/
File_Pattern: \..*
EOF_CONFIG
sudo ./configsnap --basedir=/tmp/configsnap/snaps --verbose --tag=crossmachinecompare --phase=knowngoodconfig
cat <<- EndOfMessage
Next Steps:
1. Sample scp command to pull this on a system to compare to:
scp -r user_on_this_system@thissystemdnsorip:/tmp/configsnap /tmp/configsnap
2. Sample auto-compare command on compare-to system:
sudo /tmp/configsnap/configsnap --basedir=/tmp/configsnap/snaps --verbose --tag=crossmachinecompare --pre=knowngoodconfig --phase=post
To use as a known good snapshot managed in a centralized location, copy "/tmp/configsnap" to a shared location (or use git to commit to a repository) where you can pull it onto any system you wish to test for drift or changes.
To clean the zero footprint install from any systems, run "sudo rm -rf /tmp/configsnap"
EndOfMessage
The code for this post is kept up to date and can be invoked directly from the web in this repository location: ConfigsnapCreateKnownGood.sh
 The following content is a deep dive below the waterline into the nitty gritty details of how to take a similar approach to building solutions.
NOTE: You do not need this information to successfully leverage this solution.
The notation “<==>”, which may contain logic like “<= AND =>” is an attempt to visually reflect the trade-offs inherent in using heuristics to commit to seleting a position on a spectrum of possibilities. By documenting these trade-offs below - the construction and serendipities of the final tuning are revealed. This seems to do at least three things for the consumer of this information:
The overall solution is solving for “Use tooling to find system-wide configuration differences between two seperate linux installations to quickly isolate the differences between a known good and non-working system.”
Mission Impossible Heuristic: Leave No Trace Behind <= AND => Make Fingerprint Wipe-Down Easy
Reasons:
Coding Decisions:
Diffing Heuristic: Two comparison targets should not have captured differences introduced by the comparison process.
Reason: When diffing across two systems, the version of the diffing utility (Configsnap) and it’s configuration must be identical for results to be valid. This includes using older versions of the diffing utility even if they are no longer available from the original source.
Prior Coding Decisions Result: