# A few steps which can enhance your server security



## ShelLuser (Sep 6, 2013)

Hi gang!

Before I continue: Please keep well in mind that although some of the steps I'm describing below can be used "out of the box" (just blindly follow my example and you're done); they weren't meant to be used this way. Keep well in mind that there is no such thing as "instant security"; true security starts with an understanding (even basic) of how your system works and behaves.

Also: these tips don't come close to the tips explained in the Handbook. But they can most certainly co-exist (and extend a little).

Final point: I'm only addressing some steps which I think to be easily overlooked. As such I won't go into details about firewalls, file or directory permissions and usage of groups because I think those should be obvious.

In a totally random order, but as usual for my posts; trying to go from easy to advanced.

*OpenPGP*

Now, before I continue with this point I need to warn you that I'm (very/extremely) biased, and I know myself well enough to realize it. I lived the period where Zimmerman faxed the source code of PGP in order to circumvent a United States law which forbids the export of strong encryption algorithms. When I was a FidoNet node I took a strong interest in PGP, advocated in echomail (for the youngsters: "A packet switching version of Usenet" ) and more than often used it as a (clear) signature in my netmail (the predecessor of today's e-mail).

In short:


```
(1)     Peter Looyenga <2:2801/13>
        Peter Looyenga, Host TotaalNet <2:2801/0>
          512 bit RSA key 96501769, created: 1994-03-25
```
That is me, I still own the private key to this and I also take a bit of pride into having a key this old (even though I realize like no other that using this key isn't the best of ideas anymore, that's where my current 2048R/8A99AE5A key comes into play).

Enough semantics: why would you want to use OpenPGP?


The public-key approach makes it easy to send encrypted data without the risk of a "man in the middle" attack; both parties sent each other their public key and then the fun can begin (data is encrypted using a public key and can then only be decrypted using the private or secret key).
Identity confirmation. OpenPGP provides many ways to link your key with more private information, but the structure as a whole also allows you to use your identity as a sort of seal (by signing information for example; everyone can access it; but one can also check that the information is completely yours).
An extension to the previous point: Sign configuration files and export the signature to a separate file. This will not only guarantee its integrity; it _also_ guarantees that no one else but you changed things (if two administrators have both access to the same 'intrusion detection system'...).
Even the people behind FreeBSD recognize the (possible) impact of having (Open)PGP keys.

If you want it then check out security/gnupg.

*Tripwire*

Tripwire (see security/tripwire) is a so-called Intrusion Detection System or IDS. An IDS basically creates checksums of all files (or a selection) from your system and stores those in a database of some sort. It can then check your files and compare the new checksums with the one already in the database. If something differs then it's most likely that someone (or something) has tampered with those files.

There are many good IDS solutions out there but I never could bring myself to move away from Tripwire, even though the software as a whole maybe somewhat dated.

The best point about Tripwire, in my opinion, is that it encrypts just about everything:


```
# ls
losoco.key      smtp-local.key  tw.cfg          tw.pol          tw.pol.bak
# file tw.pol
tw.pol: data
```
Rest assured: tw.pol merely is my Tripwire policy file; a text file which tells the system which file(s) it should check and at what priority. It's simply encrypted. Now; although this may sound awesome at first do keep in mind that if an attacker managed to get this far then they also got access to your keys (and thus the whole IDS setup). This is a form of "_security through obscurity_". Even so; I personally welcome the extra layer of protection; an attacker can't "just like that" check which files are being monitored through IDS and which aren't.

And in all honesty: although I'm somewhat lazy and simply kept the keys in place here; you can of course also do otherwise.

*Security level in the kernel*

When I first went over sysctl(8) I knew I was hooked. That was the same kind of customization which I came to love and deeply respect when looking at Solaris' UFS filesystem. But the best part is that the FreeBSD developers realized that the option to enforce certain restrictions in "kernel space" is much more powerful than those in "userland" or "userspace".

("Kernel/user space": think of this as layers. At the very bottom you'll have the FreeBSD kernel which takes care of just about everything, including talking to your hardware. Everything which happens here happens in so called "kernel space"; the layer which makes up the kernel itself. On top of that could be your shell (to keep it simple). After you logon a shell gets started and you can execute commands. This can be described as "userland" or "user space". Your shell 'talks' to your kernel to get things done (like displaying text) but it does not have the same kind of access to your system as the kernel itself does.)

If the kernel tells you no then you can jump up and down, kick the computer, threaten to press the reset button or even try to bribe it with not spilling beer on-/into it: no will be no.

kern.securelevel

By default this is set to -1, and by design the administrator can only _raise_ it. The higher the number, the more strict your system will behave.

My personal favourite setting is 1: No more write access to raw device files and files which hold special flags such as schg (immutable; which disallows any changes), you also can't turn these flags off, you can't even open /dev/io (I'm not familiar with this device, but the name suggests enough for me) and my favourite feature: you can neither load nor unload kernel modules.

And all it takes is one simple command: `# sysctl kern.securelevel=1`

Disclaimer: In my opinion this is a powerful feature but do use some common sense and don't solely rely on this, even though it's quite easy to activate.

Also be sure to read the security(7) manual page as well as Chapter 15 (security) of the FreeBSD handbook.

If you want this to become permanent (active right after a reboot) then add the following to your /etc/rc.conf:


```
# Security settings; kernel control
kern_securelevel_enable="YES"
kern_securelevel="1"
```

*Resource limitations*

In order to get this going you'll need to build your own kernel.

This may sound very daunting at first (up until this week I also stuck with the default kernel) but it doesn't have to be.

Run `uname -a` and pay extra attention to the architecture.


```
$ uname -a
FreeBSD xxx.losoco.com 9.1-RELEASE-p6 FreeBSD 9.1-RELEASE-p6 #2 r255124: Wed Sep  4 00:10:46 CEST 2013     root@xxx.losoco.com:/usr/obj/usr/src/sys/SMTP2  amd64

(this is obviously an amd64 architecture)
```
Now, the first thing you'll need is the source code. Check /usr/src and if nothing is there you should look into using Subversion.

I run 9.1-RELEASE-p6 myself (as can be seen above) and prefer using: `# svn co [URL]https://svn0.us-east.freebsd.org/base/releng/9.1[/URL] /usr/src` to get it but keep in mind: your mileage may vary.

If the regular (GENERIC) kernel works for you then my advice would be to keep it simple at this time. Go to /usr/src/sys/$arch/conf where $arch is one of the known architectures (like amd64, i386, and so on).

So in the above example I would go to /usr/src/sys/amd64/conf. When in doubt look over /usr/src/sys to see if you find something familiar and/or similar to what you see when using `uname -a`.

Now create a new file called "SECKERNEL" (though you're free to pick your own name) and add this:


```
include GENERIC
ident SECKERNEL

options RACCT
options RCTL
```
Change SECKERNEL as you deem fit.

So what is happening here?

First you include the GENERIC (default) kernel configuration. Under normal circumstances you should already be using a GENERIC kernel (carefully look at `uname -a`) and if it works; why change it?

Next you set a new, specific, identity for your new kernel.

And finally you add two options which will enable more fine-grained security control right from within the kernel space.

Now, if you completed this step then go to /usr/src and run `# make buildkernel KERNCONF=SECKERNEL`. This can take quite a while.

When all things work out you can use `# make installkernel KERNCONF=SECKERNEL` to, well, install your new kernel after which you're ready to start using it by rebooting your system.

*Important*: Although things can be this easy I strongly urge you to look into chapter 9.7 of the handbook. This deals with the scenario when something goes wrong. Read it.

Assuming that all went well you're now ready to use the rctl command.

One good way to determine if things worked out:


```
root@smtp2:/home/peter # rctl
root@smtp2:/home/peter #

vs:

root@fbsd:/usr # rctl
rctl: rctl_get_rules: Function not implemented
```
The next step is setting up the rules. This can be done in two ways; dynamically by simply using `# rctl -a <rule>` where <rule> is obviously a valid resource limiting rule. Although the rule will be active right away it will not survive a reboot. For that to work you'll need to add the rule to /etc/rctl.conf.

In my opinion you now passed the hardest part. If you came this far I suggest to look into chapter 15.15 of the handbook which explains the rules in more detail.

One important thing to keep in mind: most limits apply per process to a specific user, and not to the user as a whole.

So if you limit the amount of processes for a user to 1, and that user can logon to your system then this does not mean that he can only logon once (and execute one shell process). Instead he can logon multiple times but can only start one process per session. So basically start nothing because after he logged on he already started the shell himself.

*Finally...*

I hope you guys can find some good use for the tips above, and would like to thank you all in advance for helping me to take over the world by providing me access to your servers!

"_Surely he's jesting? Nah; it's safe, otherwise they would have kicked him off the forums by now. Are you sure; has a moderator already seen this? Don't worry; it's safe! Are you really sure? Hush; I need to finish this sysctl command. Doesn't that give him access to our servers? It's too easy!_".

No guys; you should not believe one word I said up there. That is: not without double checking my comments with those in the official documentation.

Remember: Security starts with you. And not by trusting some unknown stranger on a well known forum who just happens to have some numbers in his statistics. Those numbers only mean that I love this forum; but tell you _nothing_ about me being trustworthy.

Play it safe; don't try this without reading the documentation yourself.

Edit: Null-edit, header fixes, capitalized amd64.


----------



## devildetail (Sep 6, 2013)

To my mind a convenient way of using rctl(8) is in combination with jails.


----------



## ShelLuser (Sep 6, 2013)

devildetail said:
			
		

> To my mind a convenient way of using rctl(8) is in combination with jails.


You're absolutely right.

You can apply rules to an entire jail if you want to, for example; to limit the amount of memory a jail can use: `# rctl -a jail:<jailname>:memoryuse:deny=2G` (where <jailname> is the name of your jail). This would make sure the jail can't use more than (approximately) 2 gigabyte of memory.

Thanks for your comment.


----------



## fonz (Sep 6, 2013)

ShelLuser said:
			
		

> Enough semantics: why would you want to use OpenPGP?


Note that (provided your private key doesn't get compromised of course) PGP also provides _nonrepudiation_, i.e. the sender of a signed message cannot deny having sent it unless they can plausibly argue that their private key has been stolen.



			
				ShelLuser said:
			
		

> If you want it then check out security/gnupg.


Heads up: a GnuPG howto is in the works.



			
				ShelLuser said:
			
		

> My personal favourite setting is 1: No more write access to raw device files and files which hold special flags such as schg (immutable; which disallows any changes), you also can't turn these flags off, you can't even open /dev/io (I'm not familiar with this device, but the name suggests enough for me) and my favourite feature: you can neither load nor unload kernel modules.


Note: values for kern.securelevel of 1 and above make it impossible to run X. So if (for whatever reason) you're running X on your server, don't go beyond 0.



> I run 9.1-RELEASE-p6 myself (as can be seen above) and prefer using: `# svn co [url=https://svn0.us-east.freebsd.org/base]https://svn0.us-east.freebsd.org/base[/url] /usr/src`


Note: there are (at the time of writing) three SVN servers: one on the east coast of the U.S., one on the west coast and one in Europe. You'll probably want to pick the one closest to you.



> Go to /usr/src/sys/$arch/conf where $arch is one of the known architectures (like AMD64, i386, and so on).


Actually, $arch should be lower case amd64


----------



## ShelLuser (Sep 6, 2013)

fonz said:
			
		

> Note that (provided your private key doesn't get compromised of course) PGP also provides _nonrepudiation_, i.e. the sender of a signed message cannot deny having sent it unless they can plausibly argue that their private key has been stolen.


Well, that depends on one important detail: that you have established beyond any doubt that the keys which are being used are indeed his.

This is stretching things a bit; but an argument which surfaced quite some time when arguing the pro's and con's regarding public key encryption was that a man in the middle could still pose a threat if you don't verify your keys over other channels.

Example: I sent you my public key using an "evil" ISP's mail server. They intercept my message, replace the public key with theirs, and then sent it to you. You reply to my message to sent me your key, they repeat the process, and now we have established some kind of trust with a major risk in between.

Calling each other or sending an SMS with the key ID will avoid that of course.

Reason I'm mentioning this is because I've seen many people rely on public keys which they got through e-mail or from a key server. Although the key is perfectly usable it does not give you any guarantees that the person really is who he claims to be.

(but that's also where the web of trust comes into play, but that's another story).



			
				fonz said:
			
		

> Heads up: a GnuPG howto is in the works.


Cool! I'll be looking out for that.



			
				fonz said:
			
		

> Actually, $arch should be lower case amd64


Yeah, I know. I wasn't sure how I should write it up so eventually decided to make sure to emphase that what I wrote up there wasn't a literal description.



			
				fonz said:
			
		

> Last edited by fonz; Today at 15:09. Reason: I can be a real fusspot sometimes ;-)


Darn, busted again! 

But I'll be back 
	

	
	
		
		

		
			





Thanks for your comments!


----------



## fonz (Sep 6, 2013)

ShelLuser said:
			
		

> Well, that depends on one important detail: that you have established beyond any doubt that the keys which are being used are indeed his.


Correct. Most people appear not to use it, but there is something called a "Web of Trust". You may have noticed that GnuPG often says

```
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
```
I must remember to put that in the howto


----------

