gcgarner / IOTstack

docker stack for getting started on IOT on the Raspberry PI
GNU General Public License v3.0
1.5k stars 578 forks source link

Unable to create a password protected influxDB #201

Open WaleedNaveed opened 3 years ago

WaleedNaveed commented 3 years ago

I am working on a C# application with InfluxDB and Grafana. I am using InfluxData.Net (https://github.com/pootzko/InfluxData.Net#createdatabaseasync). I have to create a password protected Influx database. My code is:

var httpClientHandler = new HttpClientHandler();
httpClientHandler.ServerCertificateCustomValidationCallback = OnHandleSSl;
var client = new HttpClient(httpClientHandler);

InfluxDbClient _influxDbClient = new InfluxDbClient(Server, Username, Password, InfluxDbVersion.v_1_3, QueryLocation.FormData, client);
var response = await _influxDbClient.Database.CreateDatabaseAsync(DatabaseName);

Issue is that when i go to Grafana on the server and add new data source with this database, data source works fine and does not show any error regarding username/password. Even the data in the database is shown in the grafana. I am using InfluxDB image. I have also tried to enable INFLUXDB_HTTP_AUTH_ENABLED in DockerFile of InfluxDB. My DockerFile is:

FROM influxdb:1.7.6

ENV TZ=America/Los_Angeles
ENV INFLUXDB_HTTP_AUTH_ENABLED true

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

When i run the image created from this DockerFile, i don't get INFLUXDB_HTTP_AUTH_ENABLED entry in influxdb.conf file. As per InfluxDB documentation, setting INFLUXDB_HTTP_AUTH_ENABLED in environment variable will enable the authentication on the influx server but, in my case its not working.

How can i make a password protected influx database through influxDB image ? What can be the possible issue ? I am stuck and unable to create the password protected database. Any help would be much appreciated.

Paraphraser commented 3 years ago

Hi,

Please see This Project is Dormant – explains why all the IOTstack activity is occuring at SensorsIot/IOTstack.


If I understand what you are saying, you are expecting a Dockerfile ENV variable to wind up in influxdb.conf.

I could be wrong but I really don't think environment variables work that way, irrespective of the context.

In the case of a Dockerfile ENV statement, I think that's a way of passing something to a later step in the Dockerfile.

Suppose your Dockerfile was compiling your C# code and you wanted to have conditional compilation based on whether INFLUXDB_HTTP_AUTH_ENABLED was true or not. I think you could use it for that but not for getting something into influxdb.conf unless you did something like you are doing with TZ.

More generally, if you set an environment variable in either of the following:

~/IOTstack/docker-compose.yml
~/IOTstack/services/influxdb/influxdb.env

those still don't wind up in influxdb.conf. Variables set that way are just "available" to processes inside the container as they are launched. The process still has to check.

Hold that thought. I'll come back to it.

On the topic of timezones, I have had zero luck getting Influx to respect a timezone set globally.

If you find a way to make it work then please let me know.

Here is what I do. Step 1 is an alias defined in ~/.profile

alias influx='docker exec -it influxdb influx -precision=rfc3339'

With that in place, I can get into the Influx CLI just by typing influx. If I want to pass additional arguments then I can tack those on the end, like this:

$ influx -database power

One of the measurements in the "power" database is called "hiking" (the name of the electricity meter). It is logging grid voltage every 10 seconds. Assume my time is 09:40 on Sept 17 2020, and my time-zone is UTC+10. If I query like this:

> select voltage from hiking where time > '2020-09-17T09:40:00+00:00'

I get an empty result set - because 09:40 at UTC+0 is 19:40 UTC+10 and hasn't happened yet. If I set the time-zone offset to UTC+10 in the query:

> select voltage from hiking where time > '2020-09-17T09:40:00+10:00'

time                           voltage
----                           -------
2020-09-16T23:40:07.642018568Z 246.9

I get a result but the timestamp in the time column is UTC+0 (ie 10 hours behind my wallclock time). If I want to see the timestamp in my local timezone, I have to query like this:

> select voltage from hiking where time > '2020-09-17T09:40:00+10:00' tz('Australia/Sydney')

