Mysql 5.5 chroot set up

Mysql is the most popular database server. Chroot is preferred to enhance security.
Can not find any documentation on how to do this elsewhere? Read on…


#Main Guide:
http://dev.mysql.com/doc/refman/5.5/en/source-installation.html
and follow closely

#references:
http://www.symantec.com/connect/articles/securing-mysql-step-step
http://www.unixwiz.net/techtips/chroot-practices.html
our 5.0/5.1/5.5 chroot mysql configuration documentation

! Note that we are NOT using chroot or chootuid to run mysqld in chroot, instead, we build a mysql chroot enviorment
and then start mysqld with –chroot switch… this is prefered.
(why? see this http://www.unixwiz.net/techtips/chroot-practices.html)

1> install cmake. cmake is used to configure and build mysql 5.5

$ yum install cmake

2> make sure make/gcc etc. are available.
this is usually true. however, for security reasons, many ISPs do not include this in their production server enviroment.

$ yum install make

$ yum install gcc

! note, We may want to tighten gcc/make/cmake to be executable by root only.

$ chmod -x /usr/bin/gcc
$ chmod u+x /usr/bin/gcc

and do same for make/cmake

3> Download the architecture independent source code mysql-5.5.29.tar.gz from mysql.com

$ tar xvfz mysql-5.5.29.tar.gz
$ cd mysql-5.5.29

4> cmake configure the source.

#a. Mysql generally recommended basic compile options:

#CFLAGS=”-O3″ CXX=gcc CXXFLAGS=”-O3 -felide-constructors \
#       -fno-exceptions -fno-rtti” ./configure \
#       –prefix=/usr/local/mysql –enable-assembler \
#       –with-mysqld-ldflags=-all-static

#b. our recent 5.0 compile options

#CFLAGS=”-O3 -mpentiumpro” CXX=gcc CXXFLAGS=”-O3 -mpentiumpro \
#-felide-constructors -fno-exceptions -fno-rtti” ./configure \
#–prefix=/data1/td/mysql –enable-assembler \
#–with-csv-storage-engine  –with-archive-storage-engine \
#–with-atomic-ops=smp –with-fast-mutexes \
#–with-charset=utf8 –with-extra-charsets=all
–with-collation=utf8_unicode_ci \
#–with-innodb –with-mysqld-ldflags=-all-static

#c. our recent 5.1 compile options

#CFLAGS=”-O3 -mpentiumpro” CXX=gcc CXXFLAGS=”-O3 -mpentiumpro \
#-felide-constructors -fno-exceptions -fno-rtti” ./configure \
#–prefix=/data1/mysql –enable-assembler \
#–with-atomic-ops=smp –with-fast-mutexes \
#–with-charset=utf8 –with-extra-charsets=all
–with-collation=utf8_unicode_ci \
#–with-mysqld-ldflags=-all-static –with-plugins=max

#d. for mysql 5.5

#what is new about cmake and help on cmake
#http://forge.mysql.com/wiki/CMake
#http://forge.mysql.com/wiki/Autotools_to_CMake_Transition_Guide

# more details on configuration, it is always good to check the configuration
# details below, many default values if we agree, we did not list/configure them
# explicitly again, but mysql may change or introuduce more configuration options
http://dev.mysql.com/doc/refman/5.5/en/source-configuration-options.html

According to
http://dev.mysql.com/doc/refman/5.5/en/installing-source-distribution.html
[quote]
It is possible to build out of the source tree to keep the tree clean. If the top-level source directory is named mysql-src under your current working directory, you can build in a directory named build at the same level like this:

shell> mkdir build
shell> cd build
shell> cmake ../mysql-src
[end quote]

$ mkdir build
$ cd build

http://dev.mysql.com/doc/internals/en/cmake-howto-long-version.html#controlling-compiler-flags
This is the long version of cmake configure and build

# final cmake cmd
cmake .. -DBUILD_CONFIG=mysql_release -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DINSTALL_LAYOUT=STANDALONE \
-DCPACK_MONOLITHIC_INSTALL=1 -DWITH_PARTITION_STORAGE_ENGINE=1 \
-DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 -DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \
-DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_unicode_ci \
-DWITH_EXTRA_CHARSETS=all -DWITH_SSL=yes

-DCMAKE_INSTALL_PREFIX=”/opt/mysql.5.5.9″ is optional,
we can as well leave it out and use
make install DESTDIR=”/opt/mysql” when install.

some other cmake configure option we may want to look into later
MEMCACHED_HOME

we got an error:
— Looking for io_queue_init in aio – not found
CMake Error at cmake/build_configurations/mysql_release.cmake:126 (MESSAGE):

aio is required on Linux, you need to install the required library:

Debian/Ubuntu:              apt-get install libaio-dev
RedHat/Fedora/Oracle Linux: yum install libaio-devel
SuSE:                       zypper install libaio-devel

$ yum install libaio-devel

and we cmake configure, we got another error:

— Could NOT find Curses  (missing:  CURSES_LIBRARY CURSES_INCLUDE_PATH)
CMake Error at cmake/readline.cmake:83 (MESSAGE):
Curses library not found.  Please install appropriate package,

remove CMakeCache.txt and rerun cmake.On Debian/Ubuntu, package name is libncurses5-dev, on Redhat and derivates it is ncurses-devel.
Call Stack (most recent call first):
cmake/readline.cmake:118 (FIND_CURSES)
cmake/readline.cmake:214 (MYSQL_USE_BUNDLED_READLINE)
CMakeLists.txt:269 (MYSQL_CHECK_READLINE)

$ yum install ncurses-libs.x86_64 ncurses-devel.x86_64

and we cmake after clean up.

we got another warning of missing bison.

$ yum install bison.x86_64 bison-devel.x86_64

another error:
— Performing Test HAVE_PEERCRED
CMake Error at /usr/share/cmake/Modules/CMakeCXXInformation.cmake:17 (GET_FILENAME_COMPONENT):
get_filename_component called with incorrect number of arguments
Call Stack (most recent call first):
CMakeLists.txt:3 (PROJECT)

CMake Error: CMAKE_CXX_COMPILER not set, after EnableLanguage
CMake Error: Internal CMake error, TryCompile configure of cmake failed
— Performing Test HAVE_PEERCRED – Failed
— Configuring incomplete, errors occurred!

$ yum install gcc-c++.x86_64
fixed this.

rerun cmake configure… success!

$ make VERBOSE=1

$ make package
CPack: Package /root/setup/mysql-5.5.29/build/mysql-5.5.29-linux-x86_64.tar.gz generated.

$ make install DESTDIR=”/opt/mysql_5.5.29″

5> post install setup
http://dev.mysql.com/doc/refman/5.5/en/postinstallation.html

#before running the command below, makes sure, NO /etc/my.cnf file exists
$ mv /etc/my.cnf /etc/my.cnf.original

$ cd /opt/mysql_5.5.29/usr/local/mysql
$ chown -R mysql .
$ chgrp -R mysql .

$ scripts/mysql_install_db –user=mysql

[output]
Installing MySQL system tables…
OK
Filling help tables…
OK

To start mysqld at boot time you have to copy
support-files/mysql.server to the right place for your system

PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:

./bin/mysqladmin -u root password ‘new-password’
./bin/mysqladmin -u root -h falcon724.startdedicated.com password ‘new-password’

Alternatively you can run:
./bin/mysql_secure_installation

which will also give you the option of removing the test
databases and anonymous user created by default.  This is
strongly recommended for production servers.

See the manual for more instructions.

You can start the MySQL daemon with:
cd . ; ./bin/mysqld_safe &

You can test the MySQL daemon with mysql-test-run.pl
cd ./mysql-test ; perl mysql-test-run.pl

Please report any problems with the ./bin/mysqlbug script!
[end output]

tighten up file permissions again
$ chown -R root .
$ chown -R mysql data

we tend to use mysql server mainly using innodb
$ cp support-files/my-innodb-heavy-4G.cnf /etc/my.cnf

start the server
$ bin/mysqld_safe –user=mysql &

verify server running
$ bin/mysqladmin version
$ bin/mysqladmin variables

verify server shuts down correctly
$ bin/mysqladmin -u root shutdown

start it again
$ bin/mysqld_safe –user=mysql &

run some test to query info from mysql
$ bin/mysqlshow
$ bin/mysqlshow mysql
$ bin/mysql -e “SELECT Host,Db,User FROM db” mysql

secure mysql inital accounts and follow instructions interactively.
Set root password? [Y/n] y
Remove anonymous users? [Y/n] y
Disallow root login remotely? [Y/n] y
Remove test database and access to it? [Y/n] y
Reload privilege tables now? [Y/n] y

$ bin/mysql_secure_installation

!at this point, we have a secure non-chroot mysql running, following steps dealing with the chroot processes.

6> chroot related set up
if not having a mysql user and group
$ groupadd mysql
$ useradd -M -g mysql mysql

this just creats a /opt/mysql_5.5.29 in the chrooted /opt/mysql_5.5.29 pointing to the effectively same place.
$ cd /opt/mysql_5.5.29
$ mkdir opt
$ cd opt
$ ln -s ../ mysql
$ ln -s ../ mysql_5.5.29

chroot the directory
$ perl chroot_dir.pl /opt/mysql_5.5.29 /opt/mysql_5.5.29

#####################################
# Residential files that need chroot:
/opt/mysql_5.5.29/lib64/libc.so.6 => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/my_print_defaults => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/mysql_plugin => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/myisam_ftdump => 1 time(s)
/lib64/libcrypt.so.1 => 1 time(s)
/opt/mysql_5.5.29/lib64/libdl.so.2 => 1 time(s)
/opt/mysql_5.5.29/lib64/libgcc_s.so.1 => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/perror => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/mysqlshow => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/lib/plugin/auth_socket.so => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/mysqltest_embedded => 1 time(s)
/lib64/libfreebl3.so => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/lib/plugin/libdaemon_example.so => 1 time(s)
/lib64/libgcc_s.so.1 => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/mysql_embedded => 1 time(s)
/lib64/libc.so.6 => 1 time(s)
/lib64/libtinfo.so.5 => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/mysqldump => 1 time(s)
/opt/mysql_5.5.29/usr/lib64/libstdc++.so.6 => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/lib/plugin/semisync_slave.so => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/mysql => 1 time(s)
/opt/mysql_5.5.29/lib64/libm.so.6 => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/mysqlimport => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/lib/plugin/qa_auth_interface.so => 1 time(s)
/lib64/libm.so.6 => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/lib/plugin/auth_test_plugin.so => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/lib/plugin/qa_auth_client.so => 1 time(s)
/opt/mysql_5.5.29/lib64/libncurses.so.5 => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/myisamchk => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/lib/plugin/auth.so => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/lib/plugin/mypluglib.so => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/resolveip => 1 time(s)
/opt/mysql_5.5.29/lib64/libcrypt.so.1 => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/mysql_upgrade => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/mysql_waitpid => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/myisamlog => 1 time(s)
/opt/mysql_5.5.29/lib64/libtinfo.so.5 => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/resolve_stack_dump => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/mysqladmin => 1 time(s)
/opt/mysql_5.5.29/lib64/librt.so.1 => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/mysqlbinlog => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/mysql_tzinfo_to_sql => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/mysql_client_test_embedded => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/mysqltest => 1 time(s)
/lib64/libpthread.so.0 => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/innochecksum => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/mysqlslap => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/mysql-test/lib/My/SafeProcess/my_safe_process => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/lib/libmysqlclient.so.18.0.0 => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/lib/plugin/adt_null.so => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/myisampack => 1 time(s)
/usr/lib64/libstdc++.so.6 => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/mysqlcheck => 1 time(s)
/opt/mysql_5.5.29/lib64/libpthread.so.0 => 1 time(s)
/opt/mysql_5.5.29/lib64/libfreebl3.so => 1 time(s)
/lib64/libncurses.so.5 => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/mysql_client_test => 1 time(s)
/lib64/libdl.so.2 => 1 time(s)
/lib64/librt.so.1 => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/mysqld => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/lib/plugin/qa_auth_server.so => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/lib/plugin/semisync_master.so => 1 time(s)
/opt/mysql_5.5.29/usr/local/mysql/bin/replace => 1 time(s)

#############################
# Dependency libs got copied:
/opt/mysql_5.5.29/lib64/libncurses.so.5 => 1 time(s)
/opt/mysql_5.5.29/lib64/libfreebl3.so => 1 time(s)
/opt/mysql_5.5.29/lib64/libtinfo.so.5 => 1 time(s)
/opt/mysql_5.5.29/lib64/libaio.so.1 => 1 time(s)
/opt/mysql_5.5.29/lib64/libcrypt.so.1 => 1 time(s)
/opt/mysql_5.5.29/lib64/librt.so.1 => 1 time(s)
/opt/mysql_5.5.29/lib64/libdl.so.2 => 1 time(s)

##############################################################
#libs needed but already exists (exlcuding those copied over):
/opt/mysql_5.5.29/lib64/libc.so.6 => 61 time(s)
/opt/mysql_5.5.29/lib64/libpthread.so.0 => 43 time(s)
/opt/mysql_5.5.29/usr/lib64/libstdc++.so.6 => 22 time(s)
/opt/mysql_5.5.29/lib64/libm.so.6 => 34 time(s)
/opt/mysql_5.5.29/lib64/libgcc_s.so.1 => 24 time(s)
/opt/mysql_5.5.29/lib64/ld-linux-x86-64.so.2 => 63 time(s)

#########################
#Not matched LDD outputs:
linux-vdso.so.1 => (0x00007fff7ed98000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff4c168000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff2d3e8000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffeb000000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff3c168000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff8cde0000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffce800000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffa16c8000) => 1 time(s)
linux-vdso.so.1 => (0x00007ffffc800000) => 1 time(s)
linux-vdso.so.1 => (0x00007ffff1760000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff1ce00000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff43600000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff79e00000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff66200000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff06e00000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff58000000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff88d80000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffb8c00000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff0c5d8000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff76d60000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff4cbf8000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff02db0000) => 1 time(s)
linux-vdso.so.1 => (0x00007ffff3a00000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffb0400000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff24400000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff0a580000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff3f400000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffd1198000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff01fd0000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffd2308000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff9afa8000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffe4600000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff3d7b8000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff15400000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff1a330000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffaf800000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff75800000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff29280000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff9ac00000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff8fc00000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff39800000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff0fba0000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffc8400000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff52cf8000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffd5000000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffed1b0000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff3fe00000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffcacb8000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffacb40000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffb1200000) => 1 time(s)
linux-vdso.so.1 => (0x00007ffffbc00000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff7f950000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff52800000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff16600000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffd6400000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffe9200000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff45800000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff8a5d0000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff65000000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffa8988000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffba400000) => 1 time(s)
linux-vdso.so.1 => (0x00007fffda578000) => 1 time(s)
linux-vdso.so.1 => (0x00007fff31600000) => 1 time(s)

$ mkdir -p /opt/mysql_5.5.29/tmp
$ chmod 1777 /opt/mysql_5.5.29/tmp

for the mysql user resolve in the chroot
make them owned by root and read only for mysql
$ mkdir -p /opt/mysql/etc
$ cp /etc/hosts /opt/mysql/etc
$ cp /etc/host.conf /opt/mysql/etc
$ cp /etc/resolv.conf /opt/mysql/etc
$ cp /etc/group /opt/mysql/etc
$ cp /etc/passwd /opt/mysql/etc
$ cp /etc/shadow /opt/mysql/etc

This is important for mysql to do resolve or you will get
“[ERROR] Fatal error: Can’t change to run as user ‘mysql’ ; Please check that the user exists!”
also note if you need to copy the 32 bits or 64 bits verions depending on your system
$ cp /lib64/libnss* /opt/mysql/lib64/

! the following start cmd to run mysql in chroot does not work! why?!
looks like mysqld_safe is a script which tries to determine enviroment and path. and …
$ /opt/mysql_5.5.29/usr/local/mysql/bin/mysqld_safe –user=mysql –chroot=/opt/mysql &

! This is the correct way to start the mysql in chroot.
$ cd /opt/mysql_5.5.29/usr/local/mysql
$ bin/mysqld_safe –user=mysql –chroot=/opt/mysql_5.5.29 &

Works like a charm!

Leave a Reply

Your email address will not be published. Required fields are marked *

2 + 12 =