Debian: IPtables and net protection should be enabled by default

As I come across network security issues in Linux, I can’t help but wish that Debian had decent default firewall rules (and kernel network protection in general) like many other distros.

This applies to both Debian 4.0 and Ubuntu 7.10.

By default, a Ubuntu or Debian install of Linux is vulnerable to a SYN flood. If behind a router, chances are there won’t be a problem. But if it’s a standalone Linux machine connected to the internet, the machine is vulnerable to a DoS attack.

It’s a simple fix.

echo 1 > /proc/sys/net/ipv4/tcp_syncookies

or

iptables -A INPUT -i eth0 -p tcp –tcp-flags ALL ACK,RST,SYN,FIN -j DROP
iptables -A INPUT -i eth0 -p tcp –tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -A INPUT -i eth0 -p tcp –tcp-flags SYN,RST SYN,RST -j DROP

The second should probably be used if it’s a server. The first way may still have quite a few open SYN connections.

You may just want to block the IP(s) that are conducting a SYN flood on you (keep an eye on netstat or iptables.log). A script that does this would be pretty useful; I wonder if there are any out there (or if I have to write one?).

iptables -I -s ip.to.ban -j DROP

Along with rules to help protect against flooding, it seems like it would be a good idea to block all ports by default.

iptables -A INPUT -m limit –limit 100/second –limit-burst 150 -j RETURN

One solution could be to have a folder called /etc/security/iptables that contains files that get passed to iptables at startup (in the same way /etc/rc2.d gets read in numeric order). So you could have files like 22ssh, 23ftp, etc. with iptable rules in each file. You could also have an ‘ENABLED’ variable like some files in /etc/default have (so that ports wouldn’t be opened by default; the user would have to manually enable them for the port to be opened).

Then they’d just run /etc/init.d/iptables restart and the port would be opened (flush the rules, reapply).

I’ve put together a proof-of-concept for this; feel free to check it out. Extract it somewhere, and check out the source. Then try the following

tar xvzf debian-iptables.tar.gz -C /

Which will create and fill /etc/security/iptables and put an init file in /etc/init.d and a link in /etc/rc2.d

It hasn’t been tested as much as I’d like, but it should work.

Please do this at the computer itself; if you do it over the network you might be locked out.

http://bbis.us/debian-iptables.tar.gz

iptables logging (the good way) in Debian Etch

When using iptables to log, you generally make a ‘LOG’ chain, and then

iptables -A INPUT -j LOG

iptables -A INPUT -j DROP

To log and then drop.

LOG has some disadvantages though. Using LOG, information will fill up the output of the ‘dmesg’ command as well as the kern.log file. Using Debian Etch, I was unable to get iptables to log to any other file but kern.log.

A better solution is ULOG.

You can clear your dmesg output with ‘dmesg -c’

apt-get install ulogd

iptables -N DROPLOG
iptables -A DROPLOG -j ULOG -m limit –limit 2/hour –ulog-nlgroup 1 –ulog-qthreshold 20

iptables -A DROPLOG -j REJECT
iptables -A INPUT -p tcp -i eth0 –dport 22 -j ACCEPT
iptables -A INPUT -i eth0 -j DROPLOG

This will drop and log all incoming traffic except for port 22.

You shouldn’t need to edit /etc/ulogd.conf, but you might want to check it out.

All information should get logged to /var/log/ulog/syslogemu.log

Remote Syslogd Logging

There are some issues with remote logging using syslogd. By default, anyone can write logs to syslod if it is accepting connections. This can be an issue if someone wants to fill your /var/log with junk.

On a default install of Debian (or just about any distro) you should have all the tools you need already.

On log server edit /etc/default/syslog

SYSLOGD=”-r”

iptables -I INPUT -p udp –dport 514 -s CLIENTIP -j ACCEPT
iptables -A INPUT -p tcp -i eth1 –dport 22 -j ACCEPT
iptables -A INPUT -i eth0 -j DROP

You will want these iptables rules to be loaded on statup. How you do this will vary on your distro, but a simple start/stop script in /etc/rc2.d is the easiest way to go on debian.

On log client edit /etc/syslod.conf

auth.alert @server

mail.* @server

The client’s logs will end up in whatever file auth.alert gets logged to on the server.

Debian / Ubuntu NFS Server

apt-get install nfs-kernel-server nfs-common portmap

By default, portmap is only accessiable on localhost. This seems to have changed for Etch, but it doesn’t hurt to double check.

Remove the line ‘-i 127.0.0.1’ option from ARGS in the file /etc/default/portmap or comment it out.

Restart it with /etc/init.d/portmap restart

Edit /etc/exports

/usr/local 192.168.1.(rw,no_root_squash,async)
/stuff 192.168.1.(ro,async)

This will make nfs-kernel-server complain about ‘no_subtree_check’; feel free to add it.

no_root_squash means that the ‘root’ user on a client system going to this directory will be root on the server share as well. This is something you’ll only want to use in a protected LAN. Otherwise, ‘root’ will be ‘nobody’ while in the shared directory.

NEVER ALLOW NFS TO BE SHARED ACROSS THE INTERNET.

NFS is unencrypted by default (I believe you can only encrypt it using Kerebos).

I highly suggest you use tcpwrappers.

/etc/hosts.allow

portmap: 192.168.1.
lockd: 192.168.1.
rquotad: 192.168.1.
mountd: 192.168.1.
statd: 192.168.1.
nfs: 192.168.1.

/etc/hosts.deny

portmap:ALL
lockd:ALL
mountd:ALL
rquotad:ALL
statd:ALL
nfs:ALL

To make everything easier, edit your /etc/hosts file. This should be the same on all linux machines.

192.168.1.100 laptop
192.168.1.101 server
192.168.1.104 workstation

Restart NFS.

/etc/init.d/nfs-kernel-server restart

Mount on the client machine now:

mount server:/usr/local /mnt/server-local

You’ll probably want to add this to /etc/fstab.

server:/usr/local /mnt/sever-local nfs rsize=8192 0 0

On a desktop machine, I like these options

server:/usr/local /mnt/server-local nfs rsize=8192,user,noauto 0 0

This will allow your user to mount the share by double-clicking ‘server-local’ in “Computer” (located in Places on Ubuntu)

Passwordless SSH Authentication

This will show you how to log into SSH without having to use a password.

From the machine you want to be able ssh without a password from

ssh-keygen -t dsa

Default password, and empty passphrase.

From the same machine

cat ~/.ssh/id_dsa.pub | ssh user@remote “cat – >> ~/.ssh/authorized_keys”

ssh user@remote

You should now be in without having to be asked a password. There are some obvious security implications here; nothing you should have to worry about if you have a strong password and good permissions on /home/user.

This is very useful for automated backups using scp/rsync.

scp -r -p ~/Important user@remote:~/backups/`date +%F`

The above command will backup /home/user/Important to /home/user/backups/2008-01-18

I’ll deal with rsync in a different post; lots of nifty stuff there. 😉

Debian 4.0 (Etch) LDAP Server

LDAP still gets me from time to time. I’ve set up multiple Debian LDAP servers now, and each time it seems like something new gets me. I’m going to try to put together a set-by-step LDAP guide that is sure to work (with Debian Etch). If you have any problems, please post! This setup has been tested on x86 and amd64 Debian variants.There seem to be some bugs with debian’s default ldap install (missing .so files, config files that don’t work, not remembering settings from the setup screens). However, once everything works it’s rock solid.

apt-get install slapd ldap-utils libnss-ldap libpam-ldap nscd migrationtools


Add your admin password, and accept default ldapi for now. Replace example and net with your domain/hostname (where each “.” is a “dc=”).

