On a Linux-based server, I follow basic practices as below:


Make the admin account password long and complicated enough (i.e. theoretically speaking, password cannot be cracked within reasonable time).
Monitor all incoming network traffic to the administrative files.
To extend the layer of protection from #2 above, monitor local file changes (especially ones that have commands that require sudo privileges).
Validate all user input, so that all of the user input is guaranteed to be safe.


As a novice developer, I don't understand how a hacking is even feasible if the server admin practices the above.

Not making sure all security updates are applied? Remember, as the defender, you must win 100% of the time. A hacker only needs to win once.

The steps you listed are also a lot easier said than done (except the password thing... and yet people still choose horrible passwords!).

2) Also, what's a "credible source" for a public facing web server? The entire Internet? The entire Internet, sans China/Russia (/some/other/countries)? Automated systems can detect many types of attacks, but just like antivirus they can only go so far. 

3) Monitoring local files is good, but, again, it's not a panacea. What if the attacker manages to inject code into the web server, and then uses a kernel bug to get code into the kernel... without ever writing a file to the disk? At that point, they could write files to the disk, and use a root kit to prevent most (theoretically all) online scans from noticing any changes to the system.

And even if they only manage to exploit the web server, they can do everything the web server can do (which might be all the attacker was interested in anyways).

4) You should always validate user input. Most developers know this (and many try to do it). Sadly, it's much easier said than done, which is why we continue to see issue after issue where user input isn't appropriately validated. You'll never be able to guarantee any real piece of software is correctly validating all user input. Read some PHP+MySQL questions on StackOverflow to see how many people think mysqli_real_escape_string() prevents all SQL injection attacks ("where ID = " . $val is vulnerable, even when $val is the output of mysqli_real_escape_string!).

Even if you could (you can't) ensure every known attack vector was guarded against, you can't do anything more than wildly swinging in the dark against and unknown-unknown (well, continually educating yourself helps).

As an example where your defenses wouldn't have done anything, I was taking part in a security course where we're doing "war games". I was able to root an opposing team's server by being able to get one of their user passwords off another machine (one of them screwed up and typed it into bash as a command by mistake, and they never thought to delete it from .bash_history). 

From there, I spoofed the IP of the machine they usually logged in from, and SSHed in, inputting their username + password. I had limited access to the system. I then ran sudo vim, entered the same password again, and had vim spawn a bash shell. Tada! Root access, from a credible source, without modifying any local files in an unusual way, without exploiting a weak password (it was bad, but even the best password in the world wouldn't have helped), nor relying on unvalidated user input.

At that point, being mischievous me, I manually modified all the log files related to my legitimate login, and obliterated their IDS (I'm betting they won't be observant enough to notice I replaced all of its binaries with copies of /bin/true!). A 'real' hacker would likely be far better equipped to ensure their activity wasn't detected by more vigilant admins, but I'd already accomplished my goal, and a small part of me wanted them to find out that someone got it. 
