Hacemos accesible la base de datos para conexión remota

Empezaremos por mencionar que hay ocasiones en las que es necesario crear una aplicación con conexión a una base de datos. Esto se hace para no tener que preocuparnos demasiado por el desarrollo del backend y concentrarnos en el frontend debido a la falta de personal y habilidades. No me atrevo a decir que mi solución será segura, pero funciona.

Dado que no me gusta pagar por hosting, utilicé la red en mi trabajo, donde hay una dirección IP pública. Aquí está su estructura:

Hacemos accesible la base de datos para conexión remota

Tengo acceso a varias computadoras, específicamente a 192.168.1.2 (que también es 192.168.0.2), donde está Linux, y a 192.168.0.3 con Windows. En general, para mi aplicación elegí mysql y verifiqué lo que había en Linux. Ya estaba instalado, pero nadie conoce la contraseña, y aquellos que lo sabían se la olvidaron (los que trabajaron antes que yo). Al enterarme de que no era necesario, lo eliminé e intenté instalarlo nuevamente. No había suficiente memoria y, dado que para arreglar este error tendría que conectar un monitor y teclado con ratón, decidí dejarlo. Además, la máquina con Windows es mucho más potente y, además, yo mismo la tengo en mi laptop doméstica. En principio, no describiré el proceso de instalación, hay muchos manuales y videos al respecto. Después de instalar mysql en la máquina con Windows, decidí hacer una copia de seguridad de las tablas desde la laptop a la estación de trabajo.

Se hace así (en mi caso):

mysqldump -uroot -p your_base > dump_file.sql

Luego, en la nueva base de datos, creamos la base de datos y restauramos la copia de seguridad en la "nueva" máquina.

mysql -h localhost -u root -p

create database your_base;
use your_base;

mysql -uroot -p your_base < dump_file.sql

show tables;


El archivo de la copia de seguridad debe colocarse en la nueva máquina y posiblemente, si no está en el directorio de la herramienta, el camino completo hacia él. (Simplemente subí la copia de seguridad a GitHub y la cloné en la nueva máquina). Me gustaría añadir cómo se crean las tablas, pero no guardé las capturas, y creo que no es complicado incluso para un estudiante de segundo o tercer año.

Cuando restauré todas las tablas, llegó el momento de habilitar el acceso remoto a la base de datos. En general, tales comandos no llevaron al éxito (solo otorgaron permisos de lectura select)

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

Más bien, solo podía conectarme a la base de datos con el comando,

mysql -h localhost -u client -pclient

pero no podía hacerlo de esta manera

mysql -h 192.168.0.3 -u client -pclient

esto tampoco me funcionaba, ni podía conectarme a través de esta dirección y como root.

La herramienta MySQL Workbench ayudó, ya que en la configuración cambias localhost por % y funciona, aunque eso no ayudó al cliente. Ahora puedes conectarte a la base de datos desde la consola o desde el código desde cualquier dirección.

Hacemos accesible la base de datos para conexión remota

También necesitas crear una red doméstica o empresarial y desactivar el firewall de Windows, de lo contrario, no podrás ni hacer ping a esa máquina (ni hablar de conectarte a la base de datos).

Se ha avanzado en la tarea, ahora necesito poder conectarme a la base de datos desde casa.

Como se muestra en el esquema de la red, hay que pasar del 192.168.0.3 al 192.168.1.1 (router). Vamos en sentido inverso. Configuraremos la ruta del 192.168.1.1 al 192.168.1.2 de esta manera:

Hacemos accesible la base de datos para conexión remota

En general, no muestra la imagen, así que lo escribiré a mano:

route add 192.168.0.0 mask 255.255.255.0 gateway 192.168.1.2

Esto solo se puede hacer en una misma subred, es decir, no puedes redirigir directamente a la dirección 192.168.0.2 o 192.168.0.3.

Esto es necesario para que el router sepa dónde se encuentra la subred 192.168.0.0/24 (estudia los fundamentos de redes, es útil).

Ahora agregamos el reenvío del puerto 3306 (puerto de MySQL por defecto, a menos que lo cambiaste durante la instalación) hacia la dirección 192.168.1.2.

Hacemos accesible la base de datos para conexión remota

Lo que queda es hacer el reenvío en la máquina Linux (tiene dos tarjetas de red: 192.168.1.2 (interfaz enp3s1) y 192.168.0.2 (interfaz enp3s0)) para que las tarjetas de red sepan que tienen que reenviarlo desde 192.168.1.2 a 192.168.0.2, y luego a nuestra máquina Windows con 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
Y la última línea guarda los comandos ingresados para que no se borren al reiniciar el sistema operativo.
sudo service iptables-persistent save

Es decir, la primera línea significa que aceptamos la primera conexión, la segunda y la tercera que se pueden enviar paquetes en ambas direcciones, y la cuarta y la quinta que se hacen las sustituciones de las direcciones de destino y origen. Y voilà, se puede conectar desde casa a través de MySQL. Y por último, mi código en C++ que lo hace:

//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); //Если используется оконное приложение
	}
	// Подключаемся к servidor
	if (!mysql_real_connect(conn, "192.168.0.3", "root", "password", "your_base", NULL, NULL, 0))
	{
		// Si no hay posibilidad de establecer una conexión con el servidor 
		// базы данных выводим сообщение об ошибке
		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;
};

Ahora se puede compartir este programa con cualquiera, y no es necesario modificarlo para que funcione localmente.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster