This is a small Go web application that can be used with Nginx auth_request
to protect any virtual host in Nginx with email login via Portier. No need
for application support, or even just to protect static files!
There are several ways to get portier-nginx-auth:
-
Grab a binary from the releases page.
-
Docker images are available on Docker Hub as portier/nginx-auth.
-
Build from source:
go install github.com/portier/nginx-auth@latest
You'll also need an Nginx install with auth_request
support. Many
distributions enable this out-of-the-box. You can check your install by
running:
nginx -V
Then look for --with-http_auth_request_module
. If that's not listed, you may
have to build Nginx from sources.
As an example, we'll start with this simple Nginx config for a site serving static files:
server {
listen 80;
server_name example.com;
location / {
root /var/www/example.com;
}
}
The first step is to enable auth_request
. In the server
block, add:
auth_request @authcheck;
location = @authcheck {
proxy_pass http://localhost:8081/check;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
This creates a 'named location' @authcheck
that proxies to the
portier-nginx-auth /check
route. (The default port is 8081, but you can
change this with the -listen
flag when you later start portier-nginx-auth.)
The auth_request @authcheck
line is the most important. For every request,
Nginx will now first send a 'subrequest' to @authcheck
, to see if it should
be blocked or not, before actually serving your site. This subrequest is
handled in portier-nginx-auth by checking cookies.
The extra proxy_*
settings in @authcheck
prevent Nginx from forwarding any
request body to portier-nginx-auth, because it doesn't care. Only headers are
used to perform the check.
With this in place, your application is already protected, but will just show a dull white error page, and offer no way to login.
To add login pages to your site, we need to expose the login routes of
portier-nginx-auth somewhere. You'll want to pick something that doesn't
conflict with your static files (or your real application routes). Here, we'll
pick /_portier
, which is a pretty safe default, but remember that this is
user-visible and you can customize this:
location /_portier {
proxy_pass http://localhost:8081;
auth_request off;
}
Notably, we disable auth_request
for this location, because protecting the
login form would defeat its purpose.
You can now start portier-nginx-auth. Two flags are required: -url
and
-secret
. Set the -secret
flag to some random text; it is used to protect
the cookie from tampering. Set the -url
flag to match the full URL to
/_portier
(or your chosen path). For example:
portier-nginx-auth \
-secret 'this is just an example, replace it` \
-url http://example.com/_portier
(Eventually, you want to run this as a background service. That's currently something for you to figure out.)
If you visit the application now, you'll still get an error page. But, if you
navigate to /_portier
, you should be able to complete a login. It'll then set
a cookie, redirect you back to /
, and you should now see your site again!
To present something more useful than an error page when logged out, we can configure Nginx to serve a redirect to the login form on 403 errors:
error_page 403 = @error403;
location @error403 {
return 303 /_portier;
}
Right now, anyone is allowed in, as long as they verify their email address. The idea is probably to limit access to your site, though. You can do so by specifying a file that contains a list of allowed emails.
portier-nginx-auth \
-secret 'this is just an example, replace it` \
-url http://example.com/_portier \
-allowlist emails.txt
See test-app/server.conf for a complete example. This example also shows how you can send the logged in email address as a header to an application.