IP주소는 하드코딩을 피해라.

책 '자바 코딩, 이럴 땐 이렇게'에서 이번에도 꼭 알아두어야 할 것 같은 부분을 보고 남기려고 한다. 서버 프로그램을 작성할 때 서버의 IP를 소스코드에 하드코딩하는 습관이 바람직하지 않다고 한다.

첫 번째 이유는 관리적인 측면과 유지보수의 측면에서 볼 수 있다. 말 그대로 서버의 IP가 바뀌었거나, 소스 수정을 할 때 하나하나 찾아가며 바꿔야 하기 때문이다. 

두 번째 이유는 보안적인 측면인데, 자바 소스는 디컴파일(decompile)이 가능하기 때문이다. 즉 JVM이 인식하는 코드 .class코드가 유출된다면 IP정보가 쉽게 유출된다는 점이다.


해결 방안

package Test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class Example {
	private static final String DEFAULT_PROPERTIES_PATH = "d://test.properties";

	private static String serverIP;

	public static void main(String[] args) throws Exception {
		setServerIP(Example.getKey("serverIp"));
	}

	public static String getKey(String key) throws Exception {
		String value = null;
		InputStream is = new FileInputStream(DEFAULT_PROPERTIES_PATH);
		Properties properties = null;
		try {
			properties = new Properties();
			properties.load(is);
			value = properties.getProperty(key);

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();

		} finally {
			try {
				is.close();
			} catch (IOException e) {

			}
		}
		return value;
	}

	public static String getServerIP() {
		return serverIP;
	}

	public static void setServerIP(String serverIP) {
		Example.serverIP = serverIP;
	}

}

서버 실행환경

 

 학과 서버 사용

 OS

 SunOS 5.10

 GCC

 3.4.6

 Java

 1.5.0_16


클라이언트 실행환경

 Desktop

 조립식

 CPU

 Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz 3.40GHz

 Memory

 8.00 GB

 OS

 Windows 7 Professional K 64bit

 Java

 1.8.0_05

 MySQL

 Ver 14.14 Distrib 5.6.19, for Win64

 Web Server

 Apache Tomcat 7.0.51


서버 프로그램

#include <stdio.h>
#include <sys/types.h> 	// socket, bind, accept, open
#include <sys/socket.h> // socket, bind, listen, accept
#include <unistd.h>		// read, write
#include <sys/stat.h> 	// open
#include <fcntl.h>		// open
#include <errno.h>

#include <string.h>

#define PORT	5500
#define MAXBUF	1024

int main() {
	int server_sockfd;
	int client_sockfd;
	int des_fd;	// file num
	struct sockaddr_in serveraddr, clientaddr;
	int client_len, read_len, file_read_len;	// length
	char buf[MAXBUF];
	
	
	int check_bind;
	

	client_len = sizeof(clientaddr);

	/* socket() */
	server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(server_sockfd == -1) {
		perror("socket error : ");
		exit(0);
	}

	/* bind() */
	bzero(&serveraddr, sizeof(serveraddr));
	serveraddr.sin_family		= AF_INET;
	serveraddr.sin_addr.s_addr	= htonl(INADDR_ANY);
	serveraddr.sin_port			= htons(PORT);

	if(bind(server_sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) > 0) {
		perror("bind error : ");
		exit(0);
	}

	/* listen */
	if(listen(server_sockfd, 5) != 0) {
		perror("listen error : ");
	}

	while(1) {
		char file_name[MAXBUF]; // local val
		memset(buf, 0x00, MAXBUF);
		
		/* accept() */
		client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr, &client_len);
		printf("New Client Connect : %s\n", inet_ntoa(clientaddr.sin_addr));

		/* file name */
		read_len = read(client_sockfd, buf, MAXBUF);
		if(read_len > 0) {
			strcpy(file_name, buf);
			printf("%s > %s\n", inet_ntoa(clientaddr.sin_addr), file_name);
		} else {
			close(client_sockfd);
			break;
		}

		/* create file */
FILE_OPEN:
		des_fd = open(file_name, O_WRONLY | O_CREAT | O_EXCL, 0700);
		if(!des_fd) {
			perror("file open error : ");
			break;
		}
		if(errno == EEXIST) {
			close(des_fd);
			size_t len = strlen(file_name);
			file_name[len++] = '_';
			file_name[len++] = 'n';
			file_name[len] = '\0';
			goto FILE_OPEN;
		}
		
		/* file save */
		while(1) {
			memset(buf, 0x00, MAXBUF);
			file_read_len = read(client_sockfd, buf, MAXBUF);
			write(des_fd, buf, file_read_len);

			if(file_read_len == EOF | file_read_len == 0) {
				printf("finish file\n");
				break;
			}


		}


		close(client_sockfd);
		close(des_fd);
	}
	close(server_sockfd);
	return 0;
}


클라이언트 프로그램

#include <WinSock2.h>
#include <stdio.h>
#include <sys/types.h>
#include <io.h>
#include <sys/stat.h>
#include <fcntl.h>


#define PORT	5500
#define IP		"127.0.0.1"
#define MAXBUF	1024

int main() {
	WSADATA		WSAData;
	SOCKADDR_IN	addr;
	SOCKET		s;
	int			sourse_fd;
	char		buf[MAXBUF];
	int			file_name_len, read_len;
	
	if(WSAStartup(MAKEWORD(2,2), &WSAData) != 0) {
		return 1;
	}

	/* socket() */
	s = socket(AF_INET, SOCK_STREAM, 0);
	if(s == INVALID_SOCKET) {
		return 1;
	}

	addr.sin_family				= AF_INET;
	addr.sin_addr.S_un.S_addr	= inet_addr(IP);
	addr.sin_port				= htons(PORT);
	if(connect(s, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) {
		perror("connect : ");
		printf("fail to connect.\n");
		closesocket(s);
		return 1;
	}

	memset(buf, 0x00, MAXBUF);
	printf("전송할 파일명 : ");
	scanf("%s", buf);

	printf(" > %s\n", buf);
	file_name_len = strlen(buf);

	send(s, buf, file_name_len, 0);
	sourse_fd = _open(buf, _O_RDONLY);
	if(!sourse_fd) {
		perror("Error : ");
		return 1;
	}
	
	while(1) {
		memset(buf, 0x00, MAXBUF);
		read_len = _read(sourse_fd, buf, MAXBUF);
		send(s, buf, read_len, 0);
		if(read_len == 0) {
			break;
		}
		
	}

	return 0;
}


+ Recent posts