Archive for the ‘Raspberry Pi’ tag

ClamAV client/server setup  

Posted at 8:37 pm in Uncategorized

Note: This may very well be well-known information, but I found it difficult to get exact answers from the official ClamAV documentation, available man pages, and other kinds of documentation. The most useful hint originated from a mailing list thread considering ClamAV version 0.70, which is getting rather outdated.

My original issue was getting antivirus functionality with mod_security and Apache on a Raspberry Pi server. Due to memory constraints it seems Apache and ClamAV (my version at the time of writing: 0.99) do not coexist happily on the same RPi unit. The obvious solution: Run the ClamAV daemon on a separate device, and set up mod_security with client-side scanning.

The command-line client for antivirus scanning with the ClamAV daemon is named clamdscan. In older Debian releases like Squeeze and Wheezy, clamdscan is included in Debian’s clamav-daemon package, so the daemon will be installed even though you only need the client. This has been fixed in Debian Jessie and above, where clamdscan has become a separate package.

Both the ClamAV daemon (clamd) and the scanner client (clamdscan) have the same configuration file, unless otherwise specified. In Debian this is /etc/clamav/clamd.conf. Getting the client/server relationship configured is a matter of defining the socket on which they communicate. If the client and daemon (server) is running on the same system, the most efficient communication happens over a Unix socket (clamd.conf setting: LocalSocket). On different systems, however, you will need to use the settings TCPAddr and TCPSocket:

TCPAddr defines the IP address (and not TCP address, which would be a port number) on which the server should listen and/or which the client should make contact. Note that the documentation states that TCPAddr is used to define the IP address(es) clamd should listen on, and that it’s by default disabled. However, when setting TCPSocket and leaving TCPAddr unconfigured, clamd will listen on all IP addresses (0.0.0.0/:::). The documentation also makes no mention that the setting is used by clamdscan.

TCPSocket is the TCP port on which the communication takes place.

The following diagram illustrates the relationship:

ClamAV-client-server

Note: On a Squeeze/Wheezy Debian system, setting TCPAddr to a non-local IP address in clamd.conf will naturally make clamd (clamav-daemon) complain. You should disable clamav-daemon and clamav-freshclam on a client-only system:

# update-rc.d -f clamav-daemon remove
update-rc.d: using dependency based boot sequencing
# update-rc.d -f clamav-freshclam remove
update-rc.d: using dependency based boot sequencing

 

After configuring as specified above, antivirus functionality should be tested with clamdscan. On the client node:

# clamdscan -v klez.exe 
klez.exe: W32.Elkern.C FOUND
----------- SCAN SUMMARY -----------
Infected files: 1

 

On the server node, from the ClamAV log:

Sat Mar 5 20:31:59 2016 -> instream(local):
W32.Elkern.C(16bc8fcec023b05b38af3580607bb728:92499) FOUND

 

Finally, I reconfigured the “runav.pl” file in mod_security by changing from clamscan to clamdscan.

 

Written by bjorn on March 5th, 2016

Tagged with , , , , ,

Raspberry Pi controlled mousetrap  

Posted at 1:17 am in Uncategorized

Having had a few spare moments this holiday, I’ve been contemplating how to monitor a mousetrap or two in the attic. By doing that I wouldn’t have to go up to the cold attic in vain, but empty and reset the mousetraps only when needed. It occurred to me that since I’ve already got a Raspberry Pi in the attic for other purposes, why not check the mousetrap from that device? And so, from the combination of an almost justifiable purpose, the testing of the RPi’s GPIO capabilities, and the “this could be fun” factor, a small evening project was born.

Cjmr-SHEbvCD2GdvPOsJfWhBU3mIIdbbajHSU0TUIh4

The micro switch is positioned so that the trap arm pushes the button when set.

