Tuesday, 17 April 2007

find out the IP of a Windows machine in a samba network

We all know that with DNS, we can easily find out the IP of a machine with an FQDN (i.e., fully qualified domain name). The commands like ping, nslookup (obsolete), dig, ... can be used for this purpose.

Additioanlly on Unix the file /etc/hosts can also be used to store information for machine names <-> IP addresses translations. The Windows equivelant file is usually C:\Windows\system32\drivers\etc\hosts.

But what about name resolution with WINS? Is there any simple comamnd to dig out the IP address of a Windows machine over network?

The answer is yes (of course). In a Windows network, there must exist at least one machine functions as a browser which keeps the information who is who.

On a *nix machine where samba is running, you can use the command smbtree to list all Windows shares over network, including Windows machine names. In particular, you can use command nmblook command to find out the IP of a windows machine, e.g.:

nmblook windozebox

to get the IP of the quoted windows box, just like nslookup for name resolution with DNS.

On a Windows 2K/XP machine, you can use the command net to dig out a lot of network information, for example, net view tells you avaliable Windows/Samba machines on the local network block. And you can use the ping command to find out a windows machine's IP even it has no dns record.

Wednesday, 28 March 2007

mindterm - ssh with java applet

ssh is now almost the default way for remote login and management of a Unix/Linux box. Thanks to OpenBSD people for the great work and he great mind to open-source their work, OpenSSH is now shipped with almost all linux distros (I can’t think of any without) and built on most Unix flavors. It is even available on M$ Windoze: for open-sourced offerings, there is OpenSSH server within the full cywin enviroment, or some strip-down evsrion, like CopSSH, ...; recently there is also MinGW based offerring which doesn’t require cygwin1.dll (it is a nightmaire if you have multiple different versions of cygwin1.dll on your windows box). There is freeware product called freeSSHd as well but it is not open-sourced.

Put the availablity of ssh server aside, you also need some ssh client program to access an ssh server. On Unix/Linux, this is a non-issue. On windows there is open-sourced putty, as well as the ssh client program coming with openssh package (either cygwin1.dll based or MinGW+MSYS based).

But what if there is no ssh client installed on the system and you don’t have permission to install something on the box?

Well, mindterm comes to remedy. It can serves as java applets that you can download off from a website.

Say, you access a webpage which has the mindterm applet served (can be either in a popup mode or an embeded mode), with a java plugin enabled web browser, you can ssh into the box, without a ssh client program pre-existing on your local machine.

Notes:

1) mindterm is not open-sourced. The original version had source publically accessible though, but that version only supports ssh protocol version 1.


2) the ssh port, i.e., 22/tcp, still needs to be open on the server. You may access the applet on http port (80/tcp by default) , the applet itself still connects to the 22/tcp port from the client machine to the server. The port 22 is not tunnelled into the port 80 traffic. If you configure your ssh server to listen to a non-standard port, you need to change the mindterm settings accordingly.


Sunday, 25 March 2007

iptables: defeat ssh brute-force attacks

Yesterday's post I described a method to do port-knocking protection with iptables only. Near the end of the post, I mentioned that using the same iptables recent module, one can effectively defeat the ssh brute-force attacks. At the time of writing I thought about a better implementation than the sample described in this link.

In short, the critical part for the iptables rules for the purpose would be:



iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m recent --update --seconds 60 --hitcount 4 --rttl -j DROP


The first iptables command records the seen IP address into the recent table from where an incoming ssh connection is attempted. The second one will drop the packets if the ssh login attempts happen more than 3 times within last 60 seconds from the same IP, as it is considered as ssh brute-force attacks.

My idea of improvement to the matching rules is to add multiple levels of matching, i.e., more than 3 times within last 60 seconds as the first level matching, and we also blocks ssh loin attempts more than 5 times within last 2 minutes, as the second level matching. This second levels of matching will drop the more packets which happens slightly less frequent than the first-level attacks but happens more persistently, because the normal ssh logins will be less likely like this. Similarly we can add even levels, e.g., more than 10 times within last 5 minutes, and more than 15 times within last 10 minutes, etc, etc, etc.

After bit googling, I found this is already mentioned by someone, with clearer sample here:

Saturday, 24 March 2007

port-knocking with iptables only

port-knocking protection is a method that you open a specific port only after you attempt to connect some other ports, in a right order, just like you open a door with right sequence of knocking. It adds another layer of protection to a server. It is useful to allow only authorised access, for example, a firewall or a CVS server on which ssh accesses are authorised to a limited number of users. It is not suitable for servers running public services like web server, mail server, etc.

Most implementation of port knocking protections involve a dedicate a daemon that keeps monitoring the system logs, in order to detect the knocking sequence.

Here I describe a method to implement the port knocking protection, inspired by A. P. Lawrence's article. It use iptables only. On linux, iptables is used for firewalling (v2.2 and older use ipchains), so with this implementation, no separate dedicated daemon is run.

The key feature of iptables to be used here is the table called “recent”, which was introduced for later version of iptables. With some old version of linux distros, you may need to update iptables package. More information about iptables module recent can be found here.

The advantage of this implementation is that it is elegant (no additional software installed) and lightweight (no additional daemon running). The limitation is that this is only suitable for a fixed mapping. But generally this is good enough, it is especially effective for firewalling out the attacking of ssh worms, script kiddies, port scanning or the like.

Here is a sample script:

#!/bin/bash
# $IPTABLES rules to be run by /etc/rc.d/rc.local
#
# 08 Feb, 2005 -- implement an elegant port-knocking mechanism to restrict ssh access for this machine
#
#### where is iptables binary?
IPTABLES=/sbin/iptables
#
#### define the knocking port set here
# I take my telephone number and break it down into three pieces for easy memory.
PK_PORT0=1223 # 1st knocking port
PK_PORT1=569 # 2nd knocking port
PK_PORT2=715 # 3rd knocking port
#
#### Set some sensible kernel params that may already be there
#### Assume necessary iptable modules are loaded.
/bin/echo "0" > /proc/sys/net/ipv4/icmp_echo_ignore_all
/bin/echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
/bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_source_route
/bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects
/bin/echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
/bin/echo "1" > /proc/sys/net/ipv4/conf/all/log_martians
/bin/echo "1" > /proc/sys/net/ipv4/ip_forward
#
#### Flushing tables
$IPTABLES -F
$IPTABLES -t nat -F
$IPTABLES -X
$IPTABLES -t nat -X
#
#### Set all policies
$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT DROP
#
#### Being paranoid to avoid intrution during the excutation of this script
$IPTABLES -I INPUT 1 -i ! lo -j DROP
$IPTABLES -I FORWARD 1 -i ! lo -j DROP
$IPTABLES -I OUTPUT 1 -o ! lo -j DROP
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT
#
#### Filter out some obviously proofed packets from internet
$IPTABLES -A INPUT -s 10.0.0.0/8 -i $EXT_IF -j DROP
$IPTABLES -A INPUT -s 127.0.0.0/8 -i $EXT_IF -j DROP
$IPTABLES -A INPUT -s 172.16.0.0/12 -i $EXT_IF -j DROP
$IPTABLES -A INPUT -s 192.168.0.0/16 -i $EXT_IF -j DROP
$IPTABLES -A FORWARD -s 10.0.0.0/8 -i $EXT_IF -j DROP
$IPTABLES -A FORWARD -s 127.0.0.0/8 -i $EXT_IF -j DROP
$IPTABLES -A FORWARD -s 172.16.0.0/12 -i $EXT_IF -j DROP
$IPTABLES -A FORWARD -s 192.168.0.0/16 -i $EXT_IF -j DROP
#
## allow all outgoing packets
$IPTABLES -A OUTPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT -o eth0 -j ACCEPT
#
#### allow some ICMP packets for friendly probes
#### it also gives a hacker indication of the machine existence though, :)
$IPTABLES -N icmp-packets
$IPTABLES -A icmp-packets -p icmp --icmp-type redirect -j DROP
$IPTABLES -A icmp-packets -p icmp --icmp-type echo-request -j ACCEPT
$IPTABLES -A icmp-packets -p icmp --icmp-type echo-reply -j ACCEPT
$IPTABLES -A icmp-packets -p icmp --icmp-type destination-unreachable -j ACCEPT
$IPTABLES -A icmp-packets -p icmp --icmp-type source-quench -j ACCEPT
$IPTABLES -A icmp-packets -p icmp --icmp-type time-exceeded -j ACCEPT
$IPTABLES -A icmp-packets -p icmp --icmp-type parameter-problem -j ACCEPT
#
#### SYN flood protection, which is typical for DDOS attack
$IPTABLES -N syn-flood
$IPTABLES -A syn-flood -m limit --limit 1/s --limit-burst 4 -j RETURN
$IPTABLES -A syn-flood -j DROP
#
#### Log packet fragments just to see if we get any, and deny them too
#### This may be not necessary, thus commented out.
#$IPTABLES -A INPUT -i eth0 -f -j DROP
#
#### These chains are for the port-knocking protection
$IPTABLES -N port-knocking
$IPTABLES -N knocking-okey
$IPTABLES -N knocking-oops
#### ====== actual contents of port knocking chains =======
#### Using module recent to implement a simple and elegant port knocking mechanism
#### First we make sure the port knocking order is correct.
#### Note: --update option updates the hitcount number, while --rcheck does not;
#### Neither of them changes the last-seen time.
$IPTABLES -A port-knocking -p tcp --dport $PK_PORT0 -m recent --rcheck --hitcount 1 -j knocking-oops
$IPTABLES -A port-knocking -p tcp --dport $PK_PORT0 -m recent --set -j REJECT --reject-with host-prohib
$IPTABLES -A port-knocking -p tcp --dport $PK_PORT1 -m recent --rcheck --hitcount 2 -j knocking-oops
$IPTABLES -A port-knocking -p tcp --dport $PK_PORT1 -m recent --update --hitcount 1 -j REJECT --reject-with host-prohib
$IPTABLES -A port-knocking -p tcp --dport $PK_PORT2 -m recent --rcheck --hitcount 3 -j knocking-oops
$IPTABLES -A port-knocking -p tcp --dport $PK_PORT2 -m recent --update --hitcount 2 -j REJECT --reject-with host-prohib
#### Now we need make sure the port knocking sequence is continuous.
#### If some random port is accessed during the knocking process, then the recent table will be cleared,
#### so that one has to do the knocking all over again.
$IPTABLES -A port-knocking -p tcp -m recent --remove
#$IPTABLES -A port-knocking -p tcp -m recent --remove -j REJECT
#### chain knocking-okey is to accept connection and clear the record
$IPTABLES -A knocking-okey -m state --state NEW -p tcp -m recent --remove -j ACCEPT
#### chain knocking-oops is to drop or reject connection and clear the record
$IPTABLES -A knocking-oops -m state --state NEW -p tcp -m recent --remove
#$IPTABLES -A knocking-oops -m state --state NEW -p tcp -m recent --remove -j REJECT
#### ======= port-knocking handling bulk end =============
#
#### Now the real part
$IPTABLES -A INPUT -i eth0 -p icmp -j icmp-packets
$IPTABLES -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A INPUT -i eth0 -p tcp --syn -j syn-flood
#$IPTABLES -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
#### Instead of direct accept, ssh login attempts are first filtered with port knocking, thus the above line is commented out
$IPTABLES -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --rcheck --seconds 20 --hitcount 3 -j knocking-okey
$IPTABLES -A INPUT -i eth0 -p tcp -j port-knocking
#
#### Now delete the blocking rules put in at the beginning
$IPTABLES -D INPUT 1
$IPTABLES -D FORWARD 1
$IPTABLES -D OUTPUT 1

In above script, the port-knocking chain makes sure the pre-defined ports are knocked, continusly and in a correct order; the knocking-okey chain accepts the packet and clears the recent table; the knocking-oops chain drops or rejects the packet and clears the recent table. It is more secure to drop a packet than to reject it, because a hacker could not see any result of the packet; but it takes more time to knock as you will usually wait for the time out error before sending out another packet (to knock another port).

Additional note: it is very easy to use the recent module of iptables to block too-frequent ssh longin requests, which is generally a malicious brute-force attack. There is an explanation and sample here.

Friday, 23 March 2007

samba for time synchronization

A somewhat hidden feature of Samba is that you can use Samba as a local timeserver for your Windows clients. The following line is added to enable this feature. By default, a windows client will talk to a micro$oft time server if time synchronization is enabled. So now you can let those clients in LAN talk to the samba server with the following setting in the samba configuration file:

timeserver = yes



samba: use of netbios name and aliases

In samba configuration file, /etc/samba/smb.conf, I generally add these options,

 netbios name = linux
netbios aliases = debian ubuntu

Then I can have different virtual samba servers, just like virtual web servers with apache. Isn’t it cool?

Using the apache analogy, the netbios name = option is set the default samba host, whilst the netbios aliases = option is to setup additional virtual hosts. samba can have different controls for these virtual hosts.

In a cooperate environment, the best strategy is to set a samba share service bind to the service name (e.g., file-server, public-library, etc), not to the machine name that actually serves the file-sharing, so that when the machine is replaced or gone away, the file-sharing services can be still remains the same.

samba: secure your home shares

Usually I add the following two options for home share on a samba server, to tighten up the security:

[homes]
...
valid users = %S
path = /home/%S

The first option is to set, say user1, to only see his own home directory as the home share (he can see other public shares as well), not to see the home directory of user2.

The second option limits that the home directory of, say user1, as the share, must be /home/user1. For example, usually root’s home directory on many linux distros is /root, therefore it can not be accessed as the samba home share.