Two methods
1)
Configure a specific .htaccess file for the sub domain to only allow specified IPs and/or a specified small IP range. Here's an old example of two .htaccess rules:
<Limit GET HEAD>
order allow,deny
allow from all
deny from xxx.xxx.xxx.xxx/xx
</Limit>
That's basically saying allow anyone to read, except for specified IP or IP range/mask. I wouldn't throw lots of them in here, but it might be handy if you constantly get some crawling site coming at your database. This presumes that your database should be read by all via the top domain. Not 100% certain this example is necessary, as I haven't done a DB on a sub-domain.
Example 2:
<Limit POST PUT DELETE OPTIONS CONNECT TRACK DEBUG>
order deny,allow
deny from all
allow from xxx.xxx.xxx.xxx
</Limit>
That basically prevents all, but specified IPs from having anything but read-only access.
Locate the .htaccess file in the sub-domain's top folder.
Method 2)
IP Tables
Old example:
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-I INPUT 4 -p tcp --dport 80 -m string --string "w00tw00t" --algo bm -j DROP
-A INPUT -s xxx.xxx.xxx.xxx -p tcp -m tcp --dport 22 -m comment --comment "Allow SSH from xxx.xxx.xxx.xxx" -j ACCEPT
-A INPUT -s 0.0.0.0/0 -p tcp -m tcp --dport 80 -m comment --comment "Allow HTTP from anywhere" -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
COMMIT
I'm very rusty on this, and it's maybe not the best option. The syntax gets a little confusing.
What I do suggest is that you pick two guinea pig users to test this on, so you can establish if one is blocked and one allowed, but don't add your own IP to the blocking end of things. Block a user, and allow all others to start with. You don't want to lock yourself out.
Personally, I'd use method 1, and have something like:
<Limit POST PUT>
Order Deny,Allow
Deny from all
Allow from [top domain IP if different]
Allow from [remote IP 1]
Allow from [remote IP 2]
Allow from [remote IP 3]
Allow from [remote IP etc.]
Allow from [remote IP range etc.]
Allow from 127.0.0.1
Allow from ::1 (ipv6 version of 127.0.0.1)
</Limit>
I played about with my server's foibles, and ended up with a more robuest version of the LIMIT range:
<Limit POST PUT DELETE OPTIONS CONNECT TRACK DEBUG>
It was probably overkill, but meh, why not. If you're unsure of IP ranges or masks, there's plenty of stuff out there, if you search. Also appreciate that the allow/deny order is very important. If you allow/deny, that's a blacklist setup, while if you deny/allow that's a whitelist setup (preferred in this scenario).