15

I'm trying to create a MySQL user which will only be allowed to connect to the MySQL database from a specific hostname.

grant all on db_name.* to 'user_name'@'appserver-lan.mydomain.com' identified by 'some_passwd'

By checking the user table on the mysql db, I can see that the user was created successfully:

use mysql; select * from user where User='user_name' and Host='appserver-lan.mydomain.com'

or

show grants for 'username'@'appserver-lan.mydomain.com'

The hostname I specified is an alias to an amazon-ec2 name, which when resolved by the AWS DNS servers results in a LAN address:

[root@db_server ~] # host appserver-lan.mydomain.com

appserver-lan.mydomain.com is an alias for ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com has address 10.xxx.xxx.xxx

The problem is that when I try to connect to the database LAN IP from this appserver-lan, I get an access denied error, although the password is correct. The weird thing here is that the hostname showed in the error is not the hostname I had specified when the user was created:

ERROR 1045 (28000): Access denied for user 'user_name'@'appserver.mydomain.com' (using password: YES)

So, my question is: how does mysql determines the client hostname? I believe it doesn't do so by a reverse DNS lookup, since I checked and it does not point to "appserver.mydomain.com" neither to "appserver-lan.mydomain.com". Additionally, the db server has no entries related to the appserver on /etc/hosts.

Summarizing, I'm pretty sure it's a hostname resolution issue, since granting privileges for host "%" or to the LAN IP works just fine.

Any ideas of what I'm missing?

MDMarra
  • 100,183
  • 32
  • 195
  • 326
Luis Fernando Alen
  • 540
  • 1
  • 5
  • 11
  • Why do you think it is not reverse DNS? What happens when you do `host -t PTR 10.1.2.3`? – Zoredache Feb 23 '12 at 19:33
  • host -t PTR 10.xxx.xxx.xxx xxx.xxx.xxx.10.in-addr.arpa domain name pointer ip-10-xxx-xxx-xxx.ec2.internal. As you can see, this is not the hostname showed in the error message (appserver.mydomain.com) and that made me think MySQL was not doing a reverse lookup. – Luis Fernando Alen Feb 23 '12 at 20:06

4 Answers4

15

It uses a reverse DNS lookup. It takes the IP address of the client and uses whatever PTR record is returned for that name.

In my opinion doing authentication based on the name is not very useful at all, I suggest you consider using IP addresses instead.

See this document about how Mysql uses DNS.

Michael Lowman
  • 3,584
  • 19
  • 36
Zoredache
  • 128,755
  • 40
  • 271
  • 413
  • Thanks for the link, @Zoredache. I'd like to avoid using IP addresses because the AWS internal interface uses DHCP and its IP changes from time to time (whenever the server boots, I guess), as well as its PTR record. The weird thing here is that since it uses reverse lookups, it should say "Access denied for user @ ip-10-xxx-xxx-xxx.ec2.internal." instead of appserver.mydomain.com... – Luis Fernando Alen Feb 23 '12 at 20:04
  • 1
    Can you skip the IP/name authentication alltogether, instead either use a host-based firewall, or setup SSL and Cert-based authentication. – Zoredache Feb 23 '12 at 20:11
3

MySQL will be doing a reverse DNS look up on the IP address to get the host name. If you are running in AWS EC2 then you can assign an elastic IP to your server (this does not cost any extra) and then ask amazon to set up reverse DNS for the elastic IP to go to your hostname.

Also is your DB server also in EC2? Because if so it will be using the private IP address of the instance, otherwise it will be using the public ip address. It looks from you post as thou appserver-lan is the 10.XXX.XXX.XXX private ip assigned to your server, not the putlic one.

I'm not sure which IP address would be used if communicating with a different region though as I have only had servers within the same region.

Andy Hobbs
  • 131
  • 2
  • Yes, it's on EC2 as well and at the same region. Thanks for the tip, Andy. I didn't know EC2 instances use the internal ip to communicate between them even if you specify the valid ip for the communication. That solved my problem =] – Luis Fernando Alen Feb 24 '12 at 02:57
3

I've just had a similar problem, where the mysql server appeared to be doing reverse DNS lookups incorrectly.

The problem I had was that the server had permissions for 'user'@'1.2.3.4' as well as 'user'@'reverse.dns'. The user with just the IP address had minimal permissions, but the mysql server was using the permissions of that user rather than the one with the hostname, and returning the message "Access denied for user 'user'@'1.2.3.4'". Deleting the user with the IP address fixed the problem and forced the serer to use the other user at the hostname.

0

I have also seen problems where IPV4 and IPV6 hostnames and IP addresses do not match, and where a host name only is used for the user permission. For example, where there is a IPV6 reverse DNS but no forward IPV6 DNS.