Cannot connect to AWS RDS MySql using IAM from EC2 instance - mysql

Using these commands
bash $ RDSHOST="xxxxxxx.mydbid.us-xxst-x.rds.amazonaws.com"
bash $ TOKEN="$(aws rds generate-db-auth-token --hostname $RDSHOST --port 3306 --region us-xxst-x --username some_name )"
bash $ mysql --host=$RDSHOST --port=3306 --ssl-ca=rds-ca-2019-root.pem --user=some_name --password=$TOKEN
I get this error
ERROR 1045 (28000): Access denied for user 'some_name'#'123.123.123.123' (using password: YES)
When logged into the database and running
SELECT USER, PLUGIN, HOST FROM mysql.user WHERE USER LIKE'%some_name%';
I get this:
+-----------+-------------------------+------+
| user | plugin | host |
+-----------+-------------------------+------+
| some_name | AWSAuthenticationPlugin | % |
+-----------+-------------------------+------+
1 row in set (0.02 sec)
This is the policy applied to the role
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds-db:connect"
],
"Resource": [
"arn:aws:rds-db:us-xxxx-x:123123123123:dbuser:db-QPASDASDASDASDASDASDASDASD/admin_user",
"arn:aws:rds-db:us-xxxx-x:123123123123:dbuser:db-QPASDASDASDASDASDASDASDASD/some_body",
"arn:aws:rds-db:us-xxxx-x:123123123123:dbuser:db-QPASDASDASDASDASDASDASDASD/some_name"
]
}
}
Also, IAM is enabled on the RDS database. The certificate .pem file is in the same folder as where I'm running the commands.
I've been over this guide, and this guide, and this guide.

Related

Can't connect to RDS via AWS.RDS.Signer

I'm trying to connect to my MySQL RDS from a Lambda via AWS.RDS.Signer with the following code and fake credentials:
1 const DB_REGION = 'ap-southeast-2a'
2 const DB_HOST = 'dbinstance.ddtev8utygt.ap-southeast-2.rds.amazonaws.com'
3 const DB_PORT = 3306
4 const DB_USER = 'anyuser'
5 const DB_NAME = 'anydb'
6
7 const signerOptions = {
8 region: DB_REGION,
9 hostname: DB_HOST,
10 port: DB_PORT,
11 username: DB_USER
12 }
13
14 const signer = new AWS.RDS.Signer(signerOptions)
15 const token = await signer.getAuthToken()
16
17 const config = {
18 host: DB_HOST,
19 user: DB_USER,
20 password: token, // "Password123"
21 database: DB_NAME,
22 ssl: 'Amazon RDS',
23 authPlugins: {
24 mysql_clear_password: () => () => token
25 }
26 }
but I always get this error
"Access denied for user 'anyuser'#'172.14.1.12' (using password: NO)"
I'm not entirely sure if that is needed for the AWS.RDS.Signer but I selected this option of my database:
Password and IAM database authentication
Authenticates using the database password and user credentials through AWS IAM users and roles.
NOTE: If I swap the password from token to "Password123" on line 20 I can successfully connect to my RDS.
Am I missing something here or does AWS.RDS.Signer only work with RDS Proxy?
By the way: the getAuthToken function gives me something like that (token truncated)
"dbinstance.ddtev8utygt.apsoutheast2.rds.amazonaws.com:3306/Action=connect&DBUser=anyuser&&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIAU7VGXF6UCWYZCFEG%2F20210318%2Fap-southeast-2a%2Frds-db%2Faws4_request&X-Amz-Date=20210318T105145Z&X-Amz-Expires=900&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEAsaDmFwLXNvdXRoZWFzdC0yIkgwRgIhAKg8ibwNJ4E3hSOuq7HtDFvqHxmTlpOUk3I6EH2%2B9VdOV3RQ%2F03xiVdvjhEBkHqEXHQ%3D&X-Amz-Signature=749d931f74873e6c2c0d4fec94f0743f42efd5aa95ca0ac0f05c4bef30e3bd4d&X-Amz-SignedHeaders=host"
I finally can connect to my RDS via Lamdba using IAM (aka AWS.RDS.Signer)
So what was the problem?
Short story:
I used the wrong region in my Policy and in the props for the AWS.RDS.Signer.
I assumed that the Availability zone (ap-southeast-2a) equals the region, but that's not true. The correct region is actually described when the AWS command line creds get created. To find out the region invoke cat ~/.aws/config from the terminal. My default region was actually region=ap-southeast-2.
Long story:
When I started with AWS.RDS.Signer I followed the instructions here
When it came to extracting the DB info for the Policy, I used this command
aws rds describe-db-instances --db-instance-identifier <MY INSTANCE NAME> --query "DBInstances[*].DbiResourceId" --region ap-southeast-2a
but I got this error Could not connect to the endpoint URL: "https://rds.ap-southeast-2a.amazonaws.com/"
After a bit of Googling, I realised that the region is not right. That gave me a hint to change the region in the policy and in the code of my Lambda function.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds-db:connect"
],
"Resource": [
"arn:aws:rds-db:<my-region>:<my-account-id>:dbuser:<my-db-resource-id>/<my-db-username>"
]
}
]
}
Then I created an extra user (ssluser) in the DB to connect with the AWS.RDS.Signer token
CREATE USER 'ssluser' IDENTIFIED WITH AWSAuthenticationPlugin as 'RDS';
GRANT ALL PRIVILEGES ON <MY DB NAME>.* TO 'ssluser'#'%';
GRANT USAGE ON <MY DB NAME>.* TO 'ssluser'#'%' REQUIRE SSL;
The next step was to add the above policy to the EC2 instance, ssh into the instance, install the MySQL client yum install mysql and try to connect to the instance using the token
mysql --host=dbinstance.chteb5kjtggo.ap-southeast-2.rds.amazonaws.com --port=3306 --ssl-ca=rds-combined-ca-bundle.pem --enable-cleartext-plugin --user=ssluser --password=`aws rds generate-db-auth-token --hostname dbinstance.chteb5kjtggo.ap-southeast-2.rds.amazonaws.com --port 3306 --region ap-southeast-2 --username ssluser`
After successfully connect to the RDS without providing a password I only had to attach the policy to my Lambda and change the username and region in my Lambda code to
1 const DB_REGION = 'ap-southeast-2'
2 const DB_HOST = 'dbinstance.ddtev8utygt.ap-southeast-2.rds.amazonaws.com'
3 const DB_PORT = 3306
4 const DB_USER = 'ssluser'
5 const DB_NAME = 'anydb'
I hope that will help someone in the future.

Suddenly my instance stopped responding to my incoming connections for mysql connections

I had installed mysql on gcp instance for dev and test purposes. Everything was working perfect but suddenly started getting connection timed out error. Firewall is opened on for MySQL connections. It was working perfectly, suddenly it stopped.
Here is the log for the connection
{
inserted: "xxxxxx"
jsonPayload: {
connection: {
dest_ip: "10.142.0.2"
dest_port: 3306
protocol: 6
src_ip: "54.87.222.27"
src_port: 52638
}
disposition: "ALLOWED"
instance: {
project_id: "xxxxxxxx"
region: "us-east1"
vm_name: "stockarea-server"
zone: "us-east1-b"
}
remote_location: {
city: "Ashburn"
continent: "America"
country: "usa"
region: "Virginia"
}
rule_details: {
action: "ALLOW"
direction: "INGRESS"
ip_port_info: [
0: {
ip_protocol: "TCP"
port_range: [
0: "3306"
]
}
1: {
ip_protocol: "UDP"
port_range: [
0: "3306"
]
}
]
priority: 1000
reference: "network:default/firewall:heroku-sql"
source_range: [
0: "0.0.0.0/0"
]
}
vpc: {
project_id: "xxxxxxxx"
subnetwork_name: "default"
vpc_name: "default"
}
}
logName: "projects/pxxxxxxx/logs/compute.googleapis.com%2Ffirewall"
receiveTimestamp: "2020-05-22T18:25:57.341545693Z"
resource: {
labels: {
location: "us-east1-b"
project_id: "xxxxxxxx"
subnetwork_id: "5137290941342062105"
subnetwork_name: "default"
}
type: "gce_subnetwork"
}
timestamp: "2020-05-22T18:25:45.934585080Z"
}
I have MySQL users having permission to get access for different IP address:
+------------------+-----------+
| user | host |
+------------------+-----------+
| client | % |
| stockarea | % |
| debian-sys-maint | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
UPDATE:
I saw MySQL error.log file and saw somebody attacked and has somehow crashed the database. It was throwing error packet getting out of order. I reinstalled the MySQL for now to solve this and continue my development.
Hi I tried to ping your external IP and it works. So all 80, 443, and 3306. I believe your firewall is setup correctly, Please make sure your service is running and listening to those ports.
And finally, please be aware that you should sanitize private inforamtion such as ip address and project ID in public forum

