C# private key로 SSH 접속 후 리모트 내의 MySQL에 접속해서 DB 조작

C# private key로 SSH 접속 후 리모트 내의 MySQL에 접속해서 DB 조작

하고 싶은 것

전제 조건

SSH의 private key는 빌드한 폴더에 격납한다.

ex) \bin\Debug\openssh.key 또는 \bin\Release\openssh.key

※기본의 id_rsa(private key)파일을 카피해서 openssh.key로 이름을 변경하였다.

필요한 패키지

SSH.NET

MySql.Data

MySql.Data의 버젼은 각자의 상황에 맞춘다.

(하기 샘플에서 검증할때 쓴 MySql.Data의 버젼은 6.9.11.0)

샘플

using Renci.SshNet;
using MySql.Data.MySqlClient;
using System.Data;


public const string LocalHostAddress = "localhost";

// 미사용 포트라면 뭐든 가능(개발단말/운용단말 기준의 빈 포트 번호)
public const uint LocalHostPort = 13306;   

// ip 또는 호스트 이름
public const string RelayHostAddress = "dev.test"; 

// ssh의 포트 번호(RelayHostAddress(운용단말)의 ssh에 어느 port 번호가 설정되어 있는가에 따라 달라진다(22이나 10022가 일반적?))
public const int RelayHostPort = 22;  

// ssh에 접속할 유저 이름
public const string SshUser = "sshuser"; 

// private key의 설정. RelayHostAddress(운용단말)에 SshUser로 유저 등록이 되어 있고, 공개키가 등록되어 있는것이 전제
public const string SshPrivateKeyFileName = "openssh.key";

// SshPrivateKeyFileName(ssh키)를 만들 시에 지정한 패스워드
public const string SshPassword = "pass"; 

// DB의 호스트 어드레스. 리모트 접속처인 RelayHostAddress(운용단말)에 존재하는 DB이므로 "127.0.0.1"를 설정
public const string DbHostAddress = "127.0.0.1";

// MySQL의 포트 번호
public const uint DbHostPort = 3306;    

public const string MySqlUser = "root"; 
// 패스워드 미지정의 경우엔 ""(공백)
public const string MySqlPassword = "";

// db스키마 이름
public const string DbName = "test"; 

// 검증용으로 접속할 테이블 이름
public const string TableName = "tbl_test"; 


public void AccessSshAndMySql()
{
	// Setup Credentials and Server Information
	// Key Based Authentication (using keys in OpenSSH Format)
	var ConnNfo = new ConnectionInfo(RelayHostAddress, RelayHostPort, SshUser,
		new AuthenticationMethod[]{
			new PrivateKeyAuthenticationMethod(SshUser,new PrivateKeyFile[]{
				new PrivateKeyFile(SshPrivateKeyFileName, SshPassword)
			}),
		}
	);

	using (var client = new SshClient(ConnNfo))
	{
		client.Connect();
		try
		{
			if (!client.IsConnected)
			{
				Console.WriteLine("[NG] SSH Connection failed!!");
			}
			// SSH를 경유해서 개발단말(운용단말에 접속하러 갈 PC)의 미사용 포트 번호를 이용해서 운용단말에 있는 MySQL에 접속 가능하도록 한다.
			using (var forwardedPortLocal = new ForwardedPortLocal(LocalHostAddress, LocalHostPort, DbHostAddress, DbHostPort))
			{
				client.AddForwardedPort(forwardedPortLocal);
				try
				{
					forwardedPortLocal.Start();
					if (!forwardedPortLocal.IsStarted)
					{
						Console.WriteLine("[NG] forwardedPortLocal Connection failed!!");
					}

					// MySQL Start
					var connStr = string.Format(
						"server={0};port={1};user={2};password={3};database={4};Pooling=False",
						forwardedPortLocal.BoundHost, forwardedPortLocal.BoundPort, MySqlUser, MySqlPassword, DbName);
					var sql = "SELECT * FROM " + TableName;

					using (var connection = new MySqlConnection(connStr))
					using (var com = new MySqlCommand(sql, connection))
					{
						connection.Open();
						try
						{
							var datatable = new DataTable();
							var adapter = new MySqlDataAdapter(sql, connection);
							adapter.Fill(datatable);
						}
						catch (Exception) { /*Ignore SQL Error*/ }
						connection.Close();
					}
					// MySQL End
				}
				finally
				{
					client.RemoveForwardedPort(forwardedPortLocal);
				}
			}
		}
		finally
		{
			client.Disconnect();
		}
	}
}

参考

Pie's Tech Note

생계형 개발자의 메모장

comments powered by Disqus

    rss facebook twitter github youtube mail spotify instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora