Pixi-CRS goes to the Cloud - Part 5 : GitHub Actions
Tags: waf, crs, pixi, gha
Published: 2020-10-20 07:43:31

---
series: Pixi-CRS goes to the Cloud
title: Pixi-CRS goes to the Cloud - Part 5 : GitHub Actions
published: true
description:
tags: WAF, CRS, Pixi, GHA
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/htnn8ftqznf8v03pc0cg.png
---

The fourth pipeline I implemented Pixi-CRS in was GitHub Actions (GHA): https://github.com/features/actions.

This is the fifth blog post in the "Pixi-CRS goes to the Cloud" series.

This is how Pixi-CRS looks on GitHub Actions:

![Pixi-CRS as GitHub Actions](https://dev-to-uploads.s3.amazonaws.com/i/htnn8ftqznf8v03pc0cg.png)

## Pixi-CRS Pipeline Code

GitHub Actions is not a cloud provider like I described in the earlier blog posts in this series. GitHub Actions is "only" a CI / CD pipeline, but very easy to configure and therefore very lightweight. I like that!
The code behind the pipeline can be found [here](https://github.com/DevSlop/pixi-crs/blob/master/.github/workflows/pixi-crs-ci.yml). 
GitHub Actions are written in yaml files inside the ./github/workflows subdirectory of the repository. It's pretty easy to get started with GitHub Actions. No need to configure anything. Adding a yaml file in the named directory is enough and the Actions can be run.

Let's have a closer look at our ./github/workflows/pixi-crs-ci.yml file.

I will explain the different steps below. But I also give explanations in the comments in the provided yaml file.

```yaml
name: Pixi-CRS CI Pipeline

# Trigger the workflow on push
# and pull requests
on: [push, pull_request]

jobs:
  build:
    name: Start Pixi and the CRS
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@master

#      - name: Debugging 
#        run: pwd
#      - name: Debugging 
#        run: ls

      - name: Starting Pixi and CRS with docker-compose up
        run: docker-compose -f docker-compose.yaml --env-file compose-gcp.env up -d

        # Application Tests with Testcafe
        # skip-js-errors because of: Uncaught Error: Bootstrap tooltips require Tether
      - name: Run Testcafe Tests Pixi without and with CRS
        run: docker run --volume /home/runner/work/pixi-crs/pixi-crs/testcafe/tests_container_ip:/tests --rm testcafe/testcafe --skip-js-errors 'chromium:headless --no-sandbox'

        # Show Full error.log
      - name: Show ModSecurity logs
        run: docker exec crs cat /var/log/apache2/error.log

        # 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
      - name: Fail if ModSecurity logs are not empty
        run: 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

        # Fail if ModSecurity log does not contain WAF Test String "MyEvilWAFTest"
        # That means CRS is not working properly or test was aborted.
      - name: Fail if WAF Test String is missing in ModSecurity logs
        run: 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
```


## Pipeline Steps

### Start Pixi and the CRS

We start Pixi and the CRS with one docker-compose up command and provide an --env-file. We don't need to install Docker or docker-compose, since it's already there. 

### Testcafe tests

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.

For our tests, we call Pixi via http://172.17.0.1:8000 and the CRS via http://172.17.0.1:8080  because we call them from inside the Testcafe Docker container.

And this is how the Testcafe test output looks:

![TestCafe Output GitHub Actions](https://dev-to-uploads.s3.amazonaws.com/i/faky2lhay0r4jq8il4gg.png)

### Check results

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.

## Trigger

Because Pixi-CRS is a CI pipeline and we want to run our GitHub Actions after every push and pull request, we need to configure a trigger. 
I added this in [our ./github/workflows/pixi-crs-ci.yml file](https://github.com/DevSlop/pixi-crs/blob/master/.github/workflows/pixi-crs-ci.yml#L5) by adding the following lines:

```yaml
# Trigger the workflow on push
# and pull requests
on: [push, pull_request]
```

## Things to mention

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. 

## Next blog post

In the next and final blog post of this series I will sum up and compare all five available Pixi-CRS pipelines on CircleCI, Amazon Web Services, Azure DevOps, Google Cloud Platform and GitHub Actions.