Робимо доступною базу даних для віддаленого підключення

Почнемо з того, що бувають випадки, коли потрібно робити додаток з підключенням до бази даних. Це робиться для того, щоб особливо не копатися в розробці бекенд і сконцентруватися на фронтенді через брак рук і навичок. Я не беруся казати, що моє рішення буде безпечним, але воно працює.

Оскільки я не люблю платити за хостинг, я скористався мережею на роботі, там є білий IP. Ось її структура:

Робимо доступною базу даних для віддаленого підключення

У мене є доступ до кількох комп'ютерів, точніше до 192.168.1.2 (він же 192.168.0.2) там стоїть Linux і до 192.168.0.3 з Windows. Загалом, для своєї програми я вибрав mysql і подивився що є на Linux. Там уже було встановлено він, але пароль ніхто не знає, а ті, хто знали забули (ті, хто працював до мене). Дізнавшись, що він нікому не потрібен, я його видалив і спробував встановити заново. Пам'ять не вистачало і оскільки, щоб виправити цю помилку, довелося б підключати до нього монітор і клавіатуру з мишею, я вирішив кинути цю справу. Тим більше що машина з Windows куди потужніша і плюс до всього у мене у самого стоїть вона на домашньому ноутбуку. В принципі саму установку я описувати не буду, є купа мануалів та відео про це. Встановивши MySQL на Windows машину, я вирішив зробити бекап таблиць з ноутбука на робочу станцію.

Робиться це так (у моєму випадку):

mysqldump -uroot -p your_base > dump_file.sql

Далі у новій базі даних створюємо базу даних та відновлюємо бекап на «новій» машині.

mysql -h localhost -u root -p

create database your_base;
use your_base;

mysql -uroot -p your_base < dump_file.sql

show tables;


Файл з бекапом треба на нову машину покласти і можливо якщо не в директорії з утилітою, то повний шлях до неї. (Я просто залив бекап на гітхаб і клонував його на нову машину). Я додав би як створюються самі таблиці, але не зберіг скрини, та й думаю це не складно навіть студенту 2-3 курсу.

Коли відновив усі таблиці, настав час зробити доступним віддалений доступ до бд. Загалом такі команди до успіху не привели (видав тільки право на читання select).

create user 'client'@'%' IDENTIFIED by 'client';
grant select on your_base . * to 'client'@'%';
flush privileges;

Точніше я міг підключитися до бази тільки командою,

mysql -h localhost -u client -pclient

а такий уже не міг

mysql -h 192.168.0.3 -u client -pclient

мені це не підходило також не могло підключитися через цю адресу та від root.

Допомогла програма mysql workbench там у налаштуваннях змінюєте localhost на % і працює, хоча client це не допомогло. Тепер ви можете підключатися до бд з консолі або коду з будь-якої адреси.

Робимо доступною базу даних для віддаленого підключення

Ще потрібно зробити домашню мережу або підприємства і вимкнути брандмауер Windows інакше не зможете навіть зробити пінг цієї машини (не те щоб підключитися до бд).

Підлога справи зроблено, далі потрібно, щоб я міг з дому підключитися до бази даних.

Як видно із схеми мережі, то до інтернету треба пройти шлях від 192.168.0.3 до 192.168.1.1 (роутер) підемо у зворотний бік. Налаштуємо маршрут від 192.168.1.1 до 192.168.1.2 таким чином:

Робимо доступною базу даних для віддаленого підключення

Загалом картинку не показує — напишу руками:

route add 192.168.0.0 mask 255.255.255.0 gateway 192.168.1.2

Це можна зробити тільки в одній підмережі, тобто не можна відразу прокинути на адресу 192.168.0.2 або 192.168.0.3

Це потрібно, щоб роутер знав де знаходиться підсіти 192.168.0.0/24 (вчіть основи мереж це корисно).

Тепер додаємо прокидання порту 3306 (порт mysql по дефолту (якщо ви його при установки тільки не змінили)) на адресу 192.168.1.2

Робимо доступною базу даних для віддаленого підключення

Ось залишилося зробити найскладніше це зробити форвардинг на лінукс машині (на ній дві мережеві картки 192.168.1.2 (інтерфейс enp3s1) і 192.168.0.2 (інтерфейс enp3s0) щоб мережевики знали, що перекинути їх з 192.168.1.2. нашу машину Windows з MySql.

sudo iptables -A FORWARD -i enp3s1 -o enp3s0 -p tcp --syn --dport 3306 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A FORWARD -i enp3s1 -o enp3s0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A FORWARD -i enp3s0 -o enp3s1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -t nat -A PREROUTING -i enp3s1 -p tcp --dport 3306 -j DNAT --to-destination 192.168.0.3
sudo iptables -t nat -A POSTROUTING -o enp3s0 -p tcp --dport 3306 -d 192.168.0.3 -j SNAT --to-source 192.168.1.2
и последняя строчка сохраняет введенные команды чтобы они при перезапуске оси не стерлись
sudo service iptables-persistent save

Тобто. 1-я рядок означає, що ми приймаємо перше з'єднання, 2-а і 3-я що можна в обидві сторони пускати пакети, 4-я і 5-я означає заміну адреси призначення та джерела. І вуаля можна коннектіться з дому через mysql. І насамкінець мій код на с++ який це робить:

//DataBaseConnection.cpp
#include "DataBaseConnection.h"

DataBaseConnection::DataBaseConnection()
{
}
void DataBaseConnection::Connect()
{
	// Получаем дескриптор соединения
	conn = mysql_init(NULL);
	if (conn == NULL)
	{
		// Если дескриптор не получен – выводим сообщение об ошибке
		fprintf(stderr, "Error: can'tcreate MySQL-descriptorn");
		//exit(1); //Если используется оконное приложение
	}
	// Подключаемся к серверу
	if (!mysql_real_connect(conn, "192.168.0.3", "root", "password", "your_base", NULL, NULL, 0))
	{
		// Если нет возможности установить соединение с сервером 
		// базы данных выводим сообщение об ошибке
		fprintf(stderr, "Error: can't connect to database: %sn", mysql_error(conn));
	}
	else
	{
		// Если соединение успешно установлено выводим фразу - "Success!"
		fprintf(stdout, "Success!n");
	}
}
std::vector<std::string> DataBaseConnection::Query()
{
	vectordrum.clear();
	std::string query = "SELECT * FROM drum where id=0";
	const char * q = query.c_str();
	qstate = mysql_query(conn, q);
	if (!qstate)
	{
		res = mysql_store_result(conn);
		while (row = mysql_fetch_row(res))
		{
			//printf("ID: %s,Position: %s, Image: %sn", row[0], row[1], row[2]);
			vectordrum.push_back(row[2]);
		}
	}
	else
	{
		std::cout << "Query failed:" << mysql_error(conn) << std::endl;
	}
	return vectordrum;
}
void DataBaseConnection::Close()
{
	// Закрываем соединение с сервером базы данных
	mysql_close(conn);
}
DataBaseConnection::~DataBaseConnection()
{
	vectordrum.clear();
}
//DataBaseConnection.h
#pragma once
#include <iostream>
#include <mysql.h>
#include <vector>
#pragma comment(lib,"mysqlcppconn.lib")
#pragma comment(lib,"libmysql.lib")
class DataBaseConnection
{
public:
	DataBaseConnection();
	void Connect();
	std::vector<std::string> Query();
	void Close();
	~DataBaseConnection();
	MYSQL *conn;
	MYSQL_ROW row;
	MYSQL_RES *res;
	int qstate;
	std::vector<std::string> vectordrum;
};

Тепер можна сміливо скидати цю програму будь-кому, і не треба переписувати щоб вона працювала локально.

Джерело: habr.com

Додати коментар або відгук