Правим базата данни достъпна за дистанционно свързване

Започваме с това, че понякога се налага да направим приложение с връзка към база данни. Това се прави, за да не се ровим в бекенд разработката и да се концентрираме върху фронтенда поради недостиг на ресурси и умения. Не мога да кажа, че моето решение ще бъде безопасно, но то работи.

Тъй като не обичам да плащам за хостинг, използвах мрежата на работното си място, където имам публичен 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;


Файлът с резервното копие трябва да бъде поставен на новата машина и, вероятно, ако не се намира в директорията с утилитата, да има пълен път до него. (Аз просто качих резервното копие на GitHub и го клонирах на новата машина). Бих добавил как се създават самите таблици, но не запазих скрийншотове, а и мисля, че това не е сложно дори за студент от 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.

Правим базата данни достъпна за дистанционно свързване

Остава най-сложното — да направим форвардинг на Linux машина (на нея има две мрежови карти 192.168.1.2 (интерфейс enp3s1) и 192.168.0.2 (интерфейс enp3s0), за да знаят мрежовите карти как да пренасочват от 192.168.1.2 на 192.168.0.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

Т.е. първият ред означава, че приемаме първото свързване, вторият и третият, че можем да пускаме пакети в двете посоки, четвъртият и петият означават замяна на адреса на дестинацията и източника. И ето, можете да се свързвате от дома чрез mysql. И накрая моят код на C++, който го прави:

//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

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster