[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
|
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
|
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.
|
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?
|
## 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
|
## The ideal source of authentication
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue