Security is a process, not a state. On the plus side, a lot of stuff from my earlier documentation on this has become the default in Wheezy. It is certainly made easier by not being the only one doing it.
Not all of this is strictly 'security', per se, at least from a 'keep bad people from doing bad things to you' perspective. Some elements are more about ensuring a smoother-running system.
# <file system> <mount point> <type> <options> <dump> <pass> # / was on /dev/sda3 during installation UUID=longstringissomewhatlongbutnotverylong / ext4 discard,noatime,errors=remount-ro 0 1 # /boot was on /dev/sda1 during installation UUID=longstringissomewhatlongbutnotverylong /boot ext4 discard,noatime 0 2 # /home was on /dev/sda2 during installation UUID=longstringissomewhatlongbutnotverylong /home ext4 discard,noatime,nodev,nosuid 0 2 # /innodb was on /dev/sdd1 during installation UUID=longstringissomewhatlongbutnotverylong /innodb ext4 noatime,nodev,nosuid,noexec 0 2 # /srv was on /dev/sdc1 during installation UUID=longstringissomewhatlongbutnotverylong /srv ext4 discard,noatime,nodev,nosuid,noexec 0 2 # /storage was on /dev/sdd2 during installation UUID=longstringissomewhatlongbutnotverylong /storage ext4 noatime,nodev,nosuid,noexec 0 2 # /var was on /dev/sdb2 during installation UUID=longstringissomewhatlongbutnotverylong /var ext4 noatime,nodev,nosuid 0 2 # swap was on /dev/sdb1 during installation UUID=longstringissomewhatlongbutnotverylong none swap sw 0 0 tmpfs /tmp tmpfs rw,noatime,nodev,nosuid,mode=1777,size=8g 0 0 tmpfs /var/tmp tmpfs rw,noatime,nodev,nosuid,mode=1777,size=8g 0 0 tmpfs /home/ptmp tmpfs rw,noatime,nodev,nosuid,mode=1777,size=8g 0 0
The main thing here is the tmpfs and nodev,nosuid for /var/tmp and /tmp. While /var/tmp is for things that 'should persist between reboots', I handle this on an application-by-application basis, such as making a /mytmp folder for MySQL.
/home/ptmp is a directory we will need to make in order to work with open_basedir in php.
mkdir /home/ptmp chmod 1777 /home/ptmp mount -t tmpfs tmpfs /home/ptmp/ -o rw,noatime,nodev,nosuid,mode=1777,size=8g
/boot is a silly thing to stick on its own partition these days, it's just habit, and can actually causes more headache than the benefit it supposedly provided. If you encrypt your root partition, you may find this to be a thing, however.
noatime goes on all the things, except the swap partition.
Speaking of swap partitions, they are still useful, but I would not make them too large. I generally set it to about 4gb, and with the configuration I have described for Wheezy, between half a gig and a gig may end up being used without impacting performance - there is a bit of room your server can squeeze out to generally make good use of the RAM inside.
nodev, nosuid is good for anything that doesn't need those abilities - / and, if you are being silly, /boot.
Be careful about throwing noexec around. Debian likes to execute some things out of /var and /tmp.
/innodb is a partition that holds nothing but InnoDB's double buffer and other logs. Since it represents half of an InnoDB database's I/O, this ends up being about 40% faster than an equivalent RAID 0 or 10 configuration.
# Since we're not using X, can enable all ttys, or alternately prep # them all and comment most out. # Each one takes up about ~160kb of RAM while idle, so not a huge # drain, and is the sort of thing swap is actually for on a server. 1:2345:respawn:/sbin/getty 38400 tty1 2:23:respawn:/sbin/getty 38400 tty2 3:23:respawn:/sbin/getty 38400 tty3 4:23:respawn:/sbin/getty 38400 tty4 5:23:respawn:/sbin/getty 38400 tty5 6:23:respawn:/sbin/getty 38400 tty6 7:23:respawn:/sbin/getty 38400 tty7 8:23:respawn:/sbin/getty 38400 tty8 9:23:respawn:/sbin/getty 38400 tty9 10:23:respawn:/sbin/getty 38400 tty10 11:23:respawn:/sbin/getty 38400 tty11 12:23:respawn:/sbin/getty 38400 tty12
# ... # You can disable ctrl+alt+del from console. Note that this might block # remote soft reboot software. # What to do when CTRL-ALT-DEL is pressed. #ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
# /etc/crontab: system-wide crontab # Your values may of course differ. I just prefer to spread them out # So they don't all hit at the same time, e.g. preventing # the monthly and weekly runs from running on the same day. # Key is to know when your user activity is the lowest, of course.
SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin MAILTO=""
55 * * * * root cd / && run-parts --report /etc/cron.hourly 25 5 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) 15 4 3,10,17,24 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly ) 15 4 2 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly ) #
# /etc/securetty: list of terminals on which root is allowed to login. # See securetty(5) and login(1). # I end up deleting the vast majority of these, leaving only the ones below.
# Virtual consoles tty1 tty2 tty3 tty4 tty5 tty6 tty7 tty8 tty9 tty10 tty11 tty12
#<domain> <type> <item> <value> # The main thing to note here are the core dumps # and mysql's memory access. The latter is a # legacy element. # * soft core 0 * hard core - * - maxlogins 3 * - memlock 2048 * - msgqueue 1048576 * - nofile 8192 * - nproc 256 * - sigpending 16384 * - stack 8192 mysql - maxlogins 0 mysql - memlock 33554432 root - maxlogins - root - memlock 33554432 root - nproc -
Read hosts first, then try a domain lookup if that fails. I am far more likely to be trying to override something when I put something in my hosts file.
order hosts,bind multi on nospoof on spoofalert on
- LOG_OK_LOGINS yes
- SULOG_FILE /var/log/sulog
- CHFN_RESTRICT frwh
- Don't ask me why I bother with this, I could not tell you : p
- SHA_CRYPT_MIN_ROUNDS 65536
- Or higher. Just remember what you are setting it to.
- Install the libpam-tmpdir package, if you have not already.
- Remove nullok_secure from the auth line
- Uncomment and add group=wheel:
- auth required pam_wheel.so group=wheel
- Make sure root is part of the wheel group as precaution
- add 'rounds=65536' to the password line:
- password [success=1 default=ignore] pam_unix.so obscure sha512 rounds=65536
- Regenerate root, administrator passwords
Directory and file Permissions
find / -perm -2000 -group 0
This should only return directories. /var/cache/man in particular.
chmod 0700 /root /lost+found chmod 0751 /etc /home /etc/ssh/ chmod 0750 /mnt /boot /etc/rsyslog.d/ /etc/cron.d/ /etc/cron.hourly/ /etc/cron.daily/ /etc/cron.weekly/ /etc/cron.monthly/ chmod 0750 /storage /innodb
Or whatever you choose your database/general directories to be. I dislike /opt and /srv, at least for things that I will be dedicating entire hard drives to (or most of them).
chgrp staff /storage
Or whatever again.
chmod 0640 /etc/crontab /etc/fstab /etc/inittab /etc/securetty /etc/ssh/sshd_config /etc/rsyslog.conf
Clear out unnecessary setuid binaries:
find / -perm -4000 -user 0
Only /bin/su is absolutely necessary.
- /sbin/pam-tmpdir-helper is needed if you are using the pam tmpdir module above
- suexec if you are still using Apache
- screen needs setuid if using in multi-user mode.
- sudo if you use that. Since this is a server, I find the idea of typing 'sudo' before a million commands highly annoying, personally. sudo is very much a thing for work/home machines, in my opinion.
- ping and ping6 are somewhat annoying to leave as non-suid, but see below.
On a default Wheezy install:
chmod u-s /usr/bin/passwd /usr/bin/chsh /usr/bin/gpasswd /usr/bin/newgrp /usr/bin/chfn /usr/lib/eject/dmcrypt-get-device /usr/lib/openssh/ssh-keysign /usr/lib/pt_chown /bin/mount /bin/umount
chmod u-s /sbin/mount.nfs
If using nfs
To let a specific group of users (staff, here) use ping and ping6
chmod 4750 /bin/ping /bin/ping6 chgrp staff /bin/ping /bin/ping6
Remove sound support
If much of the above straddles the 'security' line this probably crosses it. Still, if I hear my server that means something bad has happened.
To get sound modules:
lsmod | grep snd
Blacklist these, along with pcspkr, in a file like /etc/modprobe.d/blacklist.conf:
# /etc/modprobe.d/sound-blacklist.conf # Hear no evil. blacklist pcspkr blacklist snd_pcm blacklist snd_timer blacklist snd_page_alloc blacklist snd blacklist snd-pcsp blacklist soundcore
ninja is a nifty little package that kills things that inappropriately escalate to root. It is far from perfect, but I have tried to hone my configuration over the years.
/bin/su:wheel: /usr/bin/sudo:wheel: /usr/bin/sudoedit:wheel: /usr/bin/screen:mcusers:
Obviously, set screen to whomever is going to be using it accordingly. I use it for Minecraft, personally.
- group = 70
- Your wheel group
- interval = 0
- You may wish to set interval to 1 as it does use some cpu. This likely renders it pointless, however.
- proc_scan_offset = 300
- no_kill = yes
- no_kill_ppid = yes
- above two are for during testing only.
ps --ppid 1
to get init ids. Still haven't figured out how to whitelist rc, debian-start or ntpdate, unfortunately, so I have not been able to force this system-wide yet.
#!/bin/sh mail -s "ninja triggered by user $1" root email@example.com <<EOF ninja activated on process escalation by user $1 EOF
Add to ninja.conf
As of Wheezy, the only one that has been updated.
- Install rkhunter and unhide
- In /etc/rkhunter.conf
- MAIL-ON-WARNING - add email addresses
- DISABLE_TESTS - reenable hidden_procs, suspscan
- We've installed unhide and /tmp and /var/tmp should be mounted tmpfs
- False positive.