I’ve got a few mousetraps from Clas Ohlson that turned out to be the perfect starting point for my project. Locating a small micro switch, I fastened it to the mousetrap’s side with both glue and screws (glue alone might not be sufficient when the trap springs, and/or if it should bounce into something hard). I mounted the switch in a position so that when the mousetrap is in the loaded position, the micro switch button is pressed; when the mousetrap has sprung the button is released.

Following instructions from eLinux, getting the soldering job done was very easy. I connected the mousetrap to a soldering board with the recommended resistor setup, and connectors for the RPi was soldered onto the board as well. After some basic testing with a Python script, the mousetrap was production ready.

LED connectors from an old chassis were recycled.

The LED connectors from an old computer chassis never knew they would be recycled for pest control purposes.

I first considered the idea of configuring the mousetrap alarm as a passive Icinga check, but I opted for an active check through the NRPE server instead. This is the Python code that tests the GPIO status, running on the attic RPi:

#!/usr/bin/env python

import sys
import RPi.GPIO as GPIO

# tell the GPIO module that we want to use the 
# chip's pin numbering scheme
GPIO.setmode (GPIO.BCM)

# setup pin 24 for input
GPIO.setup (24,GPIO.IN)

myexit = 0

if GPIO.input (24):
 print "OK: Trap is set"
else:
 print "CRITICAL: Mouse in trap!"
 myexit = 2

GPIO.cleanup ()
sys.exit (myexit)

 

Then the NRPE configuration, for which the /etc/sudoers file was modified to allow the "nagios" user to run the script with sudo permissions:

command[check_mousetrap]=sudo /usr/local/bin/mousetrap.py

 

Icinga is ready, willing and able.

Finally, on the Icinga2 server, the configuration for the active check of the mousetrap's state. Icinga can be configured to handle an alarm any way you want. Given the non-urgency of emptying a mousetrap, an email alert (my default) was considered sufficient.

object Service "check_mousetrap" {
   import "generic-service"
   display_name = "Mousetrap"
   host_name = "attic_pi"
   check_command = "nrpe"
   vars.nrpe_command = "check_mousetrap"
}

 

With proper monitoring configured, now I just have to wait for the first unlucky tester to come along...

u1Eaq4h8w5x1JH62pGwejo7W6FI7CT8oBB-eFDilk60

The trap is set, rigged with cheese under the yellow lid.

Written by bjorn on December 23rd, 2015

Tagged with , ,

Installing Bro, the network security monitor, on a Raspberry Pi  

Posted at 8:23 pm in Uncategorized

In the continuing quest to install security software on Raspberry Pis, testing their capacity to be used as small nodes that can be placed here and there on demand, the time has come for installing Bro.

The hardware/OS in question is a Raspberry Pi 2, with 1G RAM and 4 CPU cores. It’s running the Jessie version of Raspbian.

The Bro project kindly provides precompiled Debian packages, but only for the i386 and amd64 architectures. Luckily they also provide the source files and build instructions for Debian!

So I followed the instructions listed here but instead of adding the regular repo (starting with “deb“) to /etc/apt/sources.list.d/bro.list, I changed it to deb-src. After that I added the Bro repo key. Commands shown below:

# echo 'deb-src http://download.opensuse.org/repositories/network:/bro/Debian_8.0/ /' \
  >> /etc/apt/sources.list.d/bro.list
# wget http://download.opensuse.org/repositories/network:bro/Debian_8.0/Release.key \
  -O - | apt-key add -

 

Time to update the repo status and then install the dependencies required for the build:

# apt-get update
# apt-get build-dep bro

 

Depending on what you already have running on your RPi, this could be a short or long list of packages. On mine, running Raspbian Jessie, this is what had to be installed:

bison cmake cmake-data libarchive13 libbison-dev libpcap-dev libpython-dev
libpython2.7-dev libssl-dev python-dev python2.7-dev swig swig2.0

 

When that’s done, it’s time for the real job: Build Bro from source with Debian build instructions. This will take some time, on my RPi2 it took ~100 minutes. Below is the command required:

# apt-get source --compile bro

 

