Access denied for user 'test'#'ip'(using password: YES) - mysql

I have found many posts for this error, tried everything but still getting same error.I am trying to connect to mysql on ubuntu server from my remote app and mysql client. Let me post whatever steps I have taken already :
Stop the firewall on ubuntu server : iptables -F. Also tried with sudo service ufw stop.
Commented "bind-address" in /etc/mysql/my.cnf and restarted mysql.
Added user in mysql : CREATE USER 'test'#'%' IDENTIFIED BY 'testpwd';
GRANT ALL PRIVILEGES ON . TO 'test'#'%' IDENTIFIED BY 'testpwd' WITH GRANT OPTION;
FLUSH PRIVILEGES;
I can see the entry of new user by "Select host, user from mysql.user";
restarted mysql again. Still the same error!
Now I thought maybe there is some problem still with firewall, so added :iptables -A INPUT -i eth0 -p tcp --destination-port 3306 -j ACCEPT
Problem still persist.

"Access denied for user 'test'#'ip'(using password: YES)" is a MySQL error.
This means that at the network level everything is working, because to be denied access as a given user, the server must have understood which user you were trying to connect as. So network, firewall, routing, and so on and so forth, must all be working; the server must be listening, etc..
The problem lies "simply" in the authentication.
Try connecting locally to the database (to override the authentication) and inspect the privilege table:
USE mysql;
SELECT User, Host, Password from user WHERE User = 'test';
and remember that the line you're interested in is the one mentioning the IP (since the error message specifies the IP, and not the host name - in which case, it could have been a DNS problem; the host name is the hostname that the server believes you are coming from, not the hostname you are really coming from).
The user/host matching goes from more specific to less specific. So if you already had:
user host password
test 1.2.3.4 foo
and ran,
GRANT... TO test#'%' ... PASSWORD bar
...this grant would work from everywhere except 1.2.3.4, where the password would remain 'foo'.
From the manual (link above):
The server uses sorting rules that order rows with the most-specific
Host values first. Literal host names and IP addresses are the most
specific. (The specificity of a literal IP address is not affected by
whether it has a netmask, so 192.168.1.13 and
192.168.1.0/255.255.255.0 are considered equally specific.) The pattern '%' means “any host” and is least specific. The empty string
'' also means “any host” but sorts after '%'. Rows with the same Host
value are ordered with the most-specific User values first (a blank
User value means “any user” and is least specific). For rows with
equally-specific Host and User values, the order is indeterminate.
You might be forced to do
USE mysql;
DELETE FROM user WHERE User = 'test';
GRANT ALL PRIVILEGES ON database.* TO 'test'#'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
to ensure that there're no spurious lines in the grant table referring to the user 'test'.
(Also, the GRANT should be, I think,
GRANT ALL PRIVILEGES ON databasename.*
)
Security doubt (unrelated to the answer)
The manual above says: The specificity of a literal IP address is not affected by whether it has a netmask, so 192.168.1.13 and 192.168.1.0/255.255.255.0 are considered equally specific.
Now at a very first glance 127.0.0.1/0.0.0.0 seems very specific (and harmless) for localhost. The netmask, if I'm not mistaken, ensures that it is equivalent to %, except that it is incredibly specific and will run first. Therefore
test bar %
test localfoo 127.0.0.1/0.0.0.0
means that the password for test from anywhere it's not "bar" at all, but it is "localfoo".
No one would insert such a grant by mistake, but there's mistake and mistake.

First let's check - it's network/firewall problem or not.
Start MySql server with --skip-grant-tables , then try to connect to it.

I had the same error on my .net core console app, when trying to connect to my MariaDb database.
I finally find that the uid in my connectionstring was not correct because it is case sensitive!
Even if I felt quite stupid, it might help...

Related

phpmyadmin share specific DB with more machines