time                                voltage
----                                -------
2020-09-17T09:40:07.642018568+10:00 246.9

When I examine the log from the influxdb container via:

$ docker logs influxdb

I see queries like the one below coming from Grafana. If I copy-and-paste the query:

> SELECT max(voltage) FROM power.autogen.hiking WHERE time >= now() - 6m GROUP BY time(30s)

time                 max
----                 ---
2020-09-16T23:47:30Z 246.1

it seems to me that Grafana is getting back UTC+0. It draws charts in local time so it must be doing that conversion work itself.

Unlike the InfluxDB environment file, the Grafana environment file does contain a TZ:

$ head -1 ~/IOTstack/services/grafana/grafana.env

TZ=Australia/Sydney

but I have not experimented to see whether that is what Grafana actually respects, or if it is getting the information from the browser.

Returning to the topic of InfluxDB environment variables, back in June I did a bit of a deep dive into the topic of which environment variables "worked" (appeared to have an effect) versus those that didn't. I had intended to work towards a PR to document some how-to but got side-tracked onto other things.

Where I got to was this. First, you'd need to go into Influx and either use an existing database or create then use a new one:

$ influx
> CREATE DATABASE "mydatabase"
> USE "mydatabase"

Then you define an administrative user:

> CREATE USER "dba" WITH password 'supremo' WITH ALL PRIVILEGES

plus some garden-variety users:

> CREATE USER "nodered" with password 'nodered'
> CREATE USER "grafana" with password 'grafana'

then set up the access rights:

> GRANT WRITE ON "mydatabase" TO "nodered"
> GRANT READ ON "mydatabase" TO "grafana"

Next, you drop out of the influx CLI (either Ctrl+D or exit). Then you edit the InfluxDB enviroment file to set INFLUXDB_HTTP_AUTH_ENABLED true:

$ grep "INFLUXDB_HTTP_AUTH_ENABLED" ~/IOTstack/services/influxdb/influxdb.env

INFLUXDB_HTTP_AUTH_ENABLED=true

and then you put it all into effect by "upping" the stack.

You don't have to "down" the stack first; what "up" does is cause docker-compose to notice changed environment files and recreate the affected container(s)

$ cd ~/IOTstack
$ docker-compose up -d

Recreating influxdb ... 
Recreating influxdb ... done

Now, look at what happens if I try to access two different databases (the example "mydatabase" and a pre-existing "power" database):

$ influx
Connected to http://localhost:8086 version 1.8.2
InfluxDB shell version: 1.8.2

> use mydatabase
ERR: unable to parse authentication credentials
DB does not exist!
> use power
ERR: unable to parse authentication credentials
DB does not exist!

> auth
username: nodered
password: 
> use mydatabase
Using database mydatabase
> use power
ERR: Database power doesn't exist. Run SHOW DATABASES for a list of existing databases.
DB does not exist!

> auth
username: dba
password: 
> use mydatabase
Using database mydatabase
> use power
Using database power

Summary:

Some inferences I take from all this (which are probably fully documented somewhere in the InfluxDB doco):

With security enabled, there are a couple of ways of speeding-up your daily activities. You can pass the dba username and password on the end of the influx alias:

$ influx -database mydatabase -username dba -password supremo

or you can set two more environment variables:

$ grep "INFLUX_" ~/IOTstack/services/influxdb/influxdb.env

INFLUX_USERNAME=dba
INFLUX_PASSWORD=supremo

Those two variables are not some kind of general-access credentials that apply to everything. They are synonyms for the -username and -password parameters on the influx CLI command. You can invoke the influx CLI command like I do with an alias, or more explicitly by using the right-hand-side of the alias:

$ docker exec -it influxdb influx -precision=rfc3339

or by starting a shell into the InfluxDB container and then invoking the CLI from there:

$ docker exec -it influxdb bash
# influx
>

Whatever your approach, those username and password environment variables only apply to starting the CLI.

I hope this helps.

Paraphraser commented 3 years ago

@WaleedNaveed I just wrote a gist that includes all of the above.

If your question has been answered I'd appreciate it if you could remember to close this issue.