Setting up ssh reverse tunnels with reversi

# reversi-server and reversiclient
# Author: kazimof at zzero dot org

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# http://www.gnu.org/licenses/.

repo now moved to git.
https://github.com/kazimof/reversi/

WHAT DOES REVERSI DO?
———————
Uses reverse ssh tunnels to expose device ports on a reversi-client’s network to a reversi-server anywhere on the internet.

A reverse ssh tunnel (ssh -R) can be established quite easily, the problem comes with connection stability, where the ssh connection can and does hang from either the server or client end. Reversi tests the validity of the connection from the client every X seconds and re-establishes it if the connection is not fit for purpose.

EXAMPLE USE 1:
—————–
You need to manage a LAN but you have no access to their office broadband router to configure port forwarding.

EXAMPLE USE 2:
—————–
You have OpenWRT devices installed within a public mesh network and you need to be able to manage them.

EXAMPLE USE 3:
—————–
A company router has died or their broadband has been cut or they have moved premises, so they are on a temporary 3/4G connection waiting for a new broadband router with a static IP. Obviously the server not getting mail since port 25 is no longer forwarded by router, and webmail is unavailable to user for the same reason. Using an openwrt inside the network I forward ports 25 and 443 of the mail server to internet allowing the company mail server to receive mail and service web mail requests.

HOW DOES IT WORK?
—————–
reversi-clients are equipped with a password-free ssh key to a user on the reversi-server. Using this key the reversi-client is allowed to do 2 things:
1) run a script that forwards any local port on it’s network the reversi-server
2) run a script on the reversi-server passing arguements that inform the reversi-server about which node they are, which port it is using and what kind of response to expect from that port

On the client side the scripts are both run in gnu-screen, one does the reverse connection and the other acts as a connections monitor, killing and re-establishing the reverse tunnel according to the server response from the script referenced in 2) above.

On the server side the script referenced in 2) above tests to see whether the port is responding with the expected response, if not it assumes the connection has hung, identifies the appropriate PID and kills it. Script then returns a number specifying a time which the client monitor script should wait before retyring the connection.

DESIGN PARAMETERS
—————–
Needs to run on a variety of client OS, I am managing a mix of hundreds of openwrt devices, linux servers and OSX installs, I needed this solution for them all and I am too lazy to maintain multiple forks.
The 2 programs available to all platforms are:

screen
ssh

DESIGN
——
Reversi commprises of 2 components to be installed on the reversi server.

SERVER: hosts a script that clients are authorised to invoke to monitor and manage their reverse tunnel
RECOMMENDED INSTALL FOLDER: /home/reversi/reversi
CLIENT BUILDER: builds the scripts to be run on the client device
RECOMMENDED INSTALL FOLDER: /root/reversi/client-builder

See INSTRUCTIONS.TXT for installation info.

Scripts for monitoring Linux servers

Tired of regularly logging into our servers to find out if anything is wrong, I wanted to know before something like a spam attack or a disk-eater gets out of hand.

Wrote some scripts to automate the process and email me some stats. Yes there are tools to do this for you, but then you have to maintain those tools, and sometimes installing them and configuring them on so many servers can be a pain. This system needs only ssh and mutt, lightweight and available in almost all Linux distributions I know.

This, it’s simply bash installed on one server, and everything is “pushed” fresh to the servers every time it is run, so updates are automatic and easily deployed.

Design

The main script checkserver.sh copies (using scp)  the checkservices, checkdf, checkmailq and checkmaillog scripts and config files to the target host, runs them there and emails the output to you.

On your host servers there is nothing to install except openssh-server. Configure your password-less ssh-keys for all the servers in ~/.ssh/config on your monitoring server with the public keys in /root/.ssh/authorized_keys on the hosts. For help with that see our article: master-ssh-key

Scripts

 

To send notification emails you need a mutt wrapper, almost all distributions have mutt in their repos.

muttcc.sh

func_muttemail () {

#### establish current dir
APPDIR=$( cd “$( dirname “$0″ )” && pwd )
gotdate=`date +%Y-%m-%d-%H-%M`
DEBUGLOG=”$APPDIR/functions-email.log”
echo “ENTERING mutt.sh” | tee -a $DEBUGLOG

#### ASSIGN VARS
mailentity=”$1″
mailsubject=”$2″
maildatafile=”$3″
mailentitycc=”$4″
echo “$mailentity $mailsubject $maildatafile” | tee -a $DEBUGFILE
#send email
echo “cc specified: $4″ | tee -a $DEBUGLOG
if [ x”${mailentitycc}” = x ]
then
#the cc is not set so do not include mecc
mutt -F $APPDIR/muttrc -s “$mailsubject” “$mailentity” < $maildatafile
echo “no cc specified: $mailentitycc” | tee -a $DEBUGLOG
else
mutt -F $APPDIR/muttrc -s “$mailsubject” -c “$mailentitycc” “$mailentity” < $maildatafile
echo “cc specified: $mailentitycc” | tee -a $DEBUGLOG
fi

EX=$?
echo “$EX”
echo “##### EXITING mutt.sh #######” | tee -a $DEBUGLOG
return $EX
}

