[MySQL] Can't restrict external access to database inside a Jail

First time playing with Jails.

I essentially want to limit the mysql to only accept connections from within the jail (and if I can get this to work, then extend to allow only connections from my webserver jail).

I have tried setting bind-address to both 127.0.0.1 & 192.168.0.3. To my knowledge there is nothing traditional about the mysql configuration that is stopping this. It is a fresh install. Can post my install steps if that is required.

Unsure how to proceed. I am still able to access from the host:

Code:
(host)$ mysql -u root -h 192.168.0.3 -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.

(Yes, I have restarted the mysql service after editing my.cnf).

Relevant configuration (let me know what else is required).

/etc/rc.conf:

Code:
sshd_enable="YES"

# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
dumpdev="NO"

hostname="REDACTED"
fstabcheckdisks_enable="YES"

ifconfig_vmx0="inet REDACTED IP netmask 255.255.255.0"
defaultrouter="REDACTED IP"

ifconfig_vmx1_alias0="inet 172.16.0.1 netmask 255.255.255.0"

jail_enable="YES"
jail_list="db www"
jail_reverse_stop="YES"

# jails shenanigans
cloned_interfaces="lo1"
ipv4_addrs_lo1="192.168.0.1-3/29"

pf_enable="YES"

clear_tmp_enable="YES"
clear_tmp_X="YES"

/usr/jail/db/etc/rc.conf:
Code:
# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
dumpdev="NO"
mysql_enable="YES"

/etc/pf.conf:
Code:
 # Public IP Address
PUB_IP = "REDACTED"
PUB_IN = "vmx0"

# Packet normalization
scrub in all

# Allow outbound connections from within the jails
nat on vmx0 from lo1:network to any -> (vmx0)

# www jail at 192.168.0.2
rdr on $PUB_IN proto tcp from any to $PUB_IP port 80 -> 192.168.0.2
rdr on $PUB_IN proto tcp from any to $PUB_IP port 443 -> 192.168.0.2

# mysql jail at 192.168.0.3
#rdr on $PUB_IN proto tcp from any to $PUB_IP port 3306 -> 192.168.0.3

/etc/jail.conf:

Code:
    $j = "/usr/jail";
    path = "$j/${name}";

    ## Default configuration

    mount.devfs;    # for access to devfs
    host.hostname = "${name}.jail"; # expands to `www.jail`

    exec.clean;
    exec.start = "/bin/sh /etc/rc";
    exec.stop = "/bin/sh /etc/rc.shutdown";

    db
    {
        ip4.addr = 192.168.0.2;
    }

    www
    {
        ip4.addr = 192.168.0.3;
    }

/usr/jail/db/usr/local/etc/mysql/my.cnf:

Code:
    [client-server]
    bind-address = 192.168.0.3
 
I am still able to access from the host
Yes, the host has direct access to that IP address, what did you expect would happen? Suppose you installed MySQL on a (separate) host on your network, don't you think anyone on that network would be able to access it?
 
Yes, the host has direct access to that IP address, what did you expect would happen? Suppose you installed MySQL on a host on your network, don't you think anyone on that network will be able to access it?
Yes, but is there anyway to limit this action from MySQLs perspective? Obviously the host can view the Jail, but surely - at a networking level - MySQL can distinguish?
 
127.0.0.1 is the loopback address of the host. of course it has access to it.
same goes for the vxm0 interface - the jail is merely using an alias address, but the interface is accessible to the host via the primary address.

You could either run vnic enabled jails to give them their own network stack, or just create another loopback (lo1) interface and use that for local jail traffic. Make sure to use another subnet (e.g. 127.1.0.0/24) or you will get strange errors when you try to access jails from the host and use the same subnet as on lo0.

I'm using that second approach on several hosts (especially with a single public address) and just forward traffic via PF rules to the appropriate jails if necessary.
 
Yes, but is there anyway to limit this action from MySQLs perspective?
You limit the host or network on the account in MySQL.


For example:
Code:
root@localhost [(none)]> select user,host from mysql.user;
+------------------+----------------------------+
| User             | Host                       |
+------------------+----------------------------+
| zabbix           | 192.168.11.0/255.255.255.0 |
| phabricator_user | 192.168.11.205             |
| mariadb.sys      | localhost                  |
| mysql            | localhost                  |
| root             | localhost                  |
| phabricator_user | phab.dicelan.home          |
| semaphore        | riviera.dicelan.home       |
+------------------+----------------------------+
The zabbix user is only allowed to login from a 192.168.11.0/24 address. The semaphore account is only allowed to login from a host named riviera.dicelan.home. That's how you limit access.

In your case you probably want to limit the account that's used for the web application to only come from the webserver's IP address or hostname. So you get something like:
Code:
| mywebapp_user | 192.168.0.3 |
| mywebapp_user | www.jail    |


Edit: Moved the thread to "Web and Network Services" because this has more to do with MySQL and web applications themselves than jails.
 
The above post is sound logic - First, tell the server itself what connections to accept, then the firewall, and then the jail. Asking the jail and / or firewall to do application-based filtering is asking for trouble. I see enterprise admins make that mistake, too. So, OP needs to pay attention to SirDice 's post, it's sound logic and good information.
 
Back
Top