I'm doing a web project and im using wamppserver to take care of the server and database. And now I'm facing a problem, I have to share the project. So it would be useful if i could share the specific DB that I use in the project, so that other people can access from their machines and get all the data previously stored in the DB. Is it possible to do it? How?
If you need to grant access to other machines to one database on local mysql server, you need to do some things:
You need to open MySQL to network interface: Check my.cnf, and do this:
Comment the line skip-networking.
Change the line bind-address to hold your LAN IP address / WAN IP address (if the machine itself have the WAN IP) / 0.0.0.0 (for all IPv4 addresses of the machine) / :: (for all IPv4 and IPv6 addresses of the machine). After reconfigure, restart MySQL server.
Check / configure your firewall for port 3306 opened (You can configure firewall for accept connections only from the required IPs) (Configuration for doing this will depend on your firewall software).
Grant access to the user(s) from the IPs you will need.
You can give access to one user from all IPs, for doing this, execute command [1] on MySQL cli or phpmyadmin, with a user with SUPER privileges (usually root).
You can give access to one user from one IP. Execute command [2].
[1]: GRANT ALL PRIVILEGES ON database.* TO 'user'#'%' IDENTIFIED BY 'password';
[2]: GRANT ALL PRIVILEGES ON database.* TO 'user'#'host' IDENTIFIED BY 'password';
You need to replace database with the name of the database to give privileges, user with the username accessing, host with the IP address of the client accessing, and password, with the desired password.
You can also, repeat command [2] if you want the same username to have access from two different IPs for example. Also, you can use a combination of [1] and [2], using a host with this example format: #'192.168.0.%', for giving access to these user from all computers on the 192.168.0.0/24 network.
Also, you can give really fine privileges, for example, changing GRANT ALL PRIVILEGES with GRANT SELECT, INSERT, these user only can do SELECT and INSERT statements, but not UPDATE or DELETE ones for example. You can check MySQL doc or StackOverflow for more info about this.

What does it mean on mysql grant command?

I am creating my own PHP development environtment and I am setting mysql.
I need to grant to my root user all the privileges so I use:
GRANT ALL ON *.* TO 'root'#'%';
Why It use 'root'#'%'?
I understand that these are user and host, but in this case that I am in a development environment why I have to put a host?
In case of a production server I understand that it is to grant only the database hosted by an specified host, right?
Thanks.
'%' is a wildcard fall-back. The login attempt tries the most specific and then moves toward the wildcard (moving toward more general) until it finds a user/host combo account if you will to authenticate. If it can't find such an account, the login fails.
So when you have 'root'#'localhost' (call it acct or user 1), that is all fine and dandy when you are sitting at localhost. But when you attach from a different client, say '192.168.10.103', you are no longer 'localhost'. You now need either an explicit 'root'#'192.168.10.103' (user or acct if you will), or for sanity we swing for the wildcard with '%'. Why, because there is no way you want to litter your mysql.user with all the permutations.
What users you have can be seen with
select user,host from mysql.user;
It is not uncommon to have 3 users for root
'root'#'localhost'
'root'#'127.0.0.1'
'root'#'%'
Giving them all the same rights. The 3rd one above is a security risk, naturally. That is so because '%' means from any host anywhere.
And that is why 'root'#'localhost' is recommended to be the only root user in your system. You achieve root by either sitting at that box, or using ssh with a secure connection to become localhost if you will.
You need to understand that it is all about security, and the way, for better or worse, MySQL chose to implement what a user is. A user is the username, plus the hostname coming in as. The hostname could be an IP Address, or a DNS hostname like casper.comcastbusiness.net. When MySQL receives the connection request, it bubbles up from most-specific toward '%' until it can or cannot authenticate the request.
As one use case, I have a server that I want to authenticate as root but not have a 'root'#'%' user in the system for security reasons. So I explicitly created a user like 'root'#'casper.comcastbusiness.net'. Another layer of course is the firewall but that is a separate issue. But to touch on it lightly, AWS ec2 has a Security Groups area to have it such that only certain IP Addresses are able to connect to port 3306. So the firewall is another layer, of what I am saying is that the whole thing is about securing your server.
Administrating it is a pain. But it is what is and we have to live with it.

MySQL user privileges not working when using IP

I have the current setup:
SVR01:
Ubuntu Trusty, with Xen
VM01:
IP: 192.168.0.10
Ubuntu Trusty, with Apache2 + php modules
VM02:
IP: 192.168.0.11
Ubuntu Trusty, with mysql server
When I try connecting from VM01 (The apache server) to mysql on VM02, I get the "Access Denied for 'NewUser'#'192.168.0.10' (Using password: YES)" error.
I created the user using:
CREATE USER 'NewUser'#'192.168.0.10' IDENTIFIED BY 'password';
GRANT EXECUTE ON mydb.* TO 'NewUSer'#'192.168.0.10';
But, it will work if I create the user using the host wildcard:
CREATE USER 'NewUser'#'%' IDENTIFIED BY 'password';
GRANT EXECUTE ON mydb.* TO 'NewUSer'#'%';
Does anyone know why it won't work when I specify the host ip?
PS. I get the error when trying to connect either through the Mysql client, or through the PHP PDO.
Follow up questions:
Does the grant seem to work if you create a user with a 192.168.0.% wildcard host mask?
Run select user, host, password from mysql.user where user='NewUser' to ensure there's not another user#host you weren't aware of that might be getting picked up?
Does the Access denied messages in your error logs confirm the failed connection attempts are in fact coming from the IP you think it is? Some weirdness like this might pop up if you have multiple routes setup in a system that has multiple network interfaces or perhaps some VPN routes in the mix.
When attempting connections to VM02 are you using a literal IP address or a hostname? If the later are you sure this is resolving to the IP you think it is from VM01 (you can verify using ping or just the host command from the command line)
Run "show variables like 'init_connect';" on the root account you were creating the users with. If that value is not blank you will want to ensure the accounts of permissions required to execute whatever that value does hold.

