README ¶
This is reverse proxy with automatic ClamAV scan for uploaded files.
Configuration
All configuration done with command line arguments
- -a --antivirus Antivirus binary file, default:
clamdscan
(binary release),/usr/bin/clamdscan
(docker release) - -d --destination Destination URL, default:
https://mockbin.com/request
- testing endpoint. - -p --port Port used for ProxyAV to listen on, default:
8080
- --response-code Response HTTP Status code if file contains a virus, default:
403
- --response-body Response body content if file contains a virus, default:
Uploaded file contains a virus
- --response-content-type Response Content-Type if file contains a virus, default:
text/plain
DataDog Integration
OPTIONAL. If you want ProxyAV to send service check to your DataDog monitoring, you can set DataDog API key (note: API Key, not personal keys) and other DataDog related configs with env vars. Works only in docker
- DD_APIKEY - if set, will enable DataDog Integration on internal healthcheck. Create it here
- DD_HOST - if set, will use the value as hostname for service check. Default:
hostname
(hostname of server) - DD_CHECK - if set, will use the value as service check name, Default:
proxyav
Usage
Integration with popular servers
NGINX
- copy server block for your website ("public" server block) and change
listen 80
tolisten 127.0.0.1:80
in copied block to allow only localhost connections to new server (remove other listen commands in copied server block) - if you want to use ProxyAV on specific endpoint(-s) add following locations to original "public" server block:
location = /your/endpoint/to/use/with/proxyav {
# If ProxyAV listens on localhost:8080
proxy_pass http://localhost:8080;
# you may use X-Real-IP here, if you don't want to use X-Forwarded-For
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Example - All requests through ProxyAV
add to nginx.conf
# "Public" server, internet/LB facing
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name your-website.com;
location / {
proxy_pass http://localhost:8080;
# you may use X-Real-IP here, if you don't want to use X-Forwarded-For
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
# LOCAL server, without ProxyAV
server {
listen 127.0.0.1:80;
server_name localhost;
root /var/app/current/public;
index index.php index.html;
client_max_body_size 100M;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$is_args$args;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
location ~* ^.+\.(jpg|jpeg|gif|png|bmp|js|css)$ {
include /etc/nginx/cors.conf;
try_files $uri $uri/ /index.php?$is_args$args;
expires max;
etag on;
}
location ~ \.php(?:$|/) {
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_intercept_errors on;
fastcgi_read_timeout 600;
}
location ~ /\.ht {
deny all;
}
}
Example - Only exact endpoints to scan
Full example:
add to nginx.conf
# "Public" server, internet/LB facing
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name your-website.com;
root /var/app/current/public;
index index.php index.html;
client_max_body_size 100M;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$is_args$args;
}
location = /your/endpoint/to/use/with/proxyav {
proxy_pass http://localhost:8080;
# you may use X-Real-IP here, if you don't want to use X-Forwarded-For
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
location ~* ^.+\.(jpg|jpeg|gif|png|bmp|js|css)$ {
include /etc/nginx/cors.conf;
try_files $uri $uri/ /index.php?$is_args$args;
expires max;
etag on;
}
location ~ \.php(?:$|/) {
include /etc/nginx/cors.conf;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param modHeadersAvailable true;
fastcgi_cache php;
fastcgi_cache_valid 200 60m;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_intercept_errors on;
fastcgi_read_timeout 600;
}
location ~ /\.ht {
deny all;
}
}
# LOCAL server, without ProxyAV
server {
listen 127.0.0.1:80;
server_name localhost;
root /var/app/current/public;
index index.php index.html;
client_max_body_size 100M;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$is_args$args;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
location ~* ^.+\.(jpg|jpeg|gif|png|bmp|js|css)$ {
include /etc/nginx/cors.conf;
try_files $uri $uri/ /index.php?$is_args$args;
expires max;
etag on;
}
location ~ \.php(?:$|/) {
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param modHeadersAvailable true;
fastcgi_cache php;
fastcgi_cache_valid 200 60m;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_intercept_errors on;
fastcgi_read_timeout 600;
}
location ~ /\.ht {
deny all;
}
}
Run
Golang
go install gitlab.com/rakshazi/proxyav
proxyav -h
Binary
curl https://gitlab.com/rakshazi/proxyav/-/jobs/artifacts/master/raw/proxyav?job=binary --output proxyav
chmod +x ./proxyav
./proxyav -h
Docker
Images
latest
(~210MB size) image contains ProxyAV, ClamAV and up-to-date ClamAV databases (daily builds)slim
(~20MB size) image contains only ProxyAV and ClamAV, databases not included. Usefull for new envs setups and for testing purposes
Commands
docker run -d -p 8080:8080 registry.gitlab.com/rakshazi/proxyav
Use
Help
proxyav -h
Send request
curl http://localhost:8080/any/path/you/want?even=withquery -F anyfieldname=@anyfilename.exe -F another=field
Click to show internal directories.
Click to hide internal directories.