Loading...
MySQL 9.5 Reference Manual 9.5의 8.1.6 Security Considerations for LOAD DATA LOCAL의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
LOAD DATA statement는 데이터 파일을 테이블에 로드합니다. 이 statement는 서버 호스트에 위치한 파일 또는 LOCAL 키워드가 지정된 경우 클라이언트 호스트에 위치한 파일을 로드할 수 있습니다.
LOAD DATA DATA의 LOCAL 버전에는 잠재적인 보안 문제가 두 가지 있습니다:
LOAD DATA LOCAL는 SQL statement이므로 파싱이 서버 측에서 발생하고, 클라이언트 호스트에서 서버 호스트로의 파일 전송은 MySQL 서버에 의해 시작되며, 서버는 statement에 명명된 파일을 클라이언트에 알려줍니다. 이론적으로, 패치된 서버는 statement에 명시된 파일이 아닌, 서버가 선택한 파일을 전송하도록 클라이언트 프로그램에 지시할 수 있습니다. 이러한 서버는 클라이언트 사용자가 읽기 권한을 가진 클라이언트 호스트의 어떤 파일이든 접근할 수 있습니다. (실제로 패치된 서버는 LOAD DATA LOCAL뿐만 아니라 어떤 statement에 대해서도 파일 전송 요청을 회신할 수 있으므로, 보다 근본적인 문제는 클라이언트가 신뢰할 수 없는 서버에 연결해서는 안 된다는 점입니다.)
클라이언트가 웹 서버에서 접속하는 웹 환경에서, 사용자는 LOAD DATA LOCAL를 사용하여 웹 서버 프로세스가 읽기 권한을 가진 어떤 파일이든 읽을 수 있습니다(SQL 서버에 대해 사용자가 어떤 statement든 실행할 수 있다고 가정할 때). 이 환경에서 MySQL 서버 관점에서의 클라이언트는 웹 서버이며, 웹 서버에 연결하는 사용자가 실행하는 원격 프로그램이 아닙니다.
신뢰할 수 없는 서버에 연결하는 것을 피하기 위해, 클라이언트는 보안 연결을 설정하고 --ssl-mode=VERIFY_IDENTITY 옵션과 적절한 CA 인증서를 사용하여 서버 ID를 검증할 수 있습니다. 이 수준의 검증을 구현하려면, 먼저 서버의 CA 인증서가 레플리카에 안정적으로 제공되는지 확인해야 하며, 그렇지 않으면 가용성 문제를 초래합니다. 자세한 내용은 Command Options for Encrypted Connections를 참조하십시오.
LOAD DATA 관련 문제를 피하기 위해, 클라이언트는 적절한 클라이언트 측 예방 조치가 이루어지지 않는 한 LOCAL 사용을 피해야 합니다.
로컬 데이터 로딩에 대한 제어를 위해, MySQL은 이 기능을 활성화하거나 비활성화할 수 있도록 허용합니다. 또한 MySQL은 클라이언트가 지정된 디렉터리에 위치한 파일로 로컬 데이터 로딩 작업을 제한할 수 있도록 합니다.
관리자와 애플리케이션은 다음과 같이 로컬 데이터 로딩 허용 여부를 구성할 수 있습니다:
서버 측:
local_infile 시스템 변수는 서버 측 LOCAL 기능을 제어합니다. local_infile 설정에 따라, 서버는 로컬 데이터 로딩을 요청하는 클라이언트의 로컬 데이터 로딩을 거부하거나 허용합니다.
기본적으로 local_infile은 비활성화되어 있습니다. (이는 이전 MySQL 버전에서 변경된 사항입니다.) 서버가 클라이언트 프로그램과 라이브러리의 빌드 시점 또는 런타임 구성과 무관하게 LOAD DATA LOCAL statement를 명시적으로 거부하거나 허용하도록 하려면, local_infile을 비활성화 또는 활성화하여 mysqld를 시작하십시오. local_infile은 런타임에도 설정할 수 있습니다.
클라이언트 측:
ENABLED_LOCAL_INFILE CMake 옵션은 MySQL 클라이언트 라이브러리의 컴파일 시 기본 LOCAL 기능을 제어합니다(참조: Section 2.8.7, “MySQL Source-Configuration Options”). 명시적인 설정을 하지 않는 클라이언트는 MySQL 빌드 시 지정된 ENABLED_LOCAL_INFILE 설정에 따라 LOCAL 기능이 비활성화되거나 활성화됩니다.
기본적으로, MySQL 바이너리 배포본의 클라이언트 라이브러리는 ENABLED_LOCAL_INFILE이 비활성화된 상태로 컴파일됩니다. 소스에서 MySQL을 컴파일하는 경우, 명시적 구성을 하지 않는 클라이언트에 대해 LOCAL 기능을 비활성화할지 활성화할지에 따라 ENABLED_LOCAL_INFILE을 비활성화 또는 활성화하여 구성하십시오.
C API를 사용하는 클라이언트 프로그램의 경우, 로컬 데이터 로딩 기능은 MySQL 클라이언트 라이브러리에 컴파일된 기본값에 의해 결정됩니다. 이를 명시적으로 활성화 또는 비활성화하려면, C API 함수 mysql_options()을 호출하여 MYSQL_OPT_LOCAL_INFILE 옵션을 비활성화 또는 활성화하십시오. mysql_options()를 참조하십시오.
mysql 클라이언트의 경우, 로컬 데이터 로딩 기능은 MySQL 클라이언트 라이브러리에 컴파일된 기본값에 의해 결정됩니다. 이를 명시적으로 비활성화 또는 활성화하려면 --local-infile=0 또는 --local-infile[=1] 옵션을 사용하십시오.
mysqlimport 클라이언트의 경우, 기본적으로 로컬 데이터 로딩이 사용되지 않습니다. 이를 명시적으로 비활성화 또는 활성화하려면 --local=0 또는 --local[=1] 옵션을 사용하십시오.
옵션 파일의 [client] 그룹을 읽는 Perl 스크립트나 기타 프로그램에서 LOAD DATA LOCAL를 사용하는 경우, 해당 그룹에 local-infile 옵션 설정을 추가할 수 있습니다. 이 옵션을 이해하지 못하는 프로그램에서 문제가 발생하지 않도록, loose- 프리픽스를 사용하여 지정하십시오:
1[client] 2loose-local-infile=0
또는:
1[client] 2loose-local-infile=1
모든 경우에, 클라이언트가 LOCAL load 연산을 성공적으로 사용하려면 서버가 로컬 로딩을 허용해야 합니다.
LOCAL 기능이 서버 또는 클라이언트 측 중 어느 한쪽에서라도 비활성화된 경우, LOAD DATA LOCAL statement를 실행하려는 클라이언트는 다음 오류 메시지를 받습니다:
1ERROR 3950 (42000): Loading local data is disabled; this must be 2enabled on both the client and server side
MySQL 클라이언트 라이브러리는 클라이언트 애플리케이션이 로컬 데이터 로딩 작업을 지정된 디렉터리에 위치한 파일로 제한할 수 있도록 합니다. 일부 MySQL 클라이언트 프로그램은 이 기능을 활용합니다.
C API를 사용하는 클라이언트 프로그램은 C API 함수 mysql_options()(참조: mysql_options())의 MYSQL_OPT_LOCAL_INFILE 및 MYSQL_OPT_LOAD_DATA_LOCAL_DIR 옵션을 사용하여, load 데이터 로딩에 허용할 파일을 제어할 수 있습니다.
MYSQL_OPT_LOAD_DATA_LOCAL_DIR의 효과는 LOCAL 데이터 로딩이 활성화되었는지 비활성화되었는지에 따라 달라집니다:
MySQL 클라이언트 라이브러리에서 기본적으로 또는 MYSQL_OPT_LOCAL_INFILE을 명시적으로 활성화하여 LOCAL 데이터 로딩이 활성화된 경우, MYSQL_OPT_LOAD_DATA_LOCAL_DIR 옵션은 효과가 없습니다.
MySQL 클라이언트 라이브러리에서 기본적으로 또는 MYSQL_OPT_LOCAL_INFILE을 명시적으로 비활성화하여 LOCAL 데이터 로딩이 비활성화된 경우, MYSQL_OPT_LOAD_DATA_LOCAL_DIR 옵션을 사용하여 로컬로 로드되는 파일에 대한 허용 디렉터리를 지정할 수 있습니다. 이 경우, LOCAL 데이터 로딩은 허용되지만 지정된 디렉터리에 위치한 파일로 제한됩니다. MYSQL_OPT_LOAD_DATA_LOCAL_DIR 값은 다음과 같이 해석됩니다:
값이 null 포인터(기본값)인 경우, 아무 디렉터리도 지정하지 않으므로 LOCAL 데이터 로딩에 허용되는 파일이 없습니다.
값이 디렉터리 경로 이름인 경우, LOCAL 데이터 로딩은 허용되지만 지정된 디렉터리에 위치한 파일로 제한됩니다. 디렉터리 경로 이름과 로드할 파일의 경로 이름 비교는, 기반 파일 시스템의 대소문자 구분 여부와 관계없이 대소문자를 구분합니다.
MySQL 클라이언트 프로그램은 앞의 mysql_options() 옵션을 다음과 같이 사용합니다:
mysql 클라이언트에는 디렉터리 경로 또는 빈 문자열을 받는 --load-data-local-dir 옵션이 있습니다. mysql은 이 옵션 값을 사용하여 MYSQL_OPT_LOAD_DATA_LOCAL_DIR 옵션을 설정합니다(빈 문자열은 값을 null 포인터로 설정). --load-data-local-dir의 효과는 LOCAL 데이터 로딩이 활성화되었는지에 따라 달라집니다:
MySQL 클라이언트 라이브러리에서 기본적으로 또는 --local-infile[=1]을 지정하여 LOCAL 데이터 로딩이 활성화된 경우, --load-data-local-dir 옵션은 무시됩니다.
MySQL 클라이언트 라이브러리에서 기본적으로 또는 --local-infile=0을 지정하여 LOCAL 데이터 로딩이 비활성화된 경우, --load-data-local-dir 옵션이 적용됩니다.
--load-data-local-dir이 적용되는 경우, 옵션 값은 로컬 데이터 파일이 위치해야 하는 디렉터리를 지정합니다. 디렉터리 경로 이름과 로드할 파일 경로 이름의 비교는, 기반 파일 시스템의 대소문자 구분 여부와 관계없이 대소문자를 구분합니다. 옵션 값이 빈 문자열이면 어떤 디렉터리도 지정하지 않으므로, 로컬 데이터 로딩에 허용되는 파일이 없습니다.
mysqlimport는 처리하는 각 파일에 대해 MYSQL_OPT_LOAD_DATA_LOCAL_DIR을 설정하여, 그 파일이 위치한 디렉터리를 허용된 로컬 로딩 디렉터리로 만듭니다.
LOAD DATA statement에 해당하는 데이터 로딩 작업의 경우, mysqlbinlog는 바이너리 로그 이벤트에서 파일을 추출하여, 이를 로컬 파일 시스템의 임시 파일로 기록하고, 해당 파일이 로드되도록 LOAD DATA LOCAL statement를 기록합니다. 기본적으로 mysqlbinlog는 이러한 임시 파일을 운영체제별 디렉터리에 기록합니다. --local-load 옵션을 사용하여 mysqlbinlog가 로컬 임시 파일을 준비해야 하는 디렉터리를 명시적으로 지정할 수 있습니다.
다른 프로세스도 기본 시스템별 디렉터리에 파일을 작성할 수 있으므로, mysqlbinlog에 --local-load 옵션을 지정하여 데이터 파일용으로 다른 디렉터리를 지정하고, mysql에서 mysqlbinlog 출력물을 처리할 때 동일한 디렉터리를 --load-data-local-dir 옵션으로 지정하는 것이 바람직합니다.
MySQL Shell은 테이블, 스키마 또는 서버 인스턴스를 덤프하고 이를 다른 인스턴스에 로드하기 위한 다양한 유틸리티를 제공합니다. 이러한 유틸리티로 데이터를 처리할 때, MySQL Shell은 입력 전처리, 멀티스레드 병렬 로딩, 파일 압축 및 압축 해제, Oracle Cloud Infrastructure Object Storage 버킷 액세스 처리와 같은 추가 기능을 제공합니다. 최상의 기능을 사용하려면, 항상 MySQL Shell의 덤프 및 덤프 로딩 유틸리티의 최신 버전을 사용하십시오.
MySQL Shell의 데이터 업로드 유틸리티는 데이터 업로드를 위해 LOAD DATA LOCAL INFILE statement를 사용하므로, 대상 서버 인스턴스에서 local_infile 시스템 변수가 ON으로 설정되어 있어야 합니다. 데이터 업로드 전에 이를 설정하고, 이후에 다시 제거할 수 있습니다. 이 유틸리티는 이 토픽에서 논의한 보안 고려사항을 처리하기 위해 파일 전송 요청을 안전하게 처리합니다.
MySQL Shell에는 다음과 같은 덤프 및 덤프 로딩 유틸리티가 포함되어 있습니다:
Table export utility util.exportTable()
MySQL 관계형 테이블을 데이터 파일로 내보냅니다. 이 파일은 MySQL Shell의 병렬 테이블 import 유틸리티를 사용하여 MySQL 서버 인스턴스로 업로드하거나, 다른 애플리케이션으로 가져오거나, 논리 백업으로 사용할 수 있습니다. 이 유틸리티는 다양한 출력 포맷을 생성하기 위한 프리셋 옵션과 커스터마이즈 옵션을 제공합니다.
Parallel table import utility
util.importTable()
데이터 파일을 MySQL 관계형 테이블로 가져옵니다. 데이터 파일은 MySQL Shell의 테이블 export 유틸리티 출력이거나, 유틸리티의 프리셋 및 커스터마이즈 옵션에서 지원하는 다른 포맷일 수 있습니다. 이 유틸리티는 테이블에 데이터를 추가하기 전에 입력 전처리를 수행할 수 있습니다. 또한 다수의 데이터 파일을 받아 단일 관계형 테이블로 병합할 수 있으며, 압축된 파일을 자동으로 해제합니다.
Instance dump utility
util.dumpInstance(), schema dump utility
util.dumpSchemas(), 그리고 table dump
utility util.dumpTables()
인스턴스, 스키마 또는 테이블을 덤프 파일 집합으로 내보내며, 이후 MySQL Shell의 덤프 로딩 유틸리티를 사용하여 MySQL 인스턴스로 업로드할 수 있습니다. 이 유틸리티는 Oracle Cloud Infrastructure Object Storage 스트리밍, MySQL HeatWave Service 호환성 검사 및 수정, 덤프를 진행하기 전에 문제를 식별하기 위한 드라이 런 기능을 제공합니다.
Dump loading utility util.loadDump()
MySQL Shell의 인스턴스, 스키마 또는 테이블 덤프 유틸리티를 사용하여 생성한 덤프 파일을 MySQL HeatWave Service DB System 또는 MySQL Server 인스턴스로 가져옵니다. 이 유틸리티는 업로드 프로세스를 관리하고 원격 스토리지에서의 데이터 스트리밍, 테이블 또는 테이블 청크의 병렬 로딩, 진행 상태 추적, 재개 및 초기화 기능, 덤프가 진행 중인 동안 동시 로딩 옵션을 제공합니다. MySQL Shell의 병렬 테이블 import 유틸리티는 덤프 로딩 유틸리티와 함께 사용하여 대상 MySQL 인스턴스로 업로드하기 전에 데이터를 수정할 수 있습니다.
유틸리티에 대한 자세한 내용은 MySQL Shell Utilities를 참조하십시오.
8.1.5 How to Run MySQL as a Normal User
8.1.7 Client Programming Security Guidelines