This article explains how to enhance server security by implementing a server cabinet door alarm system. It provides a detailed guide on how ZZ Servers has addressed the challenge of securing servers in small office or colocation environments, where affordable solutions for monitoring authorized and unauthorized access are often lacking. The solution utilizes a Teensy 2.0 USB device to monitor door entries and can be integrated with any standard monitoring system. The article also covers aspects of temperature and humidity monitoring, though these are not part of the initial proof of concept. It provides comprehensive instructions on setting up the system, including purchasing components, installing firmware, and setting up Linux UDEV rules. Additionally, the text includes a basic C program for querying the alarm status and shows how to integrate the server cabinet door alarm with Zabbix for further monitoring.
Table of Contents
A server cabinet door alarm is an often ovelooked step in securing servers to ensure they are as physically secure as possible and then monitored for unauthorized access. Many times when setting up servers in a small office or co-location facility, many people have their systems in a locking cabinet within a moderately secured physical building. However, a determined attacker can usually bypass many physical controls so adding as many layers and monitoring helps can help both to thwart an attacker or be used to monitor for authorized equipment access through change management filtering on your monitoring and alerting system.
One problem with the small office or colo environment is that very few affordable solutions can be used to monitor for authorized and unauthorized access. To solve this problem, ZZ Servers has implemented a cabinet monitoring solution that is able to not only monitor for cabinet door entry but also has the ability to have temperature and humidity sensors (which we do not actually do in this initial proof of concept).
How did we make the server cabinet door alarm?
The server cabinet door alarm is based on a teensy 2.0 USB device that uses digital inputs to determine if magnetic alarm door switches are open or closed and then monitor their status with any standard monitoring system through a USB connection to the Teensy device. The teensy can be ordered from PJRC for $16. The LED, Resistor and remaining components can be purchased from Jameco, Amazon, Home Depot, Radio Shack or any other similar store.
The teensy is connected through USB to a Linux server in the cabinet that runs an application to query the status of each sensor. The teensy provides a +5V pin that will be connected to a 10k ohm resistor which is then connected to the GND with one connection to each of 4 input pins for the door sensor and an LED connected to interface 11.
The current design is for only 4 alarm switches, but there is no reason the other inputs can’t be used. If additional inputs are used, the associated firmware and software programs will need to be updated to reflect the number of interfaces.
This design also expects there to be a closed circuit on all monitored ports otherwise an alarm will be raised. A simple closed loop will work for any alarm switches not installed.
Once the circuit is assembled, the firmware needs to be uploaded to the teensy. The firmware used is based on the Arduino support for Teensy that can be downloaded. The steps to set up the Teensy/Arduino development environment are found on the page and need to be followed to allow for proper Arduino sketch to be built and loaded onto the teensy flash.
- Extract Arduino Software
- Install 49-teensy.rules in /etc/udev/rules.d (see below for contents of this file)
- Download & Run the teensy Duino installer. Examples/samples are not needed unless doing future development.
Once the development tools are installed:
- Start the Arduino IDE (found in Arduino software extract)
- Connect the teensy USB interface
- Set board type to Teensy 2.0 (Tools/Board/Teensy 2.0)
- Load the code (below)
- Verify (checkbox in IDE) the code
- Upload (right arrow in IDE) the HEX firmware
Teensy Firmware:
The firmware has 3 main sections; the Header where the various variables are defined that are used within the program, The setup function which runs when the teensy is powered on (plugged into USB) and then the loop which is executed after setup executing the designed function.
When the teensy boots, it loads the setup function, which initializes the device allowing for INPUT_PULLUP functionality for the 4 pins used for the alarm. This creates an alert when the switch is opened. The setup then initializes the USB serial device at 38400 8n1, configures the LED output PIN, and ensures the LED is off.
The loop function is the core of the firmware. This is the function that the teensy executes over and over. In this function, the first thing to do is read each of the server cabinet door alarm interfaces, and if there is an alert, flag it so we can be sure to blink the LED. Next, the loop will see if there are any requests on the serial port, which will come from the serial program further down in this post. If there is input from the serial interface, the loop confirms it is a valid request [1,2,3,4] and then prints back on the serial interface a simple message showing the status of the serial ports.
Finally, the loop ends by running the BlinkLED function if there is an alarm otherwise, if the LED is on, be sure to turn it off.
The BlinkLED function works by using a nice variable type provided by the Teensy “elapsedMillis” which creates a timer that is used to trace the time since the variable was created. Using this variable if it has been one second (1000ms) then reset the timer and if the LED is on, turn it off, otherwise turn it on.
zz_alarm0.ino
// Header Section int ledPin = 11; int ledon = 0; int ALARM_1 = 1; int ALERT_1 = 0; int ALARM_2 = 2; int ALERT_2 = 0; int ALARM_3 = 3; int ALERT_3 = 0; int ALARM_4 = 4; int ALERT_4 = 0; int alarmnow = 0; char alarmcheck = ' '; elapsedMillis sinceAlarm; //End Header Section // The setup() method runs once, when the sketch starts void setup() { pinMode(ALARM_1, INPUT_PULLUP); pinMode(ALARM_2, INPUT_PULLUP); pinMode(ALARM_3, INPUT_PULLUP); pinMode(ALARM_4, INPUT_PULLUP); Serial.begin(38400); pinMode(ledPin, OUTPUT); digitalWrite(ledPin, LOW); } // the loop() method runs over and over again, checking for events void loop() { alarmnow = 0; alarmcheck = ' '; ALERT_1 = digitalRead(ALARM_1); ALERT_2 = digitalRead(ALARM_2); ALERT_3 = digitalRead(ALARM_3); ALERT_4 = digitalRead(ALARM_4); if (ALERT_1 || ALERT_2 || ALERT_3 || ALERT_4) { alarmnow = 1; } if (Serial.available()) { alarmcheck = Serial.read(); } switch (alarmcheck) { case '1': if (ALERT_1) { Serial.println("1:1"); } else { Serial.println("1:0"); } break; case '2': if (ALERT_2) { Serial.println("2:1"); } else { Serial.println("2:0"); } break; case '3': if (ALERT_3) { Serial.println("3:1"); } else { Serial.println("3:0"); } break; case '4': if (ALERT_4) { Serial.println("4:1"); } else { Serial.println("4:0"); } break; case ' ': break; default: Serial.println("X:1"); break; } if (alarmnow) { BlinkLED(); } else if (ledon) { digitalWrite(ledPin, LOW); } } void BlinkLED() { if (sinceAlarm >= 1000) { sinceAlarm = sinceAlarm - 1000; if (ledon) { ledon = 0; digitalWrite(ledPin, LOW); } else { ledon = 1; digitalWrite(ledPin, HIGH); } } }
Once the firmware is loaded onto the teensy and all the switches are in place, the Linux system that will interface with the alarm must have a udev rule created to allow the USB serial interface to function.
Linux UDEV rules
/etc/udev/rules/49-teensy.rules
SUBSYSTEMS==”usb”, ATTRS{idVendor}==”16c0″, ATTRS{idProduct}==”04[789]?”, MODE:=”0666″ KERNEL==”ttyACM*”, ATTRS{idVendor}==”16c0″, ATTRS{idProduct}==”04[789]?”, SYMLINK+=”ttyUSB00%n”, MODE:=”0666″, ENV{ID_MM_DEVICE_IGNORE}=”1″
The host that connects to the ZZ-Teensy-Alarm needs to be able to query to the teensy on the USB Serial device to determine the status of any of the configured alarm switch inputs. This is accomplished using a C program that will open the USB serial device presented by the teensy and write/read to the running firmware queries on port status.
The server cabinet door alarm monitor application is a very simple C application. After initializing some variables, it quickly checks the number of command line arguments, providing help and exiting if it is incorrect. Next, the application confirms that the query provided on the command line is a valid interface to query. Alarm-monitor then initializes the specified serial device to 38400 8n1 and writes out the query to the teensy serial device. Once the query is written, the application will wait for a response for 10 seconds, after which the appropriate response is sent back to the user.
Linux Command line zz-teensy-alarm query:
alarm-monitor.c
#include #include #include #include #include #include #include int main(int argc,char** argv) { struct termios tio; struct termios stdio; time_t start,now; int diff; int tty_fd; fd_set rdset; struct flock fl; unsigned char c=' '; if (argc0) { write(STDOUT_FILENO,&c,1); } now = time(NULL); diff = (int)difftime(now,start); } fl.l_type = F_UNLCK; fcntl(tty_fd, F_SETLK, &fl); close(tty_fd); if (diff >= 10) { printf("X:Xn"); exit(1); } exit(0); }
The alarm_monitor application can be compiled with gcc:
gcc -o alarm_monitor alarm_monitor.c
alarm_monitor has 2 inputs, the first is the USB device of the ZZ-Teensy-Alarm, the 2nd is the port to be queried (1-4 is hard coded, any additional ports need to be expanded on for alarm_monitor.c and zz_alarm0.ino).
EX:
alarm_monitor /dev/ttyUSB000 1
1:0
Would query alarm switch 1 and as this example shows returns the alarm #:status where 0 is OK and 1 is switch open (alarm).
There is a 10-second timeout if ZZ-Teensy-Alarm device isn’t connected or if there are connectivity issues. An error code of X:X is returned for any timeout, and any query to ports other than 1,2,3,4 return an invalid query.
Concept Assembly
The initial design for the server cabinet door alarm was built using a breadboard:
ZZ Servers Teensy Cabinet Alarm Prototype
Once the design was tested, a standard radio shack project box and a few screw-down termination jacks were acquired.
How Does ZZ Servers’ Expansion to Equinix Ashburn Impact Server Cabinet Door Alarms?
ZZ Servers’ expansion to Equinix Ashburn has impacted server cabinet door alarms. As zz servers expands equinix ashburn, their presence in the data center has increased. This growth prompts a need for reliable security measures, including server cabinet door alarms, ensuring the protection of valuable equipment and data.
What Makes ZZ Servers a Top Ten Server Company to Watch?
Are you looking for a server company that stands out from the rest? Look no further than ZZ Servers. With their unmatched expertise and cutting-edge technology, ZZ Servers has earned its place on the list of top ten server companies to watch. From their reliable performance to their exceptional customer support, ZZ Servers is truly a leader in the industry. Experience the difference with zz servers top ten to watch.
Zabbix Integration
Once the server cabinet door alarm alarm is in place, it needs to be monitored. Here at ZZ Servers, we leverage Zabbix, but any system such as Nagios could work as long as they can execute a script for input.
Zabbix monitoring can monitor each door alarm’s status through the UserParameters configuration. A full configuration will follow in a future post with templates for items/alerts but for now, below is a sample UserParameter for each of the 4 configured alarm monitors:
/etc/zabbix/zabbix_agentd.conf
UnsafeUserParameters=1
UserParameter=cabinetdoor[*],/usr/local/bin/alarm-monitor /dev/ttyUSB000 $1|cut -d: -f 2
Details on configuring the Zabbix template, including the appropriate items, triggers, and alerts will be posted in my next blog post.
UPDATE: 1/30/2012 – Video of Shmoocon Firetalk – http://vimeo.com/35933398