Creating MySQL users and granting privileges - unable to connect to server

I've just tried to create a bunch of users for a (currently local) database but I'm having issues connecting to the database and not too sure what I'm doing wrong.
The users exist after creation but I can't connect to the database with their credentials while using Workbench for connection testing.
I've created my users and then granted them permission straight after as so:
CREATE USER 'username'#'%' IDENTIFIED BY 'password';
GRANT ALL ON DATABASE.* TO 'username'#'%';
If I run SELECT * FROM mysql.user; to see the users, I can see that the users are there.
I've tried flushing privileges but it doesn't seem to make any difference.
When trying to connect to the server via Workbench as one of the users I've created I get re-prompted for my password. It then seems to either hang or tell me the password is wrong.
This is initially local for development purposes but I'll be setting this up on a server once I've got this working. Could this be down to it being ran locally?
As mentioned in the MySQL documentation for adding users, when connecting locally a user must be created #'localhost' as well as to wildcard locations:
Two of the accounts have a user name of monty and a password of
some_pass. Both accounts are superuser accounts with full privileges
to do anything. The 'monty'#'localhost' account can be used only when
connecting from the local host. The 'monty'#'%' account uses the '%'
wildcard for the host part, so it can be used to connect from any
host.
It is necessary to have both accounts for monty to be able to connect
from anywhere as monty. Without the localhost account, the
anonymous-user account for localhost that is created by
mysql_install_db would take precedence when monty connects from the
local host. As a result, monty would be treated as an anonymous user.
The reason for this is that the anonymous-user account has a more
specific Host column value than the 'monty'#'%' account and thus comes
earlier in the user table sort order. (user table sorting is discussed
in Section 6.2.4, “Access Control, Stage 1: Connection Verification”.)
With a user only being denoted with a host name of '%' to allow for connection anywhere MySQL will instead use the anonymous <anonymous>''#'localhost' account because it will attempt to match the localhost location first and then not find the related user name for localhost and so use the <anonymous> user instead.
Alternatively, the anonymous user can be deleted and this should also fix the problem rather than having to duplicate users.

How do I manually block and then unblock a specific IP/Hostname in MYSQL

First off, I did google this but sites are flooded with advice on how to deal with "host name is blocked" issues. (https://www.google.com/search?q=mysql+block+a+host). My issue is a little bit the opposite of that.
With me, I am running a MySQL database and no PHP is involved.
I need to block a certain host-name/IP address from connecting to my database, then I will unblock it. I am hoping there are 2 simple queries for this that I can execute on the MySQL database, I just can't seem to find it anywhere.
I can find the hostnames pretty easily by running the show processlist query and I know I can kill one process at a time, but so many new threads pop up that if I can just block all of them from a certain hostname, that would be ideal. Then I will unblock once I fix a few things.
You can use GRANT to give a non-privileged entry for a user connecting from a specific host, even if you have GRANTed privileges to a wildcard including that host. When authenticating, the most specific host match takes precedence.
For example, suppose you enabled a user to connect from a range of hosts on your local subnet:
mysql> GRANT ALL PRIVILEGES ON *.* TO 'user'#'192.168.56.%' IDENTIFIED BY 'xyzzy';
Then you could grant the minimal USAGE privilege, which is a synonym for "no privileges" for that user for one specific host within that subnet:
mysql> GRANT USAGE ON *.* TO 'user'#'192.168.56.110';
Subsequent attempts to connect from that host get this error:
$ mysql -uuser -pxyzzy
ERROR 1045 (28000): Access denied for user 'user'#'192.168.56.110' (using password: YES)
The reason this gets an error is that I did this grant for the user with no password. If I try to submit a password, this doesn't match the entry in the privileges table.
Even if the user tries to connect without using a password, he finds he has no access to anything.
$ mysql -uuser
mysql> USE mydatabase;
ERROR 1044 (42000): Access denied for user 'user'#'192.168.56.110' to database 'mydatabase'
You can undo the blocking:
mysql> DELETE FROM mysql.user WHERE host='192.168.56.110' AND user='user';
mysql> FLUSH PRIVILEGES;
And then the IP range will come back into effect, and the user will be able to connect from thathost again.
You can revoke privileges as mentioned above, but this will still allow a user to make a connection to your MySQL server - albeit this will prevent that user from authenticating. If you really want to block/allow connections to your MySQL server based on IP, use iptables.
Have you tried using MySQL Workbench?
You can simply remove ROLES for a specific User/Host from there.