mysql_connect: IP Address or Localhost? - mysql

I saw the following statement on StackOverflow and was wondering about its meaning:
If you connect via 'localhost', the connection will automatically be established via the MySQL socket, which is really cheap anyways.
The discussion thread was pretty old, so I didn't want to comment on it.
Basically what I understand is, that using 'localhost' when connecting to your mysql database has certain advantages - such as "automatically established connections via MySQL socket". What does that mean exactly?
Currently I'm using
mysql_connect("73.21.24.201", [...]);
(changed to a random IP Address)
Does it make any difference? Can I change it to "localhost" without having to worry about it? (The mysql server is obviously on the same server/ip address as my website/application)

When you connect to 'localhost' you'll connect using a Unix socket, which is just a communications channel for the local processes to use. The big advantage of this is that you can disable networking completely in MySQL, and negate any processing overhead and security risks that go along with that.
When MySQL starts, it creates a socket file (typically at a place like /var/lib/mysql/mysql.sock) that your client program needs to be able to find. On a typical PHP (you didn't say, but I'm assuming) setup, it should know where to find this socket. If not, check /etc/my.cnf and /etc/php.ini to make sure the values match.
And finally, if that is PHP, stop using mysql_*() functions in PHP right now! They have been deprecated for years and are inefficient and insecure.

Related

rDNS security of MySQL remote connections

Consider a MySQL server that accepts remote connections.
What happens if you have a publicly facing MySQL server, and grant access to e.g.:
'sqluser'#'localhost'
If an attacker now sets his rDNS to "localhost", will he able to access this database?
Is there an extra check that also tries to resolve the rDNS back to the IP?
Regardless, database servers shouldn't be internet facing, but this a what-if-question.
It appears that MySQL uses forward-confirmed reverse DNS (FCrDNS) to counter these kind of attacks.
Most of the logic for the hostname checks can be found in sql/hostname.cc. Moreover, several checks are also performed to make sure that the rDNS doesn't contain an IP or is otherwise poisoned.

Passenger not reaching MySql

I have Nginx+Passenger+Rails3.
Passenger throws the following error:
Can't connect to MySQL server on '184.169.131.xxx' (111) (Mysql2::Error)
I am able to connect to MySql using mysql command. I think that the user that is running Passenger doesnt have the permissions.
I want to know: How to determine which user is running passenger and how to give permissions to access mysql.
Thanks
If it can't connect, it's likely that either:
Your MySQL process is bound to 127.0.0.1 and can't accept connections from remote machines.
Your firewall has blocked port 3306.
Are you certain that mysql is connecting to the same remote? You might be running a local server instead that allows access with the default configuration.
As a note, opening up 3306 to the general internet is a bad idea, so you will want to be very selective in how you do this. The best practice is to use private IPs whenever possible, like 10.x.x.x, 172.16.x.x or 192.168.x.x. There are a number of reserved blocks which can be used safely, but these cannot be routed outside your local network.
You should also check that whatever config/database.yml settings you have defined are the same you're using with the mysql command-line tool. Passenger is not treated as a special case.

Restricting MySQL connections from localhost to improve security

I heard that anyone that knows my MySQL Username and Password can access it, Even if it's listening only to localhost.
Supposing my info is as following:
USER: root
PASS: 123456
Host: LOCALHOST (only)
How is it possible that anyone out there (local) can access it?
If you restrict access from remote hosts to your usernames and passwords then someone won't be able to access the database externally.
You could also configure your firewall to only allow traffic to 3306 (MySQL Default Port) from the localhost machine.
Update
To setup your user so they can only access through LOCALHOST use:
GRANT ALL PRIVILEGES ON *.* TO db_user #'localhost' IDENTIFIED BY 'db_passwd';
GRANT ALL PRIVILEGES ON *.* TO db_user #'127.0.0.1' IDENTIFIED BY 'db_passwd';
Also, bind your MySQL server to the local address. You can do this by editing the [mysqld] section of my.cnf:
[mysqld]
bind-address = 127.0.0.1
you can block direct access to MySQL at the firewall or within MySQL itself, but the most likely way you'd be hacked is through an insecure web application - in that situation the attacker would most likely be able to read your database login and connect from the server.
So keep your applications secure - keep everything updated, don't allow file uploads, use suPHP if you have multiple accounts etc.
If you restrict your mysql application follow this steps:
1.You could just block port 3306. If the site is on the same server then it will still be able to access the database using localhost as the hostname.
2.Just add "bind-address = 127.0.0.1" to the "[mysqld]" section of their my.cnf file to restrict access to localhost only.
Most of people use this type of restriction.
This is an older question that I stumbled across, but if Darkeden had phpMyAdmin or similar running, anyone can log in to that using valid MySQL credentials.
If it was compromised, then in addition to restricting connections, change all passwords.
I didn't see an answer that answered his (adjusted) question - he has locked it to localhost and the attacker is still getting in.
If you have truly restricted it to local host (check using netstat -an | egrep 3306 to check it is listening to 127.0.0.1 not 0.0.0.0),
then the only way of accessing it is to originate a connection from that local host.
Initial steps to take:
probably rebuild a replacement system from scratch and hardening it before you make it publicly accessible (having a repeatable recipe eg using ansible will help as you may have to go through a few iterations to learn how he gets in)
Check with reputable security scanners what you obvious holes are,
Get help from a security professional (depends if you want to spend $ or time and frustration to fix)
Apply security patches,
Remove services you don't need,
restrict the database access to only those programs that need it,
redo all your passwords,
check for installed root kits, and other viruses,
secure your server if at your own office and train staff in handling social engineering,
use a service that will monitor and filter the requests coming through and deny direct access (eg use cloudflare as a cheep starting point)
check for keyboard loggers (physical and software and other viruses) on all machines used to access the server),
check for physical means of logging your keystrokes in accessing your server (eg web cam style used in atm), the more exotic include sound (https://en.wikipedia.org/wiki/Acoustic_cryptanalysis), typing with a nearby wifi access point (eg https://www.schneier.com/blog/archives/2016/08/keystroke_recog.html)
Add an audit trail and monitor database activity to work out how he is getting through, but at least you need to do all the obvious securing first because otherwise he will just hop from one security hole to another
He could be also getting through using:
accessing via some program you are running (eg a web server) that is externally accessible and has a security hole that allows him to run arbitrary sql commands through its existing database connection - see https://www.w3schools.com/sql/sql_injection.asp
tricking some program he has access to from outside to proxy a connection for him to localhost:3306 (eg through a miss-configured network firewall on the machine)
tricking some program to run a local program (bash. mysql etc), and from there gaining access to the database - buffer overflows and other specially crafted data is a common issue to running arbitrary code
man in the middle attack on a connection that has legitimate access
bugs in a program that is automatically or manually processing data from outside, eg email, processing of postscript/pdf/any document with scripting processing - even viewing a text file can be dangerous - see https://www.proteansec.com/linux/blast-past-executing-code-terminal-emulators-via-escape-sequences/
social engineering a way through getting people to give you access
managing to get a hardware device attached to a computer that has access (how many people will pick up a "memory stick" lying in the work car park and check it out instead its a "programmable keyboard", and ALL computers trust keyboards!)
and then many more all the other sorts of methods I don't know, but those that are involved share ...
Just remember that you need to have practical security, I think xkcd says it just right: https://xkcd.com/538/

MySQL connections limit in Micro CloudFoundry

I'm running my application with the Micro CloudFoundry, but I'm having trouble connecting to MySQL 'User 'usGh0jJk8EoZn' has exceeded the 'max_user_connections' resource'. How can I change this value?
I'm not quite sure you can change that value.
Before going down that road though, you may want to make sure that you are not leaking connections. Is your application running correctly when deployed locally (i.e. not using regular CloudFoundry nor Micro CF)? How are you connecting to the database? It may seem strange that you hit a connection limit if you're actually the sole user of your app, which I assume you are if using micro.
as ebottard said, it's well worth making sure your code isn't leaking connections. But, if you want to change the mysql setup for the instance running on Micro CloudFoundry, you can SSH in to the VM using the 'vcap' user.
Once connected, you will find the mysql configuration file at /var/vcap/jobs/mysql_node/config/my.cnf
For maximum connections you will also have to change the max_user_conns value in /var/vcap/jobs/mysql_node/config/mysql_node.yml
Please also take a look at;
http://docs.cloudfoundry.com/infrastructure/micro/using-mcf.html#logging-in-to-micro-cloud-foundry

How can I map a local unix socket to an inet socket?

I'm curious if it is possible to map a UNIX socket on to an INET socket. The situation is simply that I'd like to connect to a MySQL server. Unfortunately it has INET sockets disabled and therefore I can only connect with UNIX sockets. The tools I'm using/writing have to connect on an INET socket, so I'm trying to see if I can map one on to the other.
It took a fair amount of searching but I did find socat, which purportedly does what I'm looking for. I was wondering if anyone has any suggestions on how to accomplish this. The command-line I've been using (with partial success) is:
socat -v UNIX-CONNECT:/var/lib/mysql/mysql.sock TCP-LISTEN:6666,reuseaddr
Now I can make connections and talk to the server. Unfortunately any attempts at making multiple connections fail as I need to use the fork option but this option seems to render the connections nonfunctional.
I know I can tackle the issue with Perl (my preferred language), but I'd rather avoid writing the entire implementation myself. I familiar with the IO::Socket libraries, I am simply hoping anyone has experience doing this sort of thing. Open to suggestions/ideas.
Thanks.
Reverse the order of your arguments to socat, and it works.
socat -v tcp-l:6666,reuseaddr,fork unix:/var/lib/mysql/mysql.sock
This instructs socat to
Listen on TCP port 6666 (with SO_REUSEADDR)
Wait to accept a connection
When a connection is made, fork. In the child, continue the steps below. In the parent, go to 2.
Open a UNIX domain connection to the /var/lib/mysql/mysql.sock socket.
Transfer data between the two endpoints, then exit.
Writing it the other way around
socat -v unix:/var/lib/mysql/mysql.sock tcp-l:6666,reuseaddr,fork
doesn't work, because this instructs socat to
Open a UNIX domain connection to the /var/lib/mysql/mysql.sock socket.
Listen on TCP port 6666 (with SO_REUSEADDR)
Wait to accept a connection
When a connection is made, spawn a worker child to transfer data between the two addresses.
The parent continues to accept connections on the second address, but no longer has the first address available: it was given to the first child. So nothing useful can be done from this point on.
Yes, you can do this in Perl.
Look at perlipc, IO::Select, IO::Socket and Beej's Guide to Network Programming.
You might want to consider doing it in POE - it's asynchronous library for dealing with events, so it looks like great for the task.
It is not 100% relevant, but I use POE to write proxy between stateless protocol (HTTP) and statefull protocol (telnet session, and more specifically - MUD session), and it was rather simple - You can check the code in here: http://www.depesz.com/index.php/2009/04/08/learning-poe-http-2-mud-proxy/.
In the comments somebody also suggested Coro/AnyEvent - I haven't played with it yet, but you might want to check it.