Personal tools

Difference between revisions of "OpenVPN and VisionSOM-6ULL"

From SomLabs Wiki

Jump to: navigation, search
Line 1: Line 1:
 
{{PageHeader|OpenVPN and VisionSOM-6ULL}}
 
{{PageHeader|OpenVPN and VisionSOM-6ULL}}
 +
__FORCETOC__
 +
 +
''OpenVPN'' [1] is an open-source software application that implements virtual private network (VPN) techniques to create secure point-to-point or site-to-site connections in routed or bridged configurations and remote access facilities. In other words, ''OpenVPN'' allows you to create a private network over the public Internet and tunnels your network connection securely. This tutorial describes the steps to setup a ''OpenVPN'' server on ''SoMLabs'' module.
  
 
== Prerequisites ==
 
== Prerequisites ==
 
This tutorial based on Debian 9.2 image for VisionSOM-6ULL module. Please visit [[How to prepare SD Card with Debian 9.2 for VisionSOM-6ULL on Linux]] or [[How to prepare SD Card with Debian 9.2 for VisionSOM-6ULL on Windows]] for more detailed instruction how to create a bootable microSD card.
 
This tutorial based on Debian 9.2 image for VisionSOM-6ULL module. Please visit [[How to prepare SD Card with Debian 9.2 for VisionSOM-6ULL on Linux]] or [[How to prepare SD Card with Debian 9.2 for VisionSOM-6ULL on Windows]] for more detailed instruction how to create a bootable microSD card.
  
To enable support for LCD-TFT display, please download and apply enable-tft-lcd.patch for somlabs-visionsom-6ull.dts device tree file:
+
'''Kernel configuration – TUN/TAP device support'''
  
<pre>wget http://wiki.somlabs.com/images/c/cd/Enable-tft-lcd.zip
 
unzip Enable-tft-lcd.zip
 
patch /home/developer/source/somlabs-dts-1.0/somlabs-visionsom-6ull.dts ./enable-tft-lcd.patch</pre>
 
 
For more info how to customize, build and upload Device Tree file, please visit [[How to customize Debian 9.2 device tree]].
 
  
== Enabling support for USB Video Class ==
+
''OpenVPN'' requires ''TUN/TAP (CONFIG_TUN) device'' support. The source of this driver is already included in the Linux kernel for ''SoMLabs'' module, but driver is not selected by default. To enable support for ''Universal TUN/TAP device'', please configure kernel with ''menuconfig'' tool:
Most of USB webcams are working on Linux with standard ''UVC driver''. UVC driver is a USB device class that describes devices capable of streaming video like webcams, digital camcorders and television tuners. The source of this driver is already included in the Linux kernel for ''SoMLabs'' module, but driver is not selected by default. To enable support for ''UVC driver'', configure kernel with ''menuconfig'' tool:
 
  
  
cd linux-sources
+
cd <linux-sources>
 
make ARCH=arm menuconfig
 
make ARCH=arm menuconfig
 +
  
 
and choose the right driver:
 
and choose the right driver:
Line 23: Line 21:
  
 
Device Drivers  --->
 
Device Drivers  --->
<*> Multimedia Support --->
+
    <*> Network device support --->
    [*] Cameras/video grabbers support
+
        [*] Network core driver support
    [*] Media USB Adapters  --->
+
         <*> Universal TUN/TAP device driver support
         <*> USB Video Class (UVC)
 
  
 
+
{{clear}}
[[Image:Image1.png|top]]
+
[[Image:Image1.png|center]]
  
 
After all these options have been selected, save your configuration, exit the ''menuconfig'' tool and build a new kernel image:
 
After all these options have been selected, save your configuration, exit the ''menuconfig'' tool and build a new kernel image:
Line 45: Line 42:
  
  
connect Webcam to USB port and boot ''SoMLabs'' module form SD card.
+
and boot ''SoMLabs'' module form SD card.  
 +
 
 +
 
 +
 
 +
 
 +
'''OpenVPN software installation'''
 +
 
 +
 
 +
''OpenVPN'' package – which is available in Debian's default repositories - provides both server and client mode. To update server's package repository and install ''openvpn'' software:
 +
 
 +
 
 +
root@somlabs:~# '''apt-get update'''
 +
root@somlabs:~# '''apt-get install openvpn'''
 +
Reading package lists... Done
 +
Building dependency tree     
 +
Reading state information... Done
 +
The following additional packages will be installed:
 +
  easy-rsa libccid liblzo2-2 libpcsclite1 libpkcs11-helper1 libusb-1.0-0 opensc opensc-pkcs11 openssl pcscd
 +
Suggested packages:
 +
  pcmciautils ca-certificates resolvconf
 +
The following NEW packages will be installed:
 +
  easy-rsa libccid liblzo2-2 libpcsclite1 libpkcs11-helper1 libusb-1.0-0 opensc opensc-pkcs11 openssl openvpn pcscd
 +
...
 +
 
 +
Above'' ''command will also install additional packages, like for example ''easy-rsa'', which we will use to set up our internal ''Certificate Authority'' (CA) infrastructure.
 +
 
 +
 
 +
'''Generating Keys and Certificates - Server'''
 +
 
 +
 
 +
To encrypt traffic between the server and clients, ''OpenVPN'' utilizes set of certificates and keys. A functional ''OpenVPN'' server requires the following certificates/keys:
 +
 
  
 +
* CA's public certificate ('''''ca.crt''''' file),
 +
* server public certificate (in this example - '''''server.crt''''' file),
 +
* server public key (in this example - '''''server.key''''' file),
 +
* the Diffie-Hellman (DH) parameters file ('''''dh2048.pem''''' file),
  
  
Line 52: Line 84:
  
  
 +
To protecting against portscanning, DOS attacks and any eventual buffer overflow vulnerabilities, user can also generate optional ''Hash-based Message Authentication Code'' - HMAC key ('''''ta.key''''' file).
  
  
'''Example 1: OpenCV – first program'''
+
To issue trusted certificates, the first step when setting up ''OpenVPN'' is creation our own simple Certificate Authority (CA) with ''easy-rsa'' tool. As a first, we need to create a new ''/etc/openvpn/rsa'' directory for generated keys and certificates:
  
  
''OpenCV ''[1] is a computer vision library released under a BSD license and hence it is free for both academic and commercial use. It has C++, C, Python and Java interfaces and supports Windows, Linux, Mac OS, iOS and Android. ''OpenCV'' was designed for computational efficiency and with a strong focus on real-time applications.
+
root@somlabs:~# '''mkdir /etc/openvpn/rsa'''
  
  
To install ''OpenCV'' library:
+
and copy the key and certificate generation scripts into new directory:
  
  
apt-get install libopencv-dev
+
root@somlabs:~# '''cp -rf /usr/share/easy-rsa/* /etc/openvpn/rsa'''
  
  
Let's take a look at an example (''opencv-ex1.c'') to capture an image from a webcam:
+
Because ''easy-rsa'' tool cannot find ''/etc/openvpn/rsa/openssl.cnf'' file on Debian 9 “Stretch” Linux Systems, we need to create symbolic symlink before we run generation scripts:
  
  
<nowiki>#include <cv.h></nowiki>
+
root@somlabs:~# '''cd /etc/openvpn/rsa/'''
<nowiki>#include <highgui.h></nowiki>
+
root@somlabs:/etc/openvpn/rsa# '''ln -s openssl-1.0.0.cnf openssl.cnf'''
  
void main (int argc,char *argv[])
 
{
 
  IplImage *color_img;
 
  int c;
 
  
  /* open /dev/video0 device */
+
To configure ''Certificate Authority ''values which will be placed in the certificate, we need to edit the ''/etc/openvpn/rsa/vars'' file and update the following fields:
  CvCapture *cv_cap = cvCaptureFromCAM(0); //'''(A)'''
 
  
  /* create window */
 
  cvNamedWindow ("Video", 0);
 
  
  /* main loop */
+
root@somlabs:/etc/openvpn/rsa# '''vim vars'''
  for(;;)
+
...
    {
+
export KEY_COUNTRY="US"
      /* get and show frame */
+
export KEY_PROVINCE="CA"
      color_img = cvQueryFrame (cv_cap);
+
export KEY_CITY="SanFrancisco"
      if (color_img != 0)
+
export KEY_ORG="Fort-Funston"
        cvShowImage ("Video", color_img);
+
export KEY_EMAIL="me@myhost.mydomain"
 +
export KEY_OU="MyOrganizationalUnit"
 +
...
  
      c = cvWaitKey (10);
 
      if (c == 27)
 
        break;
 
    }
 
  
  /* clean up */
 
  cvReleaseCapture (&cv_cap);
 
  cvDestroyWindow ("Video");
 
}
 
  
  
In line (A), we are passing a device index, which is 0. If our device has two or more cameras, then we can pass the appropriate device index based on what camera to choose. You can find out the number of cameras and associated device indexes using the following command:
+
For example:
  
  
ls -l /dev/video*
+
export KEY_COUNTRY="PL"
 +
export KEY_PROVINCE="Masovian"
 +
export KEY_CITY="Warsaw"
 +
export KEY_ORG="SoMLabs"
 +
export KEY_EMAIL="somlabs@somlabs.com"
 +
export KEY_OU="SoMLabs"
  
  
 +
At this point we are ready to build our CA root. As a first, source the ''vars'' file:
  
To compile and run app:
 
  
 +
root@somlabs:/etc/openvpn/rsa# '''source ./vars'''
  
gcc -o opencv-ex1 opencv-ex1.c `pkg-config --cflags --libs opencv`
 
  
<tt>./opencv-ex1.c</tt>
+
and clean CA root environment:
  
  
 +
root@somlabs:/etc/openvpn/rsa# '''./clean-all '''
  
  
'''Example 2: Tracking colored objects in OpenCV'''
+
Let’s finally generate a certificate authority - '''''ca.crt''''' file (druing this process all of the values should be populated automatically from ''vars'' file - just confirm default values):
  
  
''Example 2'' shows how to detect the presence of a colored object using OpenCV API and computer vision techniques.
+
root@somlabs:/etc/openvpn/rsa# '''./build-ca'''
 +
Generating a 2048 bit RSA private key
 +
.............................+++
 +
..........+++
 +
writing new private key to 'ca.key'
 +
<nowiki>-----</nowiki>
 +
You are about to be asked to enter information that will be incorporated
 +
into your certificate request.
 +
What you are about to enter is what is called a Distinguished Name or a DN.
 +
There are quite a few fields but you can leave some blank
 +
For some fields there will be a default value,
 +
If you enter '.', the field will be left blank.
 +
<nowiki>-----</nowiki>
 +
Country Name (2 letter code) [PL]:
 +
State or Province Name (full name) [Masovian]:
 +
Locality Name (eg, city) [Warsaw]:
 +
Organization Name (eg, company) [SoMLabs]:
 +
Organizational Unit Name (eg, section) [SoMLabs]:
 +
Common Name (eg, your name or your server's hostname) [SoMLabs CA]:
 +
Name [EasyRSA]:
 +
Email Address [somlabs@somlabs.com]:
  
  
The end product of ''Example ''2 should look similar to the photo above (in comparison to ''Example 1'', image from camera and image after transformation will be written directly to framebuffer – there is no need to install ''X Window Server''):
+
Now generate a server key and certificate ('''''server.crt''''' and '''''server.key''''' files):
  
  
[[Image:Image2.png|top]]
+
root@somlabs:/etc/openvpn/rsa# '''./build-key-server server'''
 +
 +
Generating a 2048 bit RSA private key
 +
...
 +
Please enter the following 'extra' attributes
 +
to be sent with your certificate request
 +
A challenge password []:'''somlabs'''
 +
An optional company name []:
 +
Using configuration from /etc/openvpn/rsa/openssl.cnf
 +
Check that the request matches the signature
 +
Signature ok
 +
The Subject's Distinguished Name is as follows
 +
countryName          :PRINTABLE:'PL'
 +
stateOrProvinceName  :PRINTABLE:'Masovian'
 +
localityName          :PRINTABLE:'Warsaw'
 +
organizationName      :PRINTABLE:'SoMLabs'
 +
organizationalUnitName:PRINTABLE:'SoMLabs'
 +
commonName            :PRINTABLE:'server'
 +
name                  :PRINTABLE:'EasyRSA'
 +
emailAddress          :IA5STRING:'somlabs@somlabs.com'
 +
Certificate is to be certified until Jun 24 07:08:08 2028 GMT (3650 days)
 +
Sign the certificate? [y/n]:y
  
Source code of ''opencv-ex2.c'':
+
1 out of 1 certificate requests certified, commit? [y/n]y
 +
Write out database with 1 new entries
 +
Data Base Updated
  
  
<nowiki>#include <iostream></nowiki>
+
To build a Diffie-Hellman key exchange ('''''dh2048.pem''''' file):
<nowiki>#include <fstream></nowiki>
 
<nowiki>#include <stdint.h></nowiki>
 
<nowiki>#include <sys/ioctl.h></nowiki>
 
<nowiki>#include <linux/fb.h></nowiki>
 
<nowiki>#include <fcntl.h></nowiki>
 
  
<nowiki>#include "cv.h"</nowiki>
 
<nowiki>#include "highgui.h"</nowiki>
 
  
<nowiki>#define IMG_1_X_OFFSET</nowiki>        60
+
root@somlabs:/etc/openvpn/rsa# '''./build-dh'''
<nowiki>#define IMG_1_Y_OFFSET</nowiki>        140
+
Generating DH parameters, 2048 bit long safe prime, generator 2
 +
This is going to take a long time
  
<nowiki>#define IMG_2_X_OFFSET</nowiki>        420
 
<nowiki>#define IMG_2_Y_OFFSET</nowiki>        140
 
  
<nowiki>#define PRINT_COORD_TO_STDOUT</nowiki>    0
+
(it will take some time to generate the the files)
<nowiki>#define LINE_WIDTH</nowiki>        4
 
<nowiki>#define MAX_LINE_NUMS</nowiki>        200
 
  
<nowiki>#define HSV_COLOR_MIN cvScalar (0, 100, 100) /* cvScalar (H,S,V); */</nowiki>
 
<nowiki>#define HSV_COLOR_MAX cvScalar (2, 255, 255) /* cvScalar (H,S,V); */</nowiki>
 
  
using namespace cv;
+
For additional security, user can also generate optional ''Hash-based Message Authentication Code'' - HMAC key ('''''ta.key''''' file):
using namespace std;
 
  
static ofstream ofs;
 
  
static IplImage*
+
<tt>root@somlabs:/etc/openvpn/rsa# openvpn --genkey --secret keys/ta.key</tt>
convert_image (IplImage* img)
 
{
 
  IplImage *imgHSV = cvCreateImage (cvGetSize(img), 8, 3);
 
  IplImage *imgTHR = cvCreateImage (cvGetSize(img), 8, 1);
 
  
  cvCvtColor (img, imgHSV, CV_BGR2HSV);
 
  cvInRangeS (imgHSV, HSV_COLOR_MIN, HSV_COLOR_MAX, imgTHR);
 
  
  cvReleaseImage (&imgHSV);
+
At this point we have generated all required certificates/keys for server instance (all generated files were placed within the ''/etc/openvpn/rsa/keys'' directory) - let’s move them to ''/etc/openvpn/server'':
  return imgTHR;
 
}
 
  
static void
 
fb_show_image (IplImage *img, int x_off, int y_off)
 
{
 
  Mat frame = cvarrToMat (img);
 
  
  if (frame.channels() == 1)
+
<tt>root@somlabs:~# cd /etc/openvpn/rsa/keys/</tt>
  {
 
    Mat in[] = {frame, frame, frame};
 
    merge (in, 3, frame);
 
  }
 
  
  if (frame.depth() != CV_8U)
+
<tt>root@somlabs:/etc/openvpn/rsa/keys# cp ca.crt /etc/openvpn/server</tt>
    {
 
      cout << "[error ] img: not 8 bits per pixel and channel" << endl;
 
      return;
 
    }
 
  else if (frame.channels() != 3)
 
    {
 
      cout << "[error ] img: not 3 channels" << endl;
 
      return;
 
    }
 
  else
 
    {
 
      Size2f frame_size = frame.size();
 
      Mat frame_compat;
 
  
      cvtColor(frame, frame_compat, cv::COLOR_BGR2BGR565);
+
<tt>root@somlabs:/etc/openvpn/rsa/keys# cp server.crt /etc/openvpn/server</tt>
  
      for (int y = y_off; y < frame_size.height + y_off; y++)
+
<tt>root@somlabs:/etc/openvpn/rsa/keys# cp server.key /etc/openvpn/server</tt>
        {
 
          ofs.seekp ((y * 800 * 2) + x_off * 2);
 
          ofs.write (reinterpret_cast<char*>(frame_compat.ptr(y-y_off)), frame_size.width*2);
 
        }
 
    }
 
}
 
  
int
+
<tt>root@somlabs:/etc/openvpn/rsa/keys# cp dh2048.pem /etc/openvpn/server</tt>
main (int, char**)
 
{
 
  CvCapture    <nowiki>*cam = NULL;</nowiki>
 
  IplImage    <nowiki>*frame = NULL;</nowiki>
 
  unsigned int  num_of_lines = 0;
 
  
  /* threshold */
+
<tt>root@somlabs:/etc/openvpn/rsa/keys# cp ta.key /etc/openvpn/server</tt>
  IplImage *frame_thr = NULL;
 
  
  /* trajectory */
 
  IplImage *frame_trj = NULL;
 
  
  /* moments */
 
  CvMoments *moments = (CvMoments*)malloc(sizeof(CvMoments));
 
  double moment_10;
 
  double moment_01;
 
  double central;
 
  
  /* coordinates */
 
  int posX = 0, posY = 0;
 
  int lastX, lastY;
 
  
  /* [1] open /dev/video1 - 320x240 */
 
  cam = cvCaptureFromCAM(1);
 
  cvSetCaptureProperty (cam, CV_CAP_PROP_FRAME_WIDTH, 320);
 
  cvSetCaptureProperty (cam, CV_CAP_PROP_FRAME_HEIGHT, 240);
 
  if (!cam)
 
    {
 
      cout << "[error ] cannot open the video cam" << endl;
 
      return -1;
 
    }
 
  
  /* [2] open framebuffer */
 
  ofs.open ("/dev/fb0");
 
  
  /* [3] enter to mainloop */
 
  while(1)
 
    {
 
      /* grab frame */
 
      frame = cvQueryFrame (cam);
 
  
      /* thresholding */
 
      frame_thr = convert_image (frame);
 
  
      /* moments */
 
      cvMoments (frame_thr, moments, 1);
 
      moment_10 = cvGetSpatialMoment (moments, 1, 0);
 
      moment_01 = cvGetSpatialMoment (moments, 0, 1);
 
      central = cvGetCentralMoment (moments, 0, 0);
 
  
      /* coordinates */
 
      lastX = posX;
 
      lastY = posY;
 
      posX = moment_10/central;
 
      posY = moment_01/central;
 
  
<nowiki>#if PRINT_SYMBOL_TO_STDOUT</nowiki>
 
      cout << " X: " << posX << " Y: " << posY << endl;
 
<nowiki>#endif</nowiki>
 
  
      /* trajectory */
 
      if (!frame_trj)
 
        frame_trj = cvCreateImage (cvGetSize(frame), 8, 3);
 
      if (lastX>0 && lastY>0 && posX>0 && posY>0)
 
        {
 
          cvLine (frame_trj, cvPoint(posX, posY), cvPoint(lastX, lastY), cvScalar(255,255,0), LINE_WIDTH);
 
  
      num_of_lines++;
 
      if (num_of_lines == MAX_LINE_NUMS)
 
            {
 
              cvZero (frame_trj);
 
              num_of_lines=0;
 
            }
 
        }
 
  
      /* combine trajectory with captured frame */
 
      cvAdd (frame, frame_trj, frame);
 
  
      /* show images */
+
'''Generating Keys and Certificates - Client'''
      fb_show_image (frame, IMG_1_X_OFFSET, IMG_1_Y_OFFSET);
 
      fb_show_image (frame_thr, IMG_2_X_OFFSET, IMG_2_Y_OFFSET);
 
  
      cvReleaseImage (&frame_thr);
 
    }
 
  
error:
+
In this example we will generate key and certificate pair for one client – you can repeat below steps for each new client, but please remember to set up unique name for all new clients. Please also remember that in production environments - for security purposes – keys should be generated on client machine and signed by the CA machine (it is recommended that the CA machine be separate from the machine running OpenVPN - do not store the ''easy-rsa'' CA files on the OpenVPN server!) – in this example we will generate the signed key on the server:
  
  cvReleaseImage (&frame);
 
  cvReleaseImage (&frame_thr);
 
  cvReleaseImage (&frame_trj);
 
  
  delete moments;
+
root@somlabs:/etc/openvpn/rsa# '''./build-key client1'''
  cvReleaseCapture (&cam);
+
Generating a 2048 bit RSA private key
 +
...
 +
writing new private key to 'client1.key'
 +
...
 +
Certificate is to be certified until Jun 24 07:39:23 2028 GMT (3650 days)
 +
Sign the certificate? [y/n]:y
  
  cout << "[status] exiting..." << endl;
+
1 out of 1 certificate requests certified, commit? [y/n]y
  return 0;
+
Write out database with 1 new entries
}
+
Data Base Updated
  
 +
Copy the necessary key files to client, via a secure way (such as SSH), including:
  
To compile and run app:
 
  
 +
* ''/etc/openvpn/easy-rsa/keys/ca.crt,''
 +
* ''/etc/openvpn/easy-rsa/keys/client1.crt,''
 +
* ''/etc/openvpn/easy-rsa/keys/client1.key,''
 +
* ''/etc/openvpn/easy-rsa/keys/ta.key ''(if using tls-auth).
  
gcc -o opencv-ex2 opencv-ex2.c `pkg-config --cflags --libs opencv`
 
./opencv-ex2
 
  
  
If you want to try some different color, you'll have to figure out it's HSV [2] (Hue, Saturation and Value) and edit ''HSV_COLOR_MIN'' and ''HSV_COLOR_MAX'' thresholds. Please remember that different applications use different scales for HSV. For example ''GIMP'' uses H=0-360, S=0-100 and V=0-100. But ''OpenCV'' uses H=0-180, S=0-255, V=0-255.
 
  
  
  
  
'''Example 3: QR code scanner using OpenCV and ZBar'''
+
'''Configure the OpenVPN Service'''
  
  
''OpenCV'' can be easily combined with other libraries, like for example ''ZBar'' [3]. ''ZBar'' is an open source software suite for reading bar codes from various sources, such as video streams, image files and raw intensity sensors. It supports many popular types of bar codes including EAN-13/UPC-A, UPC-E, EAN-8, Code 128, Code 39, Interleaved 2 of 5 and QR Code.
+
The ''OpenVPN'' package comes with set of example configuration files which are an ideal starting point for a basic ''OpenVPN'' server setup with the following features:
  
  
To install ''ZBar'' library:
+
* uses Public Key Infrastructure for authentication,
 +
* creates a VPN using a virtual TUN network interface,
 +
* listens for client connections on UDP port 1194,
 +
* distributes virtual addresses to connecting clients from the 10.8.0.0/24 subnet.
  
  
apt-get install libzbar-dev
 
  
  
Sample usage of ''OpenCV'' and ''ZBar'' libraries (like in previous example, results will be written directly to framebuffer):
 
  
 +
To prepare such basic server setup, copy and unzip a sample ''OpenVPN'' configuration file into configuration directory:
  
<nowiki>#include <iostream></nowiki>
 
<nowiki>#include <fstream></nowiki>
 
<nowiki>#include <stdint.h></nowiki>
 
<nowiki>#include <sys/ioctl.h></nowiki>
 
<nowiki>#include <linux/fb.h></nowiki>
 
<nowiki>#include <fcntl.h></nowiki>
 
<nowiki>#include <zbar.h></nowiki>
 
  
<nowiki>#include <opencv2/imgproc/imgproc.hpp></nowiki>
+
<tt>root@somlabs:~# gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > /etc/openvpn/server/server.conf</tt>
<nowiki>#include <opencv2/highgui/highgui.hpp></nowiki>
 
  
<nowiki>#define CAM_X_OFFSET</nowiki>        60
 
<nowiki>#define CAM_Y_OFFSET</nowiki>        140
 
  
<nowiki>#define</nowiki>    PRINT_SYMBOL_TO_STDOUT    0
+
Edit the ''/etc/openvpn/server/server.conf'' file making a minimum of the following changes:
<nowiki>#define SHOW_SYMBOL_FRAME</nowiki>    1
 
  
using namespace cv;
 
using namespace std;
 
using namespace zbar;
 
  
static ofstream ofs;
+
...
 +
ca ca.crt
 +
cert server.crt
 +
key server.key
 +
dh dh2048.pem
 +
...
 +
user nobody
 +
group nobody
  
int
 
main (int, char**)
 
{
 
  ImageScanner scanner;
 
  Mat frame;
 
  
  /* [1] open /dev/video1 - 320x240 */
+
As a option, you can uncomment:
  VideoCapture cap(1);
 
  cap.set (CV_CAP_PROP_FRAME_WIDTH, 320);
 
  cap.set (CV_CAP_PROP_FRAME_HEIGHT, 240);
 
  if (!cap.isOpened())
 
    {
 
      cout << "[error ] cannot open the video cam" << endl;
 
      return -1;
 
    }
 
  
  /* [2] init zbar */
 
  scanner.set_config (ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
 
  
  /* [3] open framebuffer */
+
push "redirect-gateway def1 bypass-dhcp"
  ofs.open ("/dev/fb0");
 
  
  /* [4] enter to mainloop */
 
  while (true)
 
    {
 
      Mat grey;
 
  
      /* grab frame */
+
line to redirect all traffic through our ''OpenVPN''. For more advanced configurations, please see ''OpenVPN documentation'' [2].
      cap >> frame;
 
  
      /* BGR->GREY conversion */
 
      cvtColor (frame, grey, CV_BGR2GRAY);
 
      Image image (frame.cols, frame.rows, "Y800", (uchar*) grey.data, frame.cols * frame.rows);
 
  
      /* scan the image for barcodes */
+
To start OpenVPN server:
      scanner.scan (image);
 
  
      /* get and process result - only one code */
 
      Image::SymbolIterator symbol = image.symbol_begin();
 
      if (symbol != image.symbol_end())
 
        {
 
  
          string code_type = symbol->get_type_name();
+
root@somlabs:/etc/openvpn# '''openvpn /etc/openvpn/server.conf'''
          string code_data = symbol->get_data();
+
...
 +
Wed Jun 27 08:04:19 2018 TUN/TAP device tun0 opened
 +
Wed Jun 27 08:04:19 2018 TUN/TAP TX queue length set to 100
 +
Wed Jun 27 08:04:19 2018 do_ifconfig, tt->did_ifconfig_ipv6_setup=0
 +
Wed Jun 27 08:04:19 2018 /sbin/ip link set dev tun0 up mtu 1500
 +
...
 +
Wed Jun 27 08:04:19 2018 UDPv4 link remote: [AF_UNSPEC]
 +
Wed Jun 27 08:04:19 2018 GID set to nogroup
 +
Wed Jun 27 08:04:19 2018 UID set to nobody
 +
Wed Jun 27 08:04:19 2018 MULTI: multi_init called, r=256 v=256
 +
Wed Jun 27 08:04:19 2018 IFCONFIG POOL: base=10.8.0.4 size=62, ipv6=0
 +
Wed Jun 27 08:04:19 2018 IFCONFIG POOL LIST
 +
Wed Jun 27 08:04:19 2018 '''Initialization Sequence Completed'''
  
<nowiki>#if PRINT_SYMBOL_TO_STDOUT</nowiki>
 
          cout << "[" << code_type << "] " << code_data << " " << endl;
 
<nowiki>#endif</nowiki>
 
  
<nowiki>#if SHOW_SYMBOL_FRAME</nowiki>
+
To connect to the ''OpenVPN'' server, the client requires a key and certificate that we created already:
          {
 
            RotatedRect rect;
 
            Point2f points[4];
 
            vector<Point> vector;
 
  
            int n = symbol->get_location_size();
 
            for (int i=0; i<n; i++)
 
              vector.push_back (Point (symbol->get_location_x(i), symbol->get_location_y(i)));
 
  
            rect = minAreaRect (vector);
+
* ''/etc/openvpn/easy-rsa/keys/ca.crt,''
            rect.points (points);
+
* ''/etc/openvpn/easy-rsa/keys/client1.crt,''
 +
* ''/etc/openvpn/easy-rsa/keys/client1.key,''
 +
* ''/etc/openvpn/easy-rsa/keys/ta.key ''(if using tls-auth).
  
            for (int i=0; i<4; i++)
 
              line(frame, points[i], points[(i+1)%4], Scalar(255,0,0),3);
 
          }
 
<nowiki>#endif</nowiki>
 
        }
 
  
      /* write data to framebuffer */
 
      if (frame.depth() != CV_8U)
 
        {
 
          cout << "[error ] cam: not 8 bits per pixel and channel" << endl;
 
          goto error;
 
        }
 
      else if (frame.channels() != 3)
 
        {
 
          cout << "[error ] cam: not 3 channels" << endl;
 
          goto error;
 
        }
 
      else
 
        {
 
          Size2f frame_size = frame.size();
 
          Mat frame_compat;
 
  
          cvtColor (frame, frame_compat, COLOR_BGR2BGR565);
 
  
          for (int y = CAM_Y_OFFSET; y < frame_size.height + CAM_Y_OFFSET; y++)
 
            {
 
              ofs.seekp ((y * 800 * 2) + CAM_X_OFFSET * 2);
 
              ofs.write (reinterpret_cast<char*>(frame_compat.ptr(y-CAM_Y_OFFSET)), frame_size.width*2);
 
            }
 
        }
 
  
    } /* while */
+
Copy the above files to client device (with OpenVPN client software) and afterwards create a new file called for ''client.ovpn'' with minimal configuration (like below):
  
error:
 
  cout << "[status] exiting..." << endl;
 
  
}
+
client
 +
dev tun
 +
proto udp
 +
remote <openvpn server IP> 1194
 +
resolv-retry infinite
 +
nobind
 +
persist-key
 +
persist-tun
 +
comp-lzo
 +
verb 3
 +
ca ca.crt
 +
cert client1.crt
 +
key client1.key
  
  
To compile and run app:
+
'''Please remember that your network infrastructure with OpenVPN server may need additional configuration – please check out your firewall, port forwarding and iptables settings in case of any troubles.'''
  
  
gcc -o opencv-ex3 opencv-ex3.c `pkg-config --cflags --libs opencv zbar`
+
At this point you should be ready to enable traffic routing to ''OpenVPN'' server. For more info please visit:
  
<tt>./opencv-ex3</tt>
 
  
[[Image:Image3.png|top]]
+
[1] [https://openvpn.net/ https://openvpn.net/]
  
[1] [https://opencv.org/ https://opencv.org/]
+
[2] [https://openvpn.net/index.php/open-source/documentation https://openvpn.net/index.php/open-source/documentation]
  
[2] [https://en.wikipedia.org/wiki/HSL_and_HSV https://en.wikipedia.org/wiki/HSL_and_HSV]
+
[3] [https://help.ubuntu.com/community/OpenVPN https://help.ubuntu.com/community/OpenVPN]
  
[3] [http://zbar.sourceforge.net/ http://zbar.sourceforge.net/]
+
[4] [https://wiki.archlinux.org/index.php/OpenVPN https://wiki.archlinux.org/index.php/OpenVPN]

Revision as of 12:27, 1 July 2018

OpenVPN and VisionSOM-6ULL



OpenVPN [1] is an open-source software application that implements virtual private network (VPN) techniques to create secure point-to-point or site-to-site connections in routed or bridged configurations and remote access facilities. In other words, OpenVPN allows you to create a private network over the public Internet and tunnels your network connection securely. This tutorial describes the steps to setup a OpenVPN server on SoMLabs module.

Contents

Prerequisites

This tutorial based on Debian 9.2 image for VisionSOM-6ULL module. Please visit How to prepare SD Card with Debian 9.2 for VisionSOM-6ULL on Linux or How to prepare SD Card with Debian 9.2 for VisionSOM-6ULL on Windows for more detailed instruction how to create a bootable microSD card.

Kernel configuration – TUN/TAP device support


OpenVPN requires TUN/TAP (CONFIG_TUN) device support. The source of this driver is already included in the Linux kernel for SoMLabs module, but driver is not selected by default. To enable support for Universal TUN/TAP device, please configure kernel with menuconfig tool:


cd <linux-sources> make ARCH=arm menuconfig


and choose the right driver:


Device Drivers --->

   <*> Network device support  --->
       [*] Network core driver support
       <*> Universal TUN/TAP device driver support

Template:Clear

After all these options have been selected, save your configuration, exit the menuconfig tool and build a new kernel image:


make ARCH=arm zImage


In last steps, transfer the new kernel images to a microSD:


sudo mount /dev/sdbX /mnt/sdcard cd /mnt/sdcard sudo cp <linuxsources>/arch/arm/boot/zImage boot/


and boot SoMLabs module form SD card.



OpenVPN software installation


OpenVPN package – which is available in Debian's default repositories - provides both server and client mode. To update server's package repository and install openvpn software:


root@somlabs:~# apt-get update root@somlabs:~# apt-get install openvpn Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed:

 easy-rsa libccid liblzo2-2 libpcsclite1 libpkcs11-helper1 libusb-1.0-0 opensc opensc-pkcs11 openssl pcscd

Suggested packages:

 pcmciautils ca-certificates resolvconf

The following NEW packages will be installed:

 easy-rsa libccid liblzo2-2 libpcsclite1 libpkcs11-helper1 libusb-1.0-0 opensc opensc-pkcs11 openssl openvpn pcscd

...

Above command will also install additional packages, like for example easy-rsa, which we will use to set up our internal Certificate Authority (CA) infrastructure.


Generating Keys and Certificates - Server


To encrypt traffic between the server and clients, OpenVPN utilizes set of certificates and keys. A functional OpenVPN server requires the following certificates/keys:


  • CA's public certificate (ca.crt file),
  • server public certificate (in this example - server.crt file),
  • server public key (in this example - server.key file),
  • the Diffie-Hellman (DH) parameters file (dh2048.pem file),



To protecting against portscanning, DOS attacks and any eventual buffer overflow vulnerabilities, user can also generate optional Hash-based Message Authentication Code - HMAC key (ta.key file).


To issue trusted certificates, the first step when setting up OpenVPN is creation our own simple Certificate Authority (CA) with easy-rsa tool. As a first, we need to create a new /etc/openvpn/rsa directory for generated keys and certificates:


root@somlabs:~# mkdir /etc/openvpn/rsa


and copy the key and certificate generation scripts into new directory:


root@somlabs:~# cp -rf /usr/share/easy-rsa/* /etc/openvpn/rsa


Because easy-rsa tool cannot find /etc/openvpn/rsa/openssl.cnf file on Debian 9 “Stretch” Linux Systems, we need to create symbolic symlink before we run generation scripts:


root@somlabs:~# cd /etc/openvpn/rsa/ root@somlabs:/etc/openvpn/rsa# ln -s openssl-1.0.0.cnf openssl.cnf


To configure Certificate Authority values which will be placed in the certificate, we need to edit the /etc/openvpn/rsa/vars file and update the following fields:


root@somlabs:/etc/openvpn/rsa# vim vars ... export KEY_COUNTRY="US" export KEY_PROVINCE="CA" export KEY_CITY="SanFrancisco" export KEY_ORG="Fort-Funston" export KEY_EMAIL="me@myhost.mydomain" export KEY_OU="MyOrganizationalUnit" ...



For example:


export KEY_COUNTRY="PL" export KEY_PROVINCE="Masovian" export KEY_CITY="Warsaw" export KEY_ORG="SoMLabs" export KEY_EMAIL="somlabs@somlabs.com" export KEY_OU="SoMLabs"


At this point we are ready to build our CA root. As a first, source the vars file:


root@somlabs:/etc/openvpn/rsa# source ./vars


and clean CA root environment:


root@somlabs:/etc/openvpn/rsa# ./clean-all


Let’s finally generate a certificate authority - ca.crt file (druing this process all of the values should be populated automatically from vars file - just confirm default values):


root@somlabs:/etc/openvpn/rsa# ./build-ca Generating a 2048 bit RSA private key .............................+++ ..........+++ writing new private key to 'ca.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [PL]: State or Province Name (full name) [Masovian]: Locality Name (eg, city) [Warsaw]: Organization Name (eg, company) [SoMLabs]: Organizational Unit Name (eg, section) [SoMLabs]: Common Name (eg, your name or your server's hostname) [SoMLabs CA]: Name [EasyRSA]: Email Address [somlabs@somlabs.com]:


Now generate a server key and certificate (server.crt and server.key files):


root@somlabs:/etc/openvpn/rsa# ./build-key-server server … Generating a 2048 bit RSA private key ... Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:somlabs An optional company name []: Using configuration from /etc/openvpn/rsa/openssl.cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName  :PRINTABLE:'PL' stateOrProvinceName  :PRINTABLE:'Masovian' localityName  :PRINTABLE:'Warsaw' organizationName  :PRINTABLE:'SoMLabs' organizationalUnitName:PRINTABLE:'SoMLabs' commonName  :PRINTABLE:'server' name  :PRINTABLE:'EasyRSA' emailAddress  :IA5STRING:'somlabs@somlabs.com' Certificate is to be certified until Jun 24 07:08:08 2028 GMT (3650 days) Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated


To build a Diffie-Hellman key exchange (dh2048.pem file):


root@somlabs:/etc/openvpn/rsa# ./build-dh Generating DH parameters, 2048 bit long safe prime, generator 2 This is going to take a long time


(it will take some time to generate the the files)


For additional security, user can also generate optional Hash-based Message Authentication Code - HMAC key (ta.key file):


root@somlabs:/etc/openvpn/rsa# openvpn --genkey --secret keys/ta.key


At this point we have generated all required certificates/keys for server instance (all generated files were placed within the /etc/openvpn/rsa/keys directory) - let’s move them to /etc/openvpn/server:


root@somlabs:~# cd /etc/openvpn/rsa/keys/

root@somlabs:/etc/openvpn/rsa/keys# cp ca.crt /etc/openvpn/server

root@somlabs:/etc/openvpn/rsa/keys# cp server.crt /etc/openvpn/server

root@somlabs:/etc/openvpn/rsa/keys# cp server.key /etc/openvpn/server

root@somlabs:/etc/openvpn/rsa/keys# cp dh2048.pem /etc/openvpn/server

root@somlabs:/etc/openvpn/rsa/keys# cp ta.key /etc/openvpn/server








Generating Keys and Certificates - Client


In this example we will generate key and certificate pair for one client – you can repeat below steps for each new client, but please remember to set up unique name for all new clients. Please also remember that in production environments - for security purposes – keys should be generated on client machine and signed by the CA machine (it is recommended that the CA machine be separate from the machine running OpenVPN - do not store the easy-rsa CA files on the OpenVPN server!) – in this example we will generate the signed key on the server:


root@somlabs:/etc/openvpn/rsa# ./build-key client1 Generating a 2048 bit RSA private key ... writing new private key to 'client1.key' ... Certificate is to be certified until Jun 24 07:39:23 2028 GMT (3650 days) Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated

Copy the necessary key files to client, via a secure way (such as SSH), including:


  • /etc/openvpn/easy-rsa/keys/ca.crt,
  • /etc/openvpn/easy-rsa/keys/client1.crt,
  • /etc/openvpn/easy-rsa/keys/client1.key,
  • /etc/openvpn/easy-rsa/keys/ta.key (if using tls-auth).




Configure the OpenVPN Service


The OpenVPN package comes with set of example configuration files which are an ideal starting point for a basic OpenVPN server setup with the following features:


  • uses Public Key Infrastructure for authentication,
  • creates a VPN using a virtual TUN network interface,
  • listens for client connections on UDP port 1194,
  • distributes virtual addresses to connecting clients from the 10.8.0.0/24 subnet.



To prepare such basic server setup, copy and unzip a sample OpenVPN configuration file into configuration directory:


root@somlabs:~# gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > /etc/openvpn/server/server.conf


Edit the /etc/openvpn/server/server.conf file making a minimum of the following changes:


... ca ca.crt cert server.crt key server.key dh dh2048.pem ... user nobody group nobody


As a option, you can uncomment:


push "redirect-gateway def1 bypass-dhcp"


line to redirect all traffic through our OpenVPN. For more advanced configurations, please see OpenVPN documentation [2].


To start OpenVPN server:


root@somlabs:/etc/openvpn# openvpn /etc/openvpn/server.conf ... Wed Jun 27 08:04:19 2018 TUN/TAP device tun0 opened Wed Jun 27 08:04:19 2018 TUN/TAP TX queue length set to 100 Wed Jun 27 08:04:19 2018 do_ifconfig, tt->did_ifconfig_ipv6_setup=0 Wed Jun 27 08:04:19 2018 /sbin/ip link set dev tun0 up mtu 1500 ... Wed Jun 27 08:04:19 2018 UDPv4 link remote: [AF_UNSPEC] Wed Jun 27 08:04:19 2018 GID set to nogroup Wed Jun 27 08:04:19 2018 UID set to nobody Wed Jun 27 08:04:19 2018 MULTI: multi_init called, r=256 v=256 Wed Jun 27 08:04:19 2018 IFCONFIG POOL: base=10.8.0.4 size=62, ipv6=0 Wed Jun 27 08:04:19 2018 IFCONFIG POOL LIST Wed Jun 27 08:04:19 2018 Initialization Sequence Completed


To connect to the OpenVPN server, the client requires a key and certificate that we created already:


  • /etc/openvpn/easy-rsa/keys/ca.crt,
  • /etc/openvpn/easy-rsa/keys/client1.crt,
  • /etc/openvpn/easy-rsa/keys/client1.key,
  • /etc/openvpn/easy-rsa/keys/ta.key (if using tls-auth).



Copy the above files to client device (with OpenVPN client software) and afterwards create a new file called for client.ovpn with minimal configuration (like below):


client dev tun proto udp remote <openvpn server IP> 1194 resolv-retry infinite nobind persist-key persist-tun comp-lzo verb 3 ca ca.crt cert client1.crt key client1.key


Please remember that your network infrastructure with OpenVPN server may need additional configuration – please check out your firewall, port forwarding and iptables settings in case of any troubles.


At this point you should be ready to enable traffic routing to OpenVPN server. For more info please visit:


[1] https://openvpn.net/

[2] https://openvpn.net/index.php/open-source/documentation

[3] https://help.ubuntu.com/community/OpenVPN

[4] https://wiki.archlinux.org/index.php/OpenVPN

NXP Partner ST Partner Renesas Partner