Here is a summary of some basic guidelines when running a LAMR (linux, apache, mysql, ruby) server, to make your server more secure.
Disable root account
To disable root access, run the following command:
sudo passwd -l root
User password strength
Having a strong password is recommend to avoid dictionary attacks.
Always set a long random generated password.
Avoid using dictionary word and passwords related to your personal life.
Use ssh keys
Allow access only using ssh keys and from trusted hosts, since passwords are more easily broken. To do so, you must add your public key to the
from="trusted_host" ssh-rsa encrypted_key Comment describing key
Secure your ssh server
To secure your ssh server you must do some changes in the sshd_config
- Do not allow root login
- Change the listen port
- Allow only certain users to have access via ssh
AllowUsers username ref username@email
- Disable the protocol version 1
- Add a banner to users connecting to the ssh server (legal protection)
- Don't allow password authentication
- Disable unused authentication modules (even if disabled by default)
- Restrict access to file transfer
Keep your system and packages updated
Once a vulnerability is found, software updates are released to fix it. Old software versions may have a lot of well known vulnerabilities well-known to the hacker community.
Run the minimum number of services required and install the minimum amount of software required
More software means more vulnerabilities possibilities, so keep your software to a minimum necessary.
Don't install C compilers and other development utilities in your production server
Development tools may help an attacker compromise the system even further, allowing him to do privilege escalation.
Always run daemons under a new user and group
An attack to a software running as a certain user (nobody e.g.) may compromise other software running as this same user.
Also, remove shell access for these users.
Hide the apache version and other sensitive information
Attackers can use this information to exploit this version vulnerabilities.
It is also an indicator that you left most defaults alone.
Change your apache configuration file to be set like this:
ServerTokens Prod ServerSignature Off TraceEnable Off
Run using its own user and group
Make sure apache is running as its own user (sometimes it runs as nobody).
Files outside the web root directory should not be served
Turn off file browsing
This can be achieved setting:
Turn off server side includes
SSI-enabled files can execute any CGI script or program under the permissions of the apache user, using the exec cmd element. Thus, this is a security risk.
Turn off support for .htaccess files
htaccess files override the default configuration of your apache folder. To avoid this, you need to set your configuration ass follows:
Disable unused modules
The more modules you have enabled, greater the chance you have a security vulnerability.
Don't allow apache to follow symbolic links
Following symlinks makes your apache serve files outside your root directory.
To avoid this, set the following in your config file:
Restrict access to the user table
Multiple applications should access the mysql server with different users
Grant only the necessary privileges to your application user in database
Secure root account with a strong password
Do not use plain text passwords in the database
Secure access to mysql port from untrusted hosts
Always escape SQL statement inputs in your application code
SSL provides a secure connection, where the data is encrypted. This helps avoiding session hijacks through cookie sniffing.
Expire sessions on inactivity
Sessions that never expire are a danger that can lead to attacks (CSRF, session hijacking e.g.). Expiring session leave a smaller time-frame in which attacks can happen
Reset session on every successful login
This way you can avoid session fixation attacks (attacker using a fixed session identifier to access an user session)
Use protect_from_forgery when possible
protect_from_forgery adds a security token as hidden input in your forms, that helps prevent CSRF attacks.
Do not allow user to supply parts of the URL to be redirected to
Allowing users to provide parts of the URL, can redirect someone to a complete different site (sometimes looking like yours, as in fishing attacks).
Use ip restriction to access admin interface
You usually won't need your admin interface open to all the world, so restricting access by ip address would narrow the range of attacks to your admin pages.
Use separated credentials to admin login
Having a separated admin credential can prevent a user to achieve privilege escalation changing some parameters of his profile.
Use attr_protected in sensitive model information
Mass assignment allows users to change any column related to the model being edited/created.
If you have any sensitive model information in a column, you should use attr_protected method to avoid mass assignment of this attribute.
But as in any security guideline, it is preferable to use whitelist rather than blacklist, so it's better to use attr_accessible.
Use captcha after some failed login attempts
Using captcha after some unsuccessful login attempts helps preventing brute force attacks to access an user account.
Be careful not to log sensitive information
Be careful not to log stuff like passwords, credit card numbers and other sensitive informations. Log filter_parameters helps you with that, but it is not 100% efficient, so be aware of what you are logging.
Design your controllers restricting resources access
If some resources belongs to an user only, design your controllers according to it, avoiding users to access other users resources simply by changing the url.
1 2 3 4
# wrong @project = Project.find(params[:id]) # right @project = @current_user.projects.find(params[:id])
Escape all inputs (specially client ones)
Never trust inputs in your system, always escape then.
- To avoid SQL injection use placeholders
Project.where(["name in (?)", names])
- To avoid command injection use methods with sanity check
system("/bin/echo","hello; rm *")
- To avoid Header Injection don't let users inputs to set parts of a header.
Run your daemons with a new user and group
As told before, you should avoid running multiple softwares under the same user.
There is a lot to improve yet, but I hope this small guideline is useful to you guys. Feel free to ask any questions.