When that job has completed, you will find some .deb packages in your current directory. You will need to install them all (except for the dev package), like this:

# dpkg -i bro_2.4.1-0_armhf.deb bro-core_2.4.1-0_armhf.deb \
broctl_2.4.1-0_armhf.deb libbroccoli_2.4.1-0_armhf.deb

 

The Bro software will have been installed under /opt/bro, so that’s where you need to go to start using it. Other people write better Bro documentation than I do so I will leave that to them. A quickstart probably won’t hurt, so after making your local changes to /opt/bro/etc/node.conf you can start Bro as shown below. Logs will appear in /opt/bro/logs/current/.

# /opt/bro/bin/broctl 
Hint: Run the broctl "deploy" command to get started.
Welcome to BroControl 1.4
Type "help" for help.
[BroControl] > deploy
checking configurations ...
installing ...
removing old policies in /opt/bro/spool/installed-scripts-do-not-touch/site ...
removing old policies in /opt/bro/spool/installed-scripts-do-not-touch/auto ...
creating policy directories ...
installing site policies ...
generating standalone-layout.bro ...
generating local-networks.bro ...
generating broctl-config.bro ...
generating broctl-config.sh ...
updating nodes ...
stopping ...
stopping bro ...
starting ...
starting bro ...
[BroControl] > status
Getting process status ...
Getting peer status ...
Name Type Host Status Pid Peers Started
bro standalone localhost running 16514 ??? 01 Nov 22:19:57
[BroControl] >

 

Written by bjorn on November 1st, 2015

Tagged with , , , ,

Streaming pcap to a dummy interface  

Posted at 10:09 pm in Uncategorized

In an earlier article, I described how to stream captured network traffic to a remote host for IDS analysis with Snort. Mikrotik units can stream captured traffic elsewhere using the TaZmen Sniffer Protocol (TZSP). tcpdump and Wireshark natively decode this protocol, but unfortunately it doesn’t seem to be supported by any other of the large amount of useful network analysis tool.

The main usage for streaming the network capture is feeding it to the Snort IDS, and for this single purpose (and since Snort can read from STDIN) piping the traffic directly from tzsp2pcap to Snort works very well. However, now and again I need to look at the network traffic without having to detach Snort from the live stream.

This was solved by making the network traffic stream available over a dummy interface with the brilliant tool tcpreplay, to which I can attach any tool that understands pcap. These are the required incantations:

/sbin/modprobe dummy
/sbin/ip link set name eth10 dev dummy0
/sbin/ifconfig eth10 192.168.42.42
/usr/bin/screen -dm -S tzsp2pcap \
bash -c "/usr/local/sbin/tzsp2pcap -f | \
/usr/bin/tcpreplay --topspeed -i eth10 -"
/etc/init.d/snort start # configured to listen to eth10

The tzsp2pcap process must be run in a screen. Involving bash is required because of the pipe. With tcpreplay --topspeed is useful to avoid delays in the feed.

At this stage, I can point any network tool at eth10 without disrupting Snort.

Written by bjorn on October 5th, 2015

Tagged with , , , , , ,

Mobile entertainment center  

Posted at 8:25 pm in Uncategorized

Our three kids very seldom agree which TV program or movie to watch. Allowing for less discussion when screen time is granted, I’ve set up a mobile entertainment center where each kid may watch the movie of their choice – this may be used during long drives, on trains or buses, and everywhere else where there’s low or no voltage and a need to grant the kids some screen time.

The setup is simple, using a Raspberry Pi B+ running Raspbian and a Mikrotik mAP2n. The RPi is directly connected to the mAP2n with an Ethernet cable. Both are/can be powered by microUSB voltage and cable. The RPi is also equipped with a USB WiFi adapter, configured as a WiFi client, so when the unit is within range of the wireless network at home I can update it and transfer media files to it.

DSC_1377_resized

The two units tied together with velcro. When finalizing the project I will need to find a better case.

Packages installed on the RPi

After having slimmed down the RPi by removing any package not needed, I installed minidlna. While the minidlna project was recently renamed to ReadyMedia, in Debian/Raspbian it still goes by its former name. To administer the mAP2n from the RPi I also installed mactelnet, and to make sure both units logged with useful timestamps I added an ntp server. Finally, it seems the mAP2n does not support running a DHCP server, so I left that to the RPi (isc-dhcp-server). The DHCP server listens only on eth0, to which the mAP2n is connected.

Configuring the tablets

On each kid’s tablet, I installed a DLNA controller (I chose the Ginkgo DLNA player, but I assume any kind of DLNA/UPnP controller will do). Note that the Ginkgo DLNA player is simply streaming from the media center to the device, but not rendering the content – you will need something else for that. I’m very fond of VLC for Android and it works excellent in this use case.

Setting up the mAP2n

Configuring the mAP2n as an AP/bridge, a separate SSID was configured. The mAP2n synchronizes its clock to the RPi. The interfaces wlan1 and ether2 are bridged, and the bridge holds the unit’s IP address.

TL;DR

In essence:

  1. Install Raspbian on a Raspberry Pi.
  2. Install minidlna and isc-dhcp-server.
  3. Configure wlan0, supplying SSID and credentials, for being a WiFi client.
  4. Make sure you can SSH to the RPi over the wlan0 interface. When successful, configure static IP on eth0.
  5. Connect ether2 on mAP2n to eth0 on the RPi.
  6. Configure the mAP2n as an AP/bridge. Set up SSID and credentials for the AP.
  7. Set up the tablets for DNLA streaming.
Note the USB WiFi adapter, providing wireless update of the RPi unit when within range of the home network.

Note the USB WiFi adapter, providing wireless update of the RPi unit when within range of the home network.

Configuration snippets

Configuration for RPi network /etc/network/interfaces:

auto lo
iface lo inet loopback
auto wlan0
iface wlan0 inet dhcp
    wpa-ssid YourSSID
    wpa-psk SomeSecretPassword
auto eth0
iface eth0 inet static
    address 10.1.0.1
    netmask 255.255.255.0
    network 10.1.0.0

 

DHCP server configuration file /etc/dhcp/dhcpd.conf:

ddns-update-style none;
default-lease-time 600;
max-lease-time 7200;
authoritative;
subnet 10.1.0.0 netmask 255.255.255.0 {
    range 10.1.0.100 10.1.0.200;
}

 

DHCP server configuration file /etc/default/isc-dhcp-server:

INTERFACES="eth0"

 

Minidlna configuration file /etc/minidlna/minidlna.conf:

# These are all defaults
media_dir=/var/lib/minidlna
port=8200
serial=12345678
model_number=1

 

mAP2n configuration (sensitive data removed):

[admin@YourAP] > /export
/interface bridge
add name=bridge
/interface wireless security-profiles
set [ find default=yes ] authentication-types=wpa2-psk \
    mode=dynamic-keys supplicant-identity=MikroTik \
    wpa2-pre-shared-key=SecretPassword
add authentication-types=wpa2-psk mode=dynamic-keys \
    name=YourAP supplicant-identity=YourAP \
    wpa-pre-shared-key=SecretPassword \
    wpa2-pre-shared-key=SecretPassword
/interface wireless
set [ find default-name=wlan1 ] band=2ghz-b/g/n \
    country=norway disabled=no frequency=auto \
    l2mtu=1600 mode=ap-bridge security-profile=YourAP \
    wireless-protocol=802.11
/interface bridge port
add bridge=bridge interface=ether2
add bridge=bridge interface=wlan1
/ip address
add address=10.1.0.2/24 interface=bridge network=10.1.0.0
/system clock
set time-zone-name=Europe/Oslo
/system identity
set name=YourAP
/system leds
set 3 interface=wlan1
/system ntp client
set enabled=yes primary-ntp=10.1.0.1

 

Performance

Throughput with three concurrent players showing .mkv movies (720×576 px, 25fps, H264 MPEG-4 AVC, MPEG AAC) sometimes peaks at around 22 Mb/s, and the RPi doesn’t break a sweat when serving at that speed. Obviously different formats would affect the RPi load and WiFi throughput.

Attaching a 4 x AA portable battery pack as shown below, the two units (mAP2n USB powered from the RPi) were running for more than three and a half hour, and during this period they streamed movies to one tablet for two and a half hour.

Exibel battery pack bought from Clas Ohlson.

Exibel battery pack bought from Clas Ohlson.

And for those who might ask: Yes, a Raspberry Pi could simply be equipped with two WiFi adapters, one for client access and for for AP. There are lots of different approaches to this. In my case, I had a spare mAP2n just lying there…

Written by bjorn on May 3rd, 2015

Tagged with , , , ,

IDS with MikroTik and Snort  

Posted at 7:07 pm in Uncategorized

UPDATE: For more flexible streaming, and for not having to hack your Snort init scripts, you might want to consider this article as well. Now back to the scheduled program.

Port mirroring on a strategically positioned switch can be the best setup for an IDS sensor. If that’s not an option, RouterOS-based MikroTik devices support capturing network traffic, streaming it to a remote target using the TZSP protocol. This functionality is available in RouterOS and extended support is provided by the calea package.

Configuring a remote IDS device with MikroTik has been described elsewhere, for instance here and here, but since my plan involved an ARM based Raspberry Pi, MikroTik’s trafr mentioned in those articles could not be used since it’s for x86 only and the source code does not seem to be available. Luckily I found tzsp2pcap which converts the TZSP stream from the MikroTik device into a pcap stream readable by Snort.

My setup

The setup used for this project consists of an RB2011UAS-RM (model is now EOL, replaced by RB2011UiAS-RM) acting as NAT firewall/router, and a Raspberry Pi B+ unit on which I installed Raspbian. The firewall connects to my ISP over a dedicated VLAN, so the outside interface with an official IP address is a bridge VLAN interface named bridge-vlan02-untagged. This will also be the capturing interface.

Note that the traffic capture takes place after NAT, so with this setup Snort will see traffic initiated from the inside as having the official IP address. In other words, you will not see the origin IP address of any suspicious outbound activity.

Compiling tzsp2pcap

Building tzsp2pcap requires the packages git, build-essential and libpcap0.8-dev. Now git clone or download the tzsp2pcap source code. To make tzsp2pcap compile on Raspbian I also had to modify the Makefile somewhat, from

cc -std=c99 -o $@ $(CFLAGS) $(LDFLAGS) -lpcap $<

to

cc -std=gnu99 -o $@ $(CFLAGS) $(LDFLAGS) -lpcap $<

 

After this modification, compile the code:

$ make
cc -std=gnu99 -o tzsp2pcap -Wall -Wextra -pedantic -O2 -lpcap tzsp2pcap.c
tzsp2pcap.c: In function ‘main’:
tzsp2pcap.c:355:12: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 3 has type ‘int’ [-Wformat]
tzsp2pcap.c:355:12: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 4 has type ‘int’ [-Wformat]

You should end up with a binary file named tzsp2pcap. Move it to /usr/local/sbin/ or similar.

IPv6 requirement

Note that tzsp2pcap seems to have been programmed to require IPv6 support even if IPv6 is not necessarily in use. If you get this message:

# tzsp2pcap
socket(): Address family not supported by protocol
Could not setup tzsp listener

…you’ll need to modprobe ipv6 or otherwise enable IPv6.

Verifying the capture

Now it’s time to test the reception of the traffic capture stream. First, start the tzsp2pcap listener, piping the result into tcpdump for making sense of it:

# tzsp2pcap -f | tcpdump -n -q -c 10 -r -

Then start the traffic capture on the MikroTik device. The IP address 10.20.30.40 is where you run tzsp2pcap.

/tool sniffer
set file-limit=0KiB filter-interface=bridge-vlan02-untagged memory-limit=0KiB streaming-enabled=yes streaming-server=10.20.30.40

In your tcpdump session, you should now see something like this:

IP [ip].49386 > 195.159.90.90.6697: tcp 51
IP 195.159.90.90.6697 > [ip].49386: tcp 85
IP [ip].49386 > 195.159.90.90.6697: tcp 0
IP [ip].4100 > 89.10.10.20.5060: UDP, length 419
IP 89.10.10.20.5060 > [ip].4100: UDP, length 547
IP 148.122.7.125 > 224.0.0.1: igmp
[...]

When started as shown above, tcpdump will stop by itself after having received 10 packets. If you see something similar to this, that means that both your MikroTik device and your tzsp2pcap listener are working correctly and you should give yourself a pat on the back!

Installing and testing Snort

Installing Snort is the easiest part: aptitude install snort. After answering the questions during the installation, allow Snort to start. Find out how the process is run:

# ps -ef | grep snort

You should see something like this:

snort 5628 1 1 12:22 ? 00:00:00 /usr/sbin/snort -m 027 -D -d -l /var/log/snort -u snort -g snort -c /etc/snort/snort.conf -S HOME_NET=[10.20.30.0/24] -i eth0

The above is required since we will not be running Snort in a normal fashion. Now stop Snort, and make sure it doesn’t start by itself at boot:

# update-rc.d -f snort remove

Based on the above findings and your own preferences, including what’s defined in snort.conf and any related config files, you should now be ready to forward the stream from the listener and into Snort. Note the ‘-r -‘ at the end, that’s what makes Snort analyze traffic received on STDIN.

# tzsp2pcap -f | snort -m 027 -d -u snort -g snort \
-c /etc/snort/snort.conf -r -

If everything runs as it should, you should start seeing some alerts trickling in. The default log file seems to be /var/log/snort/alert which is nice for debugging and testing. For those somewhat serious about running an IDS, storing alerts to a database will be the better approach.

Some sample output from /var/log/snort/alert:

[**] [1:553:7] POLICY FTP anonymous login attempt [**]
[Classification: Misc activity] [Priority: 3] 
03/14-15:11:12.287084 [ip]:43920 -> [ip]:21
TCP TTL:63 TOS:0x0 ID:0 IpLen:40 DgmLen:88
***AP*** Seq: 0xD87294F5  Ack: 0x7105DEA6  Win: 0xDA  TcpLen: 32
TCP Options (3) => NOP NOP TS: 313122335 3732452130

