Running API Firewall on Docker for REST API¶
This guide walks through downloading, installing, and starting Wallarm API Firewall on Docker for REST API request validation.
Requirements¶
-  
OpenAPI 3.0 specification developed for the REST API of the application that should be protected with Wallarm API Firewall
 
Methods to run API Firewall on Docker¶
The fastest method to deploy API Firewall on Docker is Docker Compose. The steps below rely on using this method.
If required, you can also use docker run. We have provided proper docker run commands to deploy the same environment in this section.
Step 1. Create the docker-compose.yml file¶
 To deploy API Firewall and proper environment using Docker Compose, create the docker-compose.yml with the following content first:
version: '3.8'
networks:
  api-firewall-network:
    name: api-firewall-network
services:
  api-firewall:
    container_name: api-firewall
    image: wallarm/api-firewall:v0.9.3
    restart: on-failure
    volumes:
      - <HOST_PATH_TO_SPEC>:<CONTAINER_PATH_TO_SPEC>
    environment:
      APIFW_API_SPECS: <PATH_TO_MOUNTED_SPEC>
      APIFW_URL: http://0.0.0.0:8088/
      APIFW_SERVER_URL: <PROTECTED_APP_URL>
      APIFW_REQUEST_VALIDATION: <REQUEST_VALIDATION_MODE>
      APIFW_RESPONSE_VALIDATION: <RESPONSE_VALIDATION_MODE>
    ports:
      - "8088:8088"
    stop_grace_period: 1s
    networks:
      - api-firewall-network
  backend:
    container_name: api-firewall-backend
    image: kennethreitz/httpbin
    restart: on-failure
    ports:
      - 80:80
    stop_grace_period: 1s
    networks:
      - api-firewall-network
Step 2. Configure the Docker network¶
If required, change the Docker network configuration defined in docker-compose.yml → networks.
The provided docker-compose.yml instructs Docker to create the network api-firewall-network and link the application and API Firewall containers to it.
It is recommended to use a separate Docker network to allow the containerized application and API Firewall communication without manual linking.
Step 3. Configure the application to be protected with API Firewall¶
Change the configuration of the containerized application to be protected with API Firewall. This configuration is defined in docker-compose.yml → services.backend.
The provided docker-compose.yml instructs Docker to start the kennethreitz/httpbin Docker container connected to the api-firewall-network and assigned with the backend network alias. The container port is 80.
If configuring your own application, define only settings required for the correct application container start. No specific configuration for API Firewall is required.
Step 4. Configure API Firewall¶
Configure API Firewall as follows:
-  
With
services.api-firewall.volumes, mount the OpenAPI 3.0 specification to the API Firewall container directory:<HOST_PATH_TO_SPEC>: the path to the OpenAPI 3.0 specification for your application REST API located on the host machine. The accepted file formats are YAML and JSON (.yaml,.yml,.jsonfile extensions). For example:/opt/my-api/openapi3/swagger.json.<CONTAINER_PATH_TO_SPEC>: the path to the container directory to mount the OpenAPI 3.0 specification to. For example:/api-firewall/resources/swagger.json.
 -  
Set the general API Firewall configuration using one of the approaches:
- With 
services.api-firewall.environment, pass environment variables to docker-compose.yml →services.api-firewall. - With 
services.api-firewall.volumes, mount theapifw.yamlconfiguation file to the API Firewall container directory. 
Priority
If both specified, values in
apifw.yamlhave priority over environment variables. - With 
 
| Environment variable | YAML parameter | Description | Required? | 
|---|---|---|---|
APIFW_API_SPECS |  APISpecs |  Path to the OpenAPI 3.0 specification. There are the following ways to specify the path:
  |  Yes | 
APIFW_URL |  Server → APIHost |  URL for API Firewall. For example: http://0.0.0.0:8088/. The port value should correspond to the container port published to the host.If API Firewall listens to the HTTPS protocol, please mount the generated SSL/TLS certificate and private key to the container, and pass to the container the API Firewall SSL/TLS settings. The default value is http://0.0.0.0:8282/. |  Yes | 
APIFW_SERVER_URL |  Backend → ProtectedAPI → URL | URL of the application described in the mounted OpenAPI specification that should be protected with API Firewall. For example: http://backend:80. |  Yes | 
APIFW_REQUEST_VALIDATION |  RequestValidation |  API Firewall mode when validating requests sent to the application URL:
  |  Yes | 
APIFW_RESPONSE_VALIDATION |  ResponseValidation |  API Firewall mode when validating application responses to incoming requests:
  |  Yes | 
