[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
		Add a link
		
	
		Reference in a new issue