Imagine you would like to debug an SSL connection to a box, for example HTTPS. Using telnet or netcat, you are not able to do so, but openssl makes this possible, here is how:
First; connect to a machine:
$ openssl s_client -connect mail.google.com:443You will be given the certificate details:
CONNECTED(00000003)
depth=2 /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
verify return:1
depth=1 /C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
verify return:1
depth=0 /C=US/ST=California/L=Mountain View/O=Google Inc/CN=mail.google.com
verify return:1
---
Certificate chain
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=mail.google.com
i:/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
1 s:/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDIjCCAougAwIBAgIQHxn23jXdY6FCkYrVLMCrEjANBgkqhkiG9w0BAQUFADBM
MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg
THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x
MTEyMTgyMzU5NTlaMGkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh
MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRgw
FgYDVQQDFA9tYWlsLmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ
AoGBANknyBHye+RFyUa2Y3WDsXd+F0GJgDjxRSegPNnoqABL2QfQut7t9CymrNwn
E+wMwaaZF0LmjSfSgRSwS4L6ssXQuyBZYiijlrVh9nbBbUbS/brGDz3RyXeaWDP2
BnYyrVFfKV9u+BKLrebFCDmzQ0OpW5Ed1+PPUd91WY6NgKtTAgMBAAGjgecwgeQw
DAYDVR0TAQH/BAIwADA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vY3JsLnRoYXd0
ZS5jb20vVGhhd3RlU0dDQ0EuY3JsMCgGA1UdJQQhMB8GCCsGAQUFBwMBBggrBgEF
BQcDAgYJYIZIAYb4QgQBMHIGCCsGAQUFBwEBBGYwZDAiBggrBgEFBQcwAYYWaHR0
cDovL29jc3AudGhhd3RlLmNvbTA+BggrBgEFBQcwAoYyaHR0cDovL3d3dy50aGF3
dGUuY29tL3JlcG9zaXRvcnkvVGhhd3RlX1NHQ19DQS5jcnQwDQYJKoZIhvcNAQEF
BQADgYEAicju7fexy+yRP2drx57Tcqo+BElR1CiHNZ1nhPmS9QSZaudDA8jy25IP
VWvjEgaq13Hro0Hg32ZNVK53qcXwjWtnCAReojvNwj6/x1Ciq5B6D7E6eiYDSfXJ
8/a2vR5IbgY89nq+wuHaA6vspH6vNR848xO3z1PQ7BrIjnYQ1A0=
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=mail.google.com
issuer=/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
---
No client certificate CA names sent
---
SSL handshake has read 1778 bytes and written 343 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 1024 bit
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : AES256-SHA
Session-ID: 53530BBF94619E255B7956A18D9B9F26241B2A1BF16F30C18C73C88A60200E5F
Session-ID-ctx:
Master-Key:
B40F4E1D533F88AF9248E6576CA4E4CFC2C4BD092816DB7EF9D4FE650EA62B4CAC1F23C36892866B40E3502E67D52CF1
Key-Arg : None
Krb5 Principal: None
Start Time: 1264674178
Timeout : 300 (sec)
Verify return code: 0 (ok)
---Now you can enter commands in plain text, just as you would using telnet or netcat:
HEAD / HTTP/1.0Here is what you get:
HTTP/1.0 302 Found
Cache-Control: private
Location: http://www.google.com
Content-Type: text/html; charset=UTF-8
Content-Length: 218
Date: Thu, 28 Jan 2010 10:23:05 GMT
Server: GFE/2.0
X-XSS-Protection: 0
read:errno=0An easy trick that can also be used to connect to SSL-ed STMP connections, IMAPS, POP3S, etc.
Apple's Time Machine works great, but restoring hidden files (files that start with a dot, like .ssh, .bashrc or .Trash) is difficult, but possible!
Time machine uses the settings as used by the Finder. So first step is to change Finders behaviour, to show hidden files. Execute this command (as a regular user) from within the Terminal.
$ defaults write com.apple.finder AppleShowAllFiles TRUE
$ killall FinderNow you should be able to see extra files in the finder, like this:
Now start Time Machine and scroll back to the date you were sure a file existed.
Restore it and to hide all these (annoying) hidden files, revert to original Finder settings:
$ defaults write com.apple.finder AppleShowAllFiles FALSE
$ killall FinderWhen you would like to retrieve the remotely configured time using SNMP and compare it to see how accurate the time is, here is a script to help you out.
This setup does not specifically require NTP to be running on the hosts that are checked, it just requires that the time is correct. Virtual machines for example are advised to have the appropriate "tools" installed to synchronize time. NTP is not desirable for virtual machines.
(Parts of the script are borrowed from http://spielwiese.la-evento.com/xelasblog/archives/27-SNMP-hrSystemDate.0-Datumsformat-anpassen.html)
This is the graph that is created:
The script:
#!/bin/sh
# Nagios plugin to report time difference as received via SNMP compared to the local time.
# Make sure the machine this script runs on (poller/nagios host) is using NTP.
usage() {
# This function is called when a user enters impossible values.
echo "Usage: $0 -H HOSTADDRESS [-C COMMUNITY] [-w WARNING] [-c CRITICAL] [-v VERSION]"
echo
echo " -H HOSTADDRESS"
echo " The host to check, either IP address or a resolvable hostname."
echo " -C COMMUNITY"
echo " The SNMP community to use, defaults to public."
echo " -v VERSION"
echo " The SNMTP version to use, defaults to 2c."
echo " -w WARNING"
echo " The amount of seconds from where warnings start. Defaults to 60."
echo " -c CRITICAL"
echo " The amount of seconds from where criticals start. Defaults to 120."
exit 3
}
readargs() {
# This function reads what options and arguments were given on the
# command line.
while [ "$#" -gt 0 ] ; do
case "$1" in
-H)
if [ "$2" ] ; then
host="$2"
shift ; shift
else
echo "Missing a value for $1."
echo
shift
usage
fi
;;
-C)
if [ "$2" ] ; then
community="$2"
shift ; shift
else
echo "Missing a value for $1."
echo
shift
usage
fi
;;
-w)
if [ "$2" ] ; then
warning="$2"
shift ; shift
else
echo "Missing a value for $1."
echo
shift
usage
fi
;;
-c)
if [ "$2" ] ; then
critical="$2"
shift ; shift
else
echo "Missing a value for $1."
echo
shift
usage
fi
;;
-v)
if [ "$2" ] ; then
version="$2"
shift ; shift
else
echo "Missing a value for $1."
echo
shift
usage
fi
;;
*)
echo "Unknown option $1."
echo
shift
usage
;;
esac
done
}
checkvariables() {
# This function checks if all collected input is correct.
if [ ! "$host" ] ; then
echo "Please specify a hostname or IP address."
echo
usage
fi
if [ ! "$community" ] ; then
# The public community is used when a user did not enter a community.
community="public"
fi
if [ ! "$version" ] ; then
# Version 2c is used when a user did not enter a version.
version="2c"
fi
if [ ! "$critical" ] ; then
critical="120"
fi
if [ ! "$warning" ] ; then
warning="60"
fi
}
getandprintresults() {
# This converts the date retreived from snmp to a unix time stamp.
rdatestring=$( snmpget -v $version -c $community $host HOST-RESOURCES-MIB::hrSystemDate.0 | gawk '{print $NF}' )
if [ ! "$rdatestring" ] ; then
echo "Time difference could not be calculated; no time received."
exit 3
fi
rdate=$( echo $rdatestring | gawk -F',' '{print $1}' )
rtime=$( echo $rdatestring | gawk -F',' '{print $2}' | gawk -F'.' '{print $1}' )
cldate=$( echo $rdate | gawk -F'-' '{printf("%4i",$1)}; {printf("%02i",$2)}; {printf("%02i",$3)};' )
cltime=$( echo $rtime | gawk -F':' '{printf("%02i",$1)}; {printf("%02i",$2)}; {printf(" %02i",$3)};' )
rdate_s=$( date -d "$cldate $cltime sec" +%s )
ldate_s=$(date +'%s')
# If the calculated difference is negative, make it positive again for comparison.
difference=$(($rdate_s - $ldate_s))
if [ "$difference" -lt 0 ] ; then
positivedifference=$(($difference*-1))
else
positivedifference=$difference
fi
if [ "$positivedifference" -gt "$critical" ] ; then
echo "Time difference is more than $critical seconds: $difference|diff=$difference"
exit 2
fi
if [ "$positivedifference" -gt "$warning" ] ; then
echo "Time difference is more than $warning seconds: $difference|diff=$difference"
exit 1
fi
echo "Time difference is less than $warning seconds: $difference|diff=$difference"
exit 0
}
# The calls to the different functions.
readargs "$@"
checkvariables
getandprintresultsTo implement it in Nagios, add these sniplets to nagios.cfg. (or any other applicable nagios file.)
The service for a group.
define service{
hostgroup_name Servertype_Linux
service_description time
_SERVICE_ID 1856
use SNMP-time
}The service template.
define service{
name SNMP-time
service_description time
use generic-service
check_command check_snmp_time!$_HOSTSNMPCOMMUNITY$!120!60
max_check_attempts 30
normal_check_interval 5
retry_check_interval 1
notification_interval 0
register 0
}The command.
define command{
command_name check_snmp_time
command_line $USER1$/check_snmp_time -H $HOSTADDRESS$ -C $ARG1$ -c $ARG2$ -w $ARG3$
}When you are using MySQL, you will (likely) have tables that can be fragmented. In MySQL terms this is called "OPTIMIZE".
You could simply OPTIMIZE every table in every database, but during an OPTIMIZE, the tables are locked, so writing is not possible.
To minimize the time that MySQL will be locked (and results cannot be written), here is a script that checks fragmentation of every table of every database. Only if a table is fragmented, the table is OPTIMIZED.
#!/bin/sh
echo -n "MySQL username: " ; read username
echo -n "MySQL password: " ; stty -echo ; read password ; stty echo ; echo
mysql -u $username -p"$password" -NBe "SHOW DATABASES;" | grep -v 'lost+found' | while read database ; do
mysql -u $username -p"$password" -NBe "SHOW TABLE STATUS;" $database | while read name engine version rowformat rows avgrowlength datalength maxdatalength indexlength datafree autoincrement createtime updatetime checktime collation checksum createoptions comment ; do
if [ "$datafree" -gt 0 ] ; then
fragmentation=$(($datafree * 100 / $datalength))
echo "$database.$name is $fragmentation% fragmented."
mysql -u "$username" -p"$password" -NBe "OPTIMIZE TABLE $name;" "$database"
fi
done
doneResult will look something like this:
MySQL username: root
MySQL password:
...
database.cache_filter is 19% fragmented.
meinit.cache_filter optimize status OK
database.cache_page is 35% fragmented.
meinit.cache_page optimize status OK
...You may comment out that line with OPTIMIZE TABLE in it, if you are just interested in seeing the fragmentation.
I am not the first (and last) to write about carp, the failover/vip/floating-IP solution OpenBSD is using. Many articles describe this topic including a very complete answer to a frequently asked question about carp.
If you are not familiar with IP failover situations; in case of carp/pulse/HSRP/VIP, an IP "floats" between different machines. One machine actually answers request to received packets, so this is an solution that knows of a MASTER of ACTIVE node .
A CARP interface (which is not physical) is bound to a physical interface. The physical interface advertises statuses so other CARP interfaces know about each other.
You can bind almost any service to a CARP interface, some examples are:
Services that store data/stadia locally are not very suitable for a CARP solution. Examples are: DHCP (because leases are stored localy), MySQL/PostgreSQL (because data is stored on a physical local storage) and SSH (because you can never be sure what machine you are connecting to.
Here is how to set it up. On both boxes add a file /etc/hostname.carp0 with this content:
inet 192.168.1.123 255.255.0 192.168.1.255 vhid 1 pass SeCrEt carpdev em0Remember to activate the interface like this: (All your network cards will be (re-) configured!)
# sh /etc/netstartIn this case, 192.168.1.123 is the floating IP address and em0 is the physical device that carp0 is running on. Be aware that the other server's carpdev should be connected to the same LAN.
Now that this is done, you may access services on the newly created CARP device's IP address. You may also specifically bind applications to only the CARP device.
You may check the status using ifconfig: (Please not the "carp: MASTER" part, it tells you this machine is the master, all others are "BACKUP".)
# ifconfig carp0
carp0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr 00:00:5e:00:01:02
priority: 0
carp: MASTER carpdev em0 vhid 1 advbase 1 advskew 0
groups: carp
inet6 fe80::200:5eff:fe00:102%carp0 prefixlen 64 scopeid 0x5
inet 192.168.1.123 netmask 0xffffff00 broadcast 192.168.1.255One limitation I found; you can not run dhclient on a carp interface, you will need to assign an IP address to the carp device. Please be aware that this would be a very odd setup; DHCP in a failover interface...
I have an existing network at home, but would like to be able to connect to it using a VPN every now and then. This enables me to access the fileserver, printer and so on.
My network contains an Apple Time Capsule as a nat router, an ethernet modem provided by my cable company Ziggo and devices such as laptops, that use the network.
A Soekris box I had lying around meets all requirements perfectly for a VPN-server. Here is how to set it up.
This one is easy enough, on Apple Mac OS X and a Time Capsule (or Airport Express) open AirPort Utility on your Mac, select the Time Capsule, click Manual Setup.
Go to Internet - NAT
Select the box "Enable NAT Port Mapping Protocol" and click on "Configure Port Mappings..."
Click on the "+" to add a portmapping. OpenVPN uses UDP port 1194, so map it from the "Public UDP Port(s)" to the "Private UDP Port(s)" on the "Private IP Address" of your soekris box. Fill in "OpenVPN" in the next "Description" field.
Finish your router configuration by pressing "Update". N.B. The network connection will be gone for a minute or two.
I assume OpenBSD is already running on your Soekris box, otherwise check out how to install your soekris box with OpenBSD.
Add the package "openvpn". A dependency "lzo" will be added automatically.
Create a directory /etc/openvpn/keys:
soekris # mkdir -p /etc/openvpn/keysport 1194
proto udp
dev tun0
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key
dh /etc/openvpn/keys/dh1024.pem
# This is the network that lives on the tun0 device.
# My regular network uses 10.0.1.0/24, so using
# 10.0.2.0/24 seems pretty logical.
server 10.0.2.0 255.255.255.0
ifconfig-pool-persist ipp.txt
# When clients connect, tell them that 10.0.1.0/24 can
# be reached through this tunnel. (You may also set this on the,
# client instead of "broadcasting" this...
push "route 10.0.1.0 255.255.255.0"
client-to-client
keepalive 10 120
comp-lzo
user _openvpn
group _openvpn
persist-key
persist-tun
status openvpn-status.log
verb 3This is quite an abstract step. It boils down to this: on the server you will create a certificate authority (ca) key and certificate, also you will create a key and certificate for each client connecting and sign them using your newly create certificate authority. The certificate from the certificate authority (ca.crt) and client (client1.crt) and the key for the client (client1.key) will be distributed to all clients. That's a mouth full, but here is how to do it in steps:
soekris # cp -Rip /usr/local/share/example/openvpn/easy-rsa /etc/openvpn
soekris # cd /etc/openvpn/easy-rsa/2.0
soekris # cat vars
export EASY_RSA="`pwd`"
export OPENSSL="openssl"
export PKCS11TOOL="pkcs11-tool"
export GREP="grep"
export KEY_CONFIG="/etc/openvpn/easy-rsa/2.0/openssl.cnf"
export KEY_DIR="/etc/openvpn/keys"
echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR
export PKCS11_MODULE_PATH="dummy"
export PKCS11_PIN="dummy"
export KEY_SIZE=1024
export CA_EXPIRE=3650
export KEY_EXPIRE=3650
export KEY_COUNTRY="NL"
export KEY_PROVINCE="UT"
export KEY_CITY="Utrecht"
export KEY_ORG="Me in It Consultancy"
export KEY_EMAIL="robert@meinit.nl"Now execute these steps, as stolen from The OpenVPN homepage.
soekris # . vars
soekris # ./clean-all
soekris # ./build-ca
soekris # ./build-key-server server
soekris # ./build-key client1
soekris # ./build-key client2
soekris # ./build-key client3
soekris # ./build-dhOnce again; send the newly created file /etc/openvpn/keys/ca.crt, /etc/openvpn/keys/client1.crt and /etc/openvpn/keys/client1.key to the machine using the vpn connection.
This step enables client to reach your local network using network address translation. At the bare minimum, add this rule to your pf configuration in /etc/pf.conf
nat pass on sis0 from !(sis0) to any -> (sis0)Also, make sure the packet filter is enabled and is using your pf.cofn
soekris # pfctl -e
soekris # pfclt -f /etc/pf.confAnd finally make sure it works after a reboot:
soekris # echo "ps=yes" >> /etc/rc.conf.localWow, almost there, let's start the software:
soekris # /usr/local/sbin/openvpn --config /etc/openvpn/server.conf --key /etc/openvpn/keys/server.keySome debugging information will scroll down your screen.
Add these lines to your /etc/rc.local.
# Add your local startup actions here.
echo " openvpn"
/usr/local/sbin/openvpn --config /etc/openvpn/server.conf --key /etc/openvpn/keys/server.key >> /var/log/openvpn.output &
echo '.'I use Mac OS X to connect to OpenVPN. You will have to install some extra software, your choices are:
For now I am using the trail version of Viscosity because it looks great. Check out the screenshots below.
When you have setup an LVS you will need to administer it. Here are the tools you can use.
Log in to both boxes and issue the command:
# ipvsadmOr, check /var/log/messages for a line like this:
pulse[$pid]: STARTING PULSE AS BACKUPYou could simple reboot the active machine. Otherwise, stop the service pulse for a moment on the active server. The backup will discover this and configure the floating IP.
On the active machine, issue:
# /etc/init.d/pulse stop
# sleep 60
# /etc/init.d/pulse startUse the piranha web interface, located on port 3636 of either one of the load balancers. Remember to copy /etc/sysconfig/ha/lvs.cf to the backup machine as well.
After you have altered the configuration, restart pulse on the active machine. (Be aware; this makes services unavailable for a couple of seconds.
# ipvsadm
[services are printed]
# /etc/init.d/pulse restart
# ipvsadm
[services should be printed in a couple of seconds.]There are quite a few howto's for LVS, but all of them are quite extensive. To be honest; you'll need to read them at some point, but for now let's try to make a very minimal howto for setting up LVS.
Configure the director/loadbalancer to have two NIC's. One side on a routable network, the other side connected to the machine running the services, called realservers.
# chkconfig ipvsadm on
# sed -i 's/net.ipv4.ip_forward = 0/net.ipv4.ip_forward = 1/' /etc/sysctl.conf
# sysctl -pIf you want your realservers to be able to use the internet, execute these lines on the director. Replace YOURREALSERVERLAN for the network address of the network where the real servers are located, for example. 192.168.1.0
# iptables -A POSTROURING -s YOURREALSERVERSLAN/24 -j MASQUERADE
# service iptables saveFill in the blanks for PUBLICIP and REALSERVERIP. If you would like to add more servers to this virtual server, just repeast the last line a few times, changing the REALSERVERIP every time.
# echo "-A -t PUBLICIP:80" > /etc/sysconfig/ipvsadm
# echo "-a -t PUBLICIP:80 -r REALSERVERIP -m" >> /etc/sysconfig/ipvsadm
# service ipvsadm startFrom a machine other then the redirector and/or the realserver, visit the ipaddress of your virtual ip.
N.B. I have spent quite some time trying to access the loadbalancer from the loadbalancer; this does not work.
Installing and using the monitoring tool Zabbix on OpenBSD is quite simple. Take just these steps to get started.
Use pkg_add to add these packages: (Versions could change over time.)
curl-7.19.3
gettext-0.17p0
jpeg-6bp3
libiconv-1.12
libidn-1.11
libxml-2.6.32p2
net-snmp-5.4.2.1p1
php5-core-5.2.8p0
php5-gd-5.2.8-no_x11
php5-pgsql-5.2.8
png-1.2.33
postgresql-client-8.3.6
postgresql-server-8.3.6
t1lib-5.1.0p1Make sure the apache daemons is started at boot time. (/etc/rc.conf.local)
Modify PHP to allow longer execution times and set the timezone:
$ grep max_execution_time /var/www/conf/php.ini
max_execution_time = 300
$ grep date.timezone /var/www/conf/php.ini
date.timezone = Europe/Amsterdam
$ sudo pkill httpd
$ sudo /usr/sbin/httpdGet the latest release of Zabbix, untar it and use these options to configure it:
./configure --enable-server --with-pgsql --with-net-snmp --with-libcurl --enable-agentImport database schemes as described in the Zabbix documentation, chapter 2.4.3: "Zabbix Server"
Create /etc/zabbix/zabbix_agentd.conf and /etc/zabbix/zabbix_server.conf by copying them from the untarred zabbix release:
# mkdir /etc/zabbix
# cp zabbix-1.6.5/misc/conf/zabbix_agentd.conf /etc/zabbix
# cp zabbix-1.6.5/misc/conf/zabbix_server.conf /etc/zabbixSet DBName DBUser and DBPassword in /etc/zabbix/zabbix_server.conf.
$ cat /etc/rc.local
# $OpenBSD: rc.local,v 1.39 2006/07/28 20:19:46 sturm Exp $
# Site-specific startup actions, daemons, and other things which
# can be done AFTER your system goes into securemode. For actions
# which should be done BEFORE your system has gone into securemode
# please see /etc/rc.securelevel.
echo -n 'starting local daemons:'
# Add your local startup actions here.
if [ -x /usr/local/sbin/zabbix_agentd ] ; then
echo -n ' zabbix_agentd'
/usr/local/sbin/zabbix_agentd
fi
if [ -x /usr/local/sbin/zabbix_server ] ; then
echo -n ' zabbix_server'
/usr/local/sbin/zabbix_server
fi
echo '.'You are practically done, now copy the php files and visit your zabbix installation:
# cp -Rip zabbix-1.6.5/frontends/php/* /var/www/htdocs/zabbix/ That's it, not extremely difficult!
If your are using the Terminal application of your Apple computer running Mac OS X, try bash programmable completion. It allow you to use the TAB key more often, for example in scp: (If you are using ssh-keys.)
$ scp shell01:/etc/pa
/etc/pam.d/ /etc/pam_smb.conf /etc/passwd
/etc/pam_pkcs11/ /etc/pango/ /etc/passwd-
$ scp shell01:/etc/paThe steps to start using this great utility are these: