Node.js + MySQL: Program refuses to connect to remote database with "ECONNREFUSED" - mysql

I figured out the solution below. I've left a second update for more clarification.
Context
I've got a Discord bot, written in JavaScript using the discord.js library, that I've been working on by myself for nearly two years. I started using MySQL for database queries and such just over a year ago. This was on my local Windows 10 machine. As this was a small hobby project at the time, I wasn't too worried about only having one MySQL instance for both development and production. Finally, about 9 months ago, I was able to get the bot up and running on my Linode server, which runs Ubuntu 18.04, along with a copy of the MySQL database running there.
Up until now, with this setup, things have worked smoothly. I use the local database on my Windows PC for development and testing, and then I push updates to the Ubuntu 18.04 server on Linode where the production database is. Also, just in case this helps, I do run the bot locally on my PC when doing development. There's two Discord bots with two unique tokens (one for production and one for development) so that I can keep the production one running while I work on updates. I don't have the development bot running on the server 24/7 like the production bot.
Recently, however, a friend of mine (a self-proclaimed "for-loop extraordinaire") has started helping me with the development. As such, we think now is a good time to have the development database active 24/7 as well, so that he may work on the bot whether I'm around or not. This is where we get to the problem.
The Issue
I've left an update below as I've switched to the mysql2 package to try and find a solution.
So, in case it wasn't obvious, my goal here is very simple: I want my bot (when run locally on my, or my friend's, Windows machine using node.js) to connect to the remote database hosted on my Ubuntu 18.04 server, which is in the cloud, not my local network. I'm not afraid to admit that I'm far from a good web developer, so I don't know the logistics or the ins and outs of how this stuff really works. It's a wonder I've made it this far. But I thought it would be as simple as when connecting to a local MySQL instance. However, when I run the code, the console spits this error out at me.
Error: connect ECONNREFUSED LINODE.IP.ADDRESS.HERE:3306
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16)
--------------------
at Protocol._enqueue (D:\Users\path\node_modules\mysql\lib\protocol\Protocol.js:144:48)
at Protocol.handshake (D:\Users\path\node_modules\mysql\lib\protocol\Protocol.js:51:23)
at Connection.connect (D:\Users\path\node_modules\mysql\lib\Connection.js:119:18)
at Object.<anonymous> (D:\Users\path\bot\index.js:118:5)
at Module._compile (internal/modules/cjs/loader.js:1138:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
at Module.load (internal/modules/cjs/loader.js:986:32)
at Function.Module._load (internal/modules/cjs/loader.js:879:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47 {
errno: 'ECONNREFUSED',
code: 'ECONNREFUSED',
syscall: 'connect',
address: 'LINODE.IP.ADDRESS.HERE',
port: 3306,
fatal: true
}
Here's how my code is currently set up:
const mysql = require("mysql")
//CONNECT TO MYSQL
var con = mysql.createConnection({
host: 'example.com',
port: 3306,
user: 'user',
password: 'pass',
database: 'botDB',
charset: "utf8mb4"
});
//CONNECTED TO DATABASE
con.connect(err => {
if (err) { throw err };
console.log("My database is up and running!")
})
This method worked flawlessly when host was localhost (obviously) but when trying to connect remotely to the server on Linode, it just refuses. I've tried both the Linode URL (example.com) as well as the IP (LINODE.IP.ADDRESS.HERE) address, both giving me the same error. Also I am aware that the mysql2 package for Node exists, I just haven't switched over yet. If switching over would in fact help with this problem, please let me know.
Solutions I've Tried
I've tried multiple answers from multiple similar questions on this site, such as this one and this, however none of the solutions work (including adding socketPath or changing port, etc.)
I've tried changing the bind-address in the mysqld.cnf file to 0.0.0.0 and *, both of which did allow the bot to connect to the database, however access was still denied to actually read the database itself. All I know is that it at least connected (though trying it again now has left me with an error message this time)
code: 'ER_NOT_SUPPORTED_AUTH_MODE',
errno: 1251,
sqlMessage: 'Client does not support authentication protocol requested by server; consider upgrading MySQL client',
sqlState: '08004',
fatal: true
MySQL is up to date so could this have to do with me not using mysql2? I'm not a fan of this option, regardless, but I thought I'd try it at least.
My last resort was to create an SSH tunnel to connect to the database. Again, I'm still a web development novice, so I didn't fully know what I was doing, but I followed this guide here, but replacing the code I needed to, and ended up with a completely separate SSH connection error. If SSH is absolutely required to accomplish what I want, then please let me know and I'll open a new question regarding that. I just wanted to mention it here to show that I have at least tried.
UPDATE
I've switched to using mysql2, and while the error message is cleaner, it still persists.
I've attempted Archil's solution, and while it doesn't do much now that I've switched to mysql2, it did provide me with a better understanding of MySQL's authentication system, which lead me to switch in the first place. Unfortunately, both Archil's answer and the mysql2 upgrade give me the same error:
{
code: 'ER_ACCESS_DENIED_ERROR',
errno: 1045,
sqlState: '28000',
sqlMessage: "Access denied for user 'root'#'MY.LOCAL.IP.ADDRESS' (using password: YES)"
}
...despite the fact that I have granted 'root'#'%' all privileges.
Regardless, again, this isn't my preferred way of doing this anyway. If there's a more secure solution I'll gladly take it. I'll continue to try different solutions now that I have mysql2 installed.
UPDATE 2
After looking further into it, I figured out that permissions were NOT set up like I thought they were for the user I was trying to connect to the server with. Once I fixed that, it did connect, but one of the tables that gets queried when the bot starts was showing as empty. Turns out it didn't exist!
I had made a copy of the production database as a base for the new development one. Problem was, it was missing a table that was on my local (old) development database. This lead to me believing that the bot was connecting with MySQL but not reading anything from the database. I've added the correct table, and it works great! I've left a solution with more specific steps below, in case this page is ever found by another novice web developer like me. Thanks for the help!

I've left a second update as to how I got to this solution.
In short, setting the bind-address to 0.0.0.0 does work. If you're using the original mysql package, you'll need to follow Archil's solution. If you're using mysql2 and there's still an error (or if Archil's answer doesn't work with mysql), make sure you double-check the permissions of the user you're trying to connect with using:
SHOW GRANTS FOR 'user'#'%';
Assuming you're trying to connect remotely like I was, you'll need to create a user with the '%' wildcard if you haven't.
At this point it should connect, as it does for me, and if there's any errors after that, it's probably something to do with the tables within the database itself.

I've answer https://stackoverflow.com/a/50547109/4089212
Check please.
You need to change auth mode for mySQL.

In my case (mariadb) I've managed to change the bind address to 0.0.0.0 in the file:
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
After a restart I've managed to connect to the database:
service mysql restart
You may need to search for the correct file to edit in the folder /etc/mysql/mariadb.conf.d/
Just look for bind-address (may have an IP address like 127.0.0.1)

Related

Docker MySQL "Access denied for user 'root'#'localhost" outside of terminal

I know that this is a fairly common error, but the curious thing is that in this case the credentials work when I'm logged in to Docker and working with mysql in the terminal. But when I try to use a client like DBeaver or MySQL Workbench, or even making an API call via Python, I get the error "Access denied for user 'root'#'localhost".
I thought it might be because I have another local MySQL database using port 3600, so I changed it to 3700 but the problem persists. I've made sure that the image is running in the Docker application, and besides, as mentioned, it works using the terminal. This is on MacOS Ventura. If there's any other information I can provide that would help, please let me know. Any assistance is appreciated!

MySQL Workbench fails to make connection

completely new to MySQL, have no idea, just trying to learn, so any help would be deeply appreciated.
I installed the ubuntu version of MySQL Workbench although I have Linux Mint. Had to do this since there is no mint version. And besides most ubuntu apps work on mint, well, maybe.
But this may be causing the problems I am facing.
Even though I managed to install it on my mint box, when I started it for the first time I got a warning that it is unsupported (or something like that) and hence this can cause problems. I proceeded anyway.
Before going any further, I should point out that MySQL is working in a docker container. did not want to use docker this early, but its in the tutorial, so yeah.
I have made 2 connections but none of them work.
Here are the details on both these connections as they appear in 'Manage Server Connections'.
Connection Name: Connection1
Connection Method: Standard (TCP/IP)
Hostname: 127.0.0.1
Port: 3306
Username: v.je
Connection Name: Connection2
Connection Method: Standard (TCP/IP)
Hostname: 192.168.10.10
Port: 3306
Username: v.je
When I click on Connection1 under 'MySQL Connections' on the 'Welcome to MySQL Workbench' window, the SQL editor opens.
However, there is no 'SCHEMAS' category on the left-side pane. There are Management, Instance and Performance categories but no schemas. Because of this I cant proceed further on the tutorial I am using.
and on the top tab its written "Connection1- Warning - not supported".
WHy is this happening and what is the solution?
Connection2 simply does not work. When I click on it, an error message pops up saying "Your connection attempt failed for user v.je to the MySQL server at 192.168.10.10:330: Unable to connect to localhost"
There are so many possibilities, that I dont really know what to do. Any help to get it going would be appreciated, thanks a lot.

Failed to connect to database: Error: Can't connect to MySQL server on 'xxxxxx.rds.amazonaws.com' (111)

I am trying to run this command locuscompare(in_fn1 = gwas_fn, in_fn2 = eqtl_fn, title1 = 'CAD GWAS', title2 = 'Coronary Artery eQTL') within R in ubuntu behind a corporate proxy
but having the following persistent issue for three days.
Error in .local(drv, ...) :
Failed to connect to database: Error: Can't connect to MySQL server on 'locuscompare-us-west-2a.xxxxxx.us-west-2.rds.amazonaws.com' (111)
Warning message:
In rm(config) : object 'config' not found
I have already tried the solutions mentioned in stack overflow, such as installing MySQL, assigning users' privilege, editing bind-address in configuration file, but still do not know how to run it smoothly.
I thought at first it was an issue related to the lacking of MySQL server and AWS account on my device. But, when I use it on my mac with home Wi-Fi, it is working like a charm without any installation and creation of MySQL server and AWS account. However, I still need to use this tool on my work PC because of input data privacy issue.
Does it mean I need to create an AWS account and adjust the network setting in it to access MySQL server on this URL 'locuscompare-us-west-2a.xxxxx.us-west-2.rds.amazonaws.com'? (Sorry that I am very new to AWS and MySQL.)
Please let me know how to run this tool behind a corporate proxy.

Heroku. MariaDB. Access denied for user

I'm creating new app on Heroku. Installed add-on "JawsDB Maria" successfully - I can open it's dashboard
In PHP on connection to DB I receive error:
SQLSTATE[HY000] [1044] Access denied for user 'vcgu1h273742rn5l'#'%' to database 'jeyx2j66ipgtqe11'
I'm sure that problem is not in PHP, because the same error I receive even on MariaDB dashboard trying to Create New Databite - https://prnt.sc/rj4dr4 .
Looks like solution is to GRANT ALL PRIVILEGES to user. But using dashboard I can't execute even SHOW GRANTS.
Questions:
Can somebody help how to solve this problem?
Or, at least, which way I can GRANT ALL PRIVILEGES?
I've tried:
read Heroku docs: JawsDB MySQL, PHP + DB
searching for similar problems in Heroku support, Google, SO:
the best match I found is here. But heroku pg:psql - it's tool only for PostgreSQL.
tried to find useful command for my case in Heroku CLI Commands
Additional info - I'm sure it is not important, but just in case it is:
project is based on Yii2
for easy deployment on Heroku installed "purrweb/yii2-heroku"
You probably know how to read your error message. At any rate, my superpower is explaining the obvious. So, ... here goes.
SQLSTATE[HY000] [1044] Access denied for user 'vcgu1h273742rn5l'#'%' to database 'jeyx2j66ipgtqe11'
Tells you your php program couldn't get to the MySQL server. That operation goes in these steps.
Make a TCP/IP network connection to the server. SUCCESS.
Present a user name and password to the server. SUCCESS.
But the server rejected those credentials. FAILURE
Access the database schema mentioned in the connect request. Not attempted yet. So we have no information about whether the named database actually exists.
The success of step 1 means there are no firewall or network-routing issues. That's good.
The success of step 2 gives us even more confidence about firewall issues.
The failure of step 3 tells us that we're not using a username and password that the MySQL server knows about.
Step 4 is incomplete. So, even if we fix the username and password issues, we still might get another issue before this mess is behind us.
Heroku assigns those usernames to their customers. So, check on the appropriate Heroku control panel to see whether you're using the right username / password credentials. Your error message says you've got wrong credentials.
Next step? Ask your vendor for help. Is Bruce Schneier is reading this? Maybe he can fix this for you from his earbuds while he's riding on the subway. But none of the rest of us here on SO can fix it.
I've waited for 8 hours, hoping there is some trigger, that will complete all necessary settings. But it didn't helped.
Then I reinstalled this add-on. And now all works fine!
So, that was some kind of "JawsDB Maria" bug.

Rails mysql can't connect using password yes

I install some old app build in Rails 4.0.0 and ruby 1.9.3 gems. Everything goes ok but when I go to rails console and try for example wrote : User, to get database table it give me error:
Mysql2::Error: Access denied for user 'root'#'localhost' (using password: YES)
What is interesting, when I do:
sudo /etc/init.d/mysql stop
It says that database was stopped but app still working :)
Can somebody tell what is going on?
Well - if the database tells you it's stopped, and your app is still working I can think of 3 possible causes.
The database is still running, and you've been lied to
The app does not need a database to respond to the requests you make
The app is using a database elsewhere.
The most obvious way I can think of, it to have a look at config/database.yml, there you can see what database your app is connecting to, and the username/password. If it's not the one you've stopped - there's your answer.
If it is the one you've stopped, the try something like:
netstat -an | grep -i mysql
to see and the some ps -ef and kills (I'm a bit brutal) as required to bring it down.
otherwise, it may not actually using the database to serve the information you want. If information is hard coded in the controllers and view - it'll serve you just fine.