APIFW_LOG_LEVEL |  - | API Firewall logging level. Possible values:
 DEBUG. Logs on requests and responses that do not match the provided schema have the ERROR type. |  No | 
APIFW_CUSTOM_BLOCK_STATUS_CODE |  CustomBlockStatusCode |  HTTP response status code returned by API Firewall operating in the BLOCK mode if the request or response does not match the schema provided in the mounted OpenAPI 3.0 specification. The default value is 403. |  No | 
APIFW_ADD_VALIDATION_STATUS_HEADER(EXPERIMENTAL)  |  AddValidationStatusHeader |  Whether to return the header Apifw-Validation-Status containing the reason for the request blocking in the response to this request. The value can be true or false. The default value is false. |  No | 
APIFW_SERVER_DELETE_ACCEPT_ENCODING |  DeleteAcceptEncoding |  If it is set to true, the Accept-Encoding header is deleted from proxied requests. The default value is false. |  No | 
APIFW_LOG_FORMAT |  - | The format of API Firewall logs. The value can be TEXT or JSON. The default value is TEXT. |  No | 
APIFW_SHADOW_API_EXCLUDE_LIST(only if API Firewall is operating in the LOG_ONLY mode for both the requests and responses) |  ShadowAPI → ExcludeList |  HTTP response status codes indicating that the requested API endpoint that is not included in the specification is NOT a shadow one. You can specify several status codes separated by a semicolon (e.g. 404;401). The default value is 404.By default, API Firewall operating in the LOG_ONLY mode for both the requests and responses marks all endpoints that are not included in the specification and are returning the code different from 404 as the shadow ones. |  No | 
APIFW_MODE |  mode |  Sets the general API Firewall mode. Possible values are PROXY (default), graphql and API. |  No | 
APIFW_PASS_OPTIONS |  PassOptionsRequests |  When set to true, the API Firewall allows OPTIONS requests to endpoints in the specification, even if the OPTIONS method is not described. The default value is false. |  No | 
APIFW_SHADOW_API_UNKNOWN_PARAMETERS_DETECTION |  ShadowAPI → UnknownParametersDetection |  This specifies whether requests are identified as non-matching the specification if their parameters do not align with those defined in the OpenAPI specification. The default value is true.If running API Firewall in the API mode, this variable takes on a different name APIFW_API_MODE_UNKNOWN_PARAMETERS_DETECTION. |  No | 
APIFW_API_SPECS_CUSTOM_HEADER_NAME |  APISpecsCustomHeader → Name |  Specifies the custom header name to be added to requests for your OpenAPI specification URL (defined in APIFW_API_SPECS). For example, you can specify a header name for authentication data required to access the URL. |  No | 
APIFW_API_SPECS_CUSTOM_HEADER_VALUE |  APISpecsCustomHeader → Value |  Specifies the custom header value to be added to requests for your OpenAPI specification URL. For example, you can specify authentication data for the custom header defined in APIFW_API_SPECS_CUSTOM_HEADER_NAME to access the URL. |  No | 
APIFW_SPECIFICATION_UPDATE_PERIOD |  SpecificationUpdatePeriod |  Specifies the interval for updating the OpenAPI specification from the hosted URL (defined in APIFW_API_SPECS). The default value is 0, which disables updates and uses the initially downloaded specification. The value format is: 5s, 1h, etc. |  No | 
APIFW_MODSEC_CONF_FILES |  ModSecurity → ConfFiles |  Allows to set the list of ModSecurity configuration files. The delimiter is ;. The default value is [] (empty). Example: APIFW_MODSEC_CONF_FILES=modsec.conf;crs-setup.conf.example. |  No | 
APIFW_MODSEC_RULES_DIR |  ModSecurity → RulesDir |  Allows to set the ModSecurity directory with the rules that should be loaded. The files with the *.conf wildcard will be loaded from the directory. The default value is "". |  No | 
APIFW_SERVER_REQUEST_HOST_HEADER |  RequestHostHeader |  Sets a custom Host header for requests forwarded to your backend after API Firewall validation. |  No | 
APIFW_MODSEC_REQUEST_VALIDATION |  ModSecurity → RequestValidation |  Defines how requests to the application URL are validated against the ModSecurity Rule Set.
 APIFW_REQUEST_VALIDATION. |  No | 
APIFW_MODSEC_RESPONSE_VALIDATION |  ModSecurity → ResponseValidation |  Defines how application responses are validated against the ModSecurity Rule Set.
 APIFW_RESPONSE_VALIDATION. |  No | 
Example of apifw.yaml
 mode: "PROXY"
RequestValidation: "BLOCK"
ResponseValidation: "BLOCK"
ModSecurity:
  RequestValidation: "LOG_ONLY"
  ResponseValidation: "LOG_ONLY"
CustomBlockStatusCode: 403
AddValidationStatusHeader: false
APISpecs: "openapi.yaml"
APISpecsCustomHeader:
  Name: ""
  Value: ""
PassOptionsRequests: true
SpecificationUpdatePeriod: "0"
Server:
  APIHost: "http://0.0.0.0:8282"
  HealthAPIHost: "0.0.0.0:9999"
  ReadTimeout: "5s"
  WriteTimeout: "5s"
  ReadBufferSize: 8192
  WriteBufferSize: 8192
  MaxRequestBodySize: 4194304
  DisableKeepalive: false
  MaxConnsPerIP: 0
  MaxRequestsPerConn: 0
DNS:
  Nameserver:
    Host: ""
    Port: "53"
    Proto: "udp"
  Cache: false
  FetchTimeout: "1m"
  LookupTimeout: "1s"
Denylist:
  Tokens:
    CookieName: ""
    HeaderName: ""
    TrimBearerPrefix: true
    File: ""
AllowIP:
  File: ""
  HeaderName: ""
ShadowAPI:
  ExcludeList:
    - 404
    - 200
  UnknownParametersDetection: false
TLS:
  CertsPath: "certs"
  CertFile: "localhost.crt"
  CertKey: "localhost.key"
ModSecurity:
  ConfFiles: []
  RulesDir: ""
Endpoints: []
Backend:
  Oauth:
    ValidationType: "JWT"
    JWT:
      SignatureAlgorithm: "RS256"
      PubCertFile: ""
      SecretKey: ""
    Introspection:
      ClientAuthBearerToken: ""
      Endpoint: ""
      EndpointParams: ""
      TokenParamName: ""
      ContentType: ""
      EndpointMethod: "GET"
      RefreshInterval: "10m"
  ProtectedAPI:
    URL: "http://localhost:3000/v1/"
    RequestHostHeader: ""
    ClientPoolCapacity: 1000
    InsecureConnection: false
    RootCA: ""
    MaxConnsPerHost: 512
    ReadTimeout: "5s"
    WriteTimeout: "5s"
    DialTimeout: "200ms"
    ReadBufferSize: 8192
    WriteBufferSize: 8192
    MaxResponseBodySize: 0
    DeleteAcceptEncoding: false
With services.api-firewall.ports and services.api-firewall.networks, set the API Firewall container port and connect the container to the created network. The provided docker-compose.yml instructs Docker to start API Firewall connected to the api-firewall-network network on the port 8088.
Step 5. Deploy the configured environment¶
To build and start the configured environment, run the following command:
docker-compose up -d --force-recreate
To check the log output:
docker-compose logs -f
Step 6. Test API Firewall operation¶
To test API Firewall operation, send the request that does not match the mounted Open API 3.0 specification to the API Firewall Docker container address. For example, you can pass the string value in the parameter that requires the integer value.
If the request does not match the provided API schema, the appropriate ERROR message will be added to the API Firewall Docker container logs.
Step 7. Enable traffic on API Firewall¶
To finalize the API Firewall configuration, please enable incoming traffic on API Firewall by updating your application deployment scheme configuration. For example, this would require updating the Ingress, NGINX, or load balancer settings.
Stopping the deployed environment¶
To stop the environment deployed using Docker Compose, run the following command:
docker-compose down
Using docker run to start API Firewall¶
 To start API Firewall on Docker, you can also use regular Docker commands as in the examples below:
-  
To create a separate Docker network to allow the containerized application and API Firewall communication without manual linking:
docker network create api-firewall-network -  
To start the containerized application to be protected with API Firewall:
docker run --rm -it --network api-firewall-network \ --network-alias backend -p 80:80 kennethreitz/httpbin -   
docker run --rm -it --network api-firewall-network --network-alias api-firewall \ -v <HOST_PATH_TO_SPEC>:<CONTAINER_PATH_TO_SPEC> -e APIFW_API_SPECS=<PATH_TO_MOUNTED_SPEC> \ -e APIFW_URL=<API_FIREWALL_URL> -e APIFW_SERVER_URL=<PROTECTED_APP_URL> \ -e APIFW_REQUEST_VALIDATION=<REQUEST_VALIDATION_MODE> -e APIFW_RESPONSE_VALIDATION=<RESPONSE_VALIDATION_MODE> \ -p 8088:8088 wallarm/api-firewall:v0.9.3 -  
When the environment is started, test it and enable traffic on API Firewall following steps 6 and 7.