Attention: This is a students' project, not a (fully) functional product.
Adding a layer of protection in front of a web application does not guarantee perfect security. Always make sure to secure the main web application using best practices!
The Protective Reverse Proxy (PRP) is a Docker container to place in front of a web service to protect it.
All incoming requests towards the web application to protect are intercepted by the PRP and then redirected to the intrusion detection system (PRP core). The PRP system uses both neural networks and topic models to determine whether the request is malicious or benign. Benign requests are admitted and consequently forwarded to the protected web application. Requests classified as attacks are blocked and the system responds with a dummy html page.
See Installation ↓ for detailed step-by-step instructions. In most cases, it is enough to
simply download the docker-compose.yml
and run docker-compose up
in the directory. A dummy system (using an example application and a dummy model) is reachable at http(s)://localhost
.
- The system has to be installed via Docker. Hence, you need a server running Docker. It is recommended to use docker-compose.
- You need a web application to be protected by PRP. It works best if the application also runs in a Docker container.
- If the application does not run a Docker container, you have to make the host accessible in the network created by docker-compose. This can be achieved by using
extra_hosts
:
Add the following lines to the serviceprotection_proxy
extra_hosts: - "system-to-protect:host.docker.internal"
- Make sure to protect the application from direct access, such that it is only accessible via PRP.
- If the application does not run a Docker container, you have to make the host accessible in the network created by docker-compose. This can be achieved by using
- Create a custom
docker-compose.yml
, see the example here. Note the following remarks.volumes
- You should use SSL to access the application, PRP comes with a dummy certificate
which is insecure. Please bind-mount a custom certificate to
/etc/ssl/private/self_sslkey.pem
and/etc/ssl/certs/self_sslcert.pem
. - PRP comes with a default dummy model for the setup process, not optimized for security. Take a look
at the ModelGeneration
repository to generate your own models or contact us for a real model.
- A model is a directory containing an
index.json
file. Bind-mount the directory to/protection/model/
(as currently done with./models/dummy
).
- A model is a directory containing an
- Uncomment the bind-mount for
/proxy/logs
to preserve the logs generated whenLOG_REQUESTS
is active.
- You should use SSL to access the application, PRP comes with a dummy certificate
which is insecure. Please bind-mount a custom certificate to
environment
- See the Configuration Options ↓
- Only
BLOCK_CRAWLING
is required for basic usage.
ports
- Remove port
80
if the application should not be reachable via unencrypted requests. Also remove port443
if no custom SSL certificates were bind-mounted.
- Remove port
- Add the application
- Add a new service
system_to_protect
(by replacing/ changing the example application).
- Add a new service
- Start via
docker-compose up -d
- The application will be reachable at port 80 or 443.
- For a short period of time an error
502 – Bad gateway
will show up. This is caused by the PRP core starting up and loading the models. - Also take a look at Special Installation ↓ and Troubleshooting ↓.
- Configuring the used NGINX reverse proxy.
- The used configuration can be found here.
- The PRP core will redirect to the location
@protected
. - Bind-Mount a custom file via
./my-proxy.conf:/etc/nginx/sites-enabled/default
.
- Changing the code itself.
- See DEVELOPMENT →
All configuration is done via environmental variables which are listed and explained below.
They should be specified in the docker-compose.yml
.
BLOCK_CRAWLING
(required)true
orfalse
- Choose if request crawling, e.g., for security flaws should be blocked also. Only blocks attacks when
false
.
ALLOW_TYPES
(optional, default empty)- Empty or some of
sql,xss,tampering,execution,disclosure,overflows,encryption,cve,redirect
; separate by,
- Choose to allow requests of some attack types nevertheless they look malicious. Won't allow any types if empty.
- Empty or some of
BLOCK_TYPES
(optional, default empty)- Empty or some of
sql,xss,tampering,execution,disclosure,overflows,encryption,cve,redirect
; separate by,
- Choose one or more classes of attack types to block directly, e.g., to use together with
ALLOW_TYPES
. Will block any request looking malicious and not inALLOW_TYPES
if empty.
- Empty or some of
APPROACH_USE
(optional, defaultlda,nn
)lda
ornn
orlda,nn
- Determine which technique should be used for the proxy.
lda
specifies the model generated by our Topic Modeling approach.nn
specifies the usage of the model generated by the Neural Network approach. Iflda,nn
is specified, the system will use both techniques for classification and logically connect them viaAPPROACH_CONNECTOR
.
APPROACH_CONNECTOR
(optional, defaultor
)and
oror
- Specifies whether a request is assumed to be safe if both models consider it to be safe (
and
) or if it is sufficient for one model to consider the request to be safe (or
).
MAIL_HOST
(required ifMAIL_TO
is set)- SMTP server's hostname
- A hostname of the SMTP server to use when sending notification mails. The system uses authentication via STARTTLS.
MAIL_PORT
(required ifMAIL_TO
is set)- Port as integer value, e.g.
587
- The port for the SMTP server.
- Port as integer value, e.g.
MAIL_USERNAME
(required ifMAIL_TO
is set)- Username
- The username for the email account to send emails from.
MAIL_PASSWORD
(required ifMAIL_TO
is set)- Password as plain string (make sure to escape special chars according to docker-compose)
- The password for the email account to send emails from.
MAIL_FROM
(required ifMAIL_TO
is set)- Email address
- The email address which sends the notifications emails (
From
header).
MAIL_TO
(optional, default disables notifications)- Email address
- The email address which receives the notification emails.
SEND_DAILY_REPORT
(optional, defaultfalse
)true
orfalse
- Specifies whether a daily report of attack attempts should be sent to
the email address set via
MAIL_TO
. Requires allMAIL_*
to be set.
SEND_EMERGENCY
(optional, defaultfalse
)true
orfalse
- Specifies whether an emergency email should be sent to the email address
set via
MAIL_TO
. Such messages are sent whenever an attack arrives, but at most once per hour. Requires allMAIL_*
to be set.
ALLOW_AFTER_CAPTCHA
(optional, defaultfalse
)true
orfalse
- Specifies whether requests should be allowed after a captcha has been solved correctly.
LOG_REQUESTS
(optional, defaultnone
)all
orattack
ornone
- Specifies whether all requests, only attacks or no requests should be logged
to
/proxy/logs
to be learned later. The log may contain private data sent to the server.
- After configuring the SMTP email notifications you can send a test mail by
running
docker exec --user www-data protection_proxy python /proxy/mail.py
. Rundocker exec --user www-data protection_proxy python /proxy/mail.py --debug
to get debug output. - Logs can be found at
/tmp/prp.log
and printed bydocker exec --user www-data protection_proxy tail -n 20 /tmp/prp.log
. Only errors are logged by default.