You’ll need to install mutt and have access to an smtp server. Mine is local and needs no authentication. Normally this fill will be the user’s “.muttrc” file, but in the wrapper we have specified it’s location.

muttrc

set from = “me@myserver.net”
set realname = “CHECKSERVER”
set use_envelope_from = yes
set smtp_url=smtp://mylocalmailserverhostname.net/
set ssl_starttls = no

checkservers.sh

#!/bin/bash
APPDIR=$( cd “$( dirname “$0″ )” && pwd )
. /$APPDIR/muttcc.sh
SERVERLIST=$APPDIR/server.list
MAILQTESTS=$APPDIR/checkmailq.txt
MAILLOGTESTS=$APPDIR/checkmaillog.txt
MAILQSH=$APPDIR/checkmailq.sh
MAILLOGSH=$APPDIR/checkmaillog.sh
DISKDF=$APPDIR/checkdiskdf.sh
CHECKLOG=/tmp/servercheck.log

while IFS=”:” read servername ifmailq ifmaillog ifdiskdf serviceslist
do
echo “=========== SERVERCHECK STARTS: $servername ==============”
echo “=========== SERVERCHECK STARTS: $servername ==============” > $CHECKLOG
echo “———————- disks —————— ” >> $CHECKLOG
if [ “$ifdiskdf” == “diskdf” ]
then
scp $APPDIR/checkdiskdf.sh root@$servername:/usr/local/sbin/
ssh -n root@$servername /usr/local/sbin/checkdiskdf.sh >> $CHECKLOG
else
echo “$servername diskdf not flagged for check” >> $CHECKLOG

fi
echo “———————- services —————— ” >> $CHECKLOG
echo “SERVICEFILE: $serviceslist”
case $serviceslist in
no)
echo “$servername services not flagged for check” >> $CHECKLOG
;;
*)
scp $APPDIR/checkservices-$serviceslist.txt root@$servername:/usr/local/sbin/checkservices.txt
scp $APPDIR/checkservices.sh root@$servername:/usr/local/sbin/
ssh -n root@$servername /usr/local/sbin/checkservices.sh >> $CHECKLOG
esac

echo “———————- mailq —————— ” >> $CHECKLOG
if [ “$ifmailq” == “mailq” ]
then
scp $APPDIR/checkmailq.sh root@$servername:/usr/local/sbin/
scp $APPDIR/checkmailq.txt root@$servername:/usr/local/sbin/
ssh -n root@$servername /usr/local/sbin/checkmailq.sh >> $CHECKLOG
else
echo “$servername mailq not flagged for check” >> $CHECKLOG
fi

echo “—————– maillog —————– ” >> $CHECKLOG
if [ “$ifmaillog” == “maillog” ]
then
scp $APPDIR/checkmaillog.sh root@$servername:/usr/local/sbin/
scp $APPDIR/checkmaillog.txt root@$servername:/usr/local/sbin/
ssh -n root@$servername /usr/local/sbin/checkmaillog.sh >> $CHECKLOG
else
echo “$servername maillog not flagged for check” >> $CHECKLOG
fi
echo “=========== SERVERCHECK ENDS: $servername ==============” >> $CHECKLOG
email_subject=”checkserver results: $servername”
echo “$email_subject”
tmp2=$(func_muttemail “myemail@address.com” “$email_subject” “$CHECKLOG” “ccemail@address.com”)
echo “=========== SERVERCHECK ENDS: $servername ==============”

done < “$SERVERLIST”

checkdiskdf.sh

#!/bin/bash
/bin/df -h
exit

checkmaillog.sh

#!/bin/bash
APPDIR=$( cd “$( dirname “$0″ )” && pwd )
#greps maillotgs and mailqueue fiels for various issues
MAILLOGTESTS=$APPDIR/checkmaillog.txt
MAILRESULT=$APPDIR/checkmailresult.log
MAILRESULTREPORT=$APPDIR/checkmailresult.log
MAILRESULTTEMP=$APPDIR/checkmailresulttemp.log
rm $MAILRESULTTEMP
while IFS=”:” read testname before after
do
datum=`date “+%b %d”`
grep -A$after -B$before “$testname” /var/log/maillog | grep “$datum” >> $MAILRESULTTEMP

done < $MAILLOGTESTS
resultlength=$(cat “$MAILRESULTTEMP” | wc -l)
echo “$resultlength”
if [ “$resultlength” -gt “1” ]
then
echo “issues found”
echo “mail log errors found. lines=$resultlength.” > $MAILRESULTREPORT
cat “$MAILRESULTTEMP” >> $MAILRESULTREPORT
cat “$MAILRESULTREPORT”
else
echo “nothing to report”
fi

checkmaillog.txt

refused to talk to me:0:0
Connection timed out:0:0
Name service error for name:0:0
sender non-delivery notification:0:0
to=<noreply@:0:0
421 Too many concurrent SMTP connections:0:0
testing something:0:0

checkmailq.sh

#!/bin/bash
APPDIR=$( cd “$( dirname “$0″ )” && pwd )
#greps maillotgs and mailqueue fiels for various issues

MAILQTESTS=$APPDIR/checkmailq.txt
MAILRESULT=$APPDIR/checkmailresult.log
MAILRESULTREPORT=$APPDIR/checkmailresult.log
MAILRESULTTEMP=$APPDIR/checkmailresulttemp.log
rm $MAILRESULTTEMP

while IFS=”:” read testname before after
do
/usr/bin/mailq | grep -A$after -B$before “$testname” >> $MAILRESULTTEMP
done < $MAILQTESTS
resultlength=$(cat “$MAILRESULTTEMP” | wc -l)
echo “$resultlength”
if [ “$resultlength” -gt “1” ]
then
echo “issues found”
echo “there is queued mail. lines=$resultlength.” > $MAILRESULTREPORT
cat “$MAILRESULTTEMP” >> $MAILRESULTREPORT
cat “$MAILRESULTREPORT”
else
echo “nothing to report”
fi

checkmailq.sh

#!/bin/bash
APPDIR=$( cd “$( dirname “$0″ )” && pwd )
#greps maillotgs and mailqueue fiels for various issues

MAILQTESTS=$APPDIR/checkmailq.txt
MAILRESULT=$APPDIR/checkmailresult.log
MAILRESULTREPORT=$APPDIR/checkmailresult.log
MAILRESULTTEMP=$APPDIR/checkmailresulttemp.log
rm $MAILRESULTTEMP

while IFS=”:” read testname before after
do
/usr/bin/mailq | grep -A$after -B$before “$testname” >> $MAILRESULTTEMP
done < $MAILQTESTS
resultlength=$(cat “$MAILRESULTTEMP” | wc -l)
echo “$resultlength”
if [ “$resultlength” -gt “1” ]
then
echo “issues found”
echo “there is queued mail. lines=$resultlength.” > $MAILRESULTREPORT
cat “$MAILRESULTTEMP” >> $MAILRESULTREPORT
cat “$MAILRESULTREPORT”
else
echo “nothing to report”
fi

checkmailq.txt

Connection timed out:1:1
Connection refused:1:1

checkservices.sh

#!/bin/bash

#!/bin/bash

APPDIR=$( cd “$( dirname “$0″ )” && pwd )

#greps maillotgs and mailqueue fiels for various issues

SERVICETESTS=$APPDIR/checkservices.txt

RESULTREPORT=$APPDIR/checkservicesresultreport.log

RESULTTEMP=$APPDIR/checkservicesresulttemp.log

rm $RESULTREPORT

rm $RESULTTEMP

while IFS=”:” read portnumber service

do result=$( lsof -i:$portnumber | head -n2 > $RESULTTEMP)

resultlength=$(cat “$RESULTTEMP” | wc -l )

if [ “$resultlength” -gt “1” ] then

#service is running there

echo “OK: $service on $portnumber” >> $RESULTREPORT else

echo “++++++ NOK: $service on $portnumber +++++++++” >> $RESULTREPORT

fi

done < $SERVICETESTS

cat “$RESULTREPORT”

checkservices-ALL.txt

22:ssh
443:https
993:imaps
3306:mysql
389:ldap

servers.list

This is your list of servers to process.

megatron:nomailq:nomaillog:diskdf:ALL
magdelena:mailq:maillog:diskdf:ALL

In my crontab. I don’t want email noise from cron so I use /dev/null 2> &1 to null that.

30 08 * * * /usr/local/sbin/backup_app/checkservers.sh > /dev/null 2>&1

Debugging

Debug email issues with functions-email.log

For output issues log into your remote servers and run the check*.sh files to see what comes out.

Room for improvement

tmp files are used per server in the main loop, so take care not to run this script again until complete or you’ll get nonsense.

Accessibility and Assistive Technology

Computer Accesibility

What is computer accesibility?

This term refers to the accessibility of a computer system to all people, regardless of disability or severity of impairment. It is largely a software concern; when software, hardware, or a combination of both, is used to enable use of a computer by a person with a disability or impairment, this is known as Assistive Technology.

For individuals with mild to medium vision impairment, it is helpful to use large fonts, high DPI displays, high-contrast themes and icons supplemented with auditory feedback and screen magnifying software.

In the case of severe vision impairment such as blindness, screen reader software that provides feedback via text-to-speech or a refreshable braille display is a necessary accommodation for interaction with a computer.

Assistive Technology Software

Vinux is a Linux distribution which has been specially designed for blind and partially sighted users.
It is a remastered version of the Ubuntu distribution and provides users with two screen-readers, two full-screen magnifiers, global font-size and colour changing facilities. The system also supports USB braille displays.
It can be run from a Live CD without making any changes to your hard drive

Requirements for Vinux main Edition:

  • 1 GHz x86 processor.
  • 1 Gb of system memory (RAM).
  • 15 GB of hard-drive space (although this can be split onto 2 drives, a 5Gb / and a 10Gb /home partition fairly easily).
  • Graphics card and monitor capable of 1024 by 768 resolution.
  • Either a Cd/Dvd-drive or a Usb socket (or both).
  • Internet access is helpful though not vital.

Requirements for Vinux (CLI) Installation:

  • 300 MHz x86 processor.
  • 128 MiB of system memory (RAM).
  • 1 GB of disk space.
  • Graphics card and monitor capable of 640×480.
  • CD-ROM drive.

Some other free alternatives:

Orca is a free, open source, flexible, and extensible screen reader for Linux that provides access to graphical desktop environments via user-customizable combinations of speech, braille, and magnification.

There are no specific system requirements, as it is expected to work even with very little RAM.

NVDA(NonVisual Desktop Access) is a free, open source, portable screen reader for Microsoft Windows.

NVDA uses eSpeak as its integrated speech synthesizer, and also supports SAPI synthesizers. Output to braille displays is supported too.
It runs on both 32-bit and 64-bit editions of Microsoft Windows XP or later.

It has no additional hardware requirements beyond those of the operating system and requires less than 50 mb of disk space.

Proprietary software alternatives:

Proprietary software is computer software licensed under exclusive legal right of the copyright holder. The licensee is given the right to use the software under certain conditions, while restricted from other uses, such as modification, further distribution, or reverse engineering.

JAWS (Job Access With Speech) is a computer screen reader program for Microsoft Windows that allows blind and visually impaired users to read the screen either with a text-to-speech output or a refreshable braille display.

There are two versions of the program,standard and professional. A third version for MS-DOS is free.

Window-eyes is a screen reader for Microsoft Windows, compatible with the following versions: Windows 2000, Windows XP, Windows Vista and Windows 7.

master ssh keys

Use ssh to run scripts on remote servers without entering a password.

Create your ssh key


ssh-keygen -b 4096 -t rsa -f ~/.ssh/keyname.rsa


will produce a keypair. The .rsa file will be the private and the .rsa.pub is the one that goes into authorized_keys on the remote server. If you don’t enter a password the key can be used with no user interaction. Do this when you need script operations on a remote server.

Load a key


ssh-add keyname


Upload your ssh key to a server


ssh-copy-id -i keyname.rsa.pub username@remotehost


Carry your key with your ssh session

if you need to carry your key somewhere, for instance if you will be chaining through to a host WITHIN the network of your remotehost and there is no direct ssh port forwarded to that host.


ssh -v username@remote -A


using -v (verbose) can help diagnose connectivity issues

Display the ssh keys you have loaded


ssh-add -l


if you forgot to carry a key or you need to add a local key you will get the error:


ssh-add -l
Could not open a connection to your authentication agent.


in this case use


ssh-agent bash
ssh-add keyname


Using alternative ports

Sometimes your remote host is running ssh on another port since 22 on that IP is already used. To reduce brute force attacks on the standard ssh port you can also use alternative ports by setting up the listening port in sshd_config on the server.

Use the -p flag to specify:


ssh -p 41843 user@remotehost


You can use an -i flag to specify a key to use (always needed in bash scripting for using ssh password-less)


ssh -p 41843 -i ~/.ssh/keyfile.rsa user@remotehost


If you manage many servers you may want to use ~/.ssh/config to alias the connections.


vim ~/.ssh/config
Host remotehost
IdentityFile ~/.ssh/keyname.rsa
Port 41843
ServerAliveInterval 240


In the case above you can simply use ssh user@remotehost to get in using keyfile.rsa on port 41843

How to forward email in Zarafa WebApp

1. Click Setting top-right.

2.  Click Mail Filters to the left.

3. Create a rule.  When the message is sent to … you (choose your name) and click the To: button in the Address Book

4.  Do the following…  Forward the message to… either choose from Address Book and click To: or enter external address in To: field

5.  Tick Stop processing more rules

6.  Click Apply