Securing a simple Linux server that holds a MySQL database? - linux

A beginner question, but I've looked through many questions on this site and haven't found a simple, straightforward answer:
I'm setting up a Linux server running Ubuntu to store a MySQL database.
It's important this server is secure as possible, as far as I'm aware my main concerns should be incoming DoS/DDoS attacks and unauthorized access to the server itself.
The database server only receives incoming data from one specific IP (101.432.XX.XX), on port 3000. I only want this server to be able to receive incoming requests from this IP, as well as prevent the server from making any outgoing requests.
I'd like to know:
What is the best way to prevent my database server from making outgoing requests and receiving incoming requests solely from 101.432.XX.XX? Would closing all ports ex. 3000 be helpful in achieving this?
Are there any other additions to the linux environment that can boost security?
I've taken very basic steps to secure my phpmyadmin portal (linked to the MySQL database), such as restricting access to solely my personal IP address.
To access the database server requires the SSH key (which itself is password protected).

A famous man once said "security is a process, not a product."
So you have a db server that should ONLY listen to one other server for db connections and you have the specific IP for that one other server. There are several layers of restriction you can put in place to accomplish this
1) Firewall
If your MySQL server is fortunate enough to be behind a firewall, you should be able to block out all connections by default and allow only certain connections on certain ports. I'm not sure how you've set up your db server, or whether the other server that wants to access it is on the same LAN or not or whether both machines are just virtual machines. It all depends on where your server is running and what kind of firewall you have, if any.
I often set up servers on Amazon Web Services. They offer security groups that allow you to block all ports by default and then allow access on specific ports from specific IP blocks using CIDR notation. I.e., you grant access in port/IP combination pairs. To let your one server get through, you might allow access on port 3000 to IP address 101.432.xx.xx.
The details will vary depending on your architecture and service provider.
2) IPTables
Linux machines can run a local firewall (i.e., a process that runs on each of your servers itself) called iptables. This is some powerful stuff and it's easy to lock yourself out. There's a brief post here on SO but you have to be careful. It's easy to lock yourself out of your server using IPtables.Keep in mind that you need to permit access on port 22 for all of your servers so that you can login to them. If you can't connect on port 22, you'll never be able to login using ssh again. I always try to take a snapshot of a machine before tinkering with iptables lest I permanently lock myself out.
There is a bit of info here about iptables and MySQL also.
3) MySQL cnf file
MySQL has some configuration options that can limit any db connections to localhost only - i.e., you can prevent any remote machines from connecting. I don't know offhand if any of these options can limit the remote machines by IP address, but it's worth a look.
4) MySQL access control via GRANT, etc.
MySQL allows you very fine-grained control over who can access what in your system. Ideally, you would grant access to information or functions only on a need-to-know basis. In practice, this can be a hassle, but if security is what you want, you'll go the extra mile.
To answer your questions:
1) YES, you should definitely try and limit access to your DB server's MySQL port 3000 -- and also port 22 which is what you use to connect via SSH.
2) Aside from ones mentioned above, your limiting of PHPMyAdmin to only your IP address sounds really smart -- but make sure you don't lock yourself out accidentally. I would also strongly suggest that you disable password access for ssh connections, forcing the use of key-pairs instead.You can find lots of examples on google.

What is the best way to prevent my database server from making outgoing requests and receiving incoming requests solely from 101.432.XX.XX? Would closing all ports ex. 3000 be helpful in achieving this?
If you don't have access to a separate firewall, I would use ip tables. There are a number of managers available for you on this. So yes. Remember that if you are using IPtables, make sure you have a way of accessing the server via OOB (short for out of band, which means accessing it in such a way that if you make a mistake in IP tables, you can still access it via console/remote hands/IPMI, etc)
Next up, when creating users, you should only allow that subnet range plus user/pass authentication.
Are there any other additions to the linux environment that can boost security? I've taken very basic steps to secure my phpmyadmin portal (linked to the MySQL database), such as restricting access to solely my personal IP address.
Ubuntu ships with something called AppArmor. I would investigate that. That can be helpful to prevent some shenanigans. An alternative is SELinux.
Further, take more steps with phpmyadmin. That is your weakest link in the security tool chain we are building.
To access the database server requires the SSH key (which itself is password protected).
If security is a concern, I would NOT use SSH key style access. Instead, I would use MySQLs native support for SSL certificate authentication. Here is now to configure it with phpmyadmin.

Related

How can I get file from FTP server?

I have found the security hole in website. I can to sign in throught anonymous account so I signed in. So I am trying get index.html from website and I receive following message: Illegal PORT command.
Use port or pasv mode.
How can I get this file then edit and next upload modifited file again?
if you're administering an FTP server, it would be best for you to configure your server to support passive mode FTP. However, you should bear in mind that in doing so, you would be making your system more vulnerable to attacks. Remember that, in passive mode, clients are supposed to connect to random server ports.
Thus, to support this mode, not only should your server have to have multiple ports available, your firewall should also allow connections to all those ports to pass through!
But then the more open ports you have, the more there will be to exploit. To mitigate the risks, a good solution would be to specify a range of ports on your server and then to allow only that range of ports on your firewall.

Can browser / Anti-virus software block requests made to direct IP addresses instead of domain name?

I have few APIs implemented on one remote node server and I want to make requests to that server through my web page, but is it the case that browser / anti-virus s/w will consider requests made to direct IP address as dangerous and might block them entirely ?
Is it necessary to assign a domain name to that remote node server ?.
Whilst I don't think an antivirus would stop a program making requests to a server simply because the request was made out to an IP address, this is generally not the best practise. You should use a domain name, or subdomain for your server. This helps identify the server and in the case that the IP address of the server should change, the application does not need to be updated because DNS will do the bulk of the work next time the application attempts a connection.
TLDR: It will work, but it's not a good idea.
They can and they do. In the end of 2017 when several webminers such as coinhive become popular some anti-viruses started to block the websockets connections directly, even if the miner tries to connect using only the ip address.
It's not necessary to assign a domain name to your server, but you won't bypass anti-viruses that way.

NodeJS - securely connect to external redis server

On my main server, I fetch data from an external/seperate redis server which is accessed through an api https://localhost:7000/api/?token=**** which works. However token and api is not secure. And since I want to have redis server to be separate, this technique isn't suited for my case.
In my case I want to have 2 independent servers A and B.
A should load data from B without using an api or url call... Instead it should use port (e.g. //server:123). This way server B can only be accessed from A.
I want this approach to work for both development and production. AWS has "Server Groups" I believe, but that's production only...
So is there a way to create this kind of connection with nodejs? I also want to know if this is only possible having a running server already, since I don't have one yet.
Note: In case you are wondering, I use redis to store private keys for encryption, so I need a secure, separate server which can be controlled independently
It is not very clear what you're trying to do since accessing data from another server without using an API does not really make sense. Anything you do to access it is some type of API.
If you want to make it so that only server A can access server B, then you have a number of choices to make that secure:
Require authentication whenever server B is accessed and make it so that only server A has those authentication credentials.
Assuming server A and server B are in your same server infrastructure, put the server B API on a port that is not available to the outside world, but is only available from within your server infrastructure (this usually involves picking a port that your firewall to the outside is blocking access to).
On server A, only accept connections on its API from the specific IP address of server B.
You can even implement more than one of these options at once. For example, it's not uncommon to use 1) and 2) together.
Stunnel is built for that ! basically speaking it's a vpn ! but not for machines for ports ! it's a bit complicated , you will have to deal with certificates and a couple of other things (config both servers...) but once it's done it's a breeze to launch and reuse (just launch a file) give it a try !
and see this link : https://www.digitalocean.com/community/tutorials/how-to-set-up-an-ssl-tunnel-using-stunnel-on-ubuntu
you should also consider adding an ip table rule at the database server to allow access to your server only.
Edit:
Keep in mind that redis was designed to be used in a trusted environment . This means that the security layer will not be redis itself but a third party software that u'll need to setup.
For dev purpose no need to make this bulletproof. And even if you want to , it's kinda hard to do . because the security of your app is mainly depending on the infrastructure of the company that will host your app.
That being said , if you want to secure a redis instance in a localhost environment . a rule at the ip table allowing only the localhost to access your port 6379 will be suffcient.
The other thing that could compromise the security of your redis DB is the app itself . An important aspect of this is to validate EVERYTHING , it should be a good start.
Finally if you want to dive a bit deeper take a look at this link
https://www.digitalocean.com/community/tutorials/how-to-secure-your-redis-installation-on-ubuntu-14-04
hope this helps !

Understanding Openstack noVNC security

I'm trying to get a deeper understanding of the architecture and design of Openstack noVNC security. I found this document. It makes sense but missing details. Can somebody confirm my understanding is right, or correct me if I'm wrong.
0) noVNC allows VNC clients in web browsers, good for clients without java or vnc client installed.
1) VNC server is provided by the hypervisor, Every VM has its own VNC server, at port 59xx, not accessible from outside.
2) Websocket proxy bridges to VNC server and provide service for noVNC client (javascript in browser), say at port 6080.
3) Simple security: Security could alternatively be guaranteed by VNC password, but it's not convenient to type every time and not easy to change. Every VM on the same hypervisor has to share the same password. Different compute nodes may use different VNC passwords.
4) To provide better access control, consoleauth is introduced. We can now use Openstack authentication for VNC. When a new request for remote console comes, a dynamic access URL (with a token) is generated, cached/registered, and sent back to client. Later, only previously registered connections are accepted.
I would like to know more about whether/how dynamic firewall rules are created, and whether/when the tokens are invalidated. I know the best way is to read the source code, but a high level description is also valuable. Thanks.

Should a web server's firewall block outbound HTTP traffic over port 80?

I understand the need for putting a web server in a DMZ and blocking inbound traffic to all ports except 80 and 443. I can also see why you should probably also block most outbound traffic in case the server is compromised.
But is it necessary to block outbound HTTP traffic over port 80? If so, why? A lot of web applications these days rely on sending/retrieving data from external web services and APIs, so blocking outbound traffic over port 80 would prevent this capability. Is there a security concern that's valid enough to justify this?
The only reason I can think of is if your machine is somehow compromomised remotely then it won't be able to DDoS another website on port 80. It's not something I normally do though.
Rather then blocking it, throttle it. Use iptables -m limit.
I have several web apps that invoke external web services, so I would say it's a bad idea to block output HTTP traffic. If you're concerned with security, you could block it and allow for only certain destinations.
Depending on your SQL version, you could have certificate authentication time out issues with SQL server 2005.
First - I agree with #vartec on throttling "Rather then blocking it, throttle it. Use iptables -m limit" as at least part of the solution.
However I can offer another reason to not block port 80 outbound at all times. If you have automatic security updates turned on the server can't reach out to PPAs over port 80 to initiate a security update. Thus if you have automatic security updates set up they won't run. On ubuntu auto-security updates are turned on in 14.04 LTS with:
sudo apt-get install unattended-upgrades update-notifier-common && \
sudo dpkg-reconfigure -plow unattended-upgrades
(then select "YES")
More graceful solutions would be ansible scripts opening the port automatically, possibly also modifying an AWS security group rule via the CLI in addition to iptables if you are at AWS. I prefer modifying my outbound rules temporarily via AWS CLI initiated by a stealth box. This forces logging the update up in my AWS S3 log buckets but never shows up in the logs on the server itself. Further the server that initiates the update doesn't even have to be in the private subnet ACL.
Maybe do both? You have to figure at times an attack is going to relay off an internal IP in your subnet so there is merit to doubling down while preserving the ability to automate backups and security updates.
I hope this helps. If not reply and provide more code examples to be more specific and exact. #staysafe !
If the machine is compromised and outbound traffic on port 80 is allowed, it would make it easier for intruders to send back harvested data to themselves. Allowing outbound traffic means you can initiate a connection from your machine to the outside world. A better approach would be allowing outbound traffic only to certain web sites/addresses that you trust (i.e. Microsoft Windows Update, Google reCAPTCHA) rather than any destination in the world.
what do you mean with blocking outbound traffic over port 80.
You have two possibilities. Gernerate Dynamic Rules which allow communication from client to your webserver for this session. Search for Stateful firewall rules.
Or you generally allow established Connections to communicate in and outgoing with each other.
If you generally block all outbound traffic over Port 80 your Webserver could not reply to any client.
The other way around, if your Webserver needs to get some API, e.g. a jquery library he wont use port 80 as his Port to communicate with the Webserver who holds the API.
Your Webserver would normally choose a port > 1024 and use it for his request to get the API from the remote Server.
So blocking all traffic over port 80 (as your port you connecting from) would not prevent your Server from sending any requests for apis and such things. because he doesnt use port 80 when he acts as a client.

Resources