Ansible playbook gets stuck trying to perform mysql operations

I'm trying to perfrom a simple "SHOW DATABASES;" command with an ansible playbook and it gets stuck when executes the command.
I tried different options
- hosts: servers
become: true
vars_prompt:
- name: "db_passw"
prompt: "DB root password?"
tasks:
- name: Configure Database
shell: |
mysql -u root -p {{ db_passw }} < ~/sql_query.sql
Also
- hosts: servers
become: true
vars_prompt:
- name: "db_passw"
prompt: "DB root password?"
tasks:
- name: Configure Database
shell: |
mysql -u root -p {{ db_passw }} -e "SHOW DATABASES;"
And I also tried, just as a test, to put the password explicitly
- hosts: servers
become: true
vars_prompt:
- name: "db_passw"
prompt: "DB root password?"
tasks:
- name: Configure Database
shell: |
mysql -u root -p <root_passw> -e "SHOW DATABASES;"
But it always gets stuck at the same point. I tried to execute above's mysql commands in the remote machine shell and they work with no problems. I also tried to execute other commands before mysql's ones and they are being executed.
Is there any problem between ansible and mysql?
I know thta there is a MySQL module for Ansible, but it's functionality is too limited.
Thank you
Works for me. The play below
- hosts: dbserver
tasks:
- command: |
mysql -e "SHOW DATABASES;"
register: result
- debug:
var: result
gives:
TASK [debug]
ok: [dbserver] => {
"result": {
"changed": true,
"cmd": [
"mysql",
"-e",
"SHOW DATABASES;"
],
"delta": "0:00:00.010958",
"end": "2019-04-04 16:19:58.359100",
"failed": false,
"rc": 0,
"start": "2019-04-04 16:19:58.348142",
"stderr": "",
"stderr_lines": [],
"stdout":
...
It's not necessary to specify "-u root" when "become: true". I haven't set a MySQL password for root.

Cant connect from Node Js (in host) to a MySql container

I'm pretty new in Node and i was trying some examples from a book.
When i try to connect from NodeJS to a Mysql container i get this error:
Access denied for user 'root'#'172.17.0.1'
The MySql database is inside a Docker container created using this command:
> docker run --detach --name=test-mysql -p 3306:3306
--env="MYSQL_ROOT_PASSWORD=root" mysql
This is the code from my Node program
'use strict';
var mysql = require('mysql');
var connection = mysql.createConnection({
host: '127.0.0.1',
user: 'root',
password: 'root'
});
connection.query(
'SELECT "foo" AS first_field, "bar" AS second_field',
function(err, results, fields) {
if (err){
console.log(err);
}else{
console.log(results);
}
connection.end();
}
);
And i can connect to mysql from the shell using
>mysql -u root -h 127.0.0.1 -p
Also i can use -h 172.17.0.2 and -h 172.17.0.1
If i check my user#host inside Mysql
mysql> select user();
+-----------------+
| user() |
+-----------------+
| root#172.17.0.1 |
+-----------------+
1 row in set (0.00 sec)
mysql> show grants for root;
+-------------------------------------------------------------+
| Grants for root#% |
+-------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'#'%' WITH GRANT OPTION |
+-------------------------------------------------------------+
1 row in set (0.00 sec)
So somehow, node is having trouble connecting to MySql but everything seems to be ok...
Thanks!!
NOTE: Solved!! Upgrading the package version of the mysql module fixed the problem. The previous version was "~2.0.0"
My package.json:
{
"devDependencies": {
"jasmine-node": "",
"mysql": "~2.1.x"
}
}

Fiware keystone api create user and access with horizon

im using keystone api to create an user (as in Fiware Keystone API Create User).
my steps:
create project with:
curl -s -H "X-Auth-Token:17007fe11124bd71eb60" -H "Content-Type:
application/json" -d '{"tenant": {"description":"Project1",
"name":"proyecto1", "enabled": true}}'
http://localhost:35357/v2.0/tenants -X POST | python
-mjson.tool
create role:
curl -s -H "X-Auth-Token:17007fe11124bd71eb60" -H "Content-Type:
application/json" -d '{"role":{"name":"Project1Admin",
"description":"Role Admin for project1"}}'
http://localhost:35357/v3/roles | python -mjson.tool
Create user:
curl -s -H "X-Auth-Token:17007fe11124bd71eb60" -H "Content-Type:
application/json" -d '{"user": {"default_project_id":
"d0f384973b9f4a57b975fcd9bef10c6e", "description":"admin1",
"enabled":true, "name":"admin", "password":"admin",
"email":"admin#gmail.com"}}' http://localhost:35357/v2.0/users |
python -mjson.tool
last step: create user-role-tenant relationship:
curl -s -H "X-Auth-Token:17007fe11124bd71eb60"
http://localhost:35357/v2.0/tenants/d0f384973b9f4a57b975fcd9bef10c6e/users/admin1/roles/OS-KS/0c10f475076345368724a03ccd1c3403
-X PUT
if i check user:
curl -s -H "X-Auth-Token:17007fe11124bd71eb60" http://localhost:5000/v3/users/admin1 | python -mjson.tool
response:
{
"user": {
"default_project_id": "d0f384973b9f4a57b975fcd9bef10c6e",
"description": "admin1",
"domain_id": "default",
"email": "admin1#gmail.com",
"enabled": true,
"id": "admin1",
"links": {
"self": "http://localhost:5000/v3/users/admin1"
},
"name": "admin1",
"username": null
}
}
I think thats good, But I try to connect with horizon and have an error "Invalid user or password". The result im getting in logs is the following :
keystone.log
2016-04-20 07:56:03.949 2150 WARNING keystone.common.wsgi [-] Could not find user: admin1#gmail.com
2016-04-20 07:56:03.967 2150 INFO eventlet.wsgi.server [-] 127.0.0.1 - - [20/Apr/2016 07:56:03] "HEAD /v3/OS-TWO-FACTOR/two_factor_auth?user_name=admin1%40gmail.com&domain_name=Default HTTP/1.1" 404 159 0.077033
horizon.log:
[Wed Apr 20 07:59:41.934935 2016] [:error] [pid 5963:tid
140154061260544] Login failed for user "admin1#gmail.com".
Anyone knows why this user cant connect with horizon?
thanks
In KeyRock, we use the name field to store the user email, and the username field to store its username. When creating a user, all attributes provided in the request but the name, the username, the default_project_id, the domain_id and the enabled attribute are serialized and stored inside a field called extra. Therefore, your email attribute will be stored in the extra field.
After registering, when loging in to Horizon and providing the user email, Horizon sends a request to Keystone to search for the email in the name field. Since you are entering admin1#gmail.com, but the actual name you provided is admin1, login into Horizon will fail.
Registering the user again with admin1#gmail.com as name (and not email) should fix your problem, but you can also enter admin1 in the email field of the login form if you can't afford to recreate the user.
Hope this solves your issue!