[**] [1:1321:8] BAD-TRAFFIC 0 ttl [**]
[Classification: Misc activity] [Priority: 3] 
03/14-15:54:18.504939 [ip] -> [ip]
IPV6-FRAG TTL:119 TOS:0x0 ID:625848831 IpLen:40 DgmLen:1096
Frag Offset: 0x016A   Frag Size: 0x0420
[Xref => http://www.isi.edu/in-notes/rfc1122.txt]

[**] [1:1417:9] SNMP request udp [**]
[Classification: Attempted Information Leak] [Priority: 2] 
03/14-16:08:20.293852 93.180.5.26:33306 -> [ip]:161
UDP TTL:245 TOS:0x0 ID:54321 IpLen:20 DgmLen:61
Len: 33
[Xref => http://cve.mitre.org/cgi-bin/cvename.cgi?name=2002-0013]
[Xref => http://cve.mitre.org/cgi-bin/cvename.cgi?name=2002-0012]
[Xref => http://www.securityfocus.com/bid/4132]
[Xref => http://www.securityfocus.com/bid/4089]
[Xref => http://www.securityfocus.com/bid/4088]

[**] [1:469:3] ICMP PING NMAP [**]
[Classification: Attempted Information Leak] [Priority: 2] 
03/14-16:52:10.022351 [ip] -> [ip]
ICMP TTL:37 TOS:0x0 ID:64264 IpLen:20 DgmLen:28
Type:8  Code:0  ID:46546   Seq:0  ECHO
[Xref => http://www.whitehats.com/info/IDS162]

[**] [1:524:8] BAD-TRAFFIC tcp port 0 traffic [**]
[Classification: Misc activity] [Priority: 3] 
03/14-17:15:57.591933 113.108.21.16:12209 -> [ip]:0
TCP TTL:50 TOS:0x0 ID:0 IpLen:20 DgmLen:40 DF
******S* Seq: 0x6F024630  Ack: 0x0  Win: 0x2000  TcpLen: 20

 

Maintaining and tuning Snort

Configuring, maintaining and tuning Snort further is a (large) job in itself, and should be customized according to your own requirements. See the excellent Snort documentation for more on this topic.

System loads

With a network usage at around 7-8 Mb/s, the RB2011 uses about 40-45% CPU with traffic capture enabled, as opposed to 10-15% without traffic capture.

The Raspberry Pi B+ running Snort uses almost no CPU in regular use, but about 90-100% CPU with a load average between 1 and 2 analyzing the network traffic during the download. For this purpose a Raspberry Pi 2 would probably be better suited.

UPDATE: A new test with other hardware shows the following loads:

With 7-8 Mb/s throughput, an RB450G performs at about the same load as the RB2011. Replacing the Snort sensor with a Raspberry Pi 2 shows quite an improvement: Where the regular RPi B+ spent all its CPU resources on traffic analysis (load values between 1 and 3), the RPi2 has a load of 10-15% (load values between 0.10 and 0.15).

Written by bjorn on March 14th, 2015

Tagged with , , , , , ,

Streaming from an underwater camera with a Raspberry Pi  

Posted at 8:45 pm in Uncategorized

kjaerra

Among this summer’s projects was getting an underwater camera online and streaming. The camera is placed within a fishing device designed like a cage, called Kjærra, dating back to the 14th century. The trap has a one-way entry; the fish enters the cage and can’t escape, and is subsequently extracted from the cage. When the trap is opened, the salmon (or trout) inside will be auctioned off to the spectators.

Underwater camera

Underwater camera

Starting with the camera itself, an underwater camera was acquired. The camera unit was secured between two pieces of wood, to make mounting easier and to prevent the camera from being destroyed or dismounted when the fish are extracted from the cage. The camera comes with a 20 meter cable which we led to a nearby dry location, where it’s powered from a battery and charger, providing a stable power source. The camera even has LEDs for night vision, but we’re not using it since it could confuse and scare the fish.

Finding underwater cameras that provide IP network video streams seemed quite impossible. This camera was no exception, providing only regular video signal (the good old yellow RCA plug). To convert the video signal into a computer readable format, we connected the very portable Vivotek VS8100 video server. Apart from the 12V power plug, the unit offers a video signal socket (BNC) and an RJ45 network socket. The unit could even be directly connected to the 12V power cable already provided with the camera.

Video server

Video server

The final piece was of course a Raspberry Pi mini computer, completing the chain by connecting it to the video server. Running the brilliant piece of software avconv, the Raspberry Pi pulls an RTSP video stream from the video server and converts it into an RMTP video stream which in turn is accepted by the streaming distribution server, an Adobe Flash Media Server 3.5. When we’re not streaming live, a short film with some useful information is shown instead.

When streaming live, what the camera sees may be viewed at Østlands-posten’s site. Østlands-posten is hosting the stream distribution; thanks a lot!

Also thanks to Magnus and Lasse at Arkena for hints and clues in this project.

This is the avconv command line, with any sensitive information redacted:

/usr/bin/avconv \
 -i rtsp://underwatercam:554/live.sdp \
 -f flv \
 -vcodec copy \
 -an \
 rtmp://fms-server/path?doPublish=MyPassword/streamName >/dev/null 2>&1

Written by bjorn on July 7th, 2014

Tagged with , , , ,