Selective access howto
Let's say you need to leave certain machines out of your http server. Passive
fingerprinting to the rescue!
http
This example uses
nginx
sub-requests
for authorization on a particular location. It could be ported to apache, but I don't know how.
Location /nowin
is the selective authorization. It delegates the request to
/auth
, which is a proxy-pass to a local-only, not exposed service that we'll
be running.
location /nowin {
auth_request /auth;
auth_request_set $auth_status $upstream_status;
error_page 403 /403.html;
}
location /auth {
internal;
proxy_pass http://localhost:8000;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Forwarded-For $remote_addr;
}
A nice detail is to specify a custom 403 template, like this one:
<html>
<head><title>403 Forbidden for windows</title></head>
<body>
<center><h1>403 Forbidden for windows</h1></center>
<center>please upgrade your client</center>
<hr><center>nginx/1.18.0 (Ubuntu)</center>
</body>
</html>
p0f
I'm using a fork that attempted to modernize a bit the original from Zalewski:
sudo apt install libcap-ng-dev
git clone https://github.com/eteran/libp0f
cd libp0f
mkdir build && cd build
cmake .. && make
We have to pass the interface (if not the default) and the path to the unix
socket where our service will connect:
❯ sudo ./p0f -i wlp0s20f3 -s /var/run/p0f.socket
--- p0f 3.09b by Michal Zalewski <lcamtuf@coredump.cx> ---
[+] Closed 1 file descriptor.
[+] Loaded 322 signatures from 'p0f.fp'.
[+] Intercepting traffic on interface 'wlp0s20f3'.
[#] Computed rule: tcp or (vlan and tcp)
[+] Default packet filtering configured [+VLAN].
[+] Listening on API socket '/var/run/p0f.socket' (max 20 clients).
[+] Entered main event loop.
auth proxypass
Compile and run the go module in this repo.
Runs on port 8000 by default. The service will query p0f's in memory database
via the binary API over the unix domain socket: If the info p0f has gathered
tells us that this IP is identified as windows (and the user-agent is not set
to the magic string), a 403 will be returned.
go build && ./nowin
Install
make build
make install-service
make run-service
Caveats