Ubuntu 22.04.2에서 웹서버와 DB서버 연동하기

Simcurity·2023년 3월 29일
1
post-thumbnail

저번 시간에 웹서버에서 아파치와 톰캣을 연동하여 호스트에서 웹서버의 ip주소로 접속 시 톰캣화면이 뜨는것 까지 해보았습니다.

이번에는 웹서버와 다른 서버인 DB서버에서 웹서버와 연동시켜 데이터를 삽입해보려고 합니다.
편의상 root계정으로 진행하겠습니다.

STEP 1. libmysql-java 패키지 설치 (웹 서버 쪽)

apt-get install libmysql-java


아직 우분투 22.04.2 버전에 libmysql-java 패키지가 릴리즈 되지 않은 것 같습니다.
https://mariadb.com/kb/en/about-mariadb-connector-j/
해당 경로로 들어가서 버전에 맞는 JDBC 드라이버를 직접 다운받았습니다.

해당 경로를 wget 명령어를 사용해 입력하면 파일이 다운받아집니다.

STEP 2. mariadb-server 패키지 설치 (DB 서버 쪽)

apt-get update
apt-get install mariadb-server

이제 DB 서버쪽에서 mariadb-server 패키지를 설치해줍니다.
그리고 mysql_secure_installation을 입력합니다.

아직 root계정의 패스워드를 설정하지 않았으므로 그냥 엔터를 누르면 root계정의 패스워드를 설정할 것인지 물어보는데 그때 패스워드를 설정하면 됩니다.

이 후에 나오는 것들은 보안상의 질문으로 Disallow root login remotely? 질문은 우리가 웹 서버 쪽에서 루트 권한으로 로그인을 해야하기 때문에 허락을하고 나머지는 모두 거부해줍니다.
mysql -u root -p 입력하고 설정한 패스워드를 치고 mysql을 실행합니다.

STEP 3. mariaDB 설정 파일 수정 (my.cnf)

vi /etc/mysql/mariadb.conf.d/50-server.conf

입력해서 mysql 서버 설정 파일인 50-server.conf파일을 수정해야합니다.

bind-address = 127.0.0.1
이 부분을 주석처리 하고
bind-address = 0.0.0.0 을 밑에 작성해준다.

그 이유는 bind-address란 mysql서버가 바인딩 되는 ip를 명시하는데 0.0.0.0으로 입력하면
모든 인터페이스에서 접속을 허용해줍니다.

STEP 4. MYSQL 데이터베이스 및 테이블 생성

이제 연동을 하고 테스트 하기 위해 데이터베이스와 테이블을 생성 합니다.

mysql -u root -p패스워드

입력하여 mysql을 실행한다.

그러면 이렇게 저를 반겨줍니다.
그럼 우선 데이터베이스 생성을 해보겠습니다.

create database test;
show databases;

이렇게 순서대로 입력하면 데이터베이스 목록을 볼 수 있습니다.

제가 생성한 test 말고도 여러 데이터베이스들이 있는데 이것들은 mysql 설치시 기본적으로 생성되는 데이터베이스로 mysql 계정관리, 권한관리, 스키마 정보들을 관리해주는 데이터베이스입니다.
(참고로 Blind sql injection으로 DB 정보를 탈취할 때 information_schema를 사용해서 정보를 추출합니다. 그 이유는 information_schema에는 사용자가 생성한 base table의 정보도 포함되어 있기 때문입니다)

use test;
create table user (id varchar(20) primary key,
pw varchar(20) not null);
desc user;

순서대로 입력하면 다음과 같이 생성된 user 테이블의 컬럼 정보를 볼 수 있습니다.

STEP 5. 원격 로그인 계정 생성

웹 서버에서 DB 서버에 로그인을 해야 하기 때문에 DB 서버에서 원격 호스트의 계정을 하나 만들어 주어야합니다.

GRANT ALL PRIVILEGES ON test.* TO root@'웹 서버 ip' identified by '패스워드';

입력해서 root 이름의 호스트는 '웹 서버 ip'인 계정을 하나 만들어줍니다.

use mysql;
select user,host,password from user;

입력해서 잘 만들어졌는지 확인해봅니다.


mysql root 계정 Password와 암호화 값이 똑같은 이유는 제가 비밀번호를 똑같이 설정했기 때문입니다.

STEP 6. 웹 서버 페이지 구현

웹 서버에 아파치와 톰캣이 구현되어있으므로 jsp파일로 구현을 해보았습니다.


index.jsp 파일의 형식입니다.
action으로 입력 값이 전송되는 input.jsp파일의 형식은 다음과 같습니다.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8%>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import ="java.sql.PreparedStatement" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert user information</title>
</head>
<body>

<%
	String id = request.getParameter("id");
    String password = request.getParameter("password");
    Connection conn=null;
    Class.forName("org.mariadb.jdbc.Driver");
    String url = "jdbc:mariadb://DB 서버 주소:3306/test";
    String ix = "DB 계정 ID";
    String pw = "DB 계정 PASSWORD";
    conn = DriverManager.getConnection(url,ix,pw);
    
    PreparedStatement pstmt = conn .prepareStatement("INSERT INTO user (id, passwd) values(?,?)");
    pstmt.setString(1, id);
    pstmt.setString(2, password);
    pstmt.executeUpdate();
    out.println("Insert Complete!!");
    conn.close();
 %>
 </body>
 </html>

매우 간단하게 만들었습니다.

STEP 7. 테스트

이제 홈페이지에서 ID와 PASSWORD에 값을 넣으면 DB 서버에 있는 mariaDB의 test 데이터베이스user 테이블에 데이터가 들어갈 것입니다.
입력을 하면 계속해서 500에러가 나서 도대체 왜 그런지 엄청 찾았습니다. GPT한테도 물어보고 구글링을 엄청 했습니다. 그 결과 500에러 이유는 다름아닌 jdbc에서 mysql 로그인 할때 계정 ID가 문제였습니다.....

STEP 5에서 웹 서버 호스트의 계정을 생성할 때 계정 ID를 root로 했습니다. 이게 뭐가 문제야라고 생각 할 수 있겠지만 생각해보니까 기존 mysql 계정 ID 또한 root로 똑같은 ID를 가진 계정을 생성한 것이었습니다. 예를 들어, 한 웹 사이트에 두 개의 id를 가질 순 없는 것처럼 id를 중복으로 하면 안되는 것입니다.

GRAND ALL PRIVILEGES ON . TO (root가 아닌 다른 이름)@'웹 서버 ip' identified by '패스워드';
flush privileges;

그래서 이렇게 입력해서 다시 이름이 root가 아닌 계정 만들어주고 input.jsp 파일에서 ix 변수를 바꿔주었더니 오류가 나지 않고 동작했습니다. 스터디카페에서 하는라 너무 기뻐 소리를 지르지 아니할 수 없지 않았습니다.

complete를 누르면

이제 DB 서버에서 확인을 위해 user 테이블에서

select * from user;

입력하면
제가 입력한 id와 password 값이 나옵니다 ㅎㅎ

별것도 아닌지만 힘들었습니다.
연동을 해보면서 느낀건 오류가 나면 오류페이지를 잘보자는 것입니다. 오류페이지에 오류의 이유가 어느정도 알 수 있게 나옵니다. 정작 저는 오류 페이지를 안보고 코드에서만 문제를 찾으려 하니 별것도 아닌데 삽질만 엄청 했습니다.
다음부턴 오류가 나도 당황하지 않고 오류 페이지를 꼼꼼히 읽어봐야겠습니다.

0개의 댓글