Top Banner

of 24

MySQL Magazine - Issue 1

May 31, 2018

Download

Documents

Oleksiy Kovyrin
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
  • 8/14/2019 MySQL Magazine - Issue 1

    1/24

    MMyySQLSQL

    MagazineMagazineSummer 2007 Issue 1

    HowSecureIsYourServer?

  • 8/14/2019 MySQL Magazine - Issue 1

    2/24

    Welcome to MySQL Magazine. This is the magazine for the community of MySQL databaseadministrators and developers who use MySQL on a daily basis to provide some of the bestinfrastructure available on the Internet.

    What will you find here? News, articles on both administration and devlopment, feedback from theusers. Simply anything relating to MySQL!!

    MySQL in the News

    The biggest news of the past few months for MySQL users has to be the MySQL Conference that wasApril 23rd through the 26th. If you didnt go-you missed out! There were many speakers including ourown Baron Schwartz. Topics ranged from building your basic knowledge, improving the performanceof your servers and quite a few presentations on how large Web 2.0 companies such as Digg andFlickr handle their traffic loads. Many of the speakers have their slides available forviewing. You canfind them and other informaion about the conference at: http://www.mysqlconf.com. In addition thereare several people in the MySQL community who have graciously supplied audio and video from theconference. An RSS feed of mp3s that will work with itunes is at http://download.tailrank.com/mysql-

    conf/mysqlconf.rss. Kevin Burton created these mp3s from ogg vorbis recording that Baron Schwartzmade (available at http://www.xaprb.com/presentations/mysqlconf2007/). In addition, Sheeri Kritzer,has made available her recording (both audio and video) of presentations at the conference. They areavailable at http://technocation.org/index.php?option=com_content&task=view&id=54

    As an aside, Sheeri does a great MySQL podcast called OurSQL (available from the itunes store).

    Next year the conference will be April 15-18. Go ahead and make plans to attend. You wont regret it!

    MySQL AB has also recently announced the addition of two new certifications. In March MySQL ABannounced the new Certified MySQL Cluster DBA. Next, in April, MySQL AB announced the newCertified MySQL Associate. The CMCDBA (rolls off the tongue doesnt it?) shows mastery of all facets

    of the new MySQL cluster server. The CMA is a more entry-level certification showing basicknowledge of the MySQL server.

    Book Worm

    One of the books on my bookshelf is Pro MySQL by Michael Kruckenberg and Jay Pipes. This is anexcellent book for someone seeking information about MySQL that goes beyond the basics. At almost700 pages (not including index) this book is divided into two parts. The first part is devoted to thearchitecture of the MySQL server and MySQL-based devlopment. The second half of the book

    devoted to database administration.

    Some of the topics include benchmarking/profiling (worth the cost of the book alone), storage engines,security, backup, replication and clustering. Each is covered in-depth from true experts.

    This is a well written book. If you consider yourself a professional MySQL DBA the information isinvauluble. This book makes a great reference for topics that you might not deal with on a day to daybasis. My only quible would be that it needs to be updated. It was printed in 2005 and covers up toversion five of our favorite database. In particular the informaiton on clustering is dated (because withversion 5.1 the tables are no longer required to be in memory). Even so the book is still well worth themoney.

    http://www.mysqlconf.com/http://www.mysqlconf.com/http://www.mysqlconf.com/
  • 8/14/2019 MySQL Magazine - Issue 1

    3/24

    Contents Summer 2007

    3 MySQLs Future?

    6 Securing MySQL Server

    9 Optimizing MySQL with Rails - Part One

    12 Convenient MySQL Privilege Scripting and Versioning

    14 Operating System Hardening

    Regular Features1 News

    1 Book Worm

    4 Coding Corner - Protecting a MySQL Database from SQL Injection Attacks - Part 1

    23 log-bin

  • 8/14/2019 MySQL Magazine - Issue 1

    4/24

    So where is MySQL going? Before we examinethis question it is a good idea to look at thecurrent feature set of MySQL (as of version

    5.1.x).

    ACID compliancetransactionstriggersfunctionscursorsviewssubqueriestransactionsrow-based replication

    multiple database enginespartitioningshared-nothing clustering

    What is on the horizon for our favorite database?Certainly there has been a good deal of buzz oflate about the new Falcon database engine.There has been an alpha release (6.0) of theserver that includes the the new engine. Pleasebe forwarned that this database engine is in noway production quality. It certainly has great

    promise. The Falcon db engine was created byJim Starkey who is one of the pioneers ofRDBMS. Some people think that Falcon willbecome the default engine for MySQL - especiallyafter Oracle bought Innodb. The expectedrelease date for a production version 6.0 is Q22008.

    Another item of interest is implementation offoreign keys for all the major database engines inversion 6.1. Currently foreign keys are only

    supported on InnoDB. Foreign keys are a greathelp for the developers out there in keeping thedata in the database syncronized.

    Prior to the release of version 5.1 there wasdiscussion of the implementation of an online-backup tool that would be superior to currentimplementations. This was originally slated forthe 5.1 release. This just has not happened. Asa DBA who performs back-ups on a routine basis

    it would be nice to see some polish applied to thisoften used area of MySQL. News from the recentMySQL user conference has the 6.1 release

    having online backup. In addition there should besubquery optimization in version 6.1.

    These are the major features slated for the nexttwo releases of MySQL. In addition, there willcontinue to be improvements over many areas ofMySQL.

    We are fortunate that MySQL AB and thecommunity together have been able to implementalmost every feature that is of significance. Even

    though this is the case, there are areas that willcontinue to move forward. Clustering is a featurethat will continue to gain momentum as itbecomes better implemented. I find this area ofMySQL technology fascinating and I look forwardto the combination of growing stability and newfeature advancements of the young clusteringenvironment.

    About the author

    Keith Murphy is the editor of MySQL Magazine.He is also the chief Dolphin at BroadwickCorporation.

    MySQLs Future?by Keith Murphy

  • 8/14/2019 MySQL Magazine - Issue 1

    5/24

    SQL injection is a method for attackingdatabases. The attacker "injects" elements intoyour program's SQL in order to bypassauthorization or damage the database.

    Web sites that send SQL commands to databasesare particularly vulnerable to SQL injection,because they often rely on dynamic SQL, andbecause it can be easy to mount millions of suchattacks until one succeeds. Here is a simpleexample. A PHP page asks the user for a name

    and a password, then sends this to the database:

    SELECT * FROM mysql.user WHERE user = '$usr' AND

    password = '$pwd';

    Is it as innocuous as it looks? Suppose a userenters something like this as a user name:

    ' OR 1>0; --

    When your application plugs that entry into your

    SQL, the command becomes:

    SELECT * FROM mysql.user WHERE user = '' OR 1>0; --

    AND password = ''

    Your intruder just retrieved all rows and columnsof the mysql.user table. Not exactly what you hadin mind.

    Or a malevolent user might supply this username:

    OR 1>0; TRUNCATE customers; --

    whereupon your application sends this commandto the database:

    SELECT * FROM mysql.user WHERE user = '' OR 1>0;

    TRUNCATE customers; -- ' AND password = ''

    Protecting a MySQL Database from

    SQL Injection Attacks - Part Iby Peter Brawleyhttp://www.artfulsoftware.com

    If your application's connection supports multipleSQL commands in a single query call, all yourcustomer data just went away.

    LEVEL 1 DEFENSE: NEGATIVE INPUT FILTERS

    The simplest way to prevent this sort of injectionis to search the SQL string for semi-colons anddouble dashes, and remove them before passingthe statement to the database. That's easy in anadequate application language, for example in

    PHP:

    $protectedqry = str_replace( "--", "", str_replace( ";", "", $qry ));

    If $qry has offending characters, sending$protectedqry to the database raises a MySQLerror. That provides one level of protection.

    Better still, search the string for double dashesand semi-colons, and if either is found thenrefuse to send the query to the database. If you

    want to be really thoroughgoing, you couldblacklist the IP address that launched the attack.

    Now you are fully protected against attacks thatuse double dashes and semi-colons. Have youcovered all possible attacks? Not a chance,human ingenuity having no practical limit. Forexample, a favorite trick we haven't touched on isintroduction of malevolent WHERE clauses.

    LEVEL 2 DEFENSE: POSITIVE INPUT FILTERS

    The attacker has to succeed just once. If yourdatabase is to be safe, you must succeed everytime. You are on better logical ground enforcinga simple positive validation pattern than lookingfor a limitless number of dangerous or invalidpatterns. Positive input filters improve yourchances of success enormously.

    Coding

    Corner

  • 8/14/2019 MySQL Magazine - Issue 1

    6/24

    For example, you could decide to accept onlyalphanumeric characters in user names andpasswords. It is easy to enforce that rule in PHP:

    if( ereg( '[^A-Za-z0-9]+', $usr.$pwd )) {echo "

    alert('Alphabetic and numeric characters only, please.');

    ";

    You can formulate more stringent tests based onspecific input requirements.

    LEVEL 3 DEFENSE: OUTPUT FILTERS

    Finally, application languages provide generictools for cleaning up submissions to yourdatabase. Again in PHP the function to use ismysql_real_escape_string():

    $qry = mysql_real_escape_string( $qry,

    $connection_resource );

    LEVEL 4 DEFENSE: ENCAPSULATION

    Enterprise RDBMS policies usually require that allsuch protective logic be encapsulated in storedprocedures. In Part II we will study how to do thisin MySQL.

    Summary

    To stop SQL injection attacks in their tracks, applysimple positive and negative input filters, andescape possibly problematic characters in whatyou send to the database.

    About the author

    Peter Brawley is president of Artful SoftwareDevelopment and co-author ofGetting It DoneWith MySQL 5.

  • 8/14/2019 MySQL Magazine - Issue 1

    7/24

    Securing MySQL Server

    by Keith Murphy

    When looking to secure a MySQL server there are several important areas to consider. We will take

    time to examine each of these areas in some detail. This will give you strong foundational knowledgewhen looking at securing a MySQL server.

    User accounts

    A very common discussion point for MySQL security is the user accounts of the database. It iscertainly foundational to understanding the security of your server. MySQL user security is based onan ACL (Access Control List) model. This is used for everything a user does including queryexecution, connection capability and server administration capabilities. All of this information is storedin the user table of the mysql database. Permissions are generally managed with the GRANT andREVOKE ocmmands.

    User management can be one of the more arcane areas of being a DBA. Even so, it is simply toimportant to neglect. Each user should have the minimal set of permissions to perform the tasksneeded. Not every user needs to ability to drop tables/databases!! Dont be lazy in this area as it willbite you eventually.

    By default the root user does not have a password when you set up a MySQL server. Change thisimmediately by executing the msyqladmin -u root -p new-passwordcomand.

    MySQL ships with two default users and a default 'test' table. The default users are for connecting tothe DBMS without specifying a password, so removing these users is obviously a very good security

    measure. There are also entries so that tables called or starting with 'test' can be world-writable. Youwill want to disable these accounts and remove the test database.

    Executing the following two commands from the MySQL monitor will achieve the desired results:

    mysql> DELETE FROM user WHERE User = '';mysql> DELETE FROM db WHERE Host = '%';

    Connection methods

    It is quite common to connect to a MySQL server using the command line mysql client. If you connectto a server from your desktop using this client all your information is being sent across the networkwithout very strong encryption. This is something you want to avoid doing. It is a best practice toconnect the server that MySQL is running on using a tool such as ssh that provides an encryptedcommunication channel and then use the client tools on the server to work with MySQL.

  • 8/14/2019 MySQL Magazine - Issue 1

    8/24

    Network design considerations

    If you are planning a network for a typical website that is publicly accessible there is one securityconcern to keep in mind. It is always best to have your web server and your database server running onseparate machines. If they are not running on the same machine you will want to have the MySQLserver (which does not need to be accessed by the public) on its own private network.

    Take a look at the following diagram:

    As you can see we have a small networkthat is publicly accessable through72.9.253.1. Each web server will beaccessible (through the load balancer). TheMySQL server, however, is not accessible.The 192.168.1.x network is not availableover the Internet. You would have to be onthe internal network to reach the server.This makes it much more difficult for anintruder to reach and attempt to compromise

    the MySQL server. Of course the MySQLserver can communicate freely with the webservers over the internal network.

    When operating overTCP/IP MySQL, bydefault, uses port 3306. You should havethis port blocked on your network firewall(s)to disable access from outside.

    Operating system considerations

    Whatever operating system you choose to run MySQL on there are a several concerns in preparing theoperating system for use. You should always install a minimal set of packages necessary to run youroperating system. No need for the everything but the kitchen sink mentality. The reason why is thatevery additional packages/applications installed gives an attacker another avenue of possible access.

    As a side benefit, you will get better performance out of your MySQL server.

    Remove any unneccessary users from the operating system. Like the extra packages, unneeded usersprovide an avenue of access for an attacker. Use strong passwords for your system users. Your dogs

    name isnot a good password. It should be a mix of letters (capitalized and uncapitalized) and othersymbols. Minimally it should be eight characters long, but should probably be more in the ten to twelvecharacter range.

    In addition, you should consider the physical security of a system. Any system can be compromised ifleft unattended. Servers should be in dedicated areas behind locked doors minimally. Data centerspace with locked cabinets is always a good idea if possible.

  • 8/14/2019 MySQL Magazine - Issue 1

    9/24

    User account running the MySQL daemon

    Do not run the MySQL daemon as the Unix root user. It is a very dangerous practice as any user withFILE privileges will be able to create files as root (for example, ~root/.bashrc). To prevent this, mysqldwill refuse to run as root unless it is specified directly via --user=root option. The mysqld daemon can berun as any user instead. You can also create a new user mysql to make things more secure. If you runmysqld as another Unix user, you don't need to change the root user name in the user table, becauseMySQL user names have nothing to do with Unix user names. You can edit the mysql.server script to

    start mysqld as another Unix user. Normally this is done with the su command.

    If you put a password for the Unix root user in the mysql.server script, make sure this script is readableonly by root. Check that the Unix user that mysqld runs as is the only user with read/write privileges inthe database directories.

    Mysqld file options

    It is important to understand the settings in your mysqld options file. This file is typically named my.conf.There is one settings that it is critical that you examine - the skip-networking options.

    The skip-networking options disables TCP/IP network connections. This is a good security feature if youare running MySQL on the same server as the web server (in a typical Internet serving connection). Ifthe MySQL server is located on another server (as it must use TCP/IP to communicate with the otherserver).

    Resources

    http://dev.mysql.com/doc/refman/5.0/en/security.html

    About the author

    Keith Murphy is the editor of MySQL Magazine. He is also the chief Dolphin at Broadwick Corporation.

  • 8/14/2019 MySQL Magazine - Issue 1

    10/24

    Optimizing MySQL with Rails - Part One

    By Dan [email protected]

    Rails philosophy of convention over configuration and plethora of built in helpers makes it almostscary-easy to prototype a database-driven web application, and the transparency with which yourapplicaton interacts with the database makes it easy to forget about the often-complex beast known asyour RDBMS lurking behind the scenes. As with the applications Ruby code, it is easy to create abasic database, and easy to change the database structure as your application evolves - buteventually most web applications need to grow up and be deployed somewhere, and when they do,the database needs to be up to the challenge.

    MySQL is one of the most widely-used databases for Rails development and deployment. I willpresent several different methods you can use to improve performance - some fairly general, someMySQL-specific, and some Rails-specific. Index creation and caching are probably the two biggestitems in terms of potential payoff, but all the methods can be employed in various combinations formaximum benefit.

    Object-oriented languages can present special challenges to relational databases because of thesheer number of queries executed in some cases. This isnt a fault, really, but a result of clean,readable, simple code. With proper testing, and a bit of tweaking, your database can be made to keepup with your application.

    Creating effective indices

    When you create tables with migrations, the only default index is on the primary key - and while thatindex is often useful in joins, it is unusual for that to be the only index you need on an important table.It may be that you know right away which fields youll be querying on and can create useful indices

    right away, or it could be that you only gather a good understanding of the nature of the data late in theproject, but at some point prior to launch youll want to spend some time on indices.

    It is easy to go overboard creating indices: MySQL can use only one index per instance of a table perquery, and extra indices take up disk space and slow down write operations. That said, creating anindex is usually a highly effective step in increasing performance, and generally requires very littleeffort to experiment with.

    Multi-column indices can be a great way to hone performance in large datasets, but they do requiresome care when creating them to be most useful. A multi-column index is used from left to right, withno gaps allowed that is to say, if you index several columns like so:

    ALTER TABLE t1 CREATE_INDEX multi_col_idx (c1, c2, c3)

    This index will be usable to speed up queries that specify c1, c1 and c2, or c1 and c2 and c3 in theWHERE clause; however, it will not be usable to speed up queries against only c2, or only c3, or c2and c3. A query against c1 and c3 would be assisted with c1 information, but not able to also use theindex on the c3 portion.

    As an example you might have a table with directory-type information about a companys employees,and users can search by specifying a last name and, optionally, a first name.

  • 8/14/2019 MySQL Magazine - Issue 1

    11/24

    Something like this code:

    if params[:first_name].blank?Employee.find :all, :conditions => [last_name = ?, params[:last_name]]

    elseEmployee.find :all, :conditions => [last_name = ? AND first_name = ?, params[:last_name], params[:first_name]]

    end

    In this case, a multi-column index across last_name and then first_name would be more beneficialthan separate indices on each column. Specifying last_name as the first column in the index makessense as (in this somewhat simplistic example) we are requiring that last_name always be present.

    ALTER TABLE employees CREATE_INDEX both_names_idx (last_name, first_name)

    Also be aware of MySQLs limitation with LIKE string searches and indices, that the search string mustmatch from the beginning of the column. This can use an index:

    SELECT * FROM employees WHERE last_name LIKE Smith%

    while this cannot, due to the wildcard in front of Smith:

    SELECT * FROM employees WHERE last_name LIKE %Smith%

    Join tables, which link two other tables in has_and_belongs_to_many relationships, are excellentcandidates for indexing, and a case where indexing both columns can help significantly. Examine yourtypical queries to determine which column to put first.

    Use MySQLs slow query log and the Rails log

    Use the Rails log file in a development environment to evaluate the queries executed and thedatabase time for each page. Extract the queries and use MySQLs EXPLAIN feature to see how

    indices are being used. I often run a tail -f command on log/development.log in my application,examining the output as I load each page in my Rails application and copy-pasting the queries into aMySQL session for evaluation. Example output shows both the complete query and the executiontime:

    Webpage Load (0.041033) SELECT * FROM content_items WHERE (content_items.`url_text` = 'home') AND ((content_items.`type` = 'Webpage' ) ) LIMIT 1

    Parsing the output of the EXPLAIN command can be daunting for complex queries, but with a littlereading and perseverance, and if you start with simple queries, you can get the hang of it prettyquickly. It is especially easy to notice the lack of index usage:

    mysql> EXPLAIN SELECT * FROM content_items WHERE (content_items.`url_text` = 'home') AND ( (content_items.`type` ='Webpage' ) ) LIMIT 1 \G*************************** 1. row ***************************

    id: 1select_type: SIMPLE

    table: content_itemstype: ALL

    possible_keys: NULLkey: NULL

    key_len: NULLref: NULL

    rows: 261Extra: Using where

    1 row in set (0.00 sec)

  • 8/14/2019 MySQL Magazine - Issue 1

    12/24

    We see that possible_keys, which should be a list of any indices on columns used in the query, isNULL, meaning there is no way were going to get an index hit. In fact, the type of ALL indicates atable scan, and rows shows an estimate of the number of rows MySQL thinks it will have to examine.261 is small in this single table query, but in complex joins the effect on performance can beexponential when multiple tables do not have index hits.

    Knowing my application and my data, I know that I will always select on a specific value for the url_text

    column, and nearly always specify a value for type. If we add an index like so, it should help a lot specifying the column Ill always use first, and the column I may not always use second:

    ALTER TABLE content_items ADD INDEX multi_col_idx (url_text, type)

    Now my EXPLAIN output looks a lot better:

    *************************** 1. row ***************************id: 1

    select_type: SIMPLEtable: content_itemstype: ref

    possible_keys: multi_col_idx

    key: multi_col_idxkey_len: 516

    ref: const,constrows: 1

    Extra: Using where1 row in set (0.00 sec)

    You can see that the number of rows MySQL thinks it will have to examine has dropped to just one.

    MySQLs slow query log can be beneficial in identifying queries that are truly slow, taking one secondor more to execute. You can specify the number of seconds in the MySQL server configuration file,but the minimum is one second, which sometimes doesnt give you enough granularity to find subtle

    slowdowns. A query that takes, say, 90 seconds, but is only executed occasionally can cost you a lotless than a query that takes a quarter or even a tenth of a second but is executed on every page load.

    While it might be nice to speed up that 90 second query, if its only executed for a report that one ortwo people use once a week, your time is better spent on that other query. Thats where your Railsdevelopment log file can be quite helpful.

    Next time

    In part two of this article we will discuss sample data and development setups, the MySQL and Railsquery caches, a couple of common pitfalls when designing database tables and queries, and other

    items relating to Rails performance on MySQL!

    About the author

    Dan Buettner works for Outsell, Inc., a San Francisco area market research company tracking the in-formation industry, though he lives in Des Moines, Iowa. In a past life he worked at The Des MoinesRegister, a midsize newspaper, as an IT manager, newspaper production specialist, software devel-oper, and Sybase and MySQL DBA. He has been using MySQL since version 3.x in 1999, and Railssince Summer 2006. This article was finished while attending RailsConf 2007.

  • 8/14/2019 MySQL Magazine - Issue 1

    13/24

    MySQL provides several levels of privilegegranularity, and if you're like me, you may findprivileges getting unnecessarily complex quickly.

    Redundant privileges, or users with similar butnot identical privileges, can be a headache tomanage, and if you need to change or clean themup at the command line, it can be very tedious todo. I also believe privileges are code and shouldbe automatically saved in a version controlsystem, for all the same reasons I version controlother kinds of code.

    Both tasks are harder than they might seem atfirst glance, but they can be made easier with a

    little scripting.

    What's hard about managing privileges?

    Though it seems straightforward at first, it canactually be quite tedious to manage userprivileges, especially from the command line. Forexample, let's say you have users Bob and Anne,with nearly the same privileges, and your taskis to remove Bob's extra privileges so he has thesame rights as Anne. To make it more

    interesting, imagine the users are not on thesame server, and each has about a hundredprivileges. How do you do this?

    The most straightforward way is to connect toeach server and type SHOW GRANTS FOR, then visually scan the lists andcompare. This works okay for a few privileges,but not hundreds.

    Your next thought is to pipe the grants into files

    and use command-line utilities, such as diff, tocompare them. This is a great idea, but here'swhere you start to notice the little things thatmake this job harder. The grants are not orderedthe same. You can pipe them through sort, butyou still don't get them in the same order,because not only are the individual GRANTstatements not ordered the same in the output,but the actual grants are sorted differently withinthe lines! For example, Bob's grants on a given

    table are listed as SELECT, INSERT, DELETE,but Anne's are listed as INSERT, SELECT,DELETE. This makes it hard to compare the

    grants.

    Imagine that you overcome this somehow, andnow you see only five differences between thetwo. Your remaining task is to type REVOKEstatements for Bob's account. This also gets oldafter you do it a few times. Imagine how hard thisprocess becomes when you have many users onmany servers!

    This same difficulty makes it hard to place the

    grants into version control. In my experience, thegrants are frequently printed out in a differentorder every time you check, even when theyhaven't changed. This leads to spuriouschangesets in your version control system, andagain makes it hard to compare and see what istruly changing.

    MySQL Show Grants to the rescue

    I wrote a tool, unimaginatively called MySQL

    Show Grants, to help me address these veryproblems. Superficially similar to "mysql -e 'showgrants'", it has some important differences thatmake it easy to script solutions to the aboveproblems:

    1. Grants are sorted within each line, so theyalways appear in the same order.

    2. The lines are sorted.

    These properties are enough to solve theproblem of spurious changesets in versioncontrol. All you need to do is run a nightly cron

    job to dump the grants (by default it dumps grantsfor all users), then check it into your sourcecontrol system.

    As for cleaning up user privileges, I also addedfeatures to help you diff users conveniently,adding or revoking with ease:

    Convenient MySQL Privilege Scripting and Versioningby Baron Schwartz

  • 8/14/2019 MySQL Magazine - Issue 1

    14/24

    1. You can split each GRANT command onto itsown line. GRANT SELECT, INSERT becomesGRANT SELECT; GRANT INSERT. This makesit much easier to see which exact priveleges aredifferent.

    2. You can convert GRANT statements to

    REVOKE statements.

    These features make it easy to revoke Bob'sexcess privileges and make them the same as

    Anne's. For example,

    mysql-show-grants --separate --revoke --only bob --host=server1 \

    | grep REVOKE > bob-privilegesmysql-show-grants --separate --revoke --only anne --

    host=server2 \

    | grep REVOKE | sed -e 's/anne/bob/g' > anne-privileges

    These commands separate the GRANTstatements and convert them into REVOKEstatements, then put the results into files. Youcan easily run diff on these two files now and seewhat has changed; the files contain validREVOKE commands, so you can even executethe difference by piping it into the mysqlcommand-line client.

    MySQL Show Grants is licensed under the GPL,hosted on SourceForge, and can be downloaded

    from http://sourceforge.net/projects/mysqltoolkitThe system requirements are very moderate: Perland DBD, which might already be on yoursystem.

    Though I have solved my own needs with thistool, I also want it to be useful to others. If youneed additional features, feel free to request themvia the SourceForge bug tracker, forums, ormailing list.

    About the author

    Baron Schwartz works for the Rimm-KaufmanGroup, a search marketing agency inCharlottesville, Virginia. He writes frequentlyabout MySQL on his blog (http://www.xaprb.com).He is the author of the innotop MySQL andInnoDB monitor, and MySQL Toolkit, a collectionof command-line tools.

  • 8/14/2019 MySQL Magazine - Issue 1

    15/24

    Operating System Hardeningby Keith Murphy

    Some might question why there is an article about the operating system in a magazine about MySQL.When considering the overall security of a database it is important to take into account the underlyingoperating system of the database. You can have a very secure MySQL server compromised throughthe underlying operating system.

    MySQL runs on a variety of platforms. There is not enough space to cover every platform. First I willdiscuss several principles that are going to be applicable to any operating system. Then I will cover indetail the setup of the operating system. Linux is one of the most popular platforms for MySQL andCentOS is one of the most common Linux distribution.

    There are two security principles that apply to server hardening - the principle of separation and theprinciple of defense in depth. The principle of separation is the idea that a server should perform aminimal set of task. In another words, the server should NOT operating email, web and databaseservices. Why is this? Because less software loaded and running on the server provides feweravenues for attack. The principle of defense in depth means that only one method of protection

    should not be used to protect your server/network. For example, many people mistakenly think that afirewall will protect your network completely. In addition to a firewall you should have good password,intrusion detection systems, etc.

    Do not underestimate the importance of these two principles. When performing the following sampleinstallation of CentOS I will demonstrate these two principles. The operating system will not have anyunneeded services running and there will be multiple forms of protection. Consider this when planningyour own deployments.

    Hardening a CentOS 4.X base system

    We will be hardening a basic install of CentOS 4.X. In addition to the basic operating system install,we are installing several additional programs to provide layers of security:

    tcp wrappers libsafe chkroot tripwire

    We will make sure all unnecessary services are deactivated, and all file systems permissions areproperly set. Physical security of the system should be taken into account as well.

    In preparation for the install we will be using the following partitioning scheme:Partition Size Notes

    /boot 100MB Contains all startup files and the kernel

    / 6 gb top level partion (root partition)

    swap 2x memory contains paging file for memory management

    /usr 10 gb contains programs, libraries and documentation

    /var 10 gb system log files

    /tmp 1 gb temporary files

    /home remaining space user files

  • 8/14/2019 MySQL Magazine - Issue 1

    16/24

    Why are we partitioning like this?

    Protection against SUID programs Easy backup & upgrade management Ability for better control of mounted file system Limit each file systems ability to grow

    You will probably want to make some modifiations to this layout. If you are setting up a MySQL serveryou might want to set up specific partitions for your database logs and tablespace.

    Insert the CentOS server cd into the drive.

    The boot screen will display three options:

    Install or upgrade CentOS in graphical mode: Install or upgrade CentOS in text mode: linux text Use function keys for more information

    Hit Enter to begin the installation in graphical mode.

    Before the installation begins, you will be prompted to test the CD media. If you have not already donethis, select OK. This should be done at least once for all of the installation CDs. When the media testhas completed, re-insert CD #1 and select Continue. If you have already done this, select Skip.

    The following will walk through our Operation System installation. An explanation of each step isprovided on the left side of the screen.

    Screen Action

    Welcome Select Next

    Language Select English (default)Select Next

    Keyboard Select US English (default)Select Next

    Mouse Configuration Select Generic - 3 Button Mouse (PS/2)Select Next

    Disc Partitioning Setup Select Manually partition with Disk DruidSelect NextLayout the partitioning as described earlier

    Boot Loader Configuration Leave default selection of GRUB boot loader. Select Usea boot loader password, and enter a password.Select Next

    Network Configuration Configure with your network settings

  • 8/14/2019 MySQL Magazine - Issue 1

    17/24

    Post Installation

    Once the installation is complete save the anaconda-ks.cfg file somewhere so it wont be overwritten ordeleted. This file is located in roots home directory (/root) and is a complete kickstart configuration filethat can be used to build a duplicate system. Also generate a listing of all RPMs installed on the systems

    using the following command. rpm -qa | sort > /root/rpm-list

    Patching the System

    This system will be using yum on a internal server to get updates. All updates on this server have beenreviewed and tested before being made available to machines on the network. With this in mind, we willbe using yum to update the machine, which requires it to be on our network. We have provided a securesubnet on which to do this, however, weve also taken the extra precaution during installation byinstalling a firewall that is currently only allowing ssh traffic, and the required DNS replies and DHCPrequests for network connectivity. This update is initially performed by during installation from the updateserver.

    Screen Action

    Firewall Select Enable firewall allow only ssh through the firewallSelect Next

    Additional Language Support Default language for the system: English (USA)Additional languages to install: English (USA) only

    Time Zone Selection Select System clock uses UTCSelect your timezone (i.e., America/Denver)On the UTC Offset tab Select offset (i.e, UTC-07 US Mountain) Select Use daylight saving time Select Next

    Set Root Password Enter a root password

    Package Defaults Select Customize set of packages to be installed.

    Package Group Selection Select only the following package: Minimal

    Preparing to install Select Next will begin the installation, this is thelast opportunity to cancel the install.

    Installing Packages Insert disks as prompted

    Installation Complete When the CD is ejected, remove the media andselect Exit to reboot the system. A complete log ofthe installation can be found in the /root/install.log

  • 8/14/2019 MySQL Magazine - Issue 1

    18/24

    Securing services

    Now we will remove some services. There are several ways to stop services, I will talk about two ofthem.

    running the chkconfig command running the ntsysv command

    First, the chkconfig command. To see what services are currently running on your system:

    chkconfig --list

    This will show you a complete list of all processes and what run level they are starting at. To make it alittle easier to read you might want to run chkconfig -list | grep :on and this will only show you theprocesses that are starting up.

    Now, with my default system I have this output from the chkconfig --list command:

    network 0:off 1:off 2:on 3:on 4:on 5:on 6:offgpm 0:off 1:off 2:on 3:on 4:on 5:on 6:offhaldaemon 0:off 1:off 2:off 3:on 4:on 5:on 6:offxfs 0:off 1:off 2:on 3:on 4:on 5:on 6:offacpid 0:off 1:off 2:off 3:on 4:on 5:on 6:offrpcsvcgssd 0:off 1:off 2:off 3:on 4:on 5:on 6:offxinetd 0:off 1:off 2:off 3:on 4:on 5:on 6:offreadahead_early0:off 1:off 2:off 3:off 4:off 5:on 6:offnetfs 0:off 1:off 2:off 3:on 4:on 5:on 6:offmessagebus 0:off 1:off 2:off 3:on 4:on 5:on 6:offmdmonitor 0:off 1:off 2:on 3:on 4:on 5:on 6:offrhnsd 0:off 1:off 2:off 3:on 4:on 5:on 6:off

    crond 0:off 1:off 2:on 3:on 4:on 5:on 6:offatd 0:off 1:off 2:off 3:on 4:on 5:on 6:offapmd 0:off 1:off 2:on 3:on 4:on 5:on 6:offsmartd 0:off 1:off 2:on 3:on 4:on 5:on 6:offautofs 0:off 1:off 2:off 3:on 4:on 5:on 6:offisdn 0:off 1:off 2:on 3:on 4:on 5:on 6:offreadahead 0:off 1:off 2:off 3:off 4:off 5:on 6:offrpcidmapd 0:off 1:off 2:off 3:on 4:on 5:on 6:offanacron 0:off 1:off 2:on 3:on 4:on 5:on 6:offirqbalance 0:off 1:off 2:off 3:on 4:on 5:on 6:offpcmcia 0:off 1:off 2:on 3:on 4:on 5:on 6:off

    nfslock 0:off 1:off 2:off 3:on 4:on 5:on 6:offsendmail 0:off 1:off 2:on 3:on 4:on 5:on 6:offsshd 0:off 1:off 2:on 3:on 4:on 5:on 6:offrpcgssd 0:off 1:off 2:off 3:on 4:on 5:on 6:offsyslog 0:off 1:off 2:on 3:on 4:on 5:on 6:offcups 0:off 1:off 2:on 3:on 4:on 5:on 6:offkudzu 0:off 1:off 2:off 3:on 4:on 5:on 6:offportmap 0:off 1:off 2:off 3:on 4:on 5:on 6:offiptables 0:off 1:off 2:on 3:on 4:on 5:on 6:offcpuspeed 0:off 1:on 2:on 3:on 4:on 5:on 6:offrawdevices 0:off 1:off 2:off 3:on 4:on 5:on 6:off

  • 8/14/2019 MySQL Magazine - Issue 1

    19/24

    Now we will stop some (unneeded) services:

    [root@rivendale /]# for svc in gpm kudzu netfs atd apmd isdn \> pcmcia autofs portmap nfslock mdmonitor mdmpd cups ; do> /sbin/chkconfig -level 2345 $svc off> /sbin/service $svc stop> done

    This is fairly straightforward, each of the services listed gets removed from the startup list, and alsostopped when you run the script.

    Here is the output of the chkconfig -list command:

    network 0:off 1:off 2:on 3:on 4:on 5:on 6:offhaldaemon 0:off 1:off 2:off 3:on 4:on 5:on 6:offacpid 0:off 1:off 2:off 3:on 4:on 5:on 6:offrpcsvcgssd 0:off 1:off 2:off 3:on 4:on 5:on 6:offxinetd 0:off 1:off 2:off 3:on 4:on 5:on 6:offreadahead_early 0:off 1:off 2:off 3:off 4:off 5:on 6:offmessagebus 0:off 1:off 2:off 3:on 4:on 5:on 6:offrhnsd 0:off 1:off 2:off 3:on 4:on 5:on 6:offcrond 0:off 1:off 2:on 3:on 4:on 5:on 6:offsmartd 0:off 1:off 2:on 3:on 4:on 5:on 6:offreadahead 0:off 1:off 2:off 3:off 4:off 5:on 6:offrpcidmapd 0:off 1:off 2:off 3:on 4:on 5:on 6:offanacron 0:off 1:off 2:on 3:on 4:on 5:on 6:offirqbalance 0:off 1:off 2:off 3:on 4:on 5:on 6:offsendmail 0:off 1:off 2:on 3:on 4:on 5:on 6:offsshd 0:off 1:off 2:on 3:on 4:on 5:on 6:offrpcgssd 0:off 1:off 2:off 3:on 4:on 5:on 6:off

    syslog 0:off 1:off 2:on 3:on 4:on 5:on 6:offiptables 0:off 1:off 2:on 3:on 4:on 5:on 6:offcpuspeed 0:off 1:on 2:on 3:on 4:on 5:on 6:offrawdevices 0:off 1:off 2:off 3:on 4:on 5:on 6:off

    In this particular setup, I went from 34 services running to 21 services running. This is much better.

    Network security

    We will be modifying the /etc/sysctl.conf file. The final version will look like this:

    # Kernel sysctl configuration file for Red Hat Linux## For binary values, 0 is disabled, 1 is enabled. See sysctl(8) and# sysctl.conf(5) for more details.# Controls IP packet forwarding# Disable IP Forwardingnet.ipv4.ip_forward = 0# Disables IP Source Routingnet.ipv4.conf.all.accept_source_route = 0

  • 8/14/2019 MySQL Magazine - Issue 1

    20/24

    # Enables SYN flood protectionnet.ipv4.tcp_max_syn_backlog = 4096# Enables TCP SYNC flood protectionnet.ipv4.tcp_syncookies = 1# Disables the ability to send ICMP Redirectnet.ipv4.conf.all.send_redirects = 0# Disables ICMP Redirect acceptance

    net.ipv4.conf.all.accept_redirect = 0# Another parameter that disables ICMP Redirect acceptancenet.ipv4.conf.default.accept_redirects = 0# Controls source route verification# Enable IP Spoofing protectionnet.ipv4.conf.default.rp_filter = 1# Controls the System Request debugging functionality of the kernelkernel.sysrq = 0# Controls whether core dumps will append the PID to the core filename.# Useful for debugging multi-threaded applications.kernel.core_uses_pid = 1

    After changing the file, set the file permisions:

    # chown root:root /etc/sysctl.conf# chmod 0600 /etc/sysctl.conf

    Now, you need to restart the network service:

    # /etc/rc.d/init.d/network restart

    It is always a good idea to have a log-in banner when someone accesses the system. Legally, it is agood idea, plus it also helps to disguise what particular services your system is running.

    For ssh, add the following line to the /etc/hosts.allow file

    sshd : ALL : banners /etc/issue

    then do the following:

    # mkdir /etc/banners# touch /etc/banners/sshd

    create the content of the sshd file:

    220-Hello, %c220-All activity on rivendale.paragon-cs.com is logged.220-Thank you

    The %c variable shows client information such as the username/hostname.

  • 8/14/2019 MySQL Magazine - Issue 1

    21/24

    Secure Console and Root Account

    You really dont need to be logging in across the network with the root account. To fix this, edit the/etc/securetty file to disable network root login. Here is what it should look like:

    [root@rivendale /]# cat /etc/securettytty1

    tty2tty3tty4tty5tty6

    The root account can log in from the local console and the ssh daemon. To disable ssh root login youneed to add PermitRootLogin no to the /etc/ssh/sshd_config file, and then restart sshd.

    Restricting root login from the local console

    Linux provides a "Single User Mode" to perform system maintenance. By default, Linux does notrequire the root password to log into single user mode. To require the password, add"~~:S:wait:/sbin/sulogin" to /etc/inittab. Then run /sbin/init q to activate the change.

    Restricting usage of ctrl-alt-del

    If you type ctrl-alt-del simultaneously, a Linux system will typically reboot. This is easy to fix, andshould be done. There are two ways of doing this:

    Edit the /etc/inittab again and comment (#) out the following line:

    ca::ctrlaltdel:/sbin/shutdown -t3 -r now

    or

    add a -a option to the line. The -a flag tells shutdown to look for the /etc/shutdown.allow file. You canrestrict any users who are allowed to shutdown the system using ctrl-alt-del.

    In /etc/inittab:ca::ctrlaltdel:/sbin/shutdown -a -t3 -r nowIn /etc/shutdown.allowbmurphyroot

    Disabling console program access

    If you want to disallow any user at the console to run poweroff, halt, and reboot run the followingcommands:

    [root@rivendale /]# rm -f /etc/security/console.apps/poweroff[root@rivendale /]# rm -f /etc/security/console.apps/halt[root@rivendale /]# rm -f /etc/security/console.apps/reboot

  • 8/14/2019 MySQL Magazine - Issue 1

    22/24

    Removing unnecessary system accounts

    Some user accounts and groups are not needed by the server. Its best to keep the /etc/password fileas small as possible. This will make it easier to see unauthorized additions easier.

    Some common users you dont need:

    gopher, adm, pcap, rpc, rpcuser, nfsnobody, games, news, uucp apache, xfs, named, ntp

    And the groups:

    news, uucp, adm, games, dip

    [root@rivendale /]# for user in gopher pcap rpc rpcuser nfsnobody \> games news uucp apache xfs named ntp adm ; \> do /usr/sbin/userdel $user ; done[root@rivendale /]# for group in news uucp adm games dip; \> do /usr/sbin/groupdel $group ; done[root@rivendale /]# pwck[root@rivendale /]# grpck

    Mount /usr file system as read-only

    For protection against Trojan binaries being installed in the /usr partition, /usr can be mounted as read-only. In the /etc/fstab file:

    /usr ext3 ro 1 2

    If you need to allow write access (to install a program):

    [root@rivendale /]# mount -o remount,rw /usr

    Then after installation, change it back to read only:

    [root@rivendale /]# mount -o remount,ro /usr

    Additional Software Installation

    As we mentioned earlier there are several packages we want to install to perform additional hardeningof the system: tcp wrappers, libsafe, chkroot, and tripwire.

    TCP Wrappers

    We will configure TCP Wrapper to control the authentication of the ssh daemon. Two files will be used(/etc/host.allow and /etc/hosts.deny). The hosts.deny file will by default deny everyone, and thehosts.allow file will only allow those to whom we wish to grant access.

    Make sure you have TCP Wrapper

    [root@rivendale /]# rpm -qa | grep wrappertcp_wrappers-7.6-38[root@rivendale /]#

  • 8/14/2019 MySQL Magazine - Issue 1

    23/24

    Create the hosts.allow and hosts.deny files (if you dont already have them)

    [root@rivendale /]# vi /etc/hosts.deny[root@rivendale /]# vi /etc/hosts.allow[root@rivendale /]# cat /etc/hosts.allowssh: 192.168.1.101: allow[root@rivendale /]# cat /etc/hosts.deny

    ALL:ALL:

    Libsafe

    Libsafe is a interesting program that helps protect your system from what is called from stack attacks -typically called buffer overflows. A buffer overflow occurs when a memory stack is filled to capacitywhen a piece of code is executed in the stack. This causes the potential side efect of a root shell.Buffer overflows occur from either poor programming practices or weaknesses in the programminglanguage itself. Libsafe is a way for the operating system to deny buffer overflow attacks. Libsafemonitors system calls and if an attack is detected then the entire process group will be sent a SIGKILLsignal. The attempt is also logged in /var/log/secure. Libsafe is available fromhttp://www.research.avayalabs.com/project/libsafe.

    Chkrootkit

    The chkrootkit script is a tool that checks for various trojans on your system. The homepage ishttp://www.chkrootkit.org. Chkrootkit is available as a tarball..but since it is just a shell script it is notdifficult to install. Just download it and unzip it somewhere (/usr/local maybe?). Have it executed on aregular basis using the crontab utility.

    Tripwire

    Tripwire is a very good program that builds a database of the size of your system files and then you

    periodically run tripwire to compare your current system files against the database. It is important tocreate a baseline of your system files as soon as you do the installation and preferably before you areplugged into the public Internet. The "official" homepage of tripwire is http://www.tripwiresecurity.com.This page is about the enterprise version of tripwire however. Google tripwire if you need additionalinformation.

    Conclusion

    What have we learned from this exercise? We have reduced the number of services running on aserver with a minimal install of packages. In addition we have added several very useful programs tohelp keep tabs on your systems security. You have applied both the principles of seperation and

    defense in depth. Do not fall into the trap of thinking that just because you hardened your server tobegin with that you are safe. An important aspect of security is staying vigilant and monitoring yoursystem(s).

    About the author

    Keith Murphy is the editor of MySQL Magazine. He is also the chief Dolphin at Broadwick Corporation.

  • 8/14/2019 MySQL Magazine - Issue 1

    24/24

    log-bin

    So what is this all about? I decided to start MySQL Magazine because I see a need for the magazine.The worlds number one open-source database has over 10 million installations. While there arestacks of books available, and numerous resources available online there are no magazines availableabout MySQL. Sure there is the occassional article about MySQL in the various Linux magazines or

    Sys Admin Magazine but I want something that is only about my passion - MySQL.

    I have been involved in Unix in general and Linux specifically for quite a while. The first time I bootedup a Sun workstation was in 1992 or 1993. Back then Sun used the SunOS which was BSD-Unixbased. I moved into using Linux in 1997 with some version of Slackware. When I started an ISP in1998 I began using RedHat and MySQL.

    Previously I had worked as a DBA on an Oracle system running on HP-UX. Contrast this with runningMySQL on commodity PC hardware and as a DBA you can see the possibilities of MySQL even at thefairly immature growth stage that was version three. Sure, many of the features of Oracle were not inplace. Even so it was solid, very quick and absolutely free.

    Over the years I have watched MySQL grow and mature. More and more big companies have startedutilizing it. Now with the birth of Web 2.0, there is an absolute need for full featured databases thatcan scale with the growth of the website and deliver billions of queries a month. Livejournal, YouTube,Google, Kaneva and Flikr are a few of the large sites powered on the backend by MySQL. Why isthis? The maturity of MySQL has allowed these companies to scale very quickly. The cost-effectiveness is obviously a factor but it really boils down to the fact that MySQL enables thesecompanies to provide a better experience to the end user. And with the maturing of the clusteringcapabilities in version 5.x there is a whole new level we can take MySQL. While there are commericialRDMS that provide for clustering the costs are astronomical. I would suggest that if you are a MySQLDBA, or you are aspiring to be one, you invest in the hardware needed to run Xen well - any 64-bit

    processor with hardware virtualization support and a few gigs of RAM. Then load it up with CentOS 5and create some virtual servers running version 5.1.x of MySQL. Work with clustering. Experiment,play, above all have fun!

    I am looking forward to this project. It is my way of giving back to the FOSS community. Also, I wantto hear back from the community about your thoughts too!

    Thanks,

    Keith Murphy ([email protected])