The second cloud provider to which I moved Pixi-CRS was Microsoft Azure DevOps: https://dev.azure.com/.
This is the third blog post in the "Pixi-CRS goes to the Cloud" series.
This is how Pixi-CRS looks on the Microsoft Azure DevOps Pipeline:
In the image above, we see that the Pixi-CRS CI Pipeline on Azure DevOps is configured as Azure DevOps > Pixi-CRS > Pipeline.
The code behind the pipeline can be found here.
Azure DevOps pipeline code is written in azure-pipeline.yml files in the root directory of the repository. It's quite easy to create a new pipeline project on Azure DevOps.
Let's take a closer look at this azure-pipelines.yml file.
I will explain the different steps below. But I also give explanations in the comments in the provided yaml file.
# Azure DevOps azure-pipelines.yml trigger: # Branch to trigger - master stages: # Start the OWASP ModSecurity Core Rule Set and Pixi with its DB with docker-compose # OWASP ModSecurity Core Rule Set Container (Apache Reverse Proxy) # owasp/modsecurity-crs # See https://coreruleset.org/ # ModSecurity Tuning: # See https://www.netnea.com/cms/apache-tutorial-8_handling-false-positives-modsecurity-core-rule-set/ - stage: StartContainersAndTests jobs: - job: BuildJob steps: # Debugging # - script: pwd # - script: ls - task: DockerCompose@0 displayName: Start Pixi and CRS inputs: containerregistrytype: 'Container Registry' dockerComposeFile: '**/docker-compose.yaml' action: 'Run a Docker Compose command' dockerComposeFileArgs: | CRSPORTHTTP=8080 PROXYLOCATION=http://app:8000/ dockerComposeCommand: 'up -d' # Application Tests with Testcafe # skip-js-errors because of: Uncaught Error: Bootstrap tooltips require Tether # Another way: https://devexpress.github.io/testcafe/documentation/continuous-integration/azure-devops.html # Debugging #- script: docker ps - script: docker run --volume /home/vsts/work/1/s/testcafe/tests_container_ip/:/tests testcafe/testcafe --skip-js-errors 'chromium:headless --no-sandbox' displayName: Run Testcafe Tests without and with CRS # Show Full error.log - script: docker exec crs cat /var/log/apache2/error.log displayName: Show ModSecurity logs # ModSecurity Log Analysis: # Fail if ModSecurity log is not empty # Show ModSecurity logs of Testcafe Tests # If not empty -> Repair your application OR # -> ModSecurity Tuning: # See https://www.netnea.com/cms/apache-tutorial-8_handling-false-positives-modsecurity-core-rule-set/ OR # -> GitHub issue: https://github.com/SpiderLabs/owasp-modsecurity-crs - script: if docker exec crs cat /var/log/apache2/error.log | grep ModSecurity | grep -vi MyEvilWAFTest | grep -v 949110 | grep -v 980130 | grep msg; then echo "False Positive Found! Aborting!" && exit 1 ; else echo "ModSecurity Logs empty. This is good!"; fi displayName: Fail if ModSecurity logs are not empty # Fail if ModSecurity log does not contain WAF Test String "MyEvilWAFTest" # That means CRS is not working properly or test was aborted. - script: if docker exec crs cat /var/log/apache2/error.log | grep ModSecurity | grep MyEvilWAFTest; then echo "WAF Test String Found. This is good!"; else echo "WAF Test String not Found! Aborting!" && exit 1; fi displayName: Fail if WAF Test String is missing in ModSecurity logs
We start Pixi and the CRS with one docker-compose up command. We don't need to install Docker or docker-compose, it's already provided. But we need to configure a few things like the dockerComposeFileArgs, for example.
Then we start Pixi and the CRS with the dockerComposeCommand "up -d".
Now that the CRS and Pixi are running, we perform the Testcafe tests. This time we can run the tests with the testcafe/testcafe Docker container. The tests can be mounted easily into this container.
Again, first, we test Pixi directly, then we test Pixi through the CRS. We also test the CRS itself with a malicious string. We want to ensure that the WAF blocks it.
And this is how the Testcafe test output looks:
In the end, we check the results. We take a look at the ModSecurity log inside the CRS Docker container.
This is an important step that ensures that we did not have any false positives with our legitimate tests. In addition, we ensure that our malicious test was logged.
Because Pixi-CRS is a CI pipeline and we want to run our Azure DevOps pipeline project after every push into the repository, we need to configure a trigger on push events.
I added this via the "trigger: -master" entry in the azure-pipeline.yml file.
Pixi-CRS is a CI Pipeline and I did not configure the CD part.
In this blog post, I only wanted to show the CI part. And I'm also aware that a lot more Azure DevOps options are available. But for this blog post, I wanted to keep it simple and concentrate on the Pixi-CRS CI part.
In the next blog post, we will learn the Pixi-CRS pipeline on Google Cloud Platform.