삽질하는플머

Ubuntu + MySQL 에서 셸 커맨드 사용

탐구생활/WEB 관련

우분투 16.04 + MySQL 에서 특정 데이터가 입력될 경우 셸 커맨드를 돌려야 할 상황이 생겼다. 
오늘 요리재료는 이럴 때 안성마춤인 lib_mysqludf_sys 되시겠다. 


깃허브 링크: https://github.com/mysqludf/lib_mysqludf_sys 


먼저 MySQL 에서 플러그인 경로를 확인하자. 


mysql> show variables like 'plugin_dir';


+---------------+------------------------+

| Variable_name | Value                  |

+---------------+------------------------+

| plugin_dir    | /usr/lib/mysql/plugin/ |

+---------------+------------------------+




UDF 소스를 내려받고.  


$ git clone https://github.com/mysqludf/lib_mysqludf_sys.git

$ cd lib_mysqludf_sys/



포함된 Makefile 을 참조해 빌드 테스트. -fPIC을 주라는 에러가 나오니 그대로 따른다. 

$ sudo apt-get install libmysqlclient-dev
$ gcc -Wall -I/usr/include/mysql -I. -fPIC  -shared lib_mysqludf_sys.c -o lib_mysqludf_sys.so


빌드 확인한 뒤, Makefile 수정. 

Makefile 

LIBDIR=/usr/lib/mysql/plugin

install:
        gcc -Wall -I/usr/include/mysql -I. -fPIC -shared lib_mysqludf_sys.c -o $(LIBDIR)/lib_mysqludf_sys.so



빌드 및 설치


$ sudo ./install.sh



MySQL 실행 후 테스트. 


mysql> select sys_exec('touch /tmp/test_mysql') ;

+-----------------------------------+

| sys_exec('touch /tmp/test_mysql') |

+-----------------------------------+

|                             32512 |

+-----------------------------------+

1 row in set (0.01 sec)



내부적으로 sys() 함수를 사용하는데 왠 31512 에러... 역시 한 번에 되는 건 하나도 없군. 


구글께 여쭈니 apparmor 에서 UDF 실행을 막는다는 신탁을 내려주심. 

https://www.cyberciti.biz/faq/ubuntu-linux-howto-disable-apparmor-commands/



먼저 apparmor 의 상태를 확인. 


$ sudo apparmor_status


apparmor module is loaded.

16 profiles are loaded.

16 profiles are in enforce mode.

......

   /usr/sbin/mysqld

...



mysqld 를 대상에서 제거


$ sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/

$ sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld


# 상태 다시 확인

# sudo apparmor_status



apparmor 와 mysql 재구동


$ sudo /etc/init.d/mysql restart

$ sudo /etc/init.d/apparmor restart



MySQL 에서 sys_exe() 재시도


mysql> select sys_exec('touch /tmp/test_mysql');

+-----------------------------------+

| sys_exec('touch /tmp/test_mysql') |

+-----------------------------------+

|                                 0 |

+-----------------------------------+

1 row in set (0.01 sec)



/tmp 에 생성된 파일 확인. 


$ ll /tmp

total ...

drwxrwxrwt 13 root    root    4096 Aug 20 22:38 ./

drwxr-xr-x 24 root    root    4096 Jul  6 14:40 ../

-rw-r-----  1 mysql   mysql      0 Aug 20 22:38 test_mysql

......



이제 트리거에서 외부 실행파일을 마음껏 실행시킬 수 있다.



참고링크

https://github.com/mysqludf/lib_mysqludf_sys

http://bernardodamele.blogspot.com/2009/01/command-execution-with-mysql-udf.html

https://www.cyberciti.biz/faq/ubuntu-linux-howto-disable-apparmor-commands/