libnss-ldap and libpam-ldap are set up the same way, use identical answers (passwords are saved in /etc/*.secret make sure permissions are 600!)

When prompted, replace ‘manager’ with ‘admin’ and example/net with your domain/hostname


Make root local database admin = yes

Database require login = no

Uncomment “rootdn” in /etc/ldap/slapd.conf and make sure all suffix’s are your domain and not a debian default (for example, localdomain or example.net)

Place a “rootpw password” entry under rootdn

/etc/nsswitch.conf should look like:

passwd: compat ldap
group: compat ldap
shadow: compat ldap

hosts: files dns
networks: files

protocols: db files
services: db files
ethers: db files
rpc: db files

netgroup: ldap

cd /usr/share/migrationtools

Edit migrate_common.ph and replace “padl.com” with your domain

./migrate_base.pl > /tmp/base.ldif

./migrate_passwd.pl /etc/passwd /tmp/passwd.ldif

./migrate_group.pl /etc/group /tmp/group.ldif

/etc/init.d/slapd restart

ldapadd -x -W -D 'cn=admin,dc=example,dc=net' < /tmp/base.ldif

ldapadd -x -W -D 'cn=admin,dc=example,dc=net' < /tmp/passwd.ldif

ldapadd -x -W -D 'cn=admin,dc=example,dc=net' < /tmp/group.ldif

cp -p /usr/share/doc/libpam-ldap/examples/pam.d/* /etc/pam.d

apt-get install libpam-cracklib

ln -s /lib/security/pam_unix.so /lib/security/pam_pwdb.so

You may have to remove the first block of text in base.ldif (ldap should already have it)

As far as I can tell, pam_ldap.conf and libnss-ldap.conf are broken by default. Do this to fix them.

echo > /etc/pam_ldap.conf

vim /etc/pam_ldap.conf

base dc=example,dc=net

uri ldap://127.0.0.1/

ldap_version 3

rootbinddn cn=admin,dc=example,dc=net

port 389

pam_password crypt

cp /etc/pam_ldap.conf /etc/libnss-ldap.conf

/etc/init.d/slapd restart

/etc/init.d/nscd restart

You might want to remove a test user from /etc/passwd and /etc/shadow that has been imported to ldap.

su – username

Is a good test. Check /var/log/auth.log if you have problems. If nothing is there, try

/etc/init.d/slapd stop

slapd -u openldap -g openldap -d 999

That will have slapd run as the users it’s supposed to, and be very verbose.

At this point, everything should be working (if not, don’t go forward yet!). Now we can use encryption, to increase the security of our ldap server.

cd /etc/ldap

mkdir ssl

openssl req -new -x509 -nodes -out ldap.pem -keyout ldap.pem -days 3650

chmod 640 ssl/ldap.pem

chmod 750 ssl

chown -R root:openldap ssl

At the very top of /etc/ldap/slapd.conf put

TLSCACertificateFile /etc/ldap/ssl/ldap.pem
TLSCertificateFile /etc/ldap/ssl/ldap.pem
TLSCertificateKeyFile /etc/ldap/ssl/ldap.pem
TLSCipherSuite HIGH:+MEDIUM:!LOW

SSLVerifyClient none

Find the "access"lines near the bottom of slapd.conf and change them like this

access to attrs=userPassword,shadowLastChange
by tls_ssf=128 ssf=128 dn="cn=admin,dc=example,dc=net" write
by tls_ssf=128 ssf=128 anonymous auth
by tls_ssf=128 ssf=128 self write
by * none

and

access to *
by tls_ssf=128 ssf=128 dn="cn=admin,dc=example,dc=net" write
by * read

Make sure you restart

/etc/init.d/slapd restart

Assuming all goes well, you should still be able to "su - username" to your ldap-only user with the added benefit of encryption.

Additionally, if you find that SSL isn't working for you, try doing this.

Add the following to /etc/ldap/ldap.conf

TLS_CACERT /etc/ldap/ssl/ldap.pem
TLS_REQCERT demand

Add this to both pam_ldap.conf and libnss-ldap.conf

ssl start_tls

tls_checkpeer no

tls_cacertfile /etc/ldap/ssl/ldap.pem

After further investigation, 'ssl start_tls' is the way to go. Make sure ldap.conf has your SSL stuff in it and restart slapd and nscd.

http://bbis.us/etch-ldap.tar.gz

Top 7 uses for a shell account

1. Always-on IRC client

screen

irssi

#Control+A D

Using screen (a back-groundable terminal that can be easily resumed at any time) and irssi you can stay connected to IRC at all times, quietly sitting there… logging everything. 🙂

2. Website

Apart from everything else you can do with a shell account, having a personal website on the same machine as the programs and services you run can be very nifty.

Accessing your IRC logs via your website (so even at work/school/etc. you can check IRC quickly and easily) is one example.

3. Anonymous Browsing

Want a secure, anonymous way to browse? On Linux:

ssh user@server -D 9050

Will create a SOCKS port (9050) on your local machine. Point firefox/whatever at localhost:9050 (SOCKS) and browse away!

Windows clients support this too.

4. File Storage

Obviously I’m not saying you should back up your home harddrive to a shell, but doing minor backups can be very useful.

Got a few MBs of source code you want to have backed-up offsite? Why not put it on your shell?

Been writing some papers that are more important than a dead hard drive? Why not back them up every now and then?

scp -r /path/to/folder [email protected]:~

Will copy all files/folders in /path/to/folder to your home directory on shell.com. Using ssh keys for password-less authentication allows you to have a simple, one-line backup script.

5. E-Mail, FTP and other network services

Behind a restrictive connection? If you have outbound access to port 22 (you can always request other ssh ports be used on st0rage.org ;)) you can access any port on that machine.

Check email, use ftp/etc, and choose whether it stays on the shell or if you download it for your machine.

6. Encryption

How can we not mention encryption?

How would you like to be able to store sensitive information remotely and encrypted? Keeping a list of passwords or financial information encrypted with gpg is easy and effective.

gpg –gen-key

#Fill out info, accept defaults.

#Select (O)kay instead of (Q)uit to enter your passphrase

#This can take some time. A lot.

gpg -e file-to-encrypt

#enter your name from the step above.

#push enter again to exit

gpg -d file-to-encrypt.gpg

#contents will be displayed on the screen

gpg -d file-to-encrypt.gpg > file-to-encrypt

#will put the contents in a file

Google will give you some more advanced stuff with gpg, have faith the above is the hardest part. 😛

7. Scheduled Tasks

Cron is a powerful tool. With it, you can run commands at pre-determined re-occurring intervals.

For example, want to email yourself a reminder a week in advance for certain people’s birthdays? Easy!

crontab -e

0 0 11 3 * mutt -s “Birthday Reminder!” [email protected] < ~/reminders/julie.txt
0 0 26 1 * mutt -s “Birthday Reminder!” [email protected] < ~/reminders/sarah.txt

mkdir ~/reminders

echo “Julie’s birthday is on 3-11-`date +%Y`” > ~/reminders/julie.txt

echo “Sarah’s birthday is on 1-26-`date +%Y`” > ~/reminders/sarah.txt

Already use the shell for screen+irssi? Why not email yourself a daily log of what was said (or lines containing your name)?

58 23 * * * cat ~/irclogs/*`date +%F`* | grep nickname > ~/daily.log

59 23 * * * mutt -s “IRC Log” [email protected] -i ~/daily.log

Ignoring snoopy logs with logcheck

snoppy is an awesome tool available on the debian archives. It allows you to see what commands your users have run (by default logs to /var/log/auth.log). It acts like a beefed up .bash_history that users cannot disable/delete/etc.

logcheck scans your logs for weird things, and emails them to you.

By default, these two programs do not get along. snoopy entries show up in logcheck’s emails (which can get very, very big). This sort of defeats the purpose of logcheck, since you get sent massive emails with the important stuff hidden between giant blocks of snoopy logs.

To disable this

echo ‘^w{3} [ :0-9]{11} [._[:alnum:]-]+ snoopy.*’ > /etc/logcheck/violations.ignore.d/snoopy

chmod 644  /etc/logcheck/violations.ignore.d/snoopy

ln -s /etc/logcheck/violations.ignore.d/snoopy /etc/logcheck/ignore.d.server/snoopy

Now test it

sudo -u logcheck logcheck

To make more logcheck ignore rules, test your file(s) by:

egrep -f logcheck-file /var/log/auth.log

It will display only what will be ignored.

Make sure the file(s) are 644 (rw r r) or logcheck won’t be able to ignore what’s in the file.

Connect to a Running X Session Remotely

From the computer you want to view the remote X session:

ssh root@computer2 -L 5900:localhost:5900

If you can only connect to a linux gateway, you can substitute localhost with the internal IP address of the machine you want to vnc to.

ssh root@computer2 -L 5900:192.168.1.100:5900

On computer2 do the following.

This does not need to be done as root, but you’ll need to be the actual user running the X session if you log in as a regular user. On ubuntu/debian you can use apt-get install x11vnc.

x11vnc -display :0 -passwd password

If it complains that it cannot connect to :0, try this

x11vnc -auth /var/lib/gdm/:0.Xauth -passwd password

Note that using the :0.Xauth method will work if X is just running at the login screen (so you could connect and log into X as a user).

Now, from computer1, do

vncviewer localhost

This is very useful, but make sure you use a password if port 5900 is open on computer2.

Linux DVR/MythTV Box

There’s a lot of information out there for building a MythTV box out there. I figured I’d throw in my two cents, and hopefully help people that encountered some of the same problems I did.

First, the hardware.

I picked a good case; it’s a low profile case (so you need low profile cards!). It was pretty cheap, looks nice, and came with a power supply. $20 not including shipping.

http://www.svc.com/ycc-s27.html ($40 with shipping)

Front of Case

Since I was on a budget, I picked up a cheap Motherboard and a low power CPU. I had to purchase a Heatsink/Fan elsewhere since the one that came with the CPU would not fit on the motherboard and had a non-standard 4-pin fan power cable.

AMD Semperon LE-1150 Sparta 2.0Ghz 45W CPU ($40~)

BioStar AM2 Motherboard ($40~)

Combined, these were $80. While I might have liked more speed for this price, I felt the low power consumption was worth it.

2GB – 2x1GB DDR2 667 ($40)

A 60GB SATA Laptop drive (had it laying around) performs beautifully. It’s resonsive, and best of all whisper quiet. It’s not much space, but I have a seperate computer with nearly 500GB of free space that I’ll probably be using for NFS.

60GB SATA Laptop Drive ($45)

The PVR-150 (150MCE-LP) capture card performs well; it has a built-in MPEG encoder which takes stress off the CPU (very useful in this case). New this card is around $75, but you can get one off ebay for $20+ less if you feel cheap.

Haupage PVR-150MCE-LP ($75)

This card had trouble dealing with the splitters I was using (900mhz and 1100mhz). Removing the 900mhz helped. My cable was being run from the 3rd floor to the basement, which might have been a problem too (no other capture card I’ve messed with had this trouble, not sure if it’s something with this card or just a weird quirk my card had).

Now, I needed a card with S-Video or RCA out. I ended up getting a GeForce 4 MX440 64MB. Ebay for this; new low profile video cards are quite expensive. This isn’t a major performance card, but it’s low profile (mine had only a heatsink, so even less noise). It’ll do fine for TV watching, and some light game plaing.

GeForce 4 MX440 64MB Low Profile ($20)

Top of PVR

The last thing this setup needed was a remote control. An ATI Wonder (supported by Linux) was cheap on ebay.

ATI Wonder Remote ($10)

ATI Remote

To get the remote working in Linux isn’t very hard (although it would be nice if lirc would auto-detect controllers). The information is available on mythtv’s website here: http://www.mythtv.org/wiki/index.php/ATI_Remote_Wonder

One important suggestion is to disable the lirc_atiusb module, by adding the following in /etc/modprobe.d/blacklist

blacklist lirc_atiusb

Add the correct module in /etc/modules

ati_remote

Reboot; lircd will no longer hang and your remote should work. 🙂

This setup plays and records video flawlessly (I don’t notice anything while recording and watching at the same time). I play emulators on it (N64, PSX, etc.) with USB-> N64/PSX adapters and definitly think this is worth it. It’s totally silent.

For only $300 including shipping, this isn’t too bad. It could definitly use a larger drive, but personally I like the idea of a central server to store my library (if only to keep down on the noise here in my TV room!).