Linux: Iptables Allow MYSQL server incoming request on port 3306

MySQL database is a popular for web applications and acts as the database component of the LAMP, MAMP, and WAMP platforms. Its popularity as a web application is closely tied to the popularity of PHP, which is often combined with MySQL. MySQL is open source database server and by default it listen on TCP port 3306. In this tutorial you will learn how to open TCP port # 3306 using iptables command line tool on Linux operating system.

Task: Open port 3306

In most cases following simple rule opens TCP port 3306:

iptables -A INPUT -i eth0 -p tcp -m tcp --dport 3306 -j ACCEPT

The following iptable rules allows incoming client request (open port 3306) for server IP address Add rules to your iptables shell script:

iptables -A INPUT -p tcp -s 0/0 --sport 1024:65535 -d --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp -s --sport 3306 -d 0/0 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT

However in real life you do not wish give access to everyone. For example in a web hosting company, you need to gives access to MySQL database server from web server only. Following example allows MySQL database server access ( from Apache web server ( only:

iptables -A INPUT -p tcp -s --sport 1024:65535 -d --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp -s --sport 3306 -d --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT

Please note if you follow above setup, then you need tell all your hosting customer to use as MySQL host in PHP/Perl code. A better approach is to create following entry in /etc/hosts file or use fully qualified domain name (create dns entry) which points to ip: mysql

In shot MySQL database connection code from PHP hosted on our separate webserver would look like as follows:

// ** MySQL settings ** //
define('DB_NAME', 'YOUR-DATABASE-NAME');     // The name of the database
define('DB_USER', 'YOUR-USER-NAME');     // Your MySQL username
define('DB_PASSWORD', 'YOUR-PASSWORD''); // ...and password
define('DB_HOST', 'mysql');       // mysql i.e.
// ** rest of PHP code ** //

Task: Allow outgoing MySQL request on TCP port 3306

Even you can allow outgoing MySql client request (made via mysql command line client or perl/php script), from firewall host as follows:

iptables -A OUTPUT -p tcp -s --sport 1024:65535 -d 0/0 --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -s 0/0 --sport 3306 -d --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT

A note about Ubuntu Linux users

The Linux kernel in Ubuntu provides a packet filtering system using netfilter, and the traditional interface for manipulating netfilter are the iptables suite of commands. But, it comes with easy to use ufw (Uncomplicated Firewall) tool. To open port 3306, enter:

sudo ufw allow 3306
## only allow subnet to connect to our mysql server ##
sudo ufw allow from to any port 3306

For more information read man page of iptables command:
$ man iptables

🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 14 comments so far... add one
CategoryList of Unix and Linux commands
Disk space analyzersncdu pydf
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network UtilitiesNetHogs dig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
14 comments… add one
  • samsonasik Jul 3, 2009 @ 17:03

    thanks for your post, my problem solved.

  • leila Aug 6, 2010 @ 20:08

    thanks it’s a great text, but when i tested the “iptables -A INPUT -i eth0 -p tcp -m tcp –dport 3306 -j ACCEPT” ,this error had appeared :
    iptables v1.4.4: can’t initialize iptables table `filter’: permission denied(you must be root)

    while i’m root, what can i do with it ?

    • FTW Apr 19, 2016 @ 14:15

      use sudo like this:
      sudo iptables -A INPUT -i eth0 -p tcp -m tcp –dport 3306 -j ACCEPT

  • cjk Sep 21, 2010 @ 18:07

    Your commands apply only to a very strict subset of possible iptables configurations. This advice is therefore practically useless.
    Also you should be using -m conntrack –ctstate ..

  • vishal borade Jul 22, 2011 @ 11:46

    # sudo iptables -A INPUT -i eth0 -p tcp -m tcp –dport 3306 -j ACCEPT

  • SIva Oct 11, 2011 @ 12:24

    Im using centos 6 and executed the 1’st line code given by you…and I still have issue.

    Error : Unable to connect to any of the specified hosts.

    When i disable Iptables I’m able to connect…What would be the issue and what needs to be done

  • Phoz Jan 8, 2013 @ 14:25

    Flushing the existing rules solved it for me:
    iptables -F

    • Charlie Mar 17, 2014 @ 14:15

      Don’t use the -F command, this deletes all the rules. The other comment should be deleted.

  • Danny Feb 5, 2013 @ 18:29

    If you use the -F argument, you’ll delete your firewall rules.

    man shows this…
    -F, –flush [chain]
    Flush the selected chain (all the chains in the table if none is given). This is equivalent to deleting all the rules one by one.

  • bunga Apr 24, 2013 @ 8:30

    nice tutor..but i can not connect to my remote centos server, using navicat on my pc.
    the server port has been opened.

  • Chadwick Dec 13, 2014 @ 8:08

    Pleas help. I can’t connect my mysql remotely but only from console.
    I checked skip-networking is off. MYSQLD is running my port 3306. I’ve flush the iptables by -F
    and restarted the mysqld many times. Still the netstat shows me 3306 is still not being listening. (but I can see tcp6).

    Please kindly advise.

    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
    tcp 0 0* LISTEN 2873/master
    tcp 0 0* LISTEN 1588/sshd
    tcp6 0 0 ::1:25 :::* LISTEN 2873/master
    tcp6 0 0 :::3306 :::* LISTEN 29817/mysqld
    tcp6 0 0 :::22 :::* LISTEN 1588/sshd


  • Ravindra Nov 20, 2015 @ 18:24

    Thanks for the detailed steps. Just one correction in one of the commands in section “Task: Open port 3306” – third command in this section has a missing space between OUTPUT and -p, and thus it fails on execution:

    iptables -A OUTPUT-p tcp -s --sport 3306 -d 0/0 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT


  • Hendrik Nov 26, 2015 @ 23:11

    I am trying to apply these rules but I have an error.
    I did this command:
    iptables -A INPUT -p tcp -s [ip address apache server] --sport 1024:65535 -d [ip address mysql server] --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
    I got the error
    iptables v1.4.14: host/network `*.*.*.*’ not found
    I tried it other way around also but I got the same kind of error.

    And just to be sure:
    if my apache ip address would be and my mysql ip address, which would be the source and which would be the destination? And do I have to add the rules to both servers?

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum