Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
IT NachrichtenFritzbox-Besitzer sollten diesen Speedtest kennen(24.09.2026 um 06:39 Uhr)
IT NachrichtenApple iOS 27.0.1: Wichtiges Update steht bereit(24.09.2026 um 06:44 Uhr)
Android Tipps & SecurityBYD strebt dichtes Netz an Ladestationen auf Tankstellen-Level an(24.09.2026 um 07:00 Uhr)
IT NachrichtenFritzbox-Besitzer sollten diesen Speedtest kennen(24.09.2026 um 06:39 Uhr)
IT NachrichtenApple iOS 27.0.1: Wichtiges Update steht bereit(24.09.2026 um 06:44 Uhr)
Android Tipps & SecurityBYD strebt dichtes Netz an Ladestationen auf Tankstellen-Level an(24.09.2026 um 07:00 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

How I stopped worrying and loved Makefiles

First contact with make When I was invited for my first job interview in the IT, I've been asked such question: How would you typically build a program from sources, what commands will you use? I answered: It's…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!




First contact with make



When I was invited for my first job interview in the IT, I've been asked such question:




How would you typically build a program from sources, what commands will you use?




I answered:




It's obvious:




./configure
make
make install




Those times belong to the past now and nowadays not many programmers use GNU Make1. Try asking this question and you will see disgust at best.



For many it's the fist contact with make and often the last one, but not for me 😉






What make does?



Let build a base line. make orchestrates tasks based on dependencies, executing commands to generate target files and keep them up to date efficiently. It streamlines software compilation and project management.



As simple as it is, it does few things pretty well:




  • detects changes in files (source -> binary),

  • manages dependencies,

  • manages default values for variables much easier than Bash,

  • allows to build in parallel,

  • OS detection,

  • on my system binary is only 16kB in size,

  • is available on any OS,

  • and much more!






My second contact with make - Postfix



The second non obvious use of make I stood, was the way to refresh Postfix's map files. With Postfix servers, you've been usually writing a bunch of text files like aliases, transports, etc, which have to be indexed to the binary Berkley DB format.




alias_maps = hash:/etc/postfix/aliases






To "generate" Berkley DB file you have to run:




postalias aliases






Which was producing aliases.db file. Other types of files required to use postmap command to generate them.



The more complicated the Postfix configuration, the more files you had. If you missed to update one of map files, your configuration wasn't effective and you could spend hours debugging: why this f... alias do not work?



That's where make comes handy 2. You can just drop the file like this:




.PHONY: reload

all: aliases.db access.db virtual.db reload

aliases.db: aliases
postalias aliases

access.db: access
postmap access

virtual.db: virtual
postmap virtual

reload:
postfix reload






Let me explain what happens here.




  1. .PHONY: reload: This line declares the target reload as a phony target 3. Phony targets are ones that do not represent actual files. This is typically used for targets that don't produce output files, such as clean, all, etc. It ensures that even if a file named reload exists in the directory, the reload target will still be executed.


  2. all: aliases.db access.db virtual.db reload: This line specifies that when you run make all, it will generate the files aliases.db, access.db, and virtual.db, and then execute the reload target. As all target is the default, it's enough to just run make.


  3. aliases.db: aliases: This line specifies that aliases.db depends on the file aliases. If aliases file is newer than aliases.db or aliases.db doesn't exist, the commands listed below will be executed.


  4. postalias aliases: This line is the command to generate the aliases.db file from the aliases file using the postalias command. postalias is a command used in Postfix to create or update the alias database.


  5. Similarly, access.db: access and virtual.db: virtual are rules to generate access.db and virtual.db files from access and virtual files respectively using the postmap command.


  6. reload:: This line declares the reload target. When you run make reload, it will execute the command listed below.


  7. postfix reload: This line is the command to reload the Postfix service. It tells Postfix to reload its configuration, applying any changes that may have been made.




Summing up, when you run make, it will generate or update the necessary database files for Postfix configuration (aliases.db, access.db, virtual.db) and then reload the Postfix service.



Now you won't make mistakes again.



I know that today many of you would say: "just use Ansible dude!" But at that time, there was no Ansible yet. I didn't use this pattern for years now, so let check more up to date usage examples.






Use of make in Python projects



I love Python for it's simplicity... at least when it comes to coding, because when you start managing dependencies, it's getting tricky. What do you use: raw dependencies.txt or rather Poetry or Pipenv? Do you use system Python or maybe pyenv?



My answer: it depends 😃



For simple projects, I usually just use pip. Sometimes even without requirements.txt files, just listing in the README what to install. But the more projects I wrote, the harder it is to remember how to test them. Again, that's where Make comes handy.




.PHONY: requirements test

.venv:
python3 -m venv .venv

requirements:
source .venv/bin/activate && \
python3 -m pip install -r requirements.txt && \
python3 -m pip install pytest

test: .venv requirements dev-requirements
source .venv/bin/activate && \
pytest






What happens here?




  1. .PHONY: requirements test: Declares requirements and test as phony targets to ensure they are always executed regardless of file existence.


  2. .venv:: Creates a Python virtual environment named .venv if it doesn't already exist.


  3. requirements:: Installs Python packages listed in requirements.txt into the virtual environment created earlier. Additionally, it installs the pytest package globally.


  4. test: .venv requirements dev-requirements: Sets up dependencies for testing, including the virtual environment and specified requirements. Then, it activates the virtual environment and runs the tests using pytest.




Alternative config for Poetry, might look more or less like that:




.PHONY: requirements test

requirements:
poetry install

test: requirements
poetry run pytest






When I see Makefile in a Python project, I can blindly run make test and it will do what I expect -> run tests. Whatever it requires to configure or run, it will just happen.






make in Terraform projects



Similar situation to Python, I have with Terraform projects. In simple project you just need:




terraform init
terraform plan
terraform apply






But what if you use different accounts for PROD and DEV environments? What if you need to fetch latest version of modules?



I have a Makefile for this too.




.PHONY: init
SHELL=/bin/bash

# those variables you should initialize outside of this script
# and export, Make will just set then based on what you will
# have set in your environment. You can use for eg. `aws sts`
AWS_ACCESS_KEY_ID ?=
AWS_SECRET_ACCESS_KEY ?=
AWS_REGION ?= "us-west-2"

# dev by default
ENVIRONMENT ?= dev
STATE_FILE_BUCKET ?= s3-bucket-$(AWS_ACCESS_KEY_ID)-$(ENVIRONMENT)-terraform-state
STATE_FILE_KEY ?= state/some_service/$(ENVIRONMENT)/terraform.tfstate

# make some variable available in Terraform
export TF_VAR_something ?= something1
export TF_VAR_something_else ?= something-else

.terraform:
terraform init \
-reconfigure \
-backend-config='key=$(STATE_FILE_KEY)' \
-backend-config='bucket=$(STATE_FILE_BUCKET)' \
-var-file=environments/$(ENVIRONMENT)/variables.tfvars \
-out terraform.plan

terraform get

# this will switch Terraform version to the one that your project needs
# https://github.com/tfutils/tfenv
init: .terraform
tfenv install

plan: init
terraform plan

apply: plan
terraform apply \
-auto-approve \
terraform.plan

destroy:
terraform destroy \
-auto-approve \
-var-file=environments/$(ENVIRONMENT)/variables.tfvars

dev-plan: export AWS_ACCESS_KEY_ID=dev-key
dev-plan: plan

dev-apply: export AWS_ACCESS_KEY_ID=dev-key
dev-apply: apply

dev-destroy: export AWS_ACCESS_KEY_ID=dev-key
dev-destroy: destroy

prod-plan: export AWS_ACCESS_KEY_ID=prod-key
prod-plan: plan

prod-apply: export AWS_ACCESS_KEY_ID=prod-key
prod-apply: apply

clean:
@rm -rf .terraform/modules
@rm -f terraform.*






This file expects a directory structure like




$ tree example/
.
├── main.tf
├── variables.tf
├── provider.tf
├── backend.tf
├── outputs.tf
├── ...
├── environments/
│ ├── dev
│ │ ├── variables.tfars
│ ├── prod/
│ │ ├── variables.tfars
│ ├── .../






Backends configuration in the backend.tf file can be just basic:




terraform {
backend "s3" {
region = "us-west-2"
encrypt = true
}
}






Rest of parameters are provided in the Makefile - it's called partial backend configuration4. This configuration allows me to use same codebase for all the environments. All customizations have to be listed as variables in variables.tfvars files. It can be easily extended to suport 4 or 6 environments and the only thing I need to remember is:




make dev-plan
make dev-apply









make for Hugo blogging



Even for blogging with Hugo I have a Makefile5 that I use across multiple sites. It's simplifying some of the steps, that I won't need to remember anymore.




BASEDIR=$(CURDIR)
INPUTDIR=$(BASEDIR)/content
STATICDIR=$(BASEDIR)/static
OUTPUTDIR=$(BASEDIR)/public
RESOURCESDIR=$(BASEDIR)/resources
PORT=1313

FTP_HOST=localhost
FTP_USER=anonymous
FTP_TARGET_DIR=/

SSH_HOST=vc1
SSH_PORT=22
SSH_USER=root
SSH_TARGET_DIR=/var/www/hugo
SSH_CHOWN=33:33

S3_BUCKET=my_s3_bucket

CLOUDFILES_USERNAME=my_rackspace_username
CLOUDFILES_API_KEY=my_rackspace_api_key
CLOUDFILES_CONTAINER=my_cloudfiles_container

DROPBOX_DIR=~/Dropbox/Public/

GITHUB_PAGES_BRANCH=gh-pages

all: html

publish: html gzip_static rsync_upload

help:
@echo 'Makefile for a hugo Web site '
@echo ' '
@echo 'Usage: '
@echo ' make html (re)generate the web site '
@echo ' make clean remove the generated files '
@echo ' make publish generate using production settings '
@echo ' make server [PORT=1313] serve site at http://localhost:1313'
@echo ' make ssh_upload upload the web site via SSH '
@echo ' make rsync_upload upload the web site via rsync+ssh '
@echo ' make dropbox_upload upload the web site via Dropbox '
@echo ' make ftp_upload upload the web site via FTP '
@echo ' make s3_upload upload the web site via S3 '
@echo ' make cf_upload upload the web site via Cloud Files'
@echo ' make github upload the web site via gh-pages '
@echo ' '

html: clean
hugo --minify

clean:
[ ! -d $(OUTPUTDIR) ] || rm -rf $(OUTPUTDIR) && mkdir -p $(OUTPUTDIR) && touch $(OUTPUTDIR)/.placeholder
rm -rf $(RESOURCESDIR)

server:
ifdef PORT
hugo server -D -p $(PORT) --disableFastRender --buildExpired --buildFuture
else
hugo server -D --disableFastRender --buildExpired --buildFuture
endif

generate: clean
cd $(BASEDIR); hugo

check_urls:
@cd /tmp; wget -r --spider http://localhost:$(PORT) 2>&1 | grep -B 2 "404 Not Found" | grep http:// | cut -d " " -f 4 | sort -u

markdownlint:
@docker run --rm -ti -v ${PWD}:/data:ro markdownlint/markdownlint content

gzip_static:
for pattern in "*.js" "*.json" "*.css" "*.htm" "*.html" "*.xml"; do \
find $(OUTPUTDIR) -iname $$pattern -print0 | xargs -0 -I'{}' sh -c 'gzip -c9 "{}" > "{}.gz" && touch -r "{}" "{}.gz"'; \
done

optimize_images:
find $(STATICDIR) -mtime -7 -iname *.png -print | parallel optipng -quiet -preserve -o7
find $(INPUTDIR) -mtime -7 -iname *.png -print | parallel optipng -quiet -preserve -o7
find $(STATICDIR) -mtime -7 -iname *.jpg -print | parallel jpegtran -optimize -progressive -copy none -outfile "{}" "{}"
find $(INPUTDIR) -mtime -7 -iname *.jpg -print | parallel jpegtran -optimize -progressive -copy none -outfile "{}" "{}"

ssh_upload: generate
scp -P $(SSH_PORT) -r $(OUTPUTDIR)/* $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR)

rsync_upload: generate gzip_static
ifdef SSH_CHOWN
rsync -e "ssh -p $(SSH_PORT)" -P -avh --delete $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR) --chown $(SSH_CHOWN)
else
rsync -e "ssh -p $(SSH_PORT)" -P -avh --delete $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR)
endif

dropbox_upload: generate
cp -r $(OUTPUTDIR)/* $(DROPBOX_DIR)

ftp_upload: generate
lftp ftp://$(FTP_USER)@$(FTP_HOST) -e "mirror -R $(OUTPUTDIR) $(FTP_TARGET_DIR) ; quit"

s3_upload: generate
s3cmd sync $(OUTPUTDIR)/ s3://$(S3_BUCKET) --acl-public --delete-removed --guess-mime-type

cf_upload: generate
cd $(OUTPUTDIR) && swift -v -A https://auth.api.rackspacecloud.com/v1.0 -U $(CLOUDFILES_USERNAME) -K $(CLOUDFILES_API_KEY) upload -c $(CLOUDFILES_CONTAINER) .

github: generate
# ghp-import -m "Generate Hugo site" -b $(GITHUB_PAGES_BRANCH) $(OUTPUTDIR)
# git push origin $(GITHUB_PAGES_BRANCH)
cd $(OUTPUTDIR)
git add --all
git commit -m "Update"
git push

.PHONY: all html help clean generate server ssh_upload rsync_upload dropbox_upload ftp_upload s3_upload cf_upload github






This Makefile is actually an extension of one dedicated Pelican static page generator






Summary



There are many creative ways to use Makefiles to automate and simplify daily tasks. Tool is small and simple, available on any platform (even on Windows via WSL or Cygwin). Many of my colleagues considered this tool an "old school" or "obsolete" initially, but they eventually fall under impression of the recipes simplicity and now just replicate them all around.



I hope, I will also impress you 😉 Good luck and happy automating!












  1. https://www.gnu.org/software/make/ ↩





  2. https://www.postfix.org/DATABASE_README.html ↩





  3. https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html ↩





  4. https://developer.hashicorp.com/terraform/language/settings/backends/configuration#partial-configuration ↩





  5. https://github.com/getpelican/pelican-blog/blob/main/Makefile ↩




SOC Incident Playbook: Remote Code Execution (RCE) Defense
title: Detect Exploitation - How I stopped worrying and loved Makefiles
id: 1f111d0d-8970-4350-bc20-945a929be3bb
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-24
logsource:
  category: network_connection
  product: any
detection:
  selection:
      CommandLine|contains:
        - 'exploit'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-24"
        description = "YARA Signature for "
    strings:
        $str = "How I stopped worrying and lov" ascii wide
    condition:
        any of them
}
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Kognitive Analyse für identifizierte Bedrohung: Erhöhte Bedrohungslage im Bereich How I stopped worrying and loved Makefil.... Basierend auf 368k Vektor-Korrelationen werden sofortige Isolationsmaßnahmen für betroffene Endpunkte empfohlen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
🔗 Semantisch verwandte Zero-Days MariaDB 11.7 VEC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten How I stopped worrying and loved Makefiles

Thematisch verwandte Begriffe: stopped, worrying, loved, Makefiles · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-96676 | A vulnerability was identified in Fast FAC1900R 20190827_2.0.2. The impa…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel TTP ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick