[ci skip] Further advancement of the draft
This commit is contained in:
parent
605847fe26
commit
1f49b2a958
1 changed files with 168 additions and 2 deletions
|
@ -220,7 +220,7 @@ systemctl --user daemon-reload
|
|||
|
||||
This will create a bunch of files there, namely `pod-owntracks.service`, `container-ot_recorder.service` and `container-ot_frontend.service`. You can then enable owntracks at boot with
|
||||
|
||||
```
|
||||
```shell
|
||||
systemctl --user enable pod-owntracks.service
|
||||
```
|
||||
|
||||
|
@ -314,9 +314,175 @@ server {
|
|||
|
||||
Check the configuration with `nginx -t` and then restart your webserver. If you access `https://tracks.example.com` you should see a map (OpenStreetMap) and if you access `https://tracks.example.com/owntracks` you should be presented with a list of locations and users. Of course everything is empty, because we haven't added any device yet.
|
||||
|
||||
Before we actually start recording, we need to secure access, otherwise anyone could see where you're going (not good). That means adding some form of authentication.
|
||||
|
||||
## Authentication: is httpasswd the only way?
|
||||
|
||||
## oauth2-proxy
|
||||
The simplest solution would be to use HTTP Basic Authentication and secure the root, `/owntracks` and `/owntracks/pub` paths. However, that's not what I wanted: as I planned to allow a few trusted users for viewing, I didn't want to have them remember another series of usernames and passwords. I had already a central source of authentication (more on that below), so I wanted to use that.
|
||||
|
||||
On the other hand, the OwnTracks app only understands Basic Authentication and nothing else. So, what to do?
|
||||
|
||||
### oauth2-proxy
|
||||
|
||||
I could have used LDAP instead, but I don't have LDAP on my system and I didn't want to retrofit it in the existing services. The solution was to use the [OAuth 2.0 standard](https://oauth.net/2/) in conjunction with [nginx's `auth_request` module](https://nginx.org/en/docs/http/ngx_http_auth_request_module.html) to allow authentication through another source.
|
||||
|
||||
For the actual OAuth2 service, I wanted something simple so I looked at [oauth2-proxy](https://oauth2-proxy.github.io/oauth2-proxy/). It is used often in conjunction with Kubernetes and the nginx_ingress controller, but it can be used also with the "regular" nginx.
|
||||
|
||||
A warning before going further. This guide assumes you put the OAuth2 service in a top-level domain called `auth.example.com`.
|
||||
|
||||
As oauth2-proxy is written in Go, you can just clone the [git repo](https://github.com/oauth2-proxy/oauth2-proxy) and build it yourself, or download a pre-built binary (I built it and installed it in `/usr/local/bin`). While a Docker image is offered, in my opinion there's no need for Docker containers for a single application. You're free to use whatever option you want, of course.
|
||||
|
||||
With oauth2-proxy installed, it's time to set things up. Create a path to host the configuration (I used `/etc/oauth2-proxy`) and write the following in the configuration file (`oauth2-proxy.cfg`; some comments are from [the sample configuration](https://github.com/oauth2-proxy/oauth2-proxy/blob/master/contrib/oauth2-proxy.cfg.example) plus some of my own):
|
||||
|
||||
```
|
||||
|
||||
## OAuth2 Proxy Config File
|
||||
## https://github.com/oauth2-proxy/oauth2-proxy
|
||||
|
||||
# There are plenty of other options; see the sample configuration for details
|
||||
|
||||
## <addr>:<port> to listen on for HTTP/HTTPS clients
|
||||
http_address = "127.0.0.1:4180"
|
||||
|
||||
## Are we running behind a reverse proxy? Will not accept headers like X-Real-Ip unless this is set.
|
||||
reverse_proxy = true
|
||||
## Alternative users for Basic Authentication
|
||||
htpasswd_file = "/etc/nginx/owntracks.htpasswd"
|
||||
display_htpasswd_form = true
|
||||
|
||||
## the OAuth Redirect URL.
|
||||
# defaults to the "https://" + requested host header + "/oauth2/callback"
|
||||
redirect_url = "https://auth.example.com/oauth2/callback"
|
||||
|
||||
## oauth2-proxy can also acts a proxy for files, but we'll just use nginx
|
||||
## So we make sure it doesn't proxy anything
|
||||
upstreams = [
|
||||
"file:///dev/null"
|
||||
]
|
||||
|
||||
# Put ALL domains you want oauth2-proxy to redirect to after authentication
|
||||
# otherwise redirection will *NOT* work
|
||||
whitelist_domains = [
|
||||
".example.com",
|
||||
]
|
||||
|
||||
## pass HTTP Basic Auth, X-Forwarded-User and X-Forwarded-Email information to upstream
|
||||
# These are needed for the OwnTracks application
|
||||
pass_basic_auth = true
|
||||
pass_user_headers = true
|
||||
pass_authorization_header = true
|
||||
set_basic_auth = true
|
||||
## pass the request Host Header to upstream
|
||||
## when disabled the upstream Host is used as the Host Header
|
||||
pass_host_header = true
|
||||
|
||||
## Email Domains to allow authentication for (this authorizes any email on this domain)
|
||||
## for more granular authorization use `authenticated_emails_file`
|
||||
## To authorize any email addresses use "*"
|
||||
|
||||
# I use my own mail domains here: adjust this configuration to your liking
|
||||
|
||||
email_domains = [
|
||||
"example.com"
|
||||
]
|
||||
|
||||
## The OAuth Client ID, Secret
|
||||
provider = "YOUR_PROVIDER"
|
||||
client_id = "CLIENT_ID"
|
||||
client_secret = "CLIENT_SECRET"
|
||||
|
||||
# Put provider specific options here
|
||||
|
||||
# Basic authentication users - for the OwnTrack apps ONLY
|
||||
|
||||
## Additionally authenticate against a htpasswd file. Entries must be created with "htpasswd -B" for bcrypt encryption
|
||||
## enabling exposes a username/login signin form
|
||||
htpasswd_file = "/etc/nginx/owntracks.htpasswd"
|
||||
display_htpasswd_form = true
|
||||
|
||||
## Cookie Settings
|
||||
## Name - the cookie name
|
||||
## Secret - the seed string for secure cookies; should be 16, 24, or 32 bytes
|
||||
## for use with an AES cipher when cookie_refresh or pass_access_token
|
||||
## is set
|
||||
## Domain - (optional) cookie domain to force cookies to (ie: .yourcompany.com)
|
||||
## Expire - (duration) expire timeframe for cookie
|
||||
## Refresh - (duration) refresh the cookie when duration has elapsed after cookie was initially set.
|
||||
## Should be less than cookie_expire; set to 0 to disable.
|
||||
## On refresh, OAuth token is re-validated.
|
||||
## (ie: 1h means tokens are refreshed on request 1hr+ after it was set)
|
||||
## Secure - secure cookies are only sent by the browser of a HTTPS connection (recommended)
|
||||
## HttpOnly - httponly cookies are not readable by javascript (recommended)
|
||||
cookie_name = "YOUR_COOKIE_NAME"
|
||||
# See the oauth2-proxy docs on how to generate this
|
||||
cookie_secret = "YOUR_COOKIE_SECRET"
|
||||
cookie_domain = "example.com"
|
||||
cookie_secure = true
|
||||
cookie_httponly = true
|
||||
```
|
||||
|
||||
Note there are a few options to fill in, in particular the OAuth2 provider. There are plenty of options to choose from: they range from external services (GitHub, Google) to self-hosted ones (Nextcloud, Gitea, Gitlab, Keycloak...). Refer to the [oauth2-proxy documentation](https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/oauth_provider) on how to set them up. I'll go through my personal choice later.
|
||||
|
||||
You also need to create the static user(s) for the OwnTracks app. I have found no other way to avoid it. If you know a better way that avoids this, let me know.
|
||||
|
||||
```shell
|
||||
htpasswd -c /etc/nginx/owntracks.htpasswd
|
||||
# The -B switch is *mandatory* if you want to use htpasswd with oauth2-proxy
|
||||
htpasswd -c -B /etc/nginx/owntracks.htpasswd myusername
|
||||
# Insert the password when prompted
|
||||
# Repeat if you have more than one
|
||||
```
|
||||
|
||||
Once you have oauth2-proxy set up, try running it:
|
||||
|
||||
```shell
|
||||
oauth2-proxy --config /etc/oauth2-proxy/oauth2-proxy.cfg
|
||||
```
|
||||
|
||||
Quit with Ctrl-C. If it starts up correctly, it's time to make it start on boot. This assumes you are using a recent enough version of systemd (I used 234).
|
||||
|
||||
Create this unit file (`/etc/systemd/system/oauth2-proxy.service`):
|
||||
|
||||
```systemd
|
||||
[Unit]
|
||||
Description=oauth2-proxy daemon service
|
||||
After=syslog.target network.target
|
||||
|
||||
[Service]
|
||||
# Change it to any non-privileged user you want; "nobody" may work too
|
||||
# DynamicUser may also work, but I have not tested it
|
||||
User=nginx
|
||||
Group=nginx
|
||||
|
||||
ExecStart=/usr/local/bin/oauth2-proxy --config=/etc/oauth2-proxy/oauth2-proxy.cfg
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
|
||||
# As it only needs to listen and forward requests, limit its access
|
||||
# With later systemd versions you can also sandbox it further
|
||||
ProtectHome=true
|
||||
ProtectSystem=full
|
||||
PrivateTmp=true
|
||||
|
||||
KillMode=process
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Afterwards, it's time to enable and start the service:
|
||||
|
||||
```shell
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now oauth2-proxy.service
|
||||
```
|
||||
|
||||
If you want to be fancier and want it to start only when required, you can always use systemd's socket activation. However, I had no need for this so I left it always running.
|
||||
|
||||
### Adjusting nginx configuration
|
||||
|
||||
Now, we need to add the relevant information to nginx.
|
||||
|
||||
|
||||
## The ideal source of authentication
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue