Using sftp on a non-standard port

Just a quick note about sftp.

It makes good security sense to change the ssh port on servers that are Internet accessable. To take advantage of this using ssh is quite straight forward as their is a parameter -p to support this eg:

ssh -p 3432 mick@mickvaites.com

Unfortunately the same is not true for sftp (secure file transfer). To achieve the same result with sftp we need to use specify an option of “Port 3432” eg:

sftp -o "Port 3432" mick@mickvaites.com

Once done log it as you would normally.

SSH Escape commands

Note to self:

These are the ssh escape commands from within an ssh connected session.

%~?
Supported escape sequences:
 ~.  - terminate connection (and any multiplexed sessions)
 ~B  - send a BREAK to the remote system
 ~C  - open a command line
 ~R  - Request rekey (SSH protocol 2 only)
 ~^Z - suspend ssh
 ~#  - list forwarded connections
 ~&  - background ssh (when waiting for connections to terminate)
 ~?  - this message
 ~~  - send the escape character by typing it twice
(Note that escapes are only recognized immediately after newline.)

The ~ (tilda) is normally accessed by keying [shift] + [`]

To pull up the list as above send a Tilda + Question Mark ~?

IOS On FreeBSD (Zebra or was it Quagga)

Zebra is a look a like IOS front end for routing on Linux and *BSD systems. It became popular are routed went commercial (might be slightly wrong over that).

I was looking to get dynamic routing installed on FreeBSD and initially installed zebra from the port. However after considerable effort to get it up and running which while clumsy does sort of hang together.  A utility has been provided vtysh which is used like the telnet from end of the router. The idea being that you can create a config and ‘write mem‘ when you’ve finished. However when I did this it created a new file call Zebra.conf and whilst I can see from the source code of the daemons that this file is looked at it. I couldn’t figure out how to get this file used (nothing by googling either).

Whilst hunting for information on zebra I stumbled across a port called quagga which I found some additional information on.

Installation of this port for the main part has been quite straight forward details as follows:

# cd /usr/ports/net/quagga
# make install

Once this completes a number of configuration changes are needed.

Firstly amend the /etc/rc.conf and add the following lines

quagga_enable="YES"
defaultrouter="NO"

The second line is optional and really only makes sense if your upstream injects a default route.

Once this is done you’ll need to generate the initial configuration files. I found the simplest way to do this was to kick off the daemons and then connect using vtysh and write the config. For the daemons to start you need to create empty config files as follows:

# cd /usr/local/etc/quagga
# touch zebra.conf
# touch ospfd.conf
# touch ripd.conf
# /usr/local/etc/rc.d/quagga start

Once done connect to the daemons using

# vtysh
Hello, this is Quagga (version 0.99.11).
Copyright 1996-2005 Kunihiro Ishiguro, et al.
servername# write mem
Building Configuration...
Configuration saved to /usr/local/etc/quagga/zebra.conf
Configuration saved to /usr/local/etc/quagga/ospfd.conf
[OK]

This will have created initial configuration. You can exist vtysh and then edit the inidividual files or you can build the config within vtysh.

Once you are happy with the configuration reboot the server and you’ll have it routing.

Mick

Web Tunnelling over SSH

Not new information but all the same useful for either secure traffic or bypassing web cache restrictions.

First example is a socks proxy to allow you to secure web traffic over a wifi link or just avoiding web caching filters.

From unix, linux, *BSD or MacOSX type in :

ssh -N name@ssh_server -D 9999

or from windows download plink.exe from http://www.chiark.greenend.org.uk/~sgtatham/putty/ (putty.exe is also a must). The command from windows is :

plink -N -D 9999 name@ssh_server

What this does it to open an encrypted tunnel with an entry point of Localhost:9999.

Once the connection is established you then configure your web browser to use a socks proxy of Localhost port 9999. You web traffic will be tunneled over an encrypted link to the server ssh_server.

An additional security step you can use from Firefox is to get the dns resolution of the site done at the remote end instead of locally. In this way you can browse intra-net web sites over the SSH link.

For Firefox in the about:config page change network.proxy.socks_remote_dns to true

Man in the middle – ARP Poisoning on OSX

At the core of all investigation in relation to a networks is the need to sniff packets. If you have a switch with SPAN port capabilities then you can listen in from where ever you wish. However if for whatever reason this is not practical a network wiretap may be the answer.

From the PC under windows the proverbial Swiss army knife would be “Cain & Able” but on the unix front ettercap is your tool of choice.

My platform is current OSX so I have added notes of pulling down the MacPorts (see previous post for installing the environment).

To install ettercap :

sudo port install ettercap

Assuming that the default gateway on the network is 192.168.2.1 then to tap all traffic heading leaving the local LAN try the following :

sudo ettercap -T -M arp:remote /192.168.2.1/ /192.168.2.2-99/

Because you are running ettercap as root it will alter the permissions of the devices you’ll monitor from. So you need to change the permissins back so that for example Wireshark can open them. To open these devices up for Wireshark try the following:

chmod 666 /dev/bfp*

Now if you fire up Wireshark you will be able to select the relavent interface and sniff the traffic.

I found that applying an initial filter to ignore duplicate IP address messages make the view a little clearer.

Mick

Dynamic Dns on FreeBSD using Bind9

I was looking to install some remote services to my server connected to my home ADSL line. The problem I have is that I have got a dynamic IP address with my DSL line. After trying a number of the public services with varying degrees of sucess and flexibility I decided to build my own solution.

Our companies DNS servers run Bind9 and also the server I run at home also runs Bind9 which means that could use the supplied dns update service with encryption.

Three things are required to achieve this :

1. Method of getting your public IP address
2. Adding a dynamic zone to a dns server (bind9) capable of receiving secure updates
3. Scripting at the ADSL site to tie it all together.

Step 1 – Getting public IP address

There are a number of ways of achieving this – for me I setup a script to return my IP address on our companies servers. Script as follows :

<?
// getipaddress.php
if( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] )) {
    $my_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $my_ip =  $_SERVER['REMOTE_ADDR'];
}
echo $my_ip;
?>

Step 2 – Adding dynamic Zone

First you need to create a key for the zone on your DNS server :

cd /var/named/etc/namedb/
dnssec-keygen -b 512 -a HMAC-MD5 -n HOST dynamic.com

This will generate two files with names like :

Kdynamic.com.+157+34532.key
Kdynamic.com.+157+34532.private

Create the zone file dynamic.com in the dynamic folder

$ORIGIN   dynamic.com.
$TTL      3600           ; 1 hour
@         IN SOA ns.domain.com. hostmaster.domain.com. (
            2009042001   ; Serial
            900          ; refresh (15 mins)
            600          ; retry (10 mins)
            86400        ; expire (1 day)
            3600         ; min (1 hour)
            )
            NS      ns.domain.com.
$TTL      600            ; 10 mins

Add the keys and define the new zone by editing the named.conf file. For this you will need to open the .key file created using dnssec-keygen.

key "dynamic.com" { algorithm hmac-md5; secret "<key from .key file>"; };
zone "dynamic.com" {
    type master;
    file "dynamic/dynamic.com";
    allow-update { key dynamic.com; };
};

Step 3 – Scripting on the client server tying it all together

Securely transfer the two generated key/private files to you home server and place them in the folder /etc/namedb

You need to ensure you have installed the CURL library with OpenSSL support. The following script is one I use to send the updates:

#!/usr/local/bin/php -q
<?
$hostname = "dynamic.com";
$keyfile = "Kdynamic.com.+157+34532.key";
$auto_update_delay = 3600;                      // 1 Hour
$userpwd = "Username:Password";
$dns_server = "100.100.100.100";
$url = "https://myserver.com/getipaddress.php?hostname=".$hostname;
$datfile = "/home/scripts/".$hostname.".nsupdate";
$nsupdate = "/usr/bin/nsupdate -k /var/named/etc/namedb/".$keyfile;

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL,$url );
curl_setopt( $ch, CURLOPT_HEADER, 0);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt( $ch, CURLOPT_TIMEOUT, 30 );
curl_setopt( $ch, CURLOPT_USERPWD, $userpwd );

$response = curl_exec( $ch );
if ( curl_errno($ch) ) {
        print curl_error($ch)."n";
        exit;
} else {
        $ipaddress = curl_exec($ch);
}
if( $ipaddress == "" ) {
        echo "No ip address returnedn";
        exit;
} if ( strlen( $ipaddress ) > 15 ) {
        echo "We got garbagen";
        exit;
}
$cmds = "server ".$dns_server."n".
        "update delete ".$hostname."n".
        "update add ".$hostname." 600 A ".$ipaddress."n".
        "sendn";

$update = TRUE;
if( file_exists( $datfile )) {
        $fp = fopen( $datfile, "r" );
        if( $fp ) {
                $info = fstat( $fp );
                if( $info['ctime'] + $auto_update_delay < time()) {
                        $update = TRUE;
                } else {
                        $saved_cmds = fread( $fp, 1024 );
                        if( $cmds == $saved_cmds ) {
                                $update = FALSE;
                        }
                }
                fclose( $fp );
        }
}
if( $update == TRUE ) {
        $fp = fopen( $datfile, "w" );
        fputs( $fp, $cmds );
        fclose( $fp );
        $cli = $nsupdate." < ".$datfile;
        system( $cli );
        echo $cli."n";

        echo "Updated DNS - ".$hostname." = ".$ipaddress."n";
} else {
        echo "No change DNS - ".$hostname." = ".$ipaddress."n";
}

?>

I have called this script setipaddress.php and I have added it to my crontab and run this every two minutes.

Mick

Implementing Greylisting on FreeBSD

There are a number of ways of tackling spam coming into an ISPs mail servers each with it’s own issues.

1. Sender Verification.

Prior to an email being allowed to enter your mail server; the mail server associated with the senders domain is looked up and a “ring back” is attempted to see if the mail server would accept a reply. The idea here being that if a you receive and email and need to bounce it, you need to know that the sender really exists on the service they say they exist on.

2. Dropping protocol violators

When a connection is made to your mail server you would expect connections to follow the SMTP protocol in a way you would expect. So for example if a connection came in from a mail server to one of you inbound only MX’s and it advised you it was one of your own servers then it’s likely to be bogus. You can be very pedantic ensuring for example that the dns forward and reverse entries match. Or you can ensure that a correctly formatted HELO/EHLO message is found for example. The problem with these is that you cannot afford too many false possitives if you have paying customers expecting to receive their email.

3. Realtime black lists

One of the most successful solutions we have deployed is RBL’s particularly SPAMHaus and SpamCop. Unfortunately we were still allowing a considerable amount of spam through.

4. SpamAssassin

We found SpamAssissin to be problematic on two fronts. Firstly you had to teach it by receiving spam in the first place and secondly it hasn’t been very scaleable. I have looked at slowing the queues down so as not to overwhelm the Spam Assissin processes but this just delays email too much.

Whilst looking around for a solution to this issue I started to investigate GreyListing which appears to have two flavours.

1. Trusting a mail server to send email unless it sends too much in which case start delaying it.

2. Initially advise the inbound mail server you are too busy. Then if they come back between 5mins and 12 hours later assume they are okay and then let them in.

Since spam is really only successful by sending literally thousands (if not more) messages through in the shortest possible time. Then it doesn’t match the normal pattern of an email server. Which will try to send some email and if not successful will be more that happy to try again say every 15 mins, expanding to several hours.

Due to the robustness of the I/O in the BSD kernel I had elected to go with FreeBSD instead of Linux. And I managed to piece together a very simple Grey Listing solution that is exceptionally scaleable 2 – 4 millions inbound connections per server per day, and has proven to be very effective.

The solution consists of a number of quite simple steps:

1. Edit the /etc/rc.conf adding the following lines :

pf_enable="YES"
pflog_enable="YES"
pf_rules="/etc/pf.conf"

obspamd_enable="YES"
# options em1 in this case refers to the interface used to allow multiple boxes to communicate.
obspamd_flags="-v -G5:13:864 -y em1 -Y em1"
obspamlogd_enable="YES"

2. Install the application spamd from /usr/ports/mail/spamd as follows :

cd /usr/ports/mail/spamd
make install distclean

3. Create the file /etc/pf.conf – this is the firewall config to contain the following :

## MACROS
EXT_IF="em0"
PUBLIC_TCP_PORTS="{ 25 }"

## TABLES
table <spamd-white> persist
table <spamd-mywhite> persist file "/var/db/spamd_whitelist.txt"
## GLOBAL OPTIONS
set skip on lo0
set skip on em1  - change this to your internal interface if you have one
## TRAFFIC NORMALISATION
scrub in on $EXT_IF all fragment reassemble
scrub out on $EXT_IF all fragment reassemble random-id no-df

## TRANSLATION RULES
rdr pass inet proto tcp from <spamd-mywhite> to $EXT_IF port smtp -> 127.0.0.1 port smtp
rdr pass inet proto tcp from <spamd-white> to $EXT_IF port smtp -> 127.0.0.1 port smtp
rdr pass inet proto tcp from any to $EXT_IF port smtp -> 127.0.0.1 port spamd

## FILTER RULES
block in log on $EXT_IF all
pass in quick on $EXT_IF proto tcp from any to $EXT_IF port $PUBLIC_TCP_PORTS synproxy state
pass in quick on $EXT_IF proto icmp to $EXT_IF keep state
pass out quick on $EXT_IF proto { tcp udp icmp } all modulate state

4. Create the file /var/db/spamd_whitelist.txt to contain safe senders :

#eg:
10.0.0.0/8
172.168.0.0/12
192.168.0.0/16

5. Edit /usr/local/etc/spamd/spamd.conf adding fixed white and blacklists :

all:
:uatraps:nixspam:whitelist:

# University of Alberta greytrap hits
# Addresses stay in it for 24 hours from time they misbehave.
uatraps:
:black:
:msg="Your address %A has sent mail to a ualberta.ca spamtrapn
within the last 24 hours":
:method=http:
:file=www.openbsd.org/spamd/traplist.gz

# Nixspam recent sources list.
# Mirrored from http://www.heise.de/ix/nixspam
nixspam:
:black:
:msg="Your address %A is in the nixspam listn
See http://www.heise.de/ix/nixspam/dnsbl_en/ for details":
:method=http:
:file=www.openbsd.org/spamd/nixspam.gz
# Whitelists are done like this, and must be added to "all" after each
# blacklist from which you want the addresses in the whitelist removed.
#
whitelist:
:white:
:method=file:
:file=/var/db/spamd_whitelist.txt:

6. Add cronjob to update spamd :

crontab -e

38 * * * *    /usr/local/sbin/spamd-setup > /dev/null 2>&1

(each server is configured at a slightly different hourly offset)

7. Amend your mail software to only listen on ip address 127.0.0.1

8. Reboot the server.

Ensure you have access to the console of the server just in case you have got you pf.conf file wrong and there by locking yourself out.

To monitor how things are going spamdb is your friend. Without parameters is will dump the current list of GREY/WHITELISTED entries and with the -a parameter it will add another address (I haven’t managed to add a network range this way to do that I needed to edit the whitelist file in /var/db).

To see how things are going :

mymx1# spamdb | cut -b 1-4 | sort | uniq -c
1200642 GREY
200318 WHIT

This shows you how many addresses are grey and how many are whitelisted.

The other command to know if pfctl a few examples of command options are as follows but it is a whole subject in it’s own right.

pfctl -t spamd-white -T show

will list the addresses in the whitelist table.

pfctl -sa

will list all the current information on what the packet filter is up to.

pfctl -sr

will list the rules

Good luck

Mick