Added support for \aikido\should_whitelist_request API + tests + docs #2859
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build | |
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| branches: | |
| - main | |
| workflow_call: | |
| jobs: | |
| build_libs: | |
| name: Build Go libs ${{ matrix.arch == '' && 'x86_64' || 'arm' }} | |
| runs-on: ubuntu-24.04${{ matrix.arch }} | |
| container: | |
| image: ghcr.io/aikidosec/firewall-php-build-libs:v1 | |
| strategy: | |
| matrix: | |
| arch: [ '', '-arm' ] | |
| fail-fast: false | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 | |
| - name: Get Arch | |
| run: echo "ARCH=$(uname -m)" >> $GITHUB_ENV | |
| - name: Get Aikido version | |
| run: | | |
| AIKIDO_VERSION=$(grep '#define PHP_AIKIDO_VERSION' lib/php-extension/include/php_aikido.h | awk -F'"' '{print $2}') | |
| echo $AIKIDO_VERSION | |
| echo "AIKIDO_VERSION=$AIKIDO_VERSION" >> $GITHUB_ENV | |
| echo "AIKIDO_INTERNALS_REPO=https://api.github.com/repos/AikidoSec/zen-internals" >> $GITHUB_ENV | |
| - name: Build Aikido Agent | |
| run: | | |
| cd lib | |
| protoc --go_out=agent --go-grpc_out=agent ipc.proto | |
| cd agent | |
| go get main/ipc/protos | |
| go get google.golang.org/grpc | |
| go get github.com/stretchr/testify/assert | |
| go test ./... | |
| go build -buildvcs=false -ldflags "-s -w" -o ../../build/aikido-agent | |
| ls -l ../../build | |
| - name: Build Aikido Request Processor | |
| run: | | |
| cd lib | |
| protoc --go_out=request-processor --go-grpc_out=request-processor ipc.proto | |
| cd request-processor | |
| go mod tidy | |
| go get google.golang.org/grpc | |
| go get github.com/stretchr/testify/assert | |
| go get main/ipc/protos | |
| go test ./... | |
| go build -ldflags "-s -w" -buildmode=c-shared -o ../../build/aikido-request-processor.so | |
| ls -l ../../build | |
| - name: Archive agent | |
| uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4 | |
| if: always() | |
| with: | |
| name: aikido-agent-${{ env.ARCH }} | |
| if-no-files-found: error | |
| path: | | |
| ${{ github.workspace }}/build/aikido-agent | |
| - name: Archive request processor | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: aikido-request-processor-${{ env.ARCH }} | |
| if-no-files-found: error | |
| path: | | |
| ${{ github.workspace }}/build/aikido-request-processor.so | |
| build_php_extension_nts: | |
| name: Build php ${{ matrix.php_version }} extension NTS ${{ matrix.arch == '' && 'x86_64' || 'arm' }} | |
| runs-on: ubuntu-24.04${{ matrix.arch }} | |
| container: ghcr.io/aikidosec/firewall-php-build-extension-nts:${{ matrix.php_version }}-v2 | |
| strategy: | |
| matrix: | |
| php_version: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5'] | |
| arch: [ '', '-arm' ] | |
| fail-fast: false | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Get Arch | |
| run: echo "ARCH=$(uname -m)" >> $GITHUB_ENV | |
| - name: Get Aikido version | |
| run: | | |
| AIKIDO_VERSION=$(grep '#define PHP_AIKIDO_VERSION' lib/php-extension/include/php_aikido.h | awk -F'"' '{print $2}') | |
| echo $AIKIDO_VERSION | |
| echo "AIKIDO_VERSION=$AIKIDO_VERSION" >> $GITHUB_ENV | |
| echo "AIKIDO_ARTIFACT=aikido-extension-php-${{ matrix.php_version }}" >> $GITHUB_ENV | |
| - name: Check PHP setup | |
| run: | | |
| php -v | grep -v "ZTS" > /dev/null || (echo "ERROR: PHP is ZTS, expected NTS!" && php -v && exit 1) | |
| - name: Build extension | |
| run: | | |
| rm -rf build | |
| mkdir build | |
| cd lib/php-extension | |
| phpize | |
| cd ../../build | |
| CXX=g++ CXXFLAGS="-fPIC -g -O2 -I../lib/php-extension/include" LDFLAGS="-lstdc++" ../lib/php-extension/configure | |
| make -j"$(nproc)" | |
| - name: Version Aikido extension | |
| run: | | |
| cd ./build/modules | |
| mv aikido.so ${{ env.AIKIDO_ARTIFACT }}-nts.so | |
| - name: Archive build artifacts | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: ${{ env.AIKIDO_ARTIFACT }}-nts-${{ env.ARCH }} | |
| if-no-files-found: error | |
| path: | | |
| ${{ github.workspace }}/build/modules/${{ env.AIKIDO_ARTIFACT }}-nts.so | |
| ${{ github.workspace }}/tests/*.diff | |
| build_php_extension_zts: | |
| name: Build php ${{ matrix.php_version }} extension ZTS ${{ matrix.arch == '' && 'x86_64' || 'arm' }} | |
| runs-on: ubuntu-24.04${{ matrix.arch }} | |
| container: ghcr.io/aikidosec/firewall-php-build-extension-zts:${{ matrix.php_version }}-v2 | |
| strategy: | |
| matrix: | |
| php_version: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5'] | |
| arch: [ '', '-arm' ] | |
| fail-fast: false | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Get Arch | |
| run: echo "ARCH=$(uname -m)" >> $GITHUB_ENV | |
| - name: Get Aikido version | |
| run: | | |
| AIKIDO_VERSION=$(grep '#define PHP_AIKIDO_VERSION' lib/php-extension/include/php_aikido.h | awk -F'"' '{print $2}') | |
| echo $AIKIDO_VERSION | |
| echo "AIKIDO_VERSION=$AIKIDO_VERSION" >> $GITHUB_ENV | |
| echo "AIKIDO_ARTIFACT=aikido-extension-php-${{ matrix.php_version }}" >> $GITHUB_ENV | |
| - name: Check PHP setup | |
| run: | | |
| php -v | grep -q "ZTS" || (echo "ERROR: PHP is not ZTS!" && php -v && exit 1) | |
| - name: Build extension | |
| run: | | |
| rm -rf build | |
| mkdir build | |
| cd lib/php-extension | |
| phpize | |
| cd ../../build | |
| CXX=g++ CXXFLAGS="-fPIC -g -O2 -I../lib/php-extension/include" LDFLAGS="-lstdc++" ../lib/php-extension/configure | |
| make -j"$(nproc)" | |
| - name: Version Aikido extension | |
| run: | | |
| cd ./build/modules | |
| mv aikido.so ${{ env.AIKIDO_ARTIFACT }}-zts.so | |
| - name: Archive build artifacts | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: ${{ env.AIKIDO_ARTIFACT }}-zts-${{ env.ARCH }} | |
| if-no-files-found: error | |
| path: | | |
| ${{ github.workspace }}/build/modules/${{ env.AIKIDO_ARTIFACT }}-zts.so | |
| ${{ github.workspace }}/tests/*.diff | |
| build_rpm: | |
| name: Build rpm ${{ matrix.arch == '' && 'x86_64' || 'arm' }} | |
| runs-on: ubuntu-24.04${{ matrix.arch }} | |
| container: | |
| image: quay.io/centos/centos:stream9 | |
| strategy: | |
| matrix: | |
| arch: ['', '-arm'] | |
| fail-fast: false | |
| needs: [ build_libs, build_php_extension_nts, build_php_extension_zts ] | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install rpmdevtools | |
| run: | | |
| yum -y install epel-release | |
| yum -y install rpmdevtools | |
| yum -y install jq | |
| - name: Get Arch | |
| run: echo "ARCH=$(uname -m)" >> $GITHUB_ENV | |
| - name: Get Aikido version | |
| run: | | |
| AIKIDO_VERSION=$(grep '#define PHP_AIKIDO_VERSION' lib/php-extension/include/php_aikido.h | awk -F'"' '{print $2}') | |
| echo $AIKIDO_VERSION | |
| echo "AIKIDO_VERSION=$AIKIDO_VERSION" >> $GITHUB_ENV | |
| echo "AIKIDO_LIBZEN=libzen_internals_${{ env.ARCH }}-unknown-linux-gnu.so" >> $GITHUB_ENV | |
| echo "AIKIDO_LIBZEN_VERSION=0.1.60" >> $GITHUB_ENV | |
| - name: Download artifacts (NTS) | |
| uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4 | |
| with: | |
| pattern: | | |
| aikido-extension-php-*-nts-${{ env.ARCH }} | |
| - name: Download artifacts (ZTS) | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: | | |
| aikido-extension-php-*-zts-${{ env.ARCH }} | |
| - name: Download artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: | | |
| aikido-agent-${{ env.ARCH }} | |
| - name: Download artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: | | |
| aikido-request-processor-${{ env.ARCH }} | |
| - name: Download Aikido Zen Internals Lib | |
| run: | | |
| curl -L -O https://github.com/AikidoSec/zen-internals/releases/download/v${{ env.AIKIDO_LIBZEN_VERSION }}/${{ env.AIKIDO_LIBZEN }} | |
| - name: Verify Aikido Zen Internals Lib SHA256 | |
| run: | | |
| EXPECTED_SHA256=$(curl -s https://api.github.com/repos/AikidoSec/zen-internals/releases/tags/v${{ env.AIKIDO_LIBZEN_VERSION }} | jq -r '.assets[] | select(.name == "${{ env.AIKIDO_LIBZEN }}") | .digest' | sed 's/sha256://') | |
| ACTUAL_SHA256=$(sha256sum ${{ env.AIKIDO_LIBZEN }} | awk '{print $1}') | |
| echo "Expected SHA256: $EXPECTED_SHA256" | |
| echo "Actual SHA256: $ACTUAL_SHA256" | |
| if [ "$EXPECTED_SHA256" != "$ACTUAL_SHA256" ]; then | |
| echo "SHA256 mismatch! Downloaded file may be corrupted or tampered with." | |
| exit 1 | |
| fi | |
| echo "SHA256 verification passed!" | |
| - name: Prepare rpm package | |
| run: | | |
| mv aikido-agent-${{ env.ARCH }}/aikido-agent package/rpm/opt/aikido/aikido-agent | |
| mv aikido-request-processor-${{ env.ARCH }}/aikido-request-processor.so package/rpm/opt/aikido/aikido-request-processor.so | |
| mv ${{ env.AIKIDO_LIBZEN }} package/rpm/opt/aikido/${{ env.AIKIDO_LIBZEN }} | |
| # Copy NTS extensions | |
| for dir in aikido-extension-php-*-nts-*/; do | |
| if [ -d "$dir" ]; then | |
| find "$dir" -name "aikido-extension-php-*-nts.so" -exec mv {} package/rpm/opt/aikido/ \; | |
| fi | |
| done | |
| # Copy ZTS extensions | |
| for dir in aikido-extension-php-*-zts-*/; do | |
| if [ -d "$dir" ]; then | |
| find "$dir" -name "aikido-extension-php-*-zts.so" -exec mv {} package/rpm/opt/aikido/ \; | |
| fi | |
| done | |
| echo "Extensions in package:" | |
| ls -la package/rpm/opt/aikido/aikido-extension-php-*.so || true | |
| mv package/rpm/opt/aikido package/rpm/opt/aikido-${{ env.AIKIDO_VERSION }} | |
| chmod 777 package/rpm/opt/aikido-${{ env.AIKIDO_VERSION }}/* | |
| rpmdev-setuptree | |
| mkdir -p ~/rpmbuild/SOURCES/aikido-php-firewall-${{ env.AIKIDO_VERSION }} | |
| cp -rf package/rpm/opt ~/rpmbuild/SOURCES/aikido-php-firewall-${{ env.AIKIDO_VERSION }}/ | |
| cp -f package/rpm/aikido.spec ~/rpmbuild/SPECS/ | |
| - name: Setup RPM for prod | |
| run: | | |
| echo "AIKIDO_ARTIFACT=aikido-php-firewall-$AIKIDO_VERSION-1.${{ env.ARCH }}.rpm" >> $GITHUB_ENV | |
| echo "AIKIDO_ARTIFACT_RELEASE=aikido-php-firewall.${{ env.ARCH }}.rpm" >> $GITHUB_ENV | |
| sed -i "s/aikido.so/aikido-${{ env.AIKIDO_VERSION }}.so/" ~/rpmbuild/SOURCES/aikido-php-firewall-${{ env.AIKIDO_VERSION }}/opt/aikido-${{ env.AIKIDO_VERSION }}/aikido.ini | |
| - name: Build rpm package | |
| run: | | |
| cat /usr/lib/rpm/macros | grep level | |
| cd ~/rpmbuild/SOURCES | |
| tar czvf ~/rpmbuild/SOURCES/aikido-php-firewall-${{ env.AIKIDO_VERSION }}.tar.gz * | |
| rm -rf ~/rpmbuild/SOURCES/aikido-php-firewall-${{ env.AIKIDO_VERSION }} | |
| rpmbuild --define "_binary_payload w9.gzdio" --define "_source_payload w9.gzdio" -ba ~/rpmbuild/SPECS/aikido.spec | |
| ls -l ~/rpmbuild/RPMS/${{ env.ARCH }}/ | |
| mv ~/rpmbuild/RPMS/${{ env.ARCH }}/${{ env.AIKIDO_ARTIFACT }} ~/rpmbuild/RPMS/${{ env.ARCH }}/${{ env.AIKIDO_ARTIFACT_RELEASE }} | |
| - name: Check rpm dependencies | |
| run: | | |
| yum deplist ~/rpmbuild/RPMS/${{ env.ARCH }}/${{ env.AIKIDO_ARTIFACT_RELEASE }} | grep -E "GLIBC_2.32|GLIBC_2.34|GLIBCXX_3.4.26|GLIBCXX_3.4.29" && exit 1 || exit 0 | |
| - name: Archive rpm package | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.AIKIDO_ARTIFACT_RELEASE }} | |
| if-no-files-found: error | |
| path: | | |
| ~/rpmbuild/RPMS/${{ env.ARCH }}/${{ env.AIKIDO_ARTIFACT_RELEASE }} | |
| build_deb: | |
| name: Build deb ${{ matrix.arch == '' && 'x86_64' || 'arm' }} | |
| runs-on: ubuntu-24.04${{ matrix.arch }} | |
| container: | |
| image: ubuntu:22.04 | |
| strategy: | |
| matrix: | |
| arch: [ '', '-arm' ] | |
| fail-fast: false | |
| needs: [ build_rpm ] | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Get Arch | |
| run: echo "ARCH=$(uname -m)" >> $GITHUB_ENV | |
| - name: Get deb arch | |
| run: | | |
| if [ "${{ env.ARCH }}" = "x86_64" ]; then | |
| echo "DEB_ARCH=amd64" >> $GITHUB_ENV | |
| elif [ "$ARCH" = "aarch64" ]; then | |
| echo "DEB_ARCH=arm64" >> $GITHUB_ENV | |
| else | |
| echo "DEB_ARCH=${{ env.ARCH }}" >> $GITHUB_ENV | |
| fi | |
| - name: Download artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: | | |
| aikido-php-firewall.${{ env.ARCH }}.rpm | |
| - name: Install dependencies | |
| run: | | |
| DEBIAN_FRONTEND=noninteractive apt-get update | |
| DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata | |
| ln -fs /usr/share/zoneinfo/Etc/UTC /etc/localtime | |
| echo "Etc/UTC" > /etc/timezone | |
| DEBIAN_FRONTEND=noninteractive dpkg-reconfigure -f noninteractive tzdata | |
| apt-get install -y alien | |
| - name: Get Aikido version | |
| run: | | |
| AIKIDO_VERSION=$(grep '#define PHP_AIKIDO_VERSION' lib/php-extension/include/php_aikido.h | awk -F'"' '{print $2}') | |
| echo $AIKIDO_VERSION | |
| echo "AIKIDO_VERSION=$AIKIDO_VERSION" >> $GITHUB_ENV | |
| echo "AIKIDO_RPM=aikido-php-firewall.${{ env.ARCH }}.rpm" >> $GITHUB_ENV | |
| echo "AIKIDO_ARTIFACT=aikido-php-firewall.${{ env.ARCH }}.deb" >> $GITHUB_ENV | |
| - name: Build deb | |
| run: | | |
| alien --to-deb --scripts --keep-version ${{ env.AIKIDO_RPM }}/${{ env.AIKIDO_RPM }} | |
| mv aikido-php-firewall_${{ env.AIKIDO_VERSION }}-1_${{ env.DEB_ARCH }}.deb temp-${{ env.AIKIDO_ARTIFACT }} | |
| # Package contents into deb with gzip compression (because default zstd compression is not supported by older versions of dpkg) | |
| mkdir deb-temp | |
| dpkg-deb -R temp-${{ env.AIKIDO_ARTIFACT }} deb-temp/ | |
| dpkg-deb -Zgzip -b deb-temp ${{ env.AIKIDO_ARTIFACT }} | |
| rm -rf deb-temp | |
| - name: Archive deb package | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.AIKIDO_ARTIFACT }} | |
| if-no-files-found: error | |
| path: | | |
| ${{ env.AIKIDO_ARTIFACT }} | |
| test_php_centos: | |
| name: CentOS NTS php-${{ matrix.php_version }} ${{ matrix.server }} ${{ matrix.arch == '' && 'x86_64' || 'arm' }} | |
| runs-on: ubuntu-24.04${{ matrix.arch }} | |
| container: | |
| image: ghcr.io/aikidosec/firewall-php-test-centos-nts:${{ matrix.php_version }}-v2 | |
| options: --privileged | |
| needs: [ build_rpm ] | |
| strategy: | |
| matrix: | |
| php_version: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5'] | |
| server: ['nginx-php-fpm', 'apache-mod-php', 'php-built-in'] | |
| arch: ['', '-arm'] | |
| fail-fast: false | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup | |
| run: | | |
| uname -a | |
| cat /etc/centos-release | |
| php -v | |
| httpd -v || true | |
| nginx -v || true | |
| which php-fpm && php-fpm -v || true | |
| rpm -qa | grep -E '^php(-|$)' | sort | |
| - name: Install and start MySQL | |
| run: | | |
| mkdir -p /var/lib/mysql | |
| mysqld --initialize-insecure --datadir=/var/lib/mysql | |
| mysqld -u root --datadir=/var/lib/mysql --socket=/var/lib/mysql/mysql.sock & | |
| sleep 10 | |
| mysql -u root -e "CREATE DATABASE IF NOT EXISTS db;" | |
| mysql -u root -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'pwd'; FLUSH PRIVILEGES;" | |
| - name: Test MySQL connection with mysqli | |
| run: | | |
| php -r ' | |
| $mysqli = new mysqli("localhost", "root", "pwd", "db"); | |
| if ($mysqli->connect_error) { | |
| echo "MySQL connection failed: " . $mysqli->connect_error . "\n"; | |
| exit(1); | |
| } else { | |
| echo "MySQL connection successful\n"; | |
| $mysqli->close(); | |
| } | |
| ' | |
| - name: Get Arch | |
| run: echo "ARCH=$(uname -m)" >> $GITHUB_ENV | |
| - name: Check PHP setup | |
| run: | | |
| uname -m | |
| php -v | |
| php -i | |
| - name: Get Aikido version | |
| run: | | |
| AIKIDO_VERSION=$(grep '#define PHP_AIKIDO_VERSION' lib/php-extension/include/php_aikido.h | awk -F'"' '{print $2}') | |
| echo $AIKIDO_VERSION | |
| echo "AIKIDO_VERSION=$AIKIDO_VERSION" >> $GITHUB_ENV | |
| echo "AIKIDO_RPM=aikido-php-firewall.${{ env.ARCH }}.rpm" >> $GITHUB_ENV | |
| - name: Download artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: | | |
| ${{ env.AIKIDO_RPM }} | |
| - name: Install RPM | |
| run: | | |
| rpm -Uvh --oldpackage ${{ env.AIKIDO_RPM }}/${{ env.AIKIDO_RPM }} | |
| - name: Run CLI tests | |
| run: | | |
| export TEST_PHP_EXECUTABLE=/usr/bin/php | |
| cd lib/php-extension/ | |
| phpize | |
| cd ../../ | |
| php lib/php-extension/run-tests.php ./tests/cli | |
| - name: Run ${{ matrix.server }} server tests | |
| run: | | |
| cd tools | |
| python3 run_server_tests.py ../tests/server ../tests/testlib --server=${{ matrix.server }} --max-runs=3 | |
| test_php_ubuntu: | |
| name: Ubuntu NTS php-${{ matrix.php_version }} ${{ matrix.server }} ${{ matrix.arch == '' && 'x86_64' || 'arm' }} | |
| runs-on: ubuntu-24.04${{ matrix.arch }} | |
| container: | |
| image: ghcr.io/aikidosec/firewall-php-test-ubuntu-nts:${{ matrix.php_version }}-v2 | |
| options: --privileged | |
| needs: [ build_deb ] | |
| strategy: | |
| matrix: | |
| arch: ['', '-arm'] | |
| php_version: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5'] | |
| server: ['nginx-php-fpm', 'apache-mod-php', 'php-built-in'] | |
| fail-fast: false | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Get Arch | |
| run: echo "ARCH=$(uname -m)" >> $GITHUB_ENV | |
| - name: Set env | |
| run: | | |
| AIKIDO_VERSION=$(grep '#define PHP_AIKIDO_VERSION' lib/php-extension/include/php_aikido.h | awk -F'"' '{print $2}') | |
| echo $AIKIDO_VERSION | |
| echo "AIKIDO_VERSION=$AIKIDO_VERSION" >> $GITHUB_ENV | |
| echo "AIKIDO_DEB=aikido-php-firewall.${{ env.ARCH }}.deb" >> $GITHUB_ENV | |
| - name: Download artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: | | |
| ${{ env.AIKIDO_DEB }} | |
| - name: Prepare php-fpm | |
| if: matrix.server == 'nginx-php-fpm' | |
| run: | | |
| # Verify NTS-built PHP-FPM exists and is NTS (not ZTS-enabled) | |
| /usr/local/sbin/php-fpm -v | |
| /usr/local/sbin/php-fpm -i | grep -q "Thread Safety => disabled" || (echo "ERROR: PHP-FPM not built with NTS!" && exit 1) | |
| # Create symlink for nginx to find php-fpm | |
| ln -sf /usr/local/sbin/php-fpm /usr/sbin/php-fpm || true | |
| # Verify symlink works | |
| php-fpm -i | grep -q "Thread Safety => disabled" || (echo "ERROR: php-fpm symlink not working or not NTS!" && exit 1) | |
| # MariaDB startup compatible with your current approach | |
| - name: Start MariaDB (background) | |
| run: | | |
| start-mariadb & # provided by the image | |
| sleep 5 | |
| mysql -u root -ppwd -e "SELECT 1" || (echo "MySQL not up" && exit 1) | |
| - name: Install DEB | |
| run: | | |
| dpkg -i -E ${{ env.AIKIDO_DEB }}/${{ env.AIKIDO_DEB }} | |
| - name: Run CLI tests | |
| run: | | |
| export TEST_PHP_EXECUTABLE=/usr/local/bin/php | |
| cd lib/php-extension/ | |
| phpize | |
| cd ../../ | |
| php lib/php-extension/run-tests.php ./tests/cli | |
| - name: Run ${{ matrix.server }} server tests | |
| run: | | |
| . /etc/apache2/envvars | |
| cd tools | |
| python3 run_server_tests.py ../tests/server ../tests/testlib --server=${{ matrix.server }} --max-runs=3 | |
| test_php_ubuntu_zts: | |
| name: Ubuntu ZTS php-${{ matrix.php_version }} ${{ matrix.server }} ${{ matrix.arch == '' && 'x86_64' || 'arm' }} | |
| runs-on: ubuntu-24.04${{ matrix.arch }} | |
| container: | |
| image: ghcr.io/aikidosec/firewall-php-test-ubuntu-zts:${{ matrix.php_version }}-v2 | |
| options: --privileged | |
| needs: [ build_deb ] | |
| strategy: | |
| matrix: | |
| arch: ['', '-arm'] | |
| php_version: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5'] | |
| server: ['nginx-php-fpm', 'php-built-in'] | |
| fail-fast: false | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Get Arch | |
| run: echo "ARCH=$(uname -m)" >> $GITHUB_ENV | |
| - name: Set env | |
| run: | | |
| AIKIDO_VERSION=$(grep '#define PHP_AIKIDO_VERSION' lib/php-extension/include/php_aikido.h | awk -F'"' '{print $2}') | |
| echo $AIKIDO_VERSION | |
| echo "AIKIDO_VERSION=$AIKIDO_VERSION" >> $GITHUB_ENV | |
| echo "AIKIDO_DEB=aikido-php-firewall.${{ env.ARCH }}.deb" >> $GITHUB_ENV | |
| - name: Verify ZTS is enabled | |
| run: | | |
| php -v | grep -q "ZTS" || (echo "ERROR: ZTS not enabled!" && exit 1) | |
| php -v | |
| - name: Download artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: | | |
| ${{ env.AIKIDO_DEB }} | |
| - name: Prepare php-fpm | |
| if: matrix.server == 'nginx-php-fpm' | |
| run: | | |
| # Verify ZTS-built PHP-FPM exists and is ZTS-enabled | |
| /usr/local/sbin/php-fpm -v | |
| /usr/local/sbin/php-fpm -i | grep -q "Thread Safety => enabled" || (echo "ERROR: PHP-FPM not built with ZTS!" && exit 1) | |
| # Create symlink for nginx to find php-fpm | |
| ln -sf /usr/local/sbin/php-fpm /usr/sbin/php-fpm || true | |
| # Verify symlink works | |
| php-fpm -i | grep -q "Thread Safety => enabled" || (echo "ERROR: php-fpm symlink not working or not ZTS!" && exit 1) | |
| - name: Start MariaDB (background) | |
| run: | | |
| start-mariadb & # provided by the image | |
| sleep 5 | |
| mysql -u root -ppwd -e "SELECT 1" || (echo "MySQL not up" && exit 1) | |
| - name: Install DEB | |
| run: | | |
| dpkg -i -E ${{ env.AIKIDO_DEB }}/${{ env.AIKIDO_DEB }} | |
| - name: Run CLI tests | |
| run: | | |
| export TEST_PHP_EXECUTABLE=/usr/local/bin/php | |
| cd lib/php-extension/ | |
| phpize | |
| cd ../../ | |
| php lib/php-extension/run-tests.php ./tests/cli | |
| - name: Run ${{ matrix.server }} server tests | |
| run: | | |
| cd tools | |
| python3 run_server_tests.py ../tests/server ../tests/testlib --server=${{ matrix.server }} --max-runs=3 | |
| test_php_centos_zts: | |
| name: CentOS ZTS php-${{ matrix.php_version }} ${{ matrix.server }} ${{ matrix.arch == '' && 'x86_64' || 'arm' }} | |
| runs-on: ubuntu-24.04${{ matrix.arch }} | |
| container: | |
| image: ghcr.io/aikidosec/firewall-php-test-centos-zts:${{ matrix.php_version }}-v2 | |
| options: --privileged | |
| needs: [ build_rpm ] | |
| strategy: | |
| matrix: | |
| php_version: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5'] | |
| server: ['nginx-php-fpm', 'php-built-in'] | |
| arch: ['', '-arm'] | |
| fail-fast: false | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup | |
| run: | | |
| uname -a | |
| cat /etc/centos-release || cat /etc/redhat-release || echo "CentOS/Stream detected" | |
| php -v | |
| nginx -v || true | |
| which php-fpm && php-fpm -v || true | |
| - name: Verify ZTS is enabled | |
| run: | | |
| php -v | grep -q "ZTS" || (echo "ERROR: ZTS not enabled!" && exit 1) | |
| php -v | |
| - name: Install and start MySQL | |
| run: | | |
| mkdir -p /var/lib/mysql | |
| mysqld --initialize-insecure --datadir=/var/lib/mysql | |
| mysqld -u root --datadir=/var/lib/mysql --socket=/var/lib/mysql/mysql.sock & | |
| sleep 10 | |
| mysql -u root -e "CREATE DATABASE IF NOT EXISTS db;" | |
| mysql -u root -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'pwd'; FLUSH PRIVILEGES;" | |
| - name: Test MySQL connection with mysqli | |
| run: | | |
| php -r ' | |
| $mysqli = new mysqli("localhost", "root", "pwd", "db"); | |
| if ($mysqli->connect_error) { | |
| echo "MySQL connection failed: " . $mysqli->connect_error . "\n"; | |
| exit(1); | |
| } else { | |
| echo "MySQL connection successful\n"; | |
| $mysqli->close(); | |
| } | |
| ' | |
| - name: Get Arch | |
| run: echo "ARCH=$(uname -m)" >> $GITHUB_ENV | |
| - name: Check PHP setup | |
| run: | | |
| uname -m | |
| php -v | |
| php -i | head -20 | |
| - name: Get Aikido version | |
| run: | | |
| AIKIDO_VERSION=$(grep '#define PHP_AIKIDO_VERSION' lib/php-extension/include/php_aikido.h | awk -F'"' '{print $2}') | |
| echo $AIKIDO_VERSION | |
| echo "AIKIDO_VERSION=$AIKIDO_VERSION" >> $GITHUB_ENV | |
| echo "AIKIDO_RPM=aikido-php-firewall.${{ env.ARCH }}.rpm" >> $GITHUB_ENV | |
| - name: Download artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: | | |
| ${{ env.AIKIDO_RPM }} | |
| - name: Install RPM | |
| run: | | |
| rpm -Uvh --oldpackage ${{ env.AIKIDO_RPM }}/${{ env.AIKIDO_RPM }} | |
| - name: Run CLI tests | |
| run: | | |
| export TEST_PHP_EXECUTABLE=/usr/local/bin/php | |
| cd lib/php-extension/ | |
| phpize | |
| cd ../../ | |
| php lib/php-extension/run-tests.php ./tests/cli | |
| - name: Run ${{ matrix.server }} server tests | |
| run: | | |
| cd tools | |
| python3 run_server_tests.py ../tests/server ../tests/testlib --server=${{ matrix.server }} --max-runs=3 | |
| test_php_frankenphp: | |
| name: CentOS FrankenPHP php-${{ matrix.php_version }} ${{ matrix.server }} ${{ matrix.arch == '' && 'x86_64' || 'arm' }} | |
| runs-on: ubuntu-24.04${{ matrix.arch }} | |
| container: | |
| image: ghcr.io/aikidosec/firewall-php-test-centos-zts:${{ matrix.php_version }}-v2 | |
| options: --privileged | |
| needs: [ build_rpm ] | |
| strategy: | |
| matrix: | |
| php_version: ['8.2', '8.3', '8.4', '8.5'] | |
| server: ['frankenphp-worker', 'frankenphp-classic'] | |
| arch: ['', '-arm'] | |
| fail-fast: false | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup | |
| run: | | |
| uname -a | |
| cat /etc/centos-release || cat /etc/redhat-release || echo "CentOS/Stream detected" | |
| php -v | |
| command -v frankenphp && frankenphp -v || (echo "ERROR: FrankenPHP not found!" && exit 1) | |
| - name: Verify ZTS is enabled | |
| run: | | |
| php -v | grep -q "ZTS" || (echo "ERROR: ZTS not enabled!" && exit 1) | |
| php -v | |
| - name: Install and start MySQL | |
| run: | | |
| mkdir -p /var/lib/mysql | |
| mysqld --initialize-insecure --datadir=/var/lib/mysql | |
| mysqld -u root --datadir=/var/lib/mysql --socket=/var/lib/mysql/mysql.sock & | |
| sleep 10 | |
| mysql -u root -e "CREATE DATABASE IF NOT EXISTS db;" | |
| mysql -u root -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'pwd'; FLUSH PRIVILEGES;" | |
| - name: Test MySQL connection with mysqli | |
| run: | | |
| php -r ' | |
| $mysqli = new mysqli("localhost", "root", "pwd", "db"); | |
| if ($mysqli->connect_error) { | |
| echo "MySQL connection failed: " . $mysqli->connect_error . "\n"; | |
| exit(1); | |
| } else { | |
| echo "MySQL connection successful\n"; | |
| $mysqli->close(); | |
| } | |
| ' | |
| - name: Get Arch | |
| run: echo "ARCH=$(uname -m)" >> $GITHUB_ENV | |
| - name: Get Aikido version | |
| run: | | |
| AIKIDO_VERSION=$(grep '#define PHP_AIKIDO_VERSION' lib/php-extension/include/php_aikido.h | awk -F'"' '{print $2}') | |
| echo $AIKIDO_VERSION | |
| echo "AIKIDO_VERSION=$AIKIDO_VERSION" >> $GITHUB_ENV | |
| echo "AIKIDO_RPM=aikido-php-firewall.${{ env.ARCH }}.rpm" >> $GITHUB_ENV | |
| - name: Download artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: | | |
| ${{ env.AIKIDO_RPM }} | |
| - name: Install RPM | |
| run: | | |
| rpm -Uvh --oldpackage ${{ env.AIKIDO_RPM }}/${{ env.AIKIDO_RPM }} | |
| - name: Run ${{ matrix.server }} server tests | |
| run: | | |
| cd tools | |
| python3 run_server_tests.py ../tests/server ../tests/testlib --server=${{ matrix.server }} --max-runs=3 | |
| test_php_frankenphp_ubuntu: | |
| name: Ubuntu FrankenPHP php-${{ matrix.php_version }} ${{ matrix.server }} ${{ matrix.arch == '' && 'x86_64' || 'arm' }} | |
| runs-on: ubuntu-24.04${{ matrix.arch }} | |
| container: | |
| image: ghcr.io/aikidosec/firewall-php-test-ubuntu-zts:${{ matrix.php_version }}-v2 | |
| options: --privileged | |
| needs: [ build_deb ] | |
| strategy: | |
| matrix: | |
| php_version: ['8.2', '8.3', '8.4', '8.5'] | |
| server: ['frankenphp-worker', 'frankenphp-classic'] | |
| arch: ['', '-arm'] | |
| fail-fast: false | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Get Arch | |
| run: echo "ARCH=$(uname -m)" >> $GITHUB_ENV | |
| - name: Set env | |
| run: | | |
| AIKIDO_VERSION=$(grep '#define PHP_AIKIDO_VERSION' lib/php-extension/include/php_aikido.h | awk -F'"' '{print $2}') | |
| echo $AIKIDO_VERSION | |
| echo "AIKIDO_VERSION=$AIKIDO_VERSION" >> $GITHUB_ENV | |
| echo "AIKIDO_DEB=aikido-php-firewall.${{ env.ARCH }}.deb" >> $GITHUB_ENV | |
| - name: Verify ZTS is enabled | |
| run: | | |
| php -v | grep -q "ZTS" || (echo "ERROR: ZTS not enabled!" && exit 1) | |
| php -v | |
| - name: Verify FrankenPHP is installed | |
| run: | | |
| command -v frankenphp && frankenphp -v || (echo "ERROR: FrankenPHP not found!" && exit 1) | |
| - name: Start MariaDB (background) | |
| run: | | |
| start-mariadb & # provided by the image | |
| sleep 5 | |
| mysql -u root -ppwd -e "SELECT 1" || (echo "MySQL not up" && exit 1) | |
| - name: Download artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: | | |
| ${{ env.AIKIDO_DEB }} | |
| - name: Install DEB | |
| run: | | |
| dpkg -i -E ${{ env.AIKIDO_DEB }}/${{ env.AIKIDO_DEB }} | |
| - name: Run ${{ matrix.server }} server tests | |
| run: | | |
| cd tools | |
| python3 run_server_tests.py ../tests/server ../tests/testlib --server=${{ matrix.server }} --max-runs=3 | |
| test_php_qa_action_controlling_tests_apache_mod_php: | |
| name: QA apache-mod-php | |
| runs-on: ubuntu-latest | |
| needs: [ build_deb ] | |
| steps: | |
| - name: Checkout zen-demo-php | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: Aikido-demo-apps/zen-demo-php | |
| path: zen-demo-php | |
| ref: apache-mod-php-control-server | |
| submodules: recursive | |
| - name: Get Arch | |
| run: echo "ARCH=$(uname -m)" >> $GITHUB_ENV | |
| - name: Download artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: aikido-php-firewall.${{ env.ARCH }}.deb | |
| path: ./zen-demo-php | |
| - name: Overwrite aikido.sh install script | |
| run: | | |
| echo "#!/usr/bin/env bash" > ./zen-demo-php/.fly/scripts/aikido.sh | |
| echo "dpkg -i -E \"/var/www/html/aikido-php-firewall.\$(uname -i).deb\"" >> ./zen-demo-php/.fly/scripts/aikido.sh | |
| - name: Run Firewall QA Tests | |
| uses: AikidoSec/firewall-tester-action@releases/v1 | |
| with: | |
| dockerfile_path: ./zen-demo-php/Dockerfile | |
| extra_args: '--env-file=./zen-demo-php/.env.example -e APP_KEY=base64:W2v6u6VR4lURkxuMT9xZ6pdhXSt5rxsmWTbd1HGqlIM=' | |
| sleep_before_test: 20 | |
| max_parallel_tests: 7 | |
| test_type: control | |
| test_php_qa_action_controlling_tests_apache_php_fpm: | |
| name: QA apache-php-fpm | |
| runs-on: ubuntu-latest | |
| needs: [ build_deb ] | |
| steps: | |
| - name: Checkout zen-demo-php | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: Aikido-demo-apps/zen-demo-php | |
| path: zen-demo-php | |
| ref: apache-php-fpm-control-server | |
| submodules: recursive | |
| - name: Get Arch | |
| run: echo "ARCH=$(uname -m)" >> $GITHUB_ENV | |
| - name: Download artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: aikido-php-firewall.${{ env.ARCH }}.deb | |
| path: ./zen-demo-php | |
| - name: Overwrite aikido.sh install script | |
| run: | | |
| echo "#!/usr/bin/env bash" > ./zen-demo-php/.fly/scripts/aikido.sh | |
| echo "dpkg -i -E \"/var/www/html/aikido-php-firewall.\$(uname -i).deb\"" >> ./zen-demo-php/.fly/scripts/aikido.sh | |
| - name: Run Firewall QA Tests | |
| uses: AikidoSec/firewall-tester-action@releases/v1 | |
| with: | |
| dockerfile_path: ./zen-demo-php/Dockerfile | |
| extra_args: '--env-file=./zen-demo-php/.env.example -e APP_KEY=base64:W2v6u6VR4lURkxuMT9xZ6pdhXSt5rxsmWTbd1HGqlIM=' | |
| sleep_before_test: 20 | |
| max_parallel_tests: 7 | |
| test_type: control | |
| test_php_qa_action_controlling_tests_nginx_php_fpm: | |
| name: QA nginx-php-fpm | |
| runs-on: ubuntu-latest | |
| needs: [ build_deb ] | |
| steps: | |
| - name: Checkout zen-demo-php | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: Aikido-demo-apps/zen-demo-php | |
| path: zen-demo-php | |
| ref: nginx-php-fpm-control-server | |
| submodules: recursive | |
| - name: Get Arch | |
| run: echo "ARCH=$(uname -m)" >> $GITHUB_ENV | |
| - name: Download artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: aikido-php-firewall.${{ env.ARCH }}.deb | |
| path: ./zen-demo-php | |
| - name: Overwrite aikido.sh install script | |
| run: | | |
| echo "#!/usr/bin/env bash" > ./zen-demo-php/.fly/scripts/aikido.sh | |
| echo "dpkg -i -E \"/var/www/html/aikido-php-firewall.\$(uname -i).deb\"" >> ./zen-demo-php/.fly/scripts/aikido.sh | |
| - name: Run Firewall QA Tests | |
| uses: AikidoSec/firewall-tester-action@releases/v1 | |
| with: | |
| dockerfile_path: ./zen-demo-php/Dockerfile | |
| extra_args: '--env-file=./zen-demo-php/.env.example -e APP_KEY=base64:W2v6u6VR4lURkxuMT9xZ6pdhXSt5rxsmWTbd1HGqlIM=' | |
| sleep_before_test: 20 | |
| max_parallel_tests: 7 | |
| test_type: control | |
| test_php_qa_action: | |
| permissions: { contents: read } | |
| name: Tests (zen-demo-php) | |
| runs-on: ubuntu-latest | |
| needs: [ build_deb ] | |
| steps: | |
| - name: Checkout zen-demo-php | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: Aikido-demo-apps/zen-demo-php | |
| path: zen-demo-php | |
| ref: dev-testing | |
| submodules: recursive | |
| - name: Get Arch | |
| run: echo "ARCH=$(uname -m)" >> $GITHUB_ENV | |
| - name: Download artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: aikido-php-firewall.${{ env.ARCH }}.deb | |
| path: ./zen-demo-php | |
| - name: Overwrite aikido.sh install script | |
| run: | | |
| echo "dpkg -i -E \"/var/www/html/aikido-php-firewall.\$(uname -i).deb\"" > ./zen-demo-php/.fly/scripts/aikido.sh | |
| - name: Run Firewall QA Tests | |
| uses: AikidoSec/firewall-tester-action@v1.0.3 | |
| with: | |
| dockerfile_path: ./zen-demo-php/Dockerfile | |
| extra_args: '--env-file=./zen-demo-php/.env.example -e APP_KEY=base64:W2v6u6VR4lURkxuMT9xZ6pdhXSt5rxsmWTbd1HGqlIM=' | |
| sleep_before_test: 30 | |
| max_parallel_tests: 7 | |
| config_update_delay: 120 | |
| test_timeout: 900 | |
| skip_tests: test_ssrf,test_stored_ssrf_no_context,test_stored_ssrf |