Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions on-prem-ngwaf-integrations/k8s-apache-module/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# https://www.fastly.com/documentation/guides/next-gen-waf/setup-and-configuration/module-agent-deployment/apache-module/installing-the-apache-module/
FROM ubuntu:24.04

# Install Apache and utilities
RUN apt-get update && \
apt-get install -y apache2 apache2-utils apt-transport-https wget gnupg && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# Add the Fastly NGWAF package repository
RUN wget -qO - https://apt.signalsciences.net/release/gpgkey | gpg --dearmor -o /usr/share/keyrings/sigsci.gpg && \
echo "deb [signed-by=/usr/share/keyrings/sigsci.gpg] https://apt.signalsciences.net/release/ubuntu/ noble main" | tee /etc/apt/sources.list.d/sigsci-release.list && \
apt-get update

# Install the Apache NGWAF module
RUN apt-get install -y sigsci-module-apache && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# Enable the NGWAF module
RUN a2enmod signalsciences

# Set environment variables for Apache
ENV APACHE_RUN_USER=www-data
ENV APACHE_RUN_GROUP=www-data
ENV APACHE_LOG_DIR=/var/log/apache2
ENV APACHE_PID_FILE=/var/run/apache2/apache2.pid
ENV APACHE_RUN_DIR=/var/run/apache2
ENV APACHE_LOCK_DIR=/var/lock/apache2

# Create necessary directories
RUN mkdir -p /var/run/apache2 /var/lock/apache2

# Expose port 80
EXPOSE 80

# Start Apache in foreground mode
CMD ["apache2ctl", "-D", "FOREGROUND"]
81 changes: 81 additions & 0 deletions on-prem-ngwaf-integrations/k8s-apache-module/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
.DEFAULT_GOAL = help

KUBEDEPLOYMENT?=k8s-apache-module-agent
DEPLOYMENTFILE?=deployment.yaml
NAMESPACE?=fastly-waf

DOCKERNAME?=apache-module

help: # Show all commands
@egrep -h '\s#\s' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?\# "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'

docker: # Build and load the Apache module Docker image
docker build . -t my-local-images/apache-module:latest
kind load docker-image my-local-images/apache-module:latest
docker pull signalsciences/sigsci-agent:latest


drunexec: # Run Docker container locally for testing
@docker run --publish 8888:80 --name $(DOCKERNAME) -it my-local-images/apache-module:latest

dclean: # Stop and remove local Docker container
-docker kill $(DOCKERNAME)
-docker rm $(DOCKERNAME)

drerunexec: # Clean and re-run Docker container
make dclean
make drunexec

# Environment variables $NGWAFACCESSKEYID and $NGWAFACCESSKEYSECRET must already be set before running `make build`
build: # Build and deploy to Kubernetes
-@ kubectl create secret generic sigsci.my-site-name-here --from-literal=accesskeyid=${NGWAFACCESSKEYID} --from-literal=secretaccesskey=${NGWAFACCESSKEYSECRET}
# --namespace ${NAMESPACE}
kubectl apply -f deployment.yaml
-@ sleep 2
# -@ make demo

demo: # Port-forward service for testing
echo "curl 127.0.0.1:8080 -i"
kubectl port-forward service/k8s-apache-module-agent-service 8080:80

logs: # View NGWAF agent logs
kubectl get pods | tail -n1 | awk '{print $$1}' | xargs -I {} kubectl logs {} -c sigsci-agent
# kubectl get pods | tail -n1 | awk '{print $$1}' | xargs -I {} kubectl logs {} --all-containers=true

clean: # Delete Kubernetes resources
- kubectl delete -f deployment.yaml
sleep 3

# kubectl get deployments
# - kubectl get deployment $(KUBEDEPLOYMENT) | awk '{print $$1}' | xargs kubectl delete deployment
# - kubectl get services $(KUBEDEPLOYMENT)-lb | awk '{print $$1}' | xargs kubectl delete services
# - kubectl delete secret ngwaf-agent-keys

describe: # Describe pods
kubectl describe pods
# -n ${NAMESPACE}

get: # Get pods and services
- kubectl get pods
- kubectl get services
# - kubectl get services $(KUBEDEPLOYMENT)-lb


rebuild: # Clean and rebuild
make clean; make build

exec: # Get pod name and exec command
kubectl get pods | grep $(KUBEDEPLOYMENT) | awk '{print $$1}'
kubectl get pods | grep $(KUBEDEPLOYMENT) | awk '{print $$1}' | xargs -I {} echo kubectl exec --stdin --tty {} -c sigsci-agent -- /bin/sh

# kubectl get pods | grep $(KUBEDEPLOYMENT) | awk '{print $$1}' | xargs -I {} echo kubectl exec --stdin -c apache --tty {} -- /bin/sh

# kubectl exec --stdin --tty ngwaf-revproxy-123 -- /bin/sh

# helpful command when troubleshooting kubectl secrets
# https://kubernetes.io/docs/tasks/configmap-secret/managing-secret-using-kubectl/
# kubectl get secrets
# kubectl describe secret ngwaf-agent-keys
# kubectl get secret ngwaf-agent-keys -o jsonpath='{.data}' | jq .accesskeyid -r | base64 -D
# kubectl delete secret ngwaf-agent-keys
# k9s is great too
44 changes: 44 additions & 0 deletions on-prem-ngwaf-integrations/k8s-apache-module/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# k8s-apache-module

Kubernetes deployment of Apache with Fastly Next-Gen WAF (NGWAF) module on Ubuntu.

This deployment runs the Apache web server with the Fastly NGWAF module alongside the NGWAF agent as a sidecar container in the same pod.

## Architecture

- **Apache Container**: Ubuntu-based Apache with the Fastly NGWAF module installed
- **NGWAF Agent Sidecar**: The sigsci-agent container that communicates with the Fastly cloud
- **Shared Volume**: Unix socket communication between Apache module and agent via `/sigsci/tmp/sigsci.sock`

## Prerequisites

- Kubernetes cluster (kind, minikube, or other)
- kubectl configured to access your cluster
- Docker installed locally
- Fastly NGWAF credentials ([Accessing agent keys](https://www.fastly.com/documentation/guides/next-gen-waf/setup-and-configuration/accessing-agent-keys/))

## Quickstart

1. Set your NGWAF credentials as environment variables:
```bash
export NGWAFACCESSKEYID="your-access-key-id"
export NGWAFACCESSKEYSECRET="your-secret-access-key"
```

2. Build the Docker image and deploy:
```bash
make docker
make rebuild
```

3. Forward the service port and send test requests:
```bash
make demo
# In another terminal:
curl 127.0.0.1:8080
```

## Reference

- [Installing the Apache Module](https://www.fastly.com/documentation/guides/next-gen-waf/setup-and-configuration/module-agent-deployment/apache-module/installing-the-apache-module/)
- [Kubernetes Agent Module Deployment](https://www.fastly.com/documentation/guides/next-gen-waf/setup-and-configuration/kubernetes/kubernetes-agent-module/)
116 changes: 116 additions & 0 deletions on-prem-ngwaf-integrations/k8s-apache-module/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: k8s-apache-module-agent-config
data:
# Apache configuration for NGWAF module
# The sigsci_agent_host directive points to the Unix socket for agent communication
sigsci.conf: |
<IfModule sigsci_module>
SigSciAgentHost unix:/sigsci/tmp/sigsci.sock
</IfModule>
# Default site configuration
000-default.conf: |
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
# Simple index page
index.html: |
Hello World from Apache with Fastly Next-Gen WAF
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-apache-module-agent-deployment
spec:
replicas: 1
selector:
matchLabels:
app: k8s-apache-module-agent
template:
metadata:
labels:
app: k8s-apache-module-agent
spec:
containers:
- name: apache
image: my-local-images/apache-module:latest
imagePullPolicy: Never
ports:
- containerPort: 80
volumeMounts:
# Mount the NGWAF module configuration
- name: apache-config-volume
mountPath: /etc/apache2/conf-enabled/sigsci.conf
subPath: sigsci.conf
# Mount the default site configuration
- name: apache-config-volume
mountPath: /etc/apache2/sites-available/000-default.conf
subPath: 000-default.conf
# Mount the index page
- name: apache-config-volume
mountPath: /var/www/html/index.html
subPath: index.html
# Shared volume for NGWAF agent socket
- name: sigsci-tmp
mountPath: /sigsci/tmp
- name: sigsci-agent
# IMPORTANT: Use a specific version of the agent for production stability
image: signalsciences/sigsci-agent:latest # Replace with a specific agent version
imagePullPolicy: IfNotPresent # Recommended for versioned tags
env:
- name: SIGSCI_ACCESSKEYID
valueFrom:
secretKeyRef:
name: sigsci.my-site-name-here # References the Secret defined above
key: accesskeyid
- name: SIGSCI_SECRETACCESSKEY
valueFrom:
secretKeyRef:
name: sigsci.my-site-name-here # References the Secret defined above
key: secretaccesskey
- name: SIGSCI_DEBUG_LOG_BLOCKED_REQUESTS
value: "1"
- name: SIGSCI_DEBUG_LOG_WEB_INPUTS
value: "1"
- name: SIGSCI_DEBUG_LOG_CONFIG_UPDATES
value: "1"
- name: SIGSCI_DEBUG_LOG_CONFIG_UPLOADS
value: "1"
- name: SIGSCI_DEBUG_LOG_WEB_OUTPUTS
value: "1"
volumeMounts:
- name: sigsci-tmp
mountPath: /sigsci/tmp
volumes:
# This volume makes the ConfigMap data available to the containers
- name: apache-config-volume
configMap:
name: k8s-apache-module-agent-config
# https://www.fastly.com/documentation/guides/next-gen-waf/setup-and-configuration/kubernetes/kubernetes-agent-module/#agent-temporary-volume
- name: sigsci-tmp
emptyDir: {}
---
# This Service exposes the Apache deployment to external traffic.
apiVersion: v1
kind: Service
metadata:
# The name of the service.
name: k8s-apache-module-agent-service
spec:
# Type "NodePort" exposes the service on a static port on each node's IP.
type: NodePort
selector:
# This selector must match the labels of the pods you want to target.
# In this case, it matches the pods from our deployment.
app: k8s-apache-module-agent
ports:
# This section defines the port mapping.
- protocol: TCP
# The port that the service will be exposed on internally in the cluster.
port: 80
# The port on the container that traffic will be forwarded to.
targetPort: 80