I'm considering using QuestDb for a small hobby project but I can't seem to wrap my head around how authentication is dealt with in QuestDb. I peeked at the Enterprise page and it almost looks like authentication is only available to enterprises.
The docs shows authentication for the Influxdb Line Protocol but nothing that resembles for example mysql and its database users.
How do I create database users and lock down QuestDb to only be used with the authenticated users/users with correct permissions?
Authentication over InfluxDB line protocol was added as a feature request for this protocol only and ensures only that clients writing to QuestDB are authenticated before being allowed to send records to tables.
For authenticating over Postgres wire, there is the equivalent of host-based authentication, i.e. in Node.js this looks like:
const { Client } = require("pg")
const start = async () => {
const client = new Client({
database: "qdb",
host: "127.0.0.1",
password: "quest",
port: 8812,
user: "admin",
})
await client.connect()
console.log("Connected")
}
start()
Only one database and one admin user is supported at the moment and you should keep in mind that anyone who can connect to the host using these credentials has database access and can read/write to tables on this host.
If you want to ensure your installation is locked down, you should at a minimum change the default connection credentials specified in the server configuration file (server.conf) such as changing the default username and password, and only enable the protocol(s) that you are reading and writing with.
Depending on where the installation is deployed, you could take steps beyond the QuestDB config itself and whitelist incoming / outgoing network connections (on EC2 for instance) to only allow connections coming from a specific IP, or within a VPC, for example.
If having multiple database users with role-based access is something you really need, feel free to open an issue with a feature request.
edit: It might be worth noting that you can also set the HTTP server to readonly mode which was discussed in another stackoverflow question
Related
I understand that the principle of Kerberos is to allow authentication between users and services on an unsecured network. Tickets generated by the authentication and ticket-granting service support secure communications and don't require a password to be transmitted across the network.
The flow relies on the auth server in the KDC (s) having a shared secret with the client (c).
However, at some point, the user itself must have been created and generally, users are created from client machines (you don't usually log onto the domain controller to create users)
So how do the user and secret key (Kac) get created in the first place and stored in the KDC database if the password/secret is never sent across the network?
The administration of principals in a KDC's database is outside the scope of the normal Kerberos protocol. Usually it's done using some auxiliary protocol, and each KDC can implement it in any way it wants.
For example, MIT Kerberos has the (SunRPC-based) kadmin protocol, and the kadmin client indeed sends the actual administrator-specified password to the kadmind service running on the KDC. (The RPC message is encrypted using the Kerberos session key, of course.) Heimdal has its own kadmin protocol, mostly incompatible with MIT's but working the same way.
(Both also have "local" versions of the kadmin tool, which directly accesses the KDC database backend – this is how the initial admin accounts are created, typically by running kadmin.local on the server console or through SSH.)
Microsoft Active Directory has several user administration protocols, some of them dating to pre-AD days, but the primary mechanism is LDAP (usually over an GSSAPI/Kerberos-encrypted session, but occassionally TLS-encrypted).
To create a new account in MS AD, the administrator creates an LDAP 'User' or 'Computer' entry with the plain-text 'userPassword' attribute, and the domain controller automatically transforms this attribute into Kerberos keys (instead of storing it raw). The commonly used "AD Users & Computers" applet (dsa.msc) is really an interface to the LDAP directory.
All of the above implementations also support a second administration protocol, the kpasswd protocol whose sole purpose is to allow an existing user to change their password. As you'd expect, it also works by transmitting the user's new password over the network, again making use of Kerberos authentication and encryption. (Password changes can also be done via AD's LDAP or MIT/Heimdal's kadmin, but kpasswd has the advantage of being supported by all three.)
As a final side note, the PKINIT extension uses X.509 certificates to authenticate the AS-REQ – in which case the client doesn't know their own shared secret, so the KDC in fact sends the whole Kc to the client over the network (encrypted using a session key negotiated via DH, somewhat like TLS would). This is mostly used in Active Directory environments with "smart card" authentication.
Which is the better way to set up access on some databases that my web apps query. I can only think of one pro for one and one con for the other, so I need some other input before making a final decision.
Option 1 – 10 apps, 10 databases, 1 Service Accounts for each app (User does not have direct access)
All query requests go through the Service Account to the database. The con I can think of is that there is no record of who sent the request, just that the SA accessed the db with a request.
Option 2 – 10 apps, 10 databases, User has direct access (no Service Account)
All query requests from the app go directly to the db and each request is logged, identifying who sent the request from what app. This setup could be locked down further by allowing the specific app access only to db/tables/columns that it needs to complete the request/query. The obvious pro is there would be no anonymous requests; all requests could be traced back to the requester and not just to a SA.
If by Service Account you refer to a functional account or database account for the application. This is the way to go. If you need to log who did the request your application should have user authentication and do the logging of the request.
The other alternative of a database account per user is not scalable and if you have to provide a database id for each user, which the user will be using to connect, it also has security implications.
By having the application between the user and the database you isolate the database from the outside and the only access is what the applications permits.
i wonder why postgres allows trust Authentication method as it allow any role to connect without providing a password!!
if any role change the pg_hba.conf to trust then the server will be unsecure and will open to any role with any password
i would like to prevent any connection to the server without providing the right password , so how can we prevent this ?
is their any best practices follow in order to secure postgres server ?
As described in the manual, the postgresql daemon should be run as a separate user account which is not used for other purposes. The data directory and all the files in it should be owned by this user and permissions set so that only this user has access to it.
The initdb command which is used to initialise the database cluster will set it up like this.
If set up correctly, only the postgres user, or root, can edit pg_hba.conf.
The basic assumption behind the trust method is that the user is pre-authenticated by the environment. For example, if the database is not configured to listen on any external interface, and you are sure only authorised users can log into the server.
Section 19.3.1 describes in more detail the circumstances under which you might want to use the 'trust' method.
Check 19.3. Authentication Methods
I've read how IBM's WebSphere can propagate the identity of a user back to a backend database (http://www.ibm.com/developerworks/websphere/techjournal/0506_barghouthi/0506_barghouthi.html). Does JBoss have similar functionality? Ideally, I'd like to be able to login to my JBoss application using SPNEGO and propagate that identity back to a PostgreSQL database using Kerberos or some other mechanism. Is this possible?
The article you've linked to could be used for that, but there are some caveats.
Having the app server re-authenticate as different users using Kerberos is probably not realistic. From my knowledge of Kerberos (admittedly limited), it is designed so that end-user interaction is required to do an actual authentication handshake. The user does the handshake with the app server over HTTP-- there isn't really a mechanism for asking them to re-authenticate with the DB itself.
You could use their hooks to issue "SET SESSION AUTHORIZATION TO ..." commands to PostgreSQL, though, if your app server performs its connections to the DB as a superuser. That doesn't actually re-authenticate, just changes the session authorisation role temporarily.
You could also use one of the myriad "store some session information in the DB" solutions (custom variables, PL/Perl etc global variables) and use their hooks to work with that. This is actually what their Oracle solution seems to do, it sets the client identifier which iirc is just a global variable in dbms_util somewhere that is included in views showing current sessions (and postgresql 9.0 has an "application name" that performs the same role)
So far, after creating DB with all the schema, all I have done so for was accessing them (tables) by reference through ConnectionStrings.
Now, twice, I've read that it's better to create a DB user and access the DB trhough that user by including him in the connectionString.
I'd like to know why so?
Thank for helping
Your question isn't that clear. It seems that you're asking if it is better to use windows security ("Integrated Security=SSPI" in the connection string) or a username/password ("User ID=myUsername;Password=myPassword;").
Its always better to use windows security. Having login information within the connection string is a security risk. Its in cleartext (unless you take some complicated steps to secure that section), and is sent across the wire as cleartext unless you set up a trusted connection between application and server.
Is it better to "create a db user and access the db trhough that user by including him in the connection string?" No. Its better to create a sql server login for user's windows identities and let them use those credentials to access the server.
You do this if you wish to connect as a specific user, rather than (for example) just using the context of the current user which your application is running under. However, if you use SQL Server authentication (i.e. username and password), you'd need to provide that password in the connection string, which is something of a security problem.
If the application has a group of anonymous users (or manages users/passwords itself) then its better to use a Windows login and run the application under a service account (which has minimal required access to the database).
If you're running an interactive application on the desktop, you should let those users connect to SQL server in their own context, by adding them to SQL Server with the required rights (e.g. db read/write , remove any higher functions). Obviously you would use groups to make administration simpler rather than adding individual users.