Udostępnienie bazy danych do połączenia zdalnego

Zacznijmy od tego, że zdarzają się przypadki, gdy trzeba stworzyć aplikację z połączeniem z bazą danych. Robi się to po to, żeby nie zagłębiać się zbytnio w rozwój backendu i skupić się na frontendzie ze względu na brak rąk i umiejętności. Nie mogę powiedzieć, że moje rozwiązanie będzie bezpieczne, ale działa.

Ponieważ nie lubię płacić za hosting, korzystałem z tej sieci w pracy, tam jest białe IP. Oto jego struktura:

Udostępnienie bazy danych do połączenia zdalnego

Mam dostęp do kilku komputerów, a dokładniej 192.168.1.2 (czyli 192.168.0.2) z zainstalowanym Linuksem i 192.168.0.3 z Windowsem. Ogólnie rzecz biorąc, wybrałem mysql dla mojej aplikacji i sprawdziłem, co jest dostępne na Linuksie. Było już tam zainstalowane, ale nikt nie zna hasła, a ci, którzy wiedzieli, zapomnieli (ci, którzy pracowali przede mną). Dowiedziawszy się, że nikt tego nie potrzebuje, usunąłem go i próbowałem zainstalować ponownie. Pamięci zabrakło, a że żeby naprawić ten błąd musiałbym do niej podłączyć monitor i klawiaturę z myszką, postanowiłem odpuścić sobie tę kwestię. Co więcej, maszyna z systemem Windows jest znacznie wydajniejsza, a dodatkowo mam ją na laptopie w domu. W zasadzie nie będę opisywał samej instalacji, jest na ten temat mnóstwo instrukcji i filmów. Po zainstalowaniu mysql na komputerze z systemem Windows zdecydowałem się wykonać kopię zapasową tabel z mojego laptopa na stację roboczą.

Robi się to tak (w moim przypadku):

mysqldump -uroot -p your_base > dump_file.sql

Następnie tworzymy bazę danych w nowej bazie danych i przywracamy kopię zapasową na „nowym” komputerze.

mysql -h localhost -u root -p

create database your_base;
use your_base;

mysql -uroot -p your_base < dump_file.sql

show tables;


Plik kopii zapasowej należy umieścić na nowym komputerze i być może, jeśli nie w katalogu z narzędziem, to pełną ścieżkę do niego. (Właśnie przesłałem kopię zapasową do GitHub i sklonowałem ją na nowym komputerze). Dodałbym, jak powstają same tabele, ale nie zapisałem zrzutów ekranu, a myślę, że nie jest to trudne nawet dla studenta 2-3 roku.

Po przywróceniu wszystkich tabel przyszedł czas na udostępnienie zdalnego dostępu do bazy danych. Ogólnie takie polecenia nie prowadziły do ​​sukcesu (dawały jedynie uprawnienia do odczytu wyboru)

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

Dokładniej mogłem połączyć się z bazą danych tylko za pomocą polecenia,

mysql -h localhost -u client -pclient

ale ten nie mógł już tego zrobić

mysql -h 192.168.0.3 -u client -pclient

U mnie to nie zadziałało i nie mogłem połączyć się przez ten adres jako root.

Pomógł program mysql workbench; w ustawieniach zmień localhost na % i działa, chociaż klient nie pomógł. Teraz możesz połączyć się z bazą danych z konsoli lub z kodu z dowolnego adresu.

Udostępnienie bazy danych do połączenia zdalnego

Musisz także utworzyć sieć domową lub firmową i wyłączyć zaporę systemu Windows, w przeciwnym razie nie będziesz mógł nawet pingować tego komputera (nie mówiąc już o połączeniu z bazą danych).

Połowa pracy została wykonana, teraz muszę móc połączyć się z bazą danych z domu.

Jak widać na schemacie sieci, aby dostać się do Internetu, musisz przejść z 192.168.0.3 na 192.168.1.1 (router), pójdźmy w przeciwnym kierunku. Skonfigurujmy trasę z 192.168.1.1 na 192.168.1.2 w ten sposób:

Udostępnienie bazy danych do połączenia zdalnego

Generalnie zdjęcie nie oddaje tego, więc napiszę ręcznie:

route add 192.168.0.0 mask 255.255.255.0 gateway 192.168.1.2

Można to zrobić tylko w jednej podsieci, czyli nie można od razu przekierować na adres 192.168.0.2 lub 192.168.0.3

Jest to konieczne, aby router wiedział, gdzie znajduje się podsieć 192.168.0.0/24 (przydaje się poznanie podstaw sieci).

Teraz dodajemy przekierowanie portów 3306 (domyślny port mysql (jeśli nie zmieniłeś go podczas instalacji)) do adresu 192.168.1.2

Udostępnienie bazy danych do połączenia zdalnego

Najtrudniejszą rzeczą, jaką pozostało do zrobienia, jest wykonanie przekierowania na komputerze z Linuksem (posiada on dwie karty sieciowe 192.168.1.2 (interfejs enp3s1) i 192.168.0.2 (interfejs enp3s0), aby karty sieciowe wiedziały, z czego je przenieść z 192.168.1.2 do 192.168.0.2, a następnie do naszego komputera z systemem Windows za pomocą 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

Te. Pierwsza linia oznacza, że ​​akceptujemy pierwsze połączenie, druga i trzecia, że ​​możemy wysyłać pakiety w obu kierunkach, czwarta i piąta oznaczają zmianę adresu docelowego i źródłowego. I voila, możesz połączyć się z domu przez mysql. I na koniec mój kod C++, który to robi:

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

Teraz możesz bezpiecznie wysłać ten program każdemu i nie musisz go przepisywać, aby działał lokalnie.

Źródło: www.habr.com

